Added step() and bar updates
parent
62b8a4f2d3
commit
e893da01bc
|
@ -25,7 +25,7 @@ fn init(state) {
|
||||||
SpriteAnchor::NorthEast
|
SpriteAnchor::NorthEast
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
shield.set_progress(0.2);
|
shield.set_progress(1.0);
|
||||||
|
|
||||||
let hull = RadialBuilder(
|
let hull = RadialBuilder(
|
||||||
"hull", 2.5,
|
"hull", 2.5,
|
||||||
|
@ -36,7 +36,7 @@ fn init(state) {
|
||||||
SpriteAnchor::NorthEast
|
SpriteAnchor::NorthEast
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
hull.set_progress(0.4);
|
hull.set_progress(1.0);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
ring,
|
ring,
|
||||||
|
@ -52,4 +52,15 @@ fn event(state, event) {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step(state, elements) {
|
||||||
|
elements["shield"].set_val(
|
||||||
|
state.player_ship().get_shields()
|
||||||
|
/ state.player_ship().get_total_shields()
|
||||||
|
);
|
||||||
|
elements["hull"].set_val(
|
||||||
|
state.player_ship().get_hull()
|
||||||
|
/ state.player_ship().get_total_hull()
|
||||||
|
);
|
||||||
}
|
}
|
|
@ -2,10 +2,11 @@ mod color;
|
||||||
mod config;
|
mod config;
|
||||||
mod event;
|
mod event;
|
||||||
mod radialbuilder;
|
mod radialbuilder;
|
||||||
|
mod radialelement;
|
||||||
mod rect;
|
mod rect;
|
||||||
mod sceneaction;
|
mod sceneaction;
|
||||||
mod sprite;
|
|
||||||
mod spritebuilder;
|
mod spritebuilder;
|
||||||
|
mod spriteelement;
|
||||||
mod state;
|
mod state;
|
||||||
mod textboxbuilder;
|
mod textboxbuilder;
|
||||||
mod util;
|
mod util;
|
||||||
|
@ -14,10 +15,11 @@ pub use color::*;
|
||||||
pub use config::*;
|
pub use config::*;
|
||||||
pub use event::*;
|
pub use event::*;
|
||||||
pub use radialbuilder::*;
|
pub use radialbuilder::*;
|
||||||
|
pub use radialelement::*;
|
||||||
pub use rect::*;
|
pub use rect::*;
|
||||||
pub use sceneaction::*;
|
pub use sceneaction::*;
|
||||||
pub use sprite::*;
|
|
||||||
pub use spritebuilder::*;
|
pub use spritebuilder::*;
|
||||||
|
pub use spriteelement::*;
|
||||||
pub use state::*;
|
pub use state::*;
|
||||||
pub use textboxbuilder::*;
|
pub use textboxbuilder::*;
|
||||||
pub use util::*;
|
pub use util::*;
|
||||||
|
@ -36,9 +38,11 @@ pub fn register_into_engine(engine: &mut Engine) {
|
||||||
.build_type::<SystemObjectState>()
|
.build_type::<SystemObjectState>()
|
||||||
// Builders
|
// Builders
|
||||||
.build_type::<RadialBuilder>()
|
.build_type::<RadialBuilder>()
|
||||||
.build_type::<SpriteElement>()
|
|
||||||
.build_type::<SpriteBuilder>()
|
.build_type::<SpriteBuilder>()
|
||||||
.build_type::<TextBoxBuilder>()
|
.build_type::<TextBoxBuilder>()
|
||||||
|
// Elements
|
||||||
|
.build_type::<SpriteElement>()
|
||||||
|
.build_type::<RadialElement>()
|
||||||
// Events
|
// Events
|
||||||
.build_type::<MouseClickEvent>()
|
.build_type::<MouseClickEvent>()
|
||||||
.build_type::<MouseHoverEvent>()
|
.build_type::<MouseHoverEvent>()
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
use galactica_content::Content;
|
||||||
|
use rhai::{CustomType, TypeBuilder};
|
||||||
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
|
use crate::ui::util::RadialBar;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct RadialElement {
|
||||||
|
pub bar: Rc<RefCell<RadialBar>>,
|
||||||
|
pub ct: Rc<Content>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: remove this
|
||||||
|
unsafe impl Send for RadialElement {}
|
||||||
|
unsafe impl Sync for RadialElement {}
|
||||||
|
|
||||||
|
impl RadialElement {
|
||||||
|
pub fn new(ct: Rc<Content>, bar: Rc<RefCell<RadialBar>>) -> Self {
|
||||||
|
Self { ct, bar }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CustomType for RadialElement {
|
||||||
|
fn build(mut builder: TypeBuilder<Self>) {
|
||||||
|
builder
|
||||||
|
.with_name("RadialElement")
|
||||||
|
.with_fn("set_val", |s: &mut Self, val: f32| {
|
||||||
|
s.bar.borrow_mut().set_val(val)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -81,7 +81,13 @@ impl CustomType for ShipState {
|
||||||
})
|
})
|
||||||
.with_fn("name", |s: &mut Self| s.get_content().name.clone())
|
.with_fn("name", |s: &mut Self| s.get_content().name.clone())
|
||||||
.with_fn("thumbnail", |s: &mut Self| s.get_content().thumb)
|
.with_fn("thumbnail", |s: &mut Self| s.get_content().thumb)
|
||||||
.with_fn("landed_on", |s: &mut Self| s.landed_on());
|
.with_fn("landed_on", |s: &mut Self| s.landed_on())
|
||||||
|
.with_fn("get_shields", |s: &mut Self| s.get_data().get_shields())
|
||||||
|
.with_fn("get_total_shields", |s: &mut Self| {
|
||||||
|
s.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| s.get_data().get_hull());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use galactica_content::Content;
|
||||||
use galactica_system::phys::PhysSimShipHandle;
|
use galactica_system::phys::PhysSimShipHandle;
|
||||||
use glyphon::TextArea;
|
use glyphon::TextArea;
|
||||||
use log::{debug, error, trace};
|
use log::{debug, error, trace};
|
||||||
use rhai::{Array, Dynamic, Engine, Scope};
|
use rhai::{Array, Dynamic, Engine, Map, Scope};
|
||||||
use std::{collections::HashSet, num::NonZeroU32, rc::Rc};
|
use std::{collections::HashSet, num::NonZeroU32, rc::Rc};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
@ -17,7 +17,7 @@ use super::{
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
ui::{
|
ui::{
|
||||||
api::{RadialBuilder, SpriteBuilder, State},
|
api::{RadialBuilder, RadialElement, SpriteBuilder, State},
|
||||||
util::Sprite,
|
util::Sprite,
|
||||||
},
|
},
|
||||||
RenderInput, RenderState,
|
RenderInput, RenderState,
|
||||||
|
@ -28,9 +28,14 @@ pub(crate) struct UiManager {
|
||||||
current_scene_config: SceneConfig,
|
current_scene_config: SceneConfig,
|
||||||
engine: Engine,
|
engine: Engine,
|
||||||
scope: Scope<'static>,
|
scope: Scope<'static>,
|
||||||
elements: Vec<UiElement>,
|
|
||||||
ct: Rc<Content>,
|
ct: Rc<Content>,
|
||||||
|
|
||||||
|
/// UI elements
|
||||||
|
elements: Vec<UiElement>,
|
||||||
|
/// Map of ui element name -> api handle.
|
||||||
|
/// Used for step() function.
|
||||||
|
element_index: Map,
|
||||||
|
|
||||||
last_player_state: u32,
|
last_player_state: u32,
|
||||||
show_timings: bool,
|
show_timings: bool,
|
||||||
fps_indicator: FpsIndicator,
|
fps_indicator: FpsIndicator,
|
||||||
|
@ -40,7 +45,7 @@ impl UiManager {
|
||||||
pub fn new(ct: Rc<Content>, state: &mut RenderState) -> Self {
|
pub fn new(ct: Rc<Content>, state: &mut RenderState) -> Self {
|
||||||
let scope = Scope::new();
|
let scope = Scope::new();
|
||||||
|
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new_raw();
|
||||||
api::register_into_engine(&mut engine);
|
api::register_into_engine(&mut engine);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
@ -50,6 +55,7 @@ impl UiManager {
|
||||||
engine,
|
engine,
|
||||||
scope,
|
scope,
|
||||||
elements: Vec::new(),
|
elements: Vec::new(),
|
||||||
|
element_index: Map::new(),
|
||||||
show_timings: true,
|
show_timings: true,
|
||||||
fps_indicator: FpsIndicator::new(state),
|
fps_indicator: FpsIndicator::new(state),
|
||||||
last_player_state: 0,
|
last_player_state: 0,
|
||||||
|
@ -177,6 +183,25 @@ impl UiManager {
|
||||||
// TODO: better message
|
// TODO: better message
|
||||||
error!("bad type in builder array")
|
error!("bad type in builder array")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.element_index.clear();
|
||||||
|
for e in &self.elements {
|
||||||
|
match e {
|
||||||
|
UiElement::Text(_) => {}
|
||||||
|
UiElement::RadialBar(r) => {
|
||||||
|
self.element_index.insert(
|
||||||
|
(&r).borrow().name.clone().into(),
|
||||||
|
Dynamic::from(RadialElement::new(self.ct.clone(), r.clone())),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
UiElement::Sprite(s) => {
|
||||||
|
self.element_index.insert(
|
||||||
|
(&s).borrow().name.clone().into(),
|
||||||
|
Dynamic::from(SpriteElement::new(self.ct.clone(), s.clone())),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -192,6 +217,27 @@ impl UiManager {
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run step() (if it is defined)
|
||||||
|
let ast = &self
|
||||||
|
.ct
|
||||||
|
.get_config()
|
||||||
|
.ui_scenes
|
||||||
|
.get(self.current_scene.as_ref().unwrap())
|
||||||
|
.unwrap();
|
||||||
|
if ast.iter_functions().any(|x| x.name == "step") {
|
||||||
|
self.engine
|
||||||
|
.call_fn(
|
||||||
|
&mut self.scope,
|
||||||
|
ast,
|
||||||
|
"step",
|
||||||
|
(State::new(input.clone()), self.element_index.clone()),
|
||||||
|
)
|
||||||
|
.with_context(|| format!("while handling player state change event"))
|
||||||
|
.with_context(|| {
|
||||||
|
format!("in ui scene `{}`", self.current_scene.as_ref().unwrap())
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
// Update timings if they're being displayed
|
// Update timings if they're being displayed
|
||||||
if self.show_timings {
|
if self.show_timings {
|
||||||
self.fps_indicator.step(&input, state);
|
self.fps_indicator.step(&input, state);
|
||||||
|
|
|
@ -27,10 +27,14 @@ impl RadialBar {
|
||||||
rect,
|
rect,
|
||||||
stroke,
|
stroke,
|
||||||
color,
|
color,
|
||||||
progress,
|
progress: progress.clamp(0.0, 1.0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_val(&mut self, val: f32) {
|
||||||
|
self.progress = val.clamp(0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn push_to_buffer(&self, input: &RenderInput, state: &mut RenderState) {
|
pub fn push_to_buffer(&self, input: &RenderInput, state: &mut RenderState) {
|
||||||
let rect = self.rect.to_centered(state, input.ct.get_config().ui_scale);
|
let rect = self.rect.to_centered(state, input.ct.get_config().ui_scale);
|
||||||
|
|
||||||
|
|
|
@ -215,7 +215,7 @@ impl OutfitSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Total shield strength
|
/// Total shield strength
|
||||||
pub fn get_shield_strength(&self) -> f32 {
|
pub fn get_total_shields(&self) -> f32 {
|
||||||
self.shield_strength
|
self.shield_strength
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,7 +179,7 @@ impl ShipData {
|
||||||
/// Add an outfit to this ship
|
/// Add an outfit to this ship
|
||||||
pub fn add_outfit(&mut self, o: &Outfit) -> super::OutfitAddResult {
|
pub fn add_outfit(&mut self, o: &Outfit) -> super::OutfitAddResult {
|
||||||
let r = self.outfits.add(o);
|
let r = self.outfits.add(o);
|
||||||
self.shields = self.outfits.get_shield_strength();
|
self.shields = self.outfits.get_total_shields();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,8 +248,8 @@ impl ShipData {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regenerate shields
|
// Regenerate shields
|
||||||
if self.shields != self.outfits.get_shield_strength() {
|
if self.shields != self.outfits.get_total_shields() {
|
||||||
self.shields = self.outfits.get_shield_strength();
|
self.shields = self.outfits.get_total_shields();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,12 +263,12 @@ impl ShipData {
|
||||||
|
|
||||||
// Regenerate shields
|
// Regenerate shields
|
||||||
let time_since = self.last_hit.elapsed().as_secs_f32();
|
let time_since = self.last_hit.elapsed().as_secs_f32();
|
||||||
if self.shields != self.outfits.get_shield_strength() {
|
if self.shields != self.outfits.get_total_shields() {
|
||||||
for g in self.outfits.iter_shield_generators() {
|
for g in self.outfits.iter_shield_generators() {
|
||||||
if time_since >= g.delay {
|
if time_since >= g.delay {
|
||||||
self.shields += g.generation * t;
|
self.shields += g.generation * t;
|
||||||
if self.shields > self.outfits.get_shield_strength() {
|
if self.shields > self.outfits.get_total_shields() {
|
||||||
self.shields = self.outfits.get_shield_strength();
|
self.shields = self.outfits.get_total_shields();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue