Added step() and bar updates
parent
62b8a4f2d3
commit
e893da01bc
|
@ -25,7 +25,7 @@ fn init(state) {
|
|||
SpriteAnchor::NorthEast
|
||||
)
|
||||
);
|
||||
shield.set_progress(0.2);
|
||||
shield.set_progress(1.0);
|
||||
|
||||
let hull = RadialBuilder(
|
||||
"hull", 2.5,
|
||||
|
@ -36,7 +36,7 @@ fn init(state) {
|
|||
SpriteAnchor::NorthEast
|
||||
)
|
||||
);
|
||||
hull.set_progress(0.4);
|
||||
hull.set_progress(1.0);
|
||||
|
||||
return [
|
||||
ring,
|
||||
|
@ -53,3 +53,14 @@ fn event(state, event) {
|
|||
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 event;
|
||||
mod radialbuilder;
|
||||
mod radialelement;
|
||||
mod rect;
|
||||
mod sceneaction;
|
||||
mod sprite;
|
||||
mod spritebuilder;
|
||||
mod spriteelement;
|
||||
mod state;
|
||||
mod textboxbuilder;
|
||||
mod util;
|
||||
|
@ -14,10 +15,11 @@ pub use color::*;
|
|||
pub use config::*;
|
||||
pub use event::*;
|
||||
pub use radialbuilder::*;
|
||||
pub use radialelement::*;
|
||||
pub use rect::*;
|
||||
pub use sceneaction::*;
|
||||
pub use sprite::*;
|
||||
pub use spritebuilder::*;
|
||||
pub use spriteelement::*;
|
||||
pub use state::*;
|
||||
pub use textboxbuilder::*;
|
||||
pub use util::*;
|
||||
|
@ -36,9 +38,11 @@ pub fn register_into_engine(engine: &mut Engine) {
|
|||
.build_type::<SystemObjectState>()
|
||||
// Builders
|
||||
.build_type::<RadialBuilder>()
|
||||
.build_type::<SpriteElement>()
|
||||
.build_type::<SpriteBuilder>()
|
||||
.build_type::<TextBoxBuilder>()
|
||||
// Elements
|
||||
.build_type::<SpriteElement>()
|
||||
.build_type::<RadialElement>()
|
||||
// Events
|
||||
.build_type::<MouseClickEvent>()
|
||||
.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("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 glyphon::TextArea;
|
||||
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 super::{
|
||||
|
@ -17,7 +17,7 @@ use super::{
|
|||
};
|
||||
use crate::{
|
||||
ui::{
|
||||
api::{RadialBuilder, SpriteBuilder, State},
|
||||
api::{RadialBuilder, RadialElement, SpriteBuilder, State},
|
||||
util::Sprite,
|
||||
},
|
||||
RenderInput, RenderState,
|
||||
|
@ -28,9 +28,14 @@ pub(crate) struct UiManager {
|
|||
current_scene_config: SceneConfig,
|
||||
engine: Engine,
|
||||
scope: Scope<'static>,
|
||||
elements: Vec<UiElement>,
|
||||
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,
|
||||
show_timings: bool,
|
||||
fps_indicator: FpsIndicator,
|
||||
|
@ -40,7 +45,7 @@ impl UiManager {
|
|||
pub fn new(ct: Rc<Content>, state: &mut RenderState) -> Self {
|
||||
let scope = Scope::new();
|
||||
|
||||
let mut engine = Engine::new();
|
||||
let mut engine = Engine::new_raw();
|
||||
api::register_into_engine(&mut engine);
|
||||
|
||||
Self {
|
||||
|
@ -50,6 +55,7 @@ impl UiManager {
|
|||
engine,
|
||||
scope,
|
||||
elements: Vec::new(),
|
||||
element_index: Map::new(),
|
||||
show_timings: true,
|
||||
fps_indicator: FpsIndicator::new(state),
|
||||
last_player_state: 0,
|
||||
|
@ -177,6 +183,25 @@ impl UiManager {
|
|||
// TODO: better message
|
||||
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(());
|
||||
}
|
||||
|
@ -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
|
||||
if self.show_timings {
|
||||
self.fps_indicator.step(&input, state);
|
||||
|
|
|
@ -27,10 +27,14 @@ impl RadialBar {
|
|||
rect,
|
||||
stroke,
|
||||
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) {
|
||||
let rect = self.rect.to_centered(state, input.ct.get_config().ui_scale);
|
||||
|
||||
|
|
|
@ -215,7 +215,7 @@ impl OutfitSet {
|
|||
}
|
||||
|
||||
/// Total shield strength
|
||||
pub fn get_shield_strength(&self) -> f32 {
|
||||
pub fn get_total_shields(&self) -> f32 {
|
||||
self.shield_strength
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,7 +179,7 @@ impl ShipData {
|
|||
/// Add an outfit to this ship
|
||||
pub fn add_outfit(&mut self, o: &Outfit) -> super::OutfitAddResult {
|
||||
let r = self.outfits.add(o);
|
||||
self.shields = self.outfits.get_shield_strength();
|
||||
self.shields = self.outfits.get_total_shields();
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -248,8 +248,8 @@ impl ShipData {
|
|||
}
|
||||
|
||||
// Regenerate shields
|
||||
if self.shields != self.outfits.get_shield_strength() {
|
||||
self.shields = self.outfits.get_shield_strength();
|
||||
if self.shields != self.outfits.get_total_shields() {
|
||||
self.shields = self.outfits.get_total_shields();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,12 +263,12 @@ impl ShipData {
|
|||
|
||||
// Regenerate shields
|
||||
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() {
|
||||
if time_since >= g.delay {
|
||||
self.shields += g.generation * t;
|
||||
if self.shields > self.outfits.get_shield_strength() {
|
||||
self.shields = self.outfits.get_shield_strength();
|
||||
if self.shields > self.outfits.get_total_shields() {
|
||||
self.shields = self.outfits.get_total_shields();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue