API fixes

master
Mark 2024-02-16 13:25:50 -08:00
parent 855eb0680b
commit 308e380241
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
4 changed files with 164 additions and 61 deletions

View File

@ -5,6 +5,7 @@ use galactica_system::{
};
use galactica_util::to_degrees;
use log::error;
use nalgebra::Vector2;
use rapier2d::dynamics::RigidBody;
use rhai::{Array, CustomType, Dynamic, ImmutableString, TypeBuilder};
use std::sync::Arc;
@ -89,18 +90,16 @@ impl CustomType for ShipState {
.with_fn("content_index", |s: &mut Self| {
s.get_content().display_name.clone()
})
.with_fn("thumbnail", |s: &mut Self| {
s.get_content().thumbnail.clone()
.with_fn("thumbnail", |s: &mut Self| -> ImmutableString {
s.get_content().thumbnail.index.clone().into()
})
.with_fn("landed_on", |s: &mut Self| s.landed_on())
.with_fn("get_shields", |s: &mut Self| {
.with_fn("current_shields", |s: &mut Self| {
s.get_ship().get_data().get_shields()
})
.with_fn("get_total_shields", |s: &mut Self| {
s.get_ship().get_data().get_outfits().get_total_shields()
})
.with_fn("get_total_hull", |s: &mut Self| s.get_content().hull)
.with_fn("get_hull", |s: &mut Self| {
.with_fn("total_hull", |s: &mut Self| s.get_content().hull)
.with_fn("empty_mass", |s: &mut Self| s.get_content().mass)
.with_fn("current_hull", |s: &mut Self| {
s.get_ship().get_data().get_hull()
})
.with_fn("get_size", |s: &mut Self| s.get_content().size)
@ -113,25 +112,132 @@ impl CustomType for ShipState {
let h = s.get_ship().get_data().get_faction();
let c = h.color;
Color::new(c[0], c[1], c[2], 1.0)
})
//
// Stat getters
//
.with_fn("stat_thrust", |s: &mut Self| {
s.get_ship()
.get_data()
.get_outfits()
.get_stats()
.engine_thrust
})
.with_fn("stat_steer_power", |s: &mut Self| {
s.get_ship()
.get_data()
.get_outfits()
.get_stats()
.steer_power
})
.with_fn("stat_shield_strength", |s: &mut Self| {
s.get_ship()
.get_data()
.get_outfits()
.get_stats()
.shield_strength
})
.with_fn("stat_max_shield_generation", |s: &mut Self| {
s.get_ship()
.get_data()
.get_outfits()
.get_stats()
.shield_generation
});
}
}
#[derive(Debug, Clone)]
pub struct OutfitState {
outfit: Arc<Outfit>,
outfit: Option<Arc<Outfit>>,
}
impl OutfitState {}
impl OutfitState {
pub fn new(outfit: Arc<Outfit>) -> Self {
Self {
outfit: Some(outfit),
}
}
pub fn new_none() -> Self {
Self { outfit: None }
}
}
impl CustomType for OutfitState {
fn build(mut builder: TypeBuilder<Self>) {
builder
.with_name("OutfitState")
.with_fn("display_name", |s: &mut Self| s.outfit.display_name.clone())
.with_fn("index", |s: &mut Self| s.outfit.index.to_string())
.with_fn("is_some", |s: &mut Self| s.outfit.is_some())
.with_fn("display_name", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.display_name.clone())
.unwrap_or("".to_string())
})
.with_fn("desc", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.desc.clone())
.unwrap_or("".to_string())
})
.with_fn("index", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.index.to_string())
.unwrap_or("".to_string())
})
.with_fn("thumbnail", |s: &mut Self| {
s.outfit.thumbnail.index.to_string()
s.outfit
.as_ref()
.map(|x| x.thumbnail.index.to_string())
.unwrap_or("".to_string())
})
//
// Stat getters
//
.with_fn("stat_thrust", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.stats.steer_power)
.unwrap_or(0.0)
})
.with_fn("stat_steer_power", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.stats.steer_power)
.unwrap_or(0.0)
})
.with_fn("stat_shield_strength", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.stats.shield_strength)
.unwrap_or(0.0)
})
.with_fn("stat_shield_generation", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.stats.shield_generation)
.unwrap_or(0.0)
})
.with_fn("stat_shield_delay", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| x.stats.shield_delay)
.unwrap_or(0.0)
})
.with_fn("stat_shield_dps", |s: &mut Self| {
s.outfit
.as_ref()
.map(|x| {
if x.gun.is_some() {
(1.0 / x.gun.as_ref().unwrap().rate)
* x.gun.as_ref().unwrap().projectile.damage
} else {
0.0
}
})
.unwrap_or(0.0)
});
}
}
@ -153,7 +259,7 @@ impl SystemObjectState {
.unwrap()
.outfitter
{
a.push(Dynamic::from(OutfitState { outfit: o.clone() }));
a.push(Dynamic::from(OutfitState::new(o.clone())));
}
return a;
}
@ -234,6 +340,7 @@ impl CustomType for SystemObjectState {
pub struct State {
input: Arc<RenderInput>,
window_aspect: f32,
window_size: Vector2<u32>,
}
// TODO: remove this
@ -245,6 +352,7 @@ impl State {
Self {
input: input.clone(),
window_aspect: state.window_aspect,
window_size: Vector2::new(state.window_size.width, state.window_size.height),
}
}
@ -284,6 +392,12 @@ impl CustomType for State {
.with_fn("player_ship", Self::player_ship)
.with_fn("ships", Self::ships)
.with_fn("objects", Self::objects)
.with_fn("window_aspect", |s: &mut Self| s.window_aspect);
.with_fn("window_aspect", |s: &mut Self| s.window_aspect)
.with_fn("window_size", |s: &mut Self| {
UiVector::new(
s.window_size.x as f32 / s.input.ct.config.ui_scale,
s.window_size.y as f32 / s.input.ct.config.ui_scale,
)
});
}
}

View File

@ -1,6 +1,6 @@
use std::{collections::HashMap, sync::Arc};
use galactica_content::{ContentIndex, GunPoint, Outfit, OutfitSpace};
use galactica_content::{ContentIndex, GunPoint, Outfit, OutfitSpace, OutfitStats};
/// Possible outcomes when adding an outfit
pub enum OutfitAddResult {
@ -61,12 +61,17 @@ pub struct OutfitSet {
/// if value is Some, this point is taken.
gun_points: HashMap<GunPoint, Option<Arc<Outfit>>>,
/// Outfit values
/// This isn't strictly necessary, but we don't want to
/// re-compute this on each frame.
engine_thrust: f32,
steer_power: f32,
shield_strength: f32,
/// The combined stats of all outfits in this set.
/// There are two things to note here:
/// First, shield_delay is always zero. That is handled
/// seperately, since it is different for every outfit.
/// Second, shield_generation represents the MAXIMUM POSSIBLE
/// shield generation, after all delays have expired.
///
/// Note that this field isn't strictly necessary... we could compute stats
/// by iterating over the outfits in this set. We don't want to do this every
/// frame, though, so we keep track of the total sum here.
stats: OutfitStats,
/// All shield generators in this outfit set
// These can't be summed into one value, since each has a
@ -81,10 +86,7 @@ impl OutfitSet {
total_space: available_space,
used_space: OutfitSpace::new(),
gun_points: gun_points.iter().map(|x| (x.clone(), None)).collect(),
engine_thrust: 0.0,
steer_power: 0.0,
shield_strength: 0.0,
stats: OutfitStats::zero(),
shield_generators: Vec::new(),
}
}
@ -111,13 +113,12 @@ impl OutfitSet {
self.used_space += o.space;
self.engine_thrust += o.engine_thrust;
self.steer_power += o.steer_power;
self.shield_strength += o.shield_strength;
self.stats.add(&o.stats);
self.shield_generators.push(ShieldGenerator {
outfit: o.clone(),
delay: o.shield_delay,
generation: o.shield_generation,
delay: o.stats.shield_delay,
generation: o.stats.shield_generation,
});
if self.outfits.contains_key(&o.index) {
@ -143,9 +144,7 @@ impl OutfitSet {
self.used_space -= o.space;
self.engine_thrust -= o.engine_thrust;
self.steer_power -= o.steer_power;
self.shield_strength -= o.shield_strength;
self.stats.subtract(&o.stats);
{
// This index will exist, since we checked the hashmap
@ -183,11 +182,6 @@ impl OutfitSet {
self.shield_generators.iter()
}
/// Get maximum possible shield regen
pub fn get_max_shield_regen(&self) -> f32 {
self.shield_generators.iter().map(|x| x.generation).sum()
}
/// Get the outfit attached to the given gun point
/// Will panic if this gunpoint is not in this outfit set.
pub fn get_gun(&self, point: &GunPoint) -> Option<Arc<Outfit>> {
@ -204,18 +198,13 @@ impl OutfitSet {
&self.used_space
}
/// Total foward thrust
pub fn get_engine_thrust(&self) -> f32 {
self.engine_thrust
}
/// Total steer power
pub fn get_steer_power(&self) -> f32 {
self.steer_power
}
/// Total shield strength
pub fn get_total_shields(&self) -> f32 {
self.shield_strength
/// Get the combined stats of all outfits in this set.
/// There are two things to note here:
/// First, shield_delay is always zero. That is handled
/// seperately, since it is different for every outfit.
/// Second, shield_generation represents the MAXIMUM POSSIBLE
/// shield generation, after all delays have expired.
pub fn get_stats(&self) -> &OutfitStats {
&self.stats
}
}

View File

@ -178,7 +178,7 @@ impl ShipData {
/// Add an outfit to this ship
pub fn add_outfit(&mut self, o: &Arc<Outfit>) -> super::OutfitAddResult {
let r = self.outfits.add(o);
self.shields = self.outfits.get_total_shields();
self.shields = self.outfits.get_stats().shield_strength;
return r;
}
@ -245,8 +245,8 @@ impl ShipData {
}
// Regenerate shields
if self.shields != self.outfits.get_total_shields() {
self.shields = self.outfits.get_total_shields();
if self.shields != self.outfits.get_stats().shield_strength {
self.shields = self.outfits.get_stats().shield_strength;
}
}
@ -260,12 +260,12 @@ impl ShipData {
// Regenerate shields
let time_since = self.last_hit.elapsed().as_secs_f32();
if self.shields != self.outfits.get_total_shields() {
if self.shields != self.outfits.get_stats().shield_strength {
for g in self.outfits.iter_shield_generators() {
if time_since >= g.delay {
self.shields += g.generation * t;
if self.shields > self.outfits.get_total_shields() {
self.shields = self.outfits.get_total_shields();
if self.shields > self.outfits.get_stats().shield_strength {
self.shields = self.outfits.get_stats().shield_strength;
break;
}
}

View File

@ -390,21 +390,21 @@ impl PhysShip {
if self.controls.thrust {
rigid_body.apply_impulse(
vector![engine_force.x, engine_force.y]
* self.data.get_outfits().get_engine_thrust(),
* self.data.get_outfits().get_stats().engine_thrust,
true,
);
}
if self.controls.right {
rigid_body.apply_torque_impulse(
self.data.get_outfits().get_steer_power() * -100.0 * res.t,
self.data.get_outfits().get_stats().steer_power * -100.0 * res.t,
true,
);
}
if self.controls.left {
rigid_body.apply_torque_impulse(
self.data.get_outfits().get_steer_power() * 100.0 * res.t,
self.data.get_outfits().get_stats().steer_power * 100.0 * res.t,
true,
);
}