Compare commits
No commits in common. "39f52ddafcbdb741cf7bcf209049e1f3cb9d3ad7" and "47a73224c6650a595c24f8dfe7e2f12d3a1bdf52" have entirely different histories.
39f52ddafc
...
47a73224c6
386
Cargo.lock
generated
386
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -74,4 +74,10 @@ lazy_static = "1.4.0"
|
|||||||
clap = { version = "4.4.18", features = ["derive"] }
|
clap = { version = "4.4.18", features = ["derive"] }
|
||||||
log = "0.4.20"
|
log = "0.4.20"
|
||||||
log4rs = { version = "1.2.0", features = ["console_appender"] }
|
log4rs = { version = "1.2.0", features = ["console_appender"] }
|
||||||
rhai = { version = "1.17.1", features = ["f32_float", "no_custom_syntax"] }
|
rhai = { version = "1.17.0", features = [
|
||||||
|
"f32_float",
|
||||||
|
"only_i32",
|
||||||
|
"metadata",
|
||||||
|
"no_custom_syntax",
|
||||||
|
"no_closure",
|
||||||
|
] }
|
||||||
|
4
TODO.md
4
TODO.md
@ -1,10 +1,8 @@
|
|||||||
# Specific projects
|
# Specific projects
|
||||||
|
|
||||||
## Now:
|
## Now:
|
||||||
- Clean up API (modules)
|
|
||||||
- Persistent variables
|
|
||||||
- Better planet icons
|
|
||||||
- Clean up scripting & errors
|
- Clean up scripting & errors
|
||||||
|
- Fix radar
|
||||||
- Mouse colliders
|
- Mouse colliders
|
||||||
- UI captures input?
|
- UI captures input?
|
||||||
- No UI zoom scroll
|
- No UI zoom scroll
|
||||||
|
@ -32,46 +32,6 @@ fn init(state) {
|
|||||||
Anchor::NorthEast
|
Anchor::NorthEast
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let radar_size = 150.0;
|
|
||||||
let radar_range = 4000.0;
|
|
||||||
|
|
||||||
add_sprite(
|
|
||||||
"radar",
|
|
||||||
"ui::radar",
|
|
||||||
Rect(
|
|
||||||
5.0, -5.0,
|
|
||||||
radar_size, radar_size,
|
|
||||||
Anchor::NorthWest,
|
|
||||||
Anchor::NorthWest
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
let init_pos = Rect(
|
|
||||||
(radar_size / 2.0 + 5),
|
|
||||||
(radar_size / -2.0 - 5),
|
|
||||||
3.5, 3.5,
|
|
||||||
Anchor::Center,
|
|
||||||
Anchor::NorthWest
|
|
||||||
);
|
|
||||||
|
|
||||||
add_sprite("radar.frame.ne", "ui::radarframe", init_pos);
|
|
||||||
add_sprite("radar.frame.se", "ui::radarframe", init_pos);
|
|
||||||
add_sprite("radar.frame.sw", "ui::radarframe", init_pos);
|
|
||||||
add_sprite("radar.frame.nw", "ui::radarframe", init_pos);
|
|
||||||
sprite_set_angle("radar.frame.se", 90.0);
|
|
||||||
sprite_set_angle("radar.frame.sw", 180.0);
|
|
||||||
sprite_set_angle("radar.frame.nw", 270.0);
|
|
||||||
sprite_set_color("radar.frame.ne", Color(0.3, 0.3, 0.3, 1.0));
|
|
||||||
sprite_set_color("radar.frame.se", Color(0.3, 0.3, 0.3, 1.0));
|
|
||||||
sprite_set_color("radar.frame.sw", Color(0.3, 0.3, 0.3, 1.0));
|
|
||||||
sprite_set_color("radar.frame.nw", Color(0.3, 0.3, 0.3, 1.0));
|
|
||||||
|
|
||||||
add_sprite("radar.arrow", "ui::centerarrow", init_pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn event(state, event) {
|
fn event(state, event) {
|
||||||
@ -93,209 +53,4 @@ fn step(state) {
|
|||||||
state.player_ship().get_hull()
|
state.player_ship().get_hull()
|
||||||
/ state.player_ship().get_total_hull()
|
/ state.player_ship().get_total_hull()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// TODO: share variables with init();
|
|
||||||
let radar_size = 150.0;
|
|
||||||
let radar_range = 4000.0;
|
|
||||||
let hide_range = 0.85;
|
|
||||||
let shrink_distance = 20.0;
|
|
||||||
let p_pos = state.player_ship().get_pos();
|
|
||||||
|
|
||||||
// Radar arrow
|
|
||||||
{
|
|
||||||
let q = Vector(0.0, 0.0) - state.player_ship().get_pos();
|
|
||||||
let m = q.norm();
|
|
||||||
let angle = Vector(1.0, 0.0).clockwise_angle(q);
|
|
||||||
let position = Vector(5.0 + (radar_size / 2.0), -5.0 - (radar_size / 2.0));
|
|
||||||
let rot = Vector(0.915 * (radar_size / 2.0), 0.0);
|
|
||||||
let pos = position + rot.rotate(angle);
|
|
||||||
sprite_set_rect("radar.arrow",
|
|
||||||
Rect(
|
|
||||||
pos.x(), pos.y(),
|
|
||||||
5.0, 5.0,
|
|
||||||
Anchor::Center,
|
|
||||||
Anchor::NorthWest
|
|
||||||
)
|
|
||||||
);
|
|
||||||
sprite_set_angle("radar.arrow", angle - 90.0);
|
|
||||||
sprite_set_color(
|
|
||||||
"radar.arrow",
|
|
||||||
Color(
|
|
||||||
1.0, 1.0, 1.0,
|
|
||||||
clamp((m - 200.0) /400.0, 0.0, 1.0)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ships
|
|
||||||
{
|
|
||||||
for s in state.ships() {
|
|
||||||
let uid = s.get_uid();
|
|
||||||
let sprite_name = `radar.ship.${uid}`;
|
|
||||||
|
|
||||||
if (
|
|
||||||
!s.is_some() ||
|
|
||||||
s.is_dead() ||
|
|
||||||
s.is_landed()
|
|
||||||
){
|
|
||||||
if sprite_exists(sprite_name) {
|
|
||||||
remove_sprite(sprite_name);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let color = Color(0.2, 0.2, 0.2, 1.0);
|
|
||||||
if s.is_flying() {
|
|
||||||
color = s.get_faction_color()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let size_init = s.get_size() * (1.0 / 50.0);
|
|
||||||
let pos = s.get_pos();
|
|
||||||
let d = (pos - p_pos) / radar_range;
|
|
||||||
let m = d.norm() + (size_init / (2.0 * radar_size));
|
|
||||||
if m < hide_range {
|
|
||||||
let size = (hide_range - m) * size_init * shrink_distance;
|
|
||||||
if size > size_init {
|
|
||||||
size = size_init;
|
|
||||||
}
|
|
||||||
if size < 1.0 {
|
|
||||||
if sprite_exists(sprite_name) {
|
|
||||||
remove_sprite(sprite_name);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let pos = Vector(radar_size / 2.0 + 5.0, radar_size / -2.0 - 5.0);
|
|
||||||
pos = pos + (d * radar_size / 2.0);
|
|
||||||
|
|
||||||
if !sprite_exists(sprite_name) {
|
|
||||||
add_sprite(
|
|
||||||
sprite_name,
|
|
||||||
"ui::shipblip",
|
|
||||||
Rect(
|
|
||||||
pos.x(), pos.y(),
|
|
||||||
size, size,
|
|
||||||
Anchor::Center,
|
|
||||||
Anchor::NorthWest
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
sprite_set_rect(
|
|
||||||
sprite_name,
|
|
||||||
Rect(
|
|
||||||
pos.x(), pos.y(),
|
|
||||||
size, size,
|
|
||||||
Anchor::Center,
|
|
||||||
Anchor::NorthWest
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
sprite_set_color(sprite_name, color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// System objects
|
|
||||||
{
|
|
||||||
for o in state.objects() {
|
|
||||||
let sprite_name = `radar.object.${o.get_label()}`;
|
|
||||||
|
|
||||||
if !o.is_some() {
|
|
||||||
if sprite_exists(sprite_name) {
|
|
||||||
remove_sprite(sprite_name);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let size_init = (o.get_size() / o.get_pos_z()) / (radar_range * (1.0 / 300.0));
|
|
||||||
let pos = o.get_pos();
|
|
||||||
let d = (pos - p_pos) / radar_range;
|
|
||||||
let m = d.norm() + (size_init / (2.0 * radar_size));
|
|
||||||
if m < hide_range {
|
|
||||||
let size = (hide_range - m) * size_init * shrink_distance;
|
|
||||||
if size > size_init {
|
|
||||||
size = size_init;
|
|
||||||
}
|
|
||||||
if size < 1.0 {
|
|
||||||
// Don't draw tiny sprites, they flicker
|
|
||||||
if sprite_exists(sprite_name) {
|
|
||||||
remove_sprite(sprite_name);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let pos = (
|
|
||||||
Vector(radar_size / 2.0 + 5.0, radar_size / -2.0 - 5.0)
|
|
||||||
+ (d * radar_size / 2.0)
|
|
||||||
);
|
|
||||||
|
|
||||||
if !sprite_exists(sprite_name) {
|
|
||||||
add_sprite(
|
|
||||||
sprite_name,
|
|
||||||
"ui::planetblip",
|
|
||||||
Rect(
|
|
||||||
pos.x(), pos.y(),
|
|
||||||
size, size,
|
|
||||||
Anchor::Center,
|
|
||||||
Anchor::NorthWest
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
sprite_set_rect(
|
|
||||||
sprite_name,
|
|
||||||
Rect(
|
|
||||||
pos.x(), pos.y(),
|
|
||||||
size, size,
|
|
||||||
Anchor::Center,
|
|
||||||
Anchor::NorthWest
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Window frame
|
|
||||||
{
|
|
||||||
let dx = (((state.camera_zoom() / 2.0) * state.window_aspect()) / radar_range) * (radar_size / 2.0);
|
|
||||||
let dy = ((state.camera_zoom() / 2.0) / radar_range) * (radar_size / 2.0);
|
|
||||||
sprite_set_rect("radar.frame.ne",
|
|
||||||
Rect(
|
|
||||||
(radar_size / 2.0 + 5) - dx,
|
|
||||||
(radar_size / -2.0 - 5) + dy,
|
|
||||||
3.5, 3.5,
|
|
||||||
Anchor::Center,
|
|
||||||
Anchor::NorthWest
|
|
||||||
)
|
|
||||||
);
|
|
||||||
sprite_set_rect("radar.frame.se",
|
|
||||||
Rect(
|
|
||||||
(radar_size / 2.0 + 5) - dx,
|
|
||||||
(radar_size / -2.0 - 5) - dy,
|
|
||||||
3.5, 3.5,
|
|
||||||
Anchor::Center,
|
|
||||||
Anchor::NorthWest
|
|
||||||
)
|
|
||||||
);
|
|
||||||
sprite_set_rect("radar.frame.sw",
|
|
||||||
Rect(
|
|
||||||
(radar_size / 2.0 + 5) + dx,
|
|
||||||
(radar_size / -2.0 - 5) - dy,
|
|
||||||
3.5, 3.5,
|
|
||||||
Anchor::Center,
|
|
||||||
Anchor::NorthWest
|
|
||||||
)
|
|
||||||
);
|
|
||||||
sprite_set_rect("radar.frame.nw",
|
|
||||||
Rect(
|
|
||||||
(radar_size / 2.0 + 5) + dx,
|
|
||||||
(radar_size / -2.0 - 5) + dy,
|
|
||||||
3.5, 3.5,
|
|
||||||
Anchor::Center,
|
|
||||||
Anchor::NorthWest
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -6,7 +6,7 @@ pub(crate) mod syntax {
|
|||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use galactica_packer::SpriteAtlas;
|
use galactica_packer::SpriteAtlas;
|
||||||
use galactica_util::rhai_error_to_anyhow;
|
use galactica_util::rhai_error_to_anyhow;
|
||||||
use rhai::{Engine, OptimizationLevel};
|
use rhai::Engine;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
@ -61,9 +61,7 @@ pub(crate) mod syntax {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut engine = Engine::new_raw();
|
let engine = Engine::new();
|
||||||
engine.set_optimization_level(OptimizationLevel::Full);
|
|
||||||
engine.set_max_expr_depths(0, 0);
|
|
||||||
let mut ui_scenes = HashMap::new();
|
let mut ui_scenes = HashMap::new();
|
||||||
for (n, p) in self.ui_scene {
|
for (n, p) in self.ui_scene {
|
||||||
ui_scenes.insert(
|
ui_scenes.insert(
|
||||||
|
@ -126,12 +126,9 @@ pub struct SystemObject {
|
|||||||
/// If true, ships may land on this object
|
/// If true, ships may land on this object
|
||||||
pub landable: bool,
|
pub landable: bool,
|
||||||
|
|
||||||
/// The pretty display name of this object
|
/// The display name of this object
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
|
|
||||||
/// The system-unique label of this object
|
|
||||||
pub label: String,
|
|
||||||
|
|
||||||
/// The description of this object (shown on landed ui)
|
/// The description of this object (shown on landed ui)
|
||||||
pub desc: Option<String>,
|
pub desc: Option<String>,
|
||||||
|
|
||||||
@ -262,7 +259,6 @@ impl crate::Build for System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
objects.push(SystemObject {
|
objects.push(SystemObject {
|
||||||
label: label.clone(),
|
|
||||||
sprite: sprite_handle,
|
sprite: sprite_handle,
|
||||||
image: image_handle,
|
image: image_handle,
|
||||||
pos: resolve_position(&system.object, &obj, cycle_detector)
|
pos: resolve_position(&system.object, &obj, cycle_detector)
|
||||||
|
@ -33,4 +33,3 @@ bytemuck = { workspace = true }
|
|||||||
glyphon = { workspace = true }
|
glyphon = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
rhai = { workspace = true }
|
rhai = { workspace = true }
|
||||||
rapier2d = { workspace = true }
|
|
||||||
|
@ -3,7 +3,7 @@ use rhai::{CustomType, TypeBuilder};
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Color {
|
pub struct Color {
|
||||||
val: Vector4<f32>,
|
pub val: Vector4<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Color {
|
impl Color {
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
use rhai::{CustomType, TypeBuilder};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct SceneConfig {
|
|
||||||
pub show_phys: bool,
|
|
||||||
pub show_starfield: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SceneConfig {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
show_phys: false,
|
|
||||||
show_starfield: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CustomType for SceneConfig {
|
|
||||||
fn build(mut builder: TypeBuilder<Self>) {
|
|
||||||
builder
|
|
||||||
.with_name("SceneConfig")
|
|
||||||
.with_fn("SceneConfig", Self::new)
|
|
||||||
.with_fn("show_phys", |s: &mut Self, x: bool| s.show_phys = x)
|
|
||||||
.with_fn("show_starfield", |s: &mut Self, x: bool| {
|
|
||||||
s.show_starfield = x
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,14 +3,12 @@ mod color;
|
|||||||
mod event;
|
mod event;
|
||||||
mod rect;
|
mod rect;
|
||||||
mod state;
|
mod state;
|
||||||
mod vector;
|
|
||||||
|
|
||||||
pub use anchor::*;
|
pub use anchor::*;
|
||||||
pub use color::*;
|
pub use color::*;
|
||||||
pub use event::*;
|
pub use event::*;
|
||||||
pub use rect::*;
|
pub use rect::*;
|
||||||
pub use state::*;
|
pub use state::*;
|
||||||
pub use vector::*;
|
|
||||||
|
|
||||||
use rhai::{exported_module, Engine};
|
use rhai::{exported_module, Engine};
|
||||||
|
|
||||||
@ -19,7 +17,6 @@ pub fn register_into_engine(engine: &mut Engine) {
|
|||||||
// Helpers
|
// Helpers
|
||||||
.build_type::<Rect>()
|
.build_type::<Rect>()
|
||||||
.build_type::<Color>()
|
.build_type::<Color>()
|
||||||
.build_type::<UiVector>()
|
|
||||||
// State
|
// State
|
||||||
.build_type::<State>()
|
.build_type::<State>()
|
||||||
.build_type::<ShipState>()
|
.build_type::<ShipState>()
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
use galactica_content::{Ship, SystemObject, SystemObjectHandle};
|
use galactica_content::{Ship, SystemObject, SystemObjectHandle};
|
||||||
use galactica_system::{
|
use galactica_system::{
|
||||||
data::{self},
|
data::{self, ShipData},
|
||||||
phys::{objects::PhysShip, PhysSimShipHandle},
|
phys::PhysSimShipHandle,
|
||||||
};
|
};
|
||||||
use galactica_util::to_degrees;
|
|
||||||
use log::error;
|
use log::error;
|
||||||
use rapier2d::dynamics::RigidBody;
|
use rhai::{CustomType, TypeBuilder};
|
||||||
use rhai::{Array, CustomType, Dynamic, ImmutableString, TypeBuilder};
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use super::{Color, UiVector};
|
use crate::RenderInput;
|
||||||
use crate::{RenderInput, RenderState};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ShipState {
|
pub struct ShipState {
|
||||||
@ -18,6 +15,10 @@ pub struct ShipState {
|
|||||||
input: Arc<RenderInput>,
|
input: Arc<RenderInput>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove this
|
||||||
|
unsafe impl Send for ShipState {}
|
||||||
|
unsafe impl Sync for ShipState {}
|
||||||
|
|
||||||
impl ShipState {
|
impl ShipState {
|
||||||
fn get_content(&mut self) -> &Ship {
|
fn get_content(&mut self) -> &Ship {
|
||||||
let ship = self
|
let ship = self
|
||||||
@ -29,27 +30,18 @@ impl ShipState {
|
|||||||
self.input.ct.get_ship(handle)
|
self.input.ct.get_ship(handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_ship(&mut self) -> &PhysShip {
|
fn get_data(&mut self) -> &ShipData {
|
||||||
let ship = self
|
let ship = self
|
||||||
.input
|
.input
|
||||||
.phys_img
|
.phys_img
|
||||||
.get_ship(self.ship.as_ref().unwrap())
|
.get_ship(self.ship.as_ref().unwrap())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
&ship.ship
|
ship.ship.get_data()
|
||||||
}
|
|
||||||
|
|
||||||
fn get_body(&mut self) -> &RigidBody {
|
|
||||||
let ship = self
|
|
||||||
.input
|
|
||||||
.phys_img
|
|
||||||
.get_ship(self.ship.as_ref().unwrap())
|
|
||||||
.unwrap();
|
|
||||||
&ship.rigidbody
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn landed_on(&mut self) -> SystemObjectState {
|
fn landed_on(&mut self) -> SystemObjectState {
|
||||||
let input = self.input.clone();
|
let input = self.input.clone();
|
||||||
match self.get_ship().get_data().get_state() {
|
match self.get_data().get_state() {
|
||||||
data::ShipState::Landed { target } => {
|
data::ShipState::Landed { target } => {
|
||||||
return SystemObjectState {
|
return SystemObjectState {
|
||||||
input,
|
input,
|
||||||
@ -71,48 +63,31 @@ impl CustomType for ShipState {
|
|||||||
builder
|
builder
|
||||||
.with_name("ShipState")
|
.with_name("ShipState")
|
||||||
.with_fn("is_some", |s: &mut Self| s.ship.is_some())
|
.with_fn("is_some", |s: &mut Self| s.ship.is_some())
|
||||||
.with_fn("is_dead", |s: &mut Self| {
|
.with_fn("is_dead", |s: &mut Self| s.get_data().get_state().is_dead())
|
||||||
s.get_ship().get_data().get_state().is_dead()
|
|
||||||
})
|
|
||||||
.with_fn("is_landed", |s: &mut Self| {
|
.with_fn("is_landed", |s: &mut Self| {
|
||||||
s.get_ship().get_data().get_state().is_landed()
|
s.get_data().get_state().is_landed()
|
||||||
})
|
})
|
||||||
.with_fn("is_landing", |s: &mut Self| {
|
.with_fn("is_landing", |s: &mut Self| {
|
||||||
s.get_ship().get_data().get_state().is_landing()
|
s.get_data().get_state().is_landing()
|
||||||
})
|
})
|
||||||
.with_fn("is_flying", |s: &mut Self| {
|
.with_fn("is_flying", |s: &mut Self| {
|
||||||
s.get_ship().get_data().get_state().is_flying()
|
s.get_data().get_state().is_flying()
|
||||||
})
|
})
|
||||||
.with_fn("is_unlanding", |s: &mut Self| {
|
.with_fn("is_unlanding", |s: &mut Self| {
|
||||||
s.get_ship().get_data().get_state().is_unlanding()
|
s.get_data().get_state().is_unlanding()
|
||||||
})
|
})
|
||||||
.with_fn("is_collapsing", |s: &mut Self| {
|
.with_fn("is_collapsing", |s: &mut Self| {
|
||||||
s.get_ship().get_data().get_state().is_collapsing()
|
s.get_data().get_state().is_collapsing()
|
||||||
})
|
})
|
||||||
.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| {
|
.with_fn("get_shields", |s: &mut Self| s.get_data().get_shields())
|
||||||
s.get_ship().get_data().get_shields()
|
|
||||||
})
|
|
||||||
.with_fn("get_total_shields", |s: &mut Self| {
|
.with_fn("get_total_shields", |s: &mut Self| {
|
||||||
s.get_ship().get_data().get_outfits().get_total_shields()
|
s.get_data().get_outfits().get_total_shields()
|
||||||
})
|
})
|
||||||
.with_fn("get_total_hull", |s: &mut Self| s.get_content().hull)
|
.with_fn("get_total_hull", |s: &mut Self| s.get_content().hull)
|
||||||
.with_fn("get_hull", |s: &mut Self| {
|
.with_fn("get_hull", |s: &mut Self| s.get_data().get_hull());
|
||||||
s.get_ship().get_data().get_hull()
|
|
||||||
})
|
|
||||||
.with_fn("get_size", |s: &mut Self| s.get_content().size)
|
|
||||||
.with_fn("get_uid", |s: &mut Self| format!("{}", s.get_ship().uid))
|
|
||||||
.with_fn("get_pos", |s: &mut Self| {
|
|
||||||
let t = s.get_body().translation();
|
|
||||||
UiVector::new(t.x, t.y)
|
|
||||||
})
|
|
||||||
.with_fn("get_faction_color", |s: &mut Self| {
|
|
||||||
let h = s.get_ship().get_data().get_faction();
|
|
||||||
let c = s.input.ct.get_faction(h).color;
|
|
||||||
Color::new(c[0], c[1], c[2], 1.0)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,6 +97,10 @@ pub struct SystemObjectState {
|
|||||||
input: Arc<RenderInput>,
|
input: Arc<RenderInput>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove this
|
||||||
|
unsafe impl Send for SystemObjectState {}
|
||||||
|
unsafe impl Sync for SystemObjectState {}
|
||||||
|
|
||||||
impl SystemObjectState {
|
impl SystemObjectState {
|
||||||
fn get_content(&mut self) -> &SystemObject {
|
fn get_content(&mut self) -> &SystemObject {
|
||||||
self.input.ct.get_system_object(self.object.unwrap())
|
self.input.ct.get_system_object(self.object.unwrap())
|
||||||
@ -167,30 +146,13 @@ impl CustomType for SystemObjectState {
|
|||||||
"".to_string()
|
"".to_string()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.with_fn("is_some", |s: &mut Self| s.object.is_some())
|
.with_fn("is_some", |s: &mut Self| s.object.is_some());
|
||||||
.with_fn("==", |a: &mut Self, b: Self| a.object == b.object)
|
|
||||||
.with_fn("get_size", |s: &mut Self| s.get_content().size)
|
|
||||||
.with_fn("get_label", |s: &mut Self| {
|
|
||||||
ImmutableString::from(&s.get_content().label)
|
|
||||||
})
|
|
||||||
.with_fn("get_angle", |s: &mut Self| {
|
|
||||||
to_degrees(s.get_content().angle)
|
|
||||||
})
|
|
||||||
.with_fn("get_pos", |s: &mut Self| {
|
|
||||||
let t = s.get_content().pos;
|
|
||||||
UiVector::new(t.x, t.y)
|
|
||||||
})
|
|
||||||
.with_fn("get_pos_z", |s: &mut Self| {
|
|
||||||
let t = s.get_content().pos;
|
|
||||||
t.z
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct State {
|
pub struct State {
|
||||||
input: Arc<RenderInput>,
|
input: Arc<RenderInput>,
|
||||||
window_aspect: f32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove this
|
// TODO: remove this
|
||||||
@ -198,11 +160,8 @@ unsafe impl Send for State {}
|
|||||||
unsafe impl Sync for State {}
|
unsafe impl Sync for State {}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
pub fn new(state: &RenderState, input: Arc<RenderInput>) -> Self {
|
pub fn new(input: Arc<RenderInput>) -> Self {
|
||||||
Self {
|
Self { input }
|
||||||
input,
|
|
||||||
window_aspect: state.window_aspect,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn player_ship(&mut self) -> ShipState {
|
pub fn player_ship(&mut self) -> ShipState {
|
||||||
@ -211,39 +170,12 @@ impl State {
|
|||||||
ship: self.input.player.ship.map(|x| PhysSimShipHandle(x)),
|
ship: self.input.player.ship.map(|x| PhysSimShipHandle(x)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ships(&mut self) -> Array {
|
|
||||||
let mut a = Array::new();
|
|
||||||
for s in self.input.phys_img.iter_ships() {
|
|
||||||
a.push(Dynamic::from(ShipState {
|
|
||||||
input: self.input.clone(),
|
|
||||||
ship: Some(PhysSimShipHandle(s.ship.collider)),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn objects(&mut self) -> Array {
|
|
||||||
let mut a = Array::new();
|
|
||||||
let s = self.input.current_system;
|
|
||||||
for o in &self.input.ct.get_system(s).objects {
|
|
||||||
a.push(Dynamic::from(SystemObjectState {
|
|
||||||
input: self.input.clone(),
|
|
||||||
object: Some(o.handle),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CustomType for State {
|
impl CustomType for State {
|
||||||
fn build(mut builder: TypeBuilder<Self>) {
|
fn build(mut builder: TypeBuilder<Self>) {
|
||||||
builder
|
builder
|
||||||
.with_name("State")
|
.with_name("State")
|
||||||
.with_fn("player_ship", Self::player_ship)
|
.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("camera_zoom", |s: &mut Self| s.input.camera_zoom);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
use galactica_util::{clockwise_angle, to_degrees, to_radians};
|
|
||||||
use nalgebra::{Rotation2, Vector2};
|
|
||||||
use rhai::{CustomType, TypeBuilder};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct UiVector {
|
|
||||||
val: Vector2<f32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl UiVector {
|
|
||||||
pub fn new(x: f32, y: f32) -> Self {
|
|
||||||
Self {
|
|
||||||
val: Vector2::new(x, y),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rotate(&mut self, angle: f32) -> Self {
|
|
||||||
return UiVector {
|
|
||||||
val: Rotation2::new(to_radians(angle)) * self.val,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clockwise_angle(&mut self, other: UiVector) -> f32 {
|
|
||||||
return to_degrees(clockwise_angle(&self.val, &other.val));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CustomType for UiVector {
|
|
||||||
fn build(mut builder: TypeBuilder<Self>) {
|
|
||||||
builder
|
|
||||||
.with_name("Vector")
|
|
||||||
.with_fn("Vector", Self::new)
|
|
||||||
.with_fn("rotate", Self::rotate)
|
|
||||||
.with_fn("clockwise_angle", Self::clockwise_angle)
|
|
||||||
.with_fn("+", |a: UiVector, b: UiVector| UiVector {
|
|
||||||
val: a.val + b.val,
|
|
||||||
})
|
|
||||||
.with_fn("-", |a: UiVector, b: UiVector| UiVector {
|
|
||||||
val: a.val - b.val,
|
|
||||||
})
|
|
||||||
.with_fn("/", |s: &mut Self, x: f32| UiVector { val: s.val / x })
|
|
||||||
.with_fn("*", |s: &mut Self, x: f32| UiVector { val: s.val * x })
|
|
||||||
.with_fn("x", |s: &mut Self| s.val.x)
|
|
||||||
.with_fn("y", |s: &mut Self| s.val.y)
|
|
||||||
.with_fn("norm", |s: &mut Self| s.val.magnitude());
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,10 +4,7 @@ use galactica_system::phys::PhysSimShipHandle;
|
|||||||
use galactica_util::rhai_error_to_anyhow;
|
use galactica_util::rhai_error_to_anyhow;
|
||||||
use glyphon::{cosmic_text::Align, FamilyOwned, FontSystem, Style, Weight};
|
use glyphon::{cosmic_text::Align, FamilyOwned, FontSystem, Style, Weight};
|
||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use rhai::{
|
use rhai::{Dynamic, Engine, ImmutableString, Scope};
|
||||||
packages::{BasicArrayPackage, BasicStringPackage, LogicPackage, MoreStringPackage, Package},
|
|
||||||
Dynamic, Engine, ImmutableString, Scope,
|
|
||||||
};
|
|
||||||
use std::{cell::RefCell, num::NonZeroU32, rc::Rc, sync::Arc};
|
use std::{cell::RefCell, num::NonZeroU32, rc::Rc, sync::Arc};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -34,18 +31,6 @@ impl UiScriptExecutor {
|
|||||||
let elements = Rc::new(RefCell::new(UiState::new(ct.clone(), state)));
|
let elements = Rc::new(RefCell::new(UiState::new(ct.clone(), state)));
|
||||||
|
|
||||||
let mut engine = Engine::new_raw();
|
let mut engine = Engine::new_raw();
|
||||||
|
|
||||||
// Required for array iteration
|
|
||||||
// We may need to add more packages here later.
|
|
||||||
engine.register_global_module(BasicArrayPackage::new().as_shared_module());
|
|
||||||
engine.register_global_module(LogicPackage::new().as_shared_module());
|
|
||||||
engine.register_global_module(BasicStringPackage::new().as_shared_module());
|
|
||||||
engine.register_global_module(MoreStringPackage::new().as_shared_module());
|
|
||||||
|
|
||||||
engine.set_max_expr_depths(0, 0);
|
|
||||||
// Enables custom operators
|
|
||||||
engine.set_fast_operators(false);
|
|
||||||
|
|
||||||
api::register_into_engine(&mut engine);
|
api::register_into_engine(&mut engine);
|
||||||
Self::register_api(
|
Self::register_api(
|
||||||
ct.clone(),
|
ct.clone(),
|
||||||
@ -68,7 +53,7 @@ impl UiScriptExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Change the current scene
|
/// Change the current scene
|
||||||
pub fn set_scene(&mut self, state: &RenderState, input: Arc<RenderInput>) -> Result<()> {
|
pub fn set_scene(&mut self, input: Arc<RenderInput>) -> Result<()> {
|
||||||
let current_scene = (*self.state).borrow().get_scene().clone();
|
let current_scene = (*self.state).borrow().get_scene().clone();
|
||||||
if self.last_scene == current_scene {
|
if self.last_scene == current_scene {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -100,7 +85,7 @@ impl UiScriptExecutor {
|
|||||||
.get(current_scene.as_ref().unwrap().as_str())
|
.get(current_scene.as_ref().unwrap().as_str())
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
"init",
|
"init",
|
||||||
(State::new(state, input.clone()),),
|
(State::new(input.clone()),),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.with_context(|| format!("while running `init()`"))
|
.with_context(|| format!("while running `init()`"))
|
||||||
@ -119,7 +104,7 @@ impl UiScriptExecutor {
|
|||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.set_scene(ImmutableString::from(&ct.get_config().start_ui_scene));
|
.set_scene(ImmutableString::from(&ct.get_config().start_ui_scene));
|
||||||
}
|
}
|
||||||
self.set_scene(state, input.clone())?;
|
self.set_scene(input.clone())?;
|
||||||
let current_scene = (*self.state).borrow().get_scene().clone();
|
let current_scene = (*self.state).borrow().get_scene().clone();
|
||||||
|
|
||||||
(*self.state).borrow_mut().step(state, input.clone());
|
(*self.state).borrow_mut().step(state, input.clone());
|
||||||
@ -136,7 +121,7 @@ impl UiScriptExecutor {
|
|||||||
&mut self.scope,
|
&mut self.scope,
|
||||||
ast,
|
ast,
|
||||||
"step",
|
"step",
|
||||||
(State::new(state, input.clone()),),
|
(State::new(input.clone()),),
|
||||||
))
|
))
|
||||||
.with_context(|| format!("while calling `step()`"))
|
.with_context(|| format!("while calling `step()`"))
|
||||||
.with_context(|| format!("in ui scene `{}`", current_scene.as_ref().unwrap()))?;
|
.with_context(|| format!("in ui scene `{}`", current_scene.as_ref().unwrap()))?;
|
||||||
@ -169,7 +154,7 @@ impl UiScriptExecutor {
|
|||||||
.get(current_scene.as_ref().unwrap().as_str())
|
.get(current_scene.as_ref().unwrap().as_str())
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
"event",
|
"event",
|
||||||
(State::new(state, input.clone()), PlayerShipStateEvent {}),
|
(State::new(input.clone()), PlayerShipStateEvent {}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.with_context(|| format!("while handling player state change event"))
|
.with_context(|| format!("while handling player state change event"))
|
||||||
@ -229,7 +214,7 @@ impl UiScriptExecutor {
|
|||||||
.get(current_scene.as_ref().unwrap().as_str())
|
.get(current_scene.as_ref().unwrap().as_str())
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
"event",
|
"event",
|
||||||
(State::new(state, input.clone()), event_arg.clone()),
|
(State::new(input.clone()), event_arg.clone()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.with_context(|| format!("while handling event `{:?}`", event_arg))
|
.with_context(|| format!("while handling event `{:?}`", event_arg))
|
||||||
@ -237,7 +222,6 @@ impl UiScriptExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.scope.rewind(0);
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -269,12 +253,6 @@ impl UiScriptExecutor {
|
|||||||
let mut ui_state = c.borrow_mut();
|
let mut ui_state = c.borrow_mut();
|
||||||
ui_state.config.show_starfield = b;
|
ui_state.config.show_starfield = b;
|
||||||
});
|
});
|
||||||
|
|
||||||
engine.register_fn("print", move |d: Dynamic| {
|
|
||||||
debug!("{:?}", d);
|
|
||||||
});
|
|
||||||
|
|
||||||
engine.register_fn("clamp", move |x: f32, l: f32, h: f32| x.clamp(l, h));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sprites
|
// Sprites
|
||||||
@ -285,6 +263,7 @@ impl UiScriptExecutor {
|
|||||||
"add_sprite",
|
"add_sprite",
|
||||||
move |name: ImmutableString, sprite: ImmutableString, rect: Rect| {
|
move |name: ImmutableString, sprite: ImmutableString, rect: Rect| {
|
||||||
let mut ui_state = c.borrow_mut();
|
let mut ui_state = c.borrow_mut();
|
||||||
|
let len = ui_state.len();
|
||||||
|
|
||||||
let sprite_handle = ct.get_sprite_handle(sprite.as_str());
|
let sprite_handle = ct.get_sprite_handle(sprite.as_str());
|
||||||
if sprite_handle.is_none() {
|
if sprite_handle.is_none() {
|
||||||
@ -292,35 +271,16 @@ impl UiScriptExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ui_state.elements.contains_key(&name) {
|
ui_state.names.insert(name.clone(), len);
|
||||||
error!("tried to make a sprite using an existing name `{name}`");
|
ui_state.elements.push(UiElement::Sprite(Sprite::new(
|
||||||
return;
|
&ct,
|
||||||
}
|
|
||||||
|
|
||||||
ui_state.names.push(name.clone());
|
|
||||||
ui_state.elements.insert(
|
|
||||||
name.clone(),
|
name.clone(),
|
||||||
UiElement::Sprite(Sprite::new(
|
sprite_handle.unwrap(),
|
||||||
&ct,
|
rect,
|
||||||
name.clone(),
|
)));
|
||||||
sprite_handle.unwrap(),
|
|
||||||
rect,
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let c = s.clone();
|
|
||||||
engine.register_fn("remove_sprite", move |name: ImmutableString| {
|
|
||||||
let mut ui_state = c.borrow_mut();
|
|
||||||
if ui_state.elements.contains_key(&name) {
|
|
||||||
ui_state.elements.remove(&name).unwrap();
|
|
||||||
ui_state.names.retain(|x| *x != name);
|
|
||||||
} else {
|
|
||||||
error!("called `remove_sprite` on an invalid name `{name}`")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let c = s.clone();
|
let c = s.clone();
|
||||||
let ct = ct_src.clone();
|
let ct = ct_src.clone();
|
||||||
engine.register_fn(
|
engine.register_fn(
|
||||||
@ -339,7 +299,7 @@ impl UiScriptExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
error!("called `sprite_set_mask` on an invalid name `{name}`")
|
error!("called `set_sprite_mask` on an invalid name `{name}`")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -379,51 +339,6 @@ impl UiScriptExecutor {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let c = s.clone();
|
|
||||||
engine.register_fn("sprite_set_angle", move |name: ImmutableString, x: f32| {
|
|
||||||
let mut ui_state = c.borrow_mut();
|
|
||||||
match ui_state.get_mut_by_name(&name) {
|
|
||||||
Some(UiElement::Sprite(s)) => s.set_angle(x),
|
|
||||||
_ => {
|
|
||||||
error!("called `sprite_set_angle` on an invalid name `{name}`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let c = s.clone();
|
|
||||||
engine.register_fn("sprite_set_rect", move |name: ImmutableString, x: Rect| {
|
|
||||||
let mut ui_state = c.borrow_mut();
|
|
||||||
match ui_state.get_mut_by_name(&name) {
|
|
||||||
Some(UiElement::Sprite(s)) => s.set_rect(x),
|
|
||||||
_ => {
|
|
||||||
error!("called `sprite_set_rect` on an invalid name `{name}`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let c = s.clone();
|
|
||||||
engine.register_fn(
|
|
||||||
"sprite_set_color",
|
|
||||||
move |name: ImmutableString, x: Color| {
|
|
||||||
let mut ui_state = c.borrow_mut();
|
|
||||||
match ui_state.get_mut_by_name(&name) {
|
|
||||||
Some(UiElement::Sprite(s)) => s.set_color(x),
|
|
||||||
_ => {
|
|
||||||
error!("called `sprite_set_color` on an invalid name `{name}`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let c = s.clone();
|
|
||||||
engine.register_fn("sprite_exists", move |name: ImmutableString| {
|
|
||||||
let mut ui_state = c.borrow_mut();
|
|
||||||
match ui_state.get_mut_by_name(&name) {
|
|
||||||
Some(UiElement::Sprite(_)) => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Textboxes
|
// Textboxes
|
||||||
@ -439,24 +354,17 @@ impl UiScriptExecutor {
|
|||||||
rect: Rect,
|
rect: Rect,
|
||||||
color: Color| {
|
color: Color| {
|
||||||
let mut ui_state = c.borrow_mut();
|
let mut ui_state = c.borrow_mut();
|
||||||
|
let len = ui_state.len();
|
||||||
|
|
||||||
if ui_state.elements.contains_key(&name) {
|
ui_state.names.insert(name.clone(), len);
|
||||||
error!("tried to make a textbox using an existing name `{name}`");
|
ui_state.elements.push(UiElement::Text(TextBox::new(
|
||||||
return;
|
&mut font.borrow_mut(),
|
||||||
}
|
|
||||||
|
|
||||||
ui_state.names.push(name.clone());
|
|
||||||
ui_state.elements.insert(
|
|
||||||
name.clone(),
|
name.clone(),
|
||||||
UiElement::Text(TextBox::new(
|
font_size,
|
||||||
&mut font.borrow_mut(),
|
line_height,
|
||||||
name.clone(),
|
rect,
|
||||||
font_size,
|
color,
|
||||||
line_height,
|
)));
|
||||||
rect,
|
|
||||||
color,
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -628,23 +536,16 @@ impl UiScriptExecutor {
|
|||||||
// TODO: fix ugly spaces
|
// TODO: fix ugly spaces
|
||||||
move |name: ImmutableString, stroke: f32, color: Color, rect: Rect| {
|
move |name: ImmutableString, stroke: f32, color: Color, rect: Rect| {
|
||||||
let mut ui_state = c.borrow_mut();
|
let mut ui_state = c.borrow_mut();
|
||||||
|
let len = ui_state.len();
|
||||||
|
|
||||||
if ui_state.elements.contains_key(&name) {
|
ui_state.names.insert(name.clone(), len);
|
||||||
error!("tried to make a radialbar using an existing name `{name}`");
|
ui_state.elements.push(UiElement::RadialBar(RadialBar::new(
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ui_state.names.push(name.clone());
|
|
||||||
ui_state.elements.insert(
|
|
||||||
name.clone(),
|
name.clone(),
|
||||||
UiElement::RadialBar(RadialBar::new(
|
stroke,
|
||||||
name.clone(),
|
color,
|
||||||
stroke,
|
rect,
|
||||||
color,
|
1.0,
|
||||||
rect,
|
)));
|
||||||
1.0,
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@ pub(crate) struct UiConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct UiState {
|
pub(crate) struct UiState {
|
||||||
pub elements: HashMap<ImmutableString, UiElement>,
|
pub names: HashMap<ImmutableString, usize>,
|
||||||
pub names: Vec<ImmutableString>,
|
pub elements: Vec<UiElement>,
|
||||||
|
|
||||||
pub ct: Arc<Content>,
|
pub ct: Arc<Content>,
|
||||||
current_scene: Option<ImmutableString>,
|
current_scene: Option<ImmutableString>,
|
||||||
@ -42,8 +42,8 @@ impl UiState {
|
|||||||
pub fn new(ct: Arc<Content>, state: &mut RenderState) -> Self {
|
pub fn new(ct: Arc<Content>, state: &mut RenderState) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ct,
|
ct,
|
||||||
elements: HashMap::new(),
|
names: HashMap::new(),
|
||||||
names: Vec::new(),
|
elements: Vec::new(),
|
||||||
|
|
||||||
current_scene: None,
|
current_scene: None,
|
||||||
show_timings: true,
|
show_timings: true,
|
||||||
@ -79,15 +79,15 @@ impl UiState {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
pub fn get_mut_by_idx(&mut self, idx: usize) -> Option<&mut UiElement> {
|
pub fn get_mut_by_idx(&mut self, idx: usize) -> Option<&mut UiElement> {
|
||||||
let name = self.names.get(idx);
|
self.elements.get_mut(idx)
|
||||||
if name.is_none() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
self.elements.get_mut(name.unwrap())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut_by_name(&mut self, name: &ImmutableString) -> Option<&mut UiElement> {
|
pub fn get_mut_by_name(&mut self, name: &ImmutableString) -> Option<&mut UiElement> {
|
||||||
self.elements.get_mut(name)
|
let idx = self.names.get(name);
|
||||||
|
if idx.is_none() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
self.get_mut_by_idx(*idx.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_scene(&self) -> &Option<ImmutableString> {
|
pub fn get_scene(&self) -> &Option<ImmutableString> {
|
||||||
@ -124,7 +124,7 @@ impl<'a> UiState {
|
|||||||
v.push(self.fps_indicator.get_textarea(input, window))
|
v.push(self.fps_indicator.get_textarea(input, window))
|
||||||
}
|
}
|
||||||
|
|
||||||
for t in self.elements.values() {
|
for t in self.elements.iter() {
|
||||||
match &t {
|
match &t {
|
||||||
UiElement::Text(x) => v.push(x.get_textarea(input, window)),
|
UiElement::Text(x) => v.push(x.get_textarea(input, window)),
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
use super::super::api::Rect;
|
use super::super::api::Rect;
|
||||||
use crate::{
|
use crate::{ui::event::Event, vertexbuffer::types::UiInstance, RenderInput, RenderState};
|
||||||
ui::{api::Color, event::Event},
|
|
||||||
vertexbuffer::types::UiInstance,
|
|
||||||
RenderInput, RenderState,
|
|
||||||
};
|
|
||||||
use galactica_content::{Content, SpriteAutomaton, SpriteHandle};
|
use galactica_content::{Content, SpriteAutomaton, SpriteHandle};
|
||||||
use galactica_util::to_radians;
|
use galactica_util::to_radians;
|
||||||
use rhai::ImmutableString;
|
use rhai::ImmutableString;
|
||||||
@ -13,12 +9,8 @@ pub struct Sprite {
|
|||||||
pub anim: SpriteAutomaton,
|
pub anim: SpriteAutomaton,
|
||||||
pub name: ImmutableString,
|
pub name: ImmutableString,
|
||||||
|
|
||||||
/// Sprite angle, in degrees
|
|
||||||
angle: f32,
|
|
||||||
|
|
||||||
rect: Rect,
|
rect: Rect,
|
||||||
mask: Option<SpriteHandle>,
|
mask: Option<SpriteHandle>,
|
||||||
color: Color,
|
|
||||||
|
|
||||||
/// If true, ignore mouse events until click is released
|
/// If true, ignore mouse events until click is released
|
||||||
waiting_for_release: bool,
|
waiting_for_release: bool,
|
||||||
@ -32,8 +24,6 @@ impl Sprite {
|
|||||||
name,
|
name,
|
||||||
anim: SpriteAutomaton::new(&ct, sprite),
|
anim: SpriteAutomaton::new(&ct, sprite),
|
||||||
rect,
|
rect,
|
||||||
angle: 0.0,
|
|
||||||
color: Color::new(1.0, 1.0, 1.0, 1.0),
|
|
||||||
mask: None,
|
mask: None,
|
||||||
has_mouse: false,
|
has_mouse: false,
|
||||||
has_click: false,
|
has_click: false,
|
||||||
@ -45,18 +35,6 @@ impl Sprite {
|
|||||||
self.mask = mask;
|
self.mask = mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_angle(&mut self, angle: f32) {
|
|
||||||
self.angle = angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_rect(&mut self, rect: Rect) {
|
|
||||||
self.rect = rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_color(&mut self, color: Color) {
|
|
||||||
self.color = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
let rect = self
|
||||||
.rect
|
.rect
|
||||||
@ -68,9 +46,9 @@ impl Sprite {
|
|||||||
|
|
||||||
state.push_ui_buffer(UiInstance {
|
state.push_ui_buffer(UiInstance {
|
||||||
position: rect.pos.into(),
|
position: rect.pos.into(),
|
||||||
angle: to_radians(90.0 + self.angle),
|
angle: to_radians(90.0),
|
||||||
dim: rect.dim.into(),
|
dim: rect.dim.into(),
|
||||||
color: self.color.as_array(),
|
color: [1.0, 1.0, 1.0, 1.0],
|
||||||
texture_index: anim_state.texture_index(),
|
texture_index: anim_state.texture_index(),
|
||||||
texture_fade: anim_state.fade,
|
texture_fade: anim_state.fade,
|
||||||
mask_index: self
|
mask_index: self
|
||||||
|
@ -6,15 +6,7 @@ mod physsim;
|
|||||||
mod physwrapper;
|
mod physwrapper;
|
||||||
mod stepresources;
|
mod stepresources;
|
||||||
|
|
||||||
use std::sync::atomic::{AtomicU64, Ordering};
|
|
||||||
|
|
||||||
pub use physimage::*;
|
pub use physimage::*;
|
||||||
pub use physsim::{PhysSim, PhysSimShipHandle};
|
pub use physsim::{PhysSim, PhysSimShipHandle};
|
||||||
pub use physwrapper::PhysWrapper;
|
pub use physwrapper::PhysWrapper;
|
||||||
pub use stepresources::*;
|
pub use stepresources::*;
|
||||||
|
|
||||||
/// A unique id given to each physics object
|
|
||||||
static PHYS_UID: AtomicU64 = AtomicU64::new(0);
|
|
||||||
fn get_phys_id() -> u64 {
|
|
||||||
PHYS_UID.fetch_add(1, Ordering::Relaxed)
|
|
||||||
}
|
|
||||||
|
@ -14,7 +14,6 @@ use super::{autopilot, collapse::ShipCollapseSequence, controller::ShipControlle
|
|||||||
use crate::{
|
use crate::{
|
||||||
data::{ShipAutoPilot, ShipData, ShipPersonality, ShipState},
|
data::{ShipAutoPilot, ShipData, ShipPersonality, ShipState},
|
||||||
phys::{
|
phys::{
|
||||||
get_phys_id,
|
|
||||||
objects::{PhysEffect, PhysProjectile},
|
objects::{PhysEffect, PhysProjectile},
|
||||||
physsim::NewObjects,
|
physsim::NewObjects,
|
||||||
PhysImage, PhysSimShipHandle, PhysStepResources, PhysWrapper,
|
PhysImage, PhysSimShipHandle, PhysStepResources, PhysWrapper,
|
||||||
@ -24,9 +23,6 @@ use crate::{
|
|||||||
/// A ship instance in the physics system
|
/// A ship instance in the physics system
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct PhysShip {
|
pub struct PhysShip {
|
||||||
/// This ship's unique id
|
|
||||||
pub uid: u64,
|
|
||||||
|
|
||||||
/// This ship's physics handle
|
/// This ship's physics handle
|
||||||
pub rigid_body: RigidBodyHandle,
|
pub rigid_body: RigidBodyHandle,
|
||||||
|
|
||||||
@ -75,7 +71,6 @@ impl PhysShip {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
let ship_ct = ct.get_ship(handle);
|
let ship_ct = ct.get_ship(handle);
|
||||||
PhysShip {
|
PhysShip {
|
||||||
uid: get_phys_id(),
|
|
||||||
anim: SpriteAutomaton::new(ct, ship_ct.sprite),
|
anim: SpriteAutomaton::new(ct, ship_ct.sprite),
|
||||||
rigid_body,
|
rigid_body,
|
||||||
collider,
|
collider,
|
||||||
|
@ -13,11 +13,6 @@ pub fn to_radians(degrees: f32) -> f32 {
|
|||||||
return (degrees / 360.0) * std::f32::consts::TAU;
|
return (degrees / 360.0) * std::f32::consts::TAU;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert an angle in radians to degrees
|
|
||||||
pub fn to_degrees(radians: f32) -> f32 {
|
|
||||||
return (radians / std::f32::consts::TAU) * 360.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compute the clockwise angle between two vectors
|
/// Compute the clockwise angle between two vectors
|
||||||
/// Returns a value in [-pi, pi]
|
/// Returns a value in [-pi, pi]
|
||||||
pub fn clockwise_angle(a: &Vector2<f32>, b: &Vector2<f32>) -> f32 {
|
pub fn clockwise_angle(a: &Vector2<f32>, b: &Vector2<f32>) -> f32 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user