mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added training dummies
This commit is contained in:
parent
92c9db5291
commit
fd39ee97bc
@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Added new animals
|
- Added new animals
|
||||||
- Better pathfinding
|
- Better pathfinding
|
||||||
- Bombs
|
- Bombs
|
||||||
|
- Training dummies
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
7
assets/common/items/training_dummy.ron
Normal file
7
assets/common/items/training_dummy.ron
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Item(
|
||||||
|
name: "Training Dummy",
|
||||||
|
description: "His name is William. Fire at will.\n\n<Right-Click to use>",
|
||||||
|
kind: Throwable(
|
||||||
|
kind: TrainingDummy,
|
||||||
|
),
|
||||||
|
)
|
@ -778,11 +778,15 @@
|
|||||||
"voxel.sprite.velorite.velorite_1",
|
"voxel.sprite.velorite.velorite_1",
|
||||||
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
|
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
|
||||||
),
|
),
|
||||||
// Throwables
|
// Throwables
|
||||||
Throwable(Bomb): VoxTrans(
|
Throwable(Bomb): VoxTrans(
|
||||||
"voxel.object.bomb",
|
"voxel.object.bomb",
|
||||||
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
|
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
|
||||||
),
|
),
|
||||||
|
Throwable(TrainingDummy): VoxTrans(
|
||||||
|
"voxel.object.training_dummy",
|
||||||
|
(0.0, -1.0, 0.0), (-50.0, 40.0, 20.0), 0.8,
|
||||||
|
),
|
||||||
// Ingredients
|
// Ingredients
|
||||||
Ingredient(Flower): VoxTrans(
|
Ingredient(Flower): VoxTrans(
|
||||||
"voxel.sprite.flowers.flower_red_2",
|
"voxel.sprite.flowers.flower_red_2",
|
||||||
|
@ -123,6 +123,10 @@ pub const ALL_OBJECTS: [Body; 54] = [
|
|||||||
Body::TrainingDummy,
|
Body::TrainingDummy,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
impl From<Body> for super::Body {
|
||||||
|
fn from(body: Body) -> Self { super::Body::Object(body) }
|
||||||
|
}
|
||||||
|
|
||||||
impl Body {
|
impl Body {
|
||||||
pub fn to_string(&self) -> &str {
|
pub fn to_string(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
|
@ -31,6 +31,7 @@ pub enum Consumable {
|
|||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
pub enum Throwable {
|
pub enum Throwable {
|
||||||
Bomb,
|
Bomb,
|
||||||
|
TrainingDummy,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
@ -70,7 +70,7 @@ pub enum ServerEvent {
|
|||||||
stats: comp::Stats,
|
stats: comp::Stats,
|
||||||
loadout: comp::Loadout,
|
loadout: comp::Loadout,
|
||||||
body: comp::Body,
|
body: comp::Body,
|
||||||
agent: comp::Agent,
|
agent: Option<comp::Agent>,
|
||||||
alignment: comp::Alignment,
|
alignment: comp::Alignment,
|
||||||
scale: comp::Scale,
|
scale: comp::Scale,
|
||||||
drop_item: Option<Item>,
|
drop_item: Option<Item>,
|
||||||
|
@ -12,6 +12,7 @@ pub struct EntityInfo {
|
|||||||
pub pos: Vec3<f32>,
|
pub pos: Vec3<f32>,
|
||||||
pub is_waypoint: bool, // Edge case, overrides everything else
|
pub is_waypoint: bool, // Edge case, overrides everything else
|
||||||
pub is_giant: bool,
|
pub is_giant: bool,
|
||||||
|
pub has_agency: bool,
|
||||||
pub alignment: Alignment,
|
pub alignment: Alignment,
|
||||||
pub body: Body,
|
pub body: Body,
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
@ -28,6 +29,7 @@ impl EntityInfo {
|
|||||||
pos,
|
pos,
|
||||||
is_waypoint: false,
|
is_waypoint: false,
|
||||||
is_giant: false,
|
is_giant: false,
|
||||||
|
has_agency: true,
|
||||||
alignment: Alignment::Wild,
|
alignment: Alignment::Wild,
|
||||||
body: Body::Humanoid(humanoid::Body::random()),
|
body: Body::Humanoid(humanoid::Body::random()),
|
||||||
name: None,
|
name: None,
|
||||||
@ -66,8 +68,13 @@ impl EntityInfo {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_name(mut self, name: String) -> Self {
|
pub fn with_name(mut self, name: impl Into<String>) -> Self {
|
||||||
self.name = Some(name);
|
self.name = Some(name.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_agency(mut self, agency: bool) -> Self {
|
||||||
|
self.has_agency = agency;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@ use crate::vol::{ReadVol, Vox};
|
|||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
pub trait RayUntil<V: Vox> = FnMut(&V) -> bool;
|
pub trait RayUntil<V: Vox> = FnMut(&V) -> bool;
|
||||||
pub trait RayForEach = FnMut(Vec3<i32>);
|
pub trait RayForEach<V: Vox> = FnMut(&V, Vec3<i32>);
|
||||||
|
|
||||||
pub struct Ray<'a, V: ReadVol, F: RayUntil<V::Vox>, G: RayForEach> {
|
pub struct Ray<'a, V: ReadVol, F: RayUntil<V::Vox>, G: RayForEach<V::Vox>> {
|
||||||
vol: &'a V,
|
vol: &'a V,
|
||||||
from: Vec3<f32>,
|
from: Vec3<f32>,
|
||||||
to: Vec3<f32>,
|
to: Vec3<f32>,
|
||||||
@ -14,7 +14,7 @@ pub struct Ray<'a, V: ReadVol, F: RayUntil<V::Vox>, G: RayForEach> {
|
|||||||
ignore_error: bool,
|
ignore_error: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, V: ReadVol, F: RayUntil<V::Vox>, G: RayForEach> Ray<'a, V, F, G> {
|
impl<'a, V: ReadVol, F: RayUntil<V::Vox>, G: RayForEach<V::Vox>> Ray<'a, V, F, G> {
|
||||||
pub fn new(vol: &'a V, from: Vec3<f32>, to: Vec3<f32>, until: F) -> Self {
|
pub fn new(vol: &'a V, from: Vec3<f32>, to: Vec3<f32>, until: F) -> Self {
|
||||||
Self {
|
Self {
|
||||||
vol,
|
vol,
|
||||||
@ -29,7 +29,7 @@ impl<'a, V: ReadVol, F: RayUntil<V::Vox>, G: RayForEach> Ray<'a, V, F, G> {
|
|||||||
|
|
||||||
pub fn until(self, f: F) -> Ray<'a, V, F, G> { Ray { until: f, ..self } }
|
pub fn until(self, f: F) -> Ray<'a, V, F, G> { Ray { until: f, ..self } }
|
||||||
|
|
||||||
pub fn for_each<H: RayForEach>(self, f: H) -> Ray<'a, V, F, H> {
|
pub fn for_each<H: RayForEach<V::Vox>>(self, f: H) -> Ray<'a, V, F, H> {
|
||||||
Ray {
|
Ray {
|
||||||
for_each: Some(f),
|
for_each: Some(f),
|
||||||
vol: self.vol,
|
vol: self.vol,
|
||||||
@ -69,12 +69,16 @@ impl<'a, V: ReadVol, F: RayUntil<V::Vox>, G: RayForEach> Ray<'a, V, F, G> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let vox = self.vol.get(ipos);
|
||||||
|
|
||||||
// for_each
|
// for_each
|
||||||
if let Some(g) = &mut self.for_each {
|
if let Some(g) = &mut self.for_each {
|
||||||
g(ipos);
|
if let Ok(vox) = vox {
|
||||||
|
g(vox, ipos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.vol.get(ipos).map(|vox| (vox, (self.until)(vox))) {
|
match vox.map(|vox| (vox, (self.until)(vox))) {
|
||||||
Ok((vox, true)) => return (dist, Ok(Some(vox))),
|
Ok((vox, true)) => return (dist, Ok(Some(vox))),
|
||||||
Err(err) if !self.ignore_error => return (dist, Err(err)),
|
Err(err) if !self.ignore_error => return (dist, Err(err)),
|
||||||
_ => {},
|
_ => {},
|
||||||
|
@ -85,7 +85,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
&orientations,
|
&orientations,
|
||||||
scales.maybe(),
|
scales.maybe(),
|
||||||
agents.maybe(),
|
agents.maybe(),
|
||||||
&character_states,
|
character_states.maybe(),
|
||||||
&stats,
|
&stats,
|
||||||
&bodies,
|
&bodies,
|
||||||
)
|
)
|
||||||
@ -129,7 +129,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Block
|
// Block
|
||||||
if character_b.is_block()
|
if character_b.map(|c_b| c_b.is_block()).unwrap_or(false)
|
||||||
&& ori_b.0.angle_between(pos.0 - pos_b.0) < BLOCK_ANGLE.to_radians() / 2.0
|
&& ori_b.0.angle_between(pos.0 - pos_b.0) < BLOCK_ANGLE.to_radians() / 2.0
|
||||||
{
|
{
|
||||||
healthchange *= 1.0 - BLOCK_EFFICIENCY
|
healthchange *= 1.0 - BLOCK_EFFICIENCY
|
||||||
|
@ -33,13 +33,10 @@ impl<'a> System<'a> for Sys {
|
|||||||
}
|
}
|
||||||
stats.set_event_emission(true);
|
stats.set_event_emission(true);
|
||||||
|
|
||||||
// Mutates all stats every tick causing the server to resend this component for
|
// Update stats
|
||||||
// every entity every tick
|
for (entity, mut stats) in (
|
||||||
for (entity, character_state, mut stats, mut energy) in (
|
|
||||||
&entities,
|
&entities,
|
||||||
&character_states,
|
|
||||||
&mut stats.restrict_mut(),
|
&mut stats.restrict_mut(),
|
||||||
&mut energies.restrict_mut(),
|
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
{
|
{
|
||||||
@ -74,7 +71,15 @@ impl<'a> System<'a> for Sys {
|
|||||||
stat.health
|
stat.health
|
||||||
.set_to(stat.health.maximum(), HealthSource::LevelUp);
|
.set_to(stat.health.maximum(), HealthSource::LevelUp);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update energies
|
||||||
|
for (character_state, mut energy) in (
|
||||||
|
&character_states,
|
||||||
|
&mut energies.restrict_mut(),
|
||||||
|
)
|
||||||
|
.join()
|
||||||
|
{
|
||||||
match character_state {
|
match character_state {
|
||||||
// Accelerate recharging energy.
|
// Accelerate recharging energy.
|
||||||
CharacterState::Idle { .. }
|
CharacterState::Idle { .. }
|
||||||
|
@ -102,7 +102,7 @@ pub trait ReadVol: BaseVol {
|
|||||||
&'a self,
|
&'a self,
|
||||||
from: Vec3<f32>,
|
from: Vec3<f32>,
|
||||||
to: Vec3<f32>,
|
to: Vec3<f32>,
|
||||||
) -> Ray<'a, Self, fn(&Self::Vox) -> bool, fn(Vec3<i32>)>
|
) -> Ray<'a, Self, fn(&Self::Vox) -> bool, fn(&Self::Vox, Vec3<i32>)>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
|
@ -31,7 +31,7 @@ pub fn handle_create_npc(
|
|||||||
stats: Stats,
|
stats: Stats,
|
||||||
loadout: Loadout,
|
loadout: Loadout,
|
||||||
body: Body,
|
body: Body,
|
||||||
agent: Agent,
|
agent: impl Into<Option<Agent>>,
|
||||||
alignment: Alignment,
|
alignment: Alignment,
|
||||||
scale: Scale,
|
scale: Scale,
|
||||||
drop_item: Option<Item>,
|
drop_item: Option<Item>,
|
||||||
@ -39,10 +39,15 @@ pub fn handle_create_npc(
|
|||||||
let entity = server
|
let entity = server
|
||||||
.state
|
.state
|
||||||
.create_npc(pos, stats, loadout, body)
|
.create_npc(pos, stats, loadout, body)
|
||||||
.with(agent)
|
|
||||||
.with(scale)
|
.with(scale)
|
||||||
.with(alignment);
|
.with(alignment);
|
||||||
|
|
||||||
|
let entity = if let Some(agent) = agent.into() {
|
||||||
|
entity.with(agent)
|
||||||
|
} else {
|
||||||
|
entity
|
||||||
|
};
|
||||||
|
|
||||||
let entity = if let Some(drop_item) = drop_item {
|
let entity = if let Some(drop_item) = drop_item {
|
||||||
entity.with(ItemDrop(drop_item))
|
entity.with(ItemDrop(drop_item))
|
||||||
} else {
|
} else {
|
||||||
|
@ -211,7 +211,7 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, power: f32, owner: Opti
|
|||||||
for (pos_b, ori_b, character_b, stats_b) in (
|
for (pos_b, ori_b, character_b, stats_b) in (
|
||||||
&ecs.read_storage::<comp::Pos>(),
|
&ecs.read_storage::<comp::Pos>(),
|
||||||
&ecs.read_storage::<comp::Ori>(),
|
&ecs.read_storage::<comp::Ori>(),
|
||||||
&ecs.read_storage::<comp::CharacterState>(),
|
ecs.read_storage::<comp::CharacterState>().maybe(),
|
||||||
&mut ecs.write_storage::<comp::Stats>(),
|
&mut ecs.write_storage::<comp::Stats>(),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
@ -231,7 +231,7 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, power: f32, owner: Opti
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Block
|
// Block
|
||||||
if character_b.is_block()
|
if character_b.map(|c_b| c_b.is_block()).unwrap_or(false)
|
||||||
&& ori_b.0.angle_between(pos - pos_b.0) < BLOCK_ANGLE.to_radians() / 2.0
|
&& ori_b.0.angle_between(pos - pos_b.0) < BLOCK_ANGLE.to_radians() / 2.0
|
||||||
{
|
{
|
||||||
dmg = (dmg as f32 * (1.0 - BLOCK_EFFICIENCY)) as u32
|
dmg = (dmg as f32 * (1.0 - BLOCK_EFFICIENCY)) as u32
|
||||||
@ -261,7 +261,7 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, power: f32, owner: Opti
|
|||||||
.read_resource::<TerrainGrid>()
|
.read_resource::<TerrainGrid>()
|
||||||
.ray(pos, pos + dir * color_range)
|
.ray(pos, pos + dir * color_range)
|
||||||
.until(|_| rand::random::<f32>() < 0.05)
|
.until(|_| rand::random::<f32>() < 0.05)
|
||||||
.for_each(|pos| touched_blocks.push(pos))
|
.for_each(|_: &Block, pos| touched_blocks.push(pos))
|
||||||
.cast();
|
.cast();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,12 +296,8 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, power: f32, owner: Opti
|
|||||||
let _ = terrain
|
let _ = terrain
|
||||||
.ray(pos, pos + dir * power)
|
.ray(pos, pos + dir * power)
|
||||||
.until(|block| block.is_fluid() || rand::random::<f32>() < 0.05)
|
.until(|block| block.is_fluid() || rand::random::<f32>() < 0.05)
|
||||||
.for_each(|pos| {
|
.for_each(|block: &Block, pos| {
|
||||||
if terrain
|
if block.is_explodable() {
|
||||||
.get(pos)
|
|
||||||
.map(|block| block.is_explodable())
|
|
||||||
.unwrap_or(false)
|
|
||||||
{
|
|
||||||
block_change.set(pos, Block::empty());
|
block_change.set(pos, Block::empty());
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -159,7 +159,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
|||||||
maybe_effect = Some(*effect);
|
maybe_effect = Some(*effect);
|
||||||
Some(comp::InventoryUpdateEvent::Consumed(*kind))
|
Some(comp::InventoryUpdateEvent::Consumed(*kind))
|
||||||
},
|
},
|
||||||
ItemKind::Throwable { .. } => {
|
ItemKind::Throwable { kind, .. } => {
|
||||||
if let Some(pos) =
|
if let Some(pos) =
|
||||||
state.ecs().read_storage::<comp::Pos>().get(entity)
|
state.ecs().read_storage::<comp::Pos>().get(entity)
|
||||||
{
|
{
|
||||||
@ -177,7 +177,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
|||||||
.get(entity)
|
.get(entity)
|
||||||
.copied()
|
.copied()
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
item,
|
kind.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Some(comp::InventoryUpdateEvent::Used)
|
Some(comp::InventoryUpdateEvent::Used)
|
||||||
@ -344,8 +344,8 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drop items
|
// Throw items
|
||||||
for (pos, vel, ori, item) in thrown_items {
|
for (pos, vel, ori, kind) in thrown_items {
|
||||||
let vel = vel.0
|
let vel = vel.0
|
||||||
+ *ori.0 * 20.0
|
+ *ori.0 * 20.0
|
||||||
+ Vec3::unit_z() * 15.0
|
+ Vec3::unit_z() * 15.0
|
||||||
@ -353,26 +353,31 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
|||||||
|
|
||||||
let uid = state.read_component_cloned::<Uid>(entity);
|
let uid = state.read_component_cloned::<Uid>(entity);
|
||||||
|
|
||||||
let mut entity = state
|
let mut new_entity = state
|
||||||
.create_object(Default::default(), comp::object::Body::Bomb)
|
.create_object(Default::default(), match kind {
|
||||||
|
item::Throwable::Bomb => comp::object::Body::Bomb,
|
||||||
|
item::Throwable::TrainingDummy => comp::object::Body::TrainingDummy,
|
||||||
|
})
|
||||||
.with(comp::Pos(pos.0 + Vec3::unit_z() * 0.25))
|
.with(comp::Pos(pos.0 + Vec3::unit_z() * 0.25))
|
||||||
.with(comp::Vel(vel));
|
.with(comp::Vel(vel));
|
||||||
|
|
||||||
#[allow(clippy::single_match)]
|
match kind {
|
||||||
match item.kind {
|
item::Throwable::Bomb => {
|
||||||
item::ItemKind::Throwable {
|
new_entity = new_entity.with(comp::Object::Bomb {
|
||||||
kind: item::Throwable::Bomb,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
entity = entity.with(comp::Object::Bomb {
|
|
||||||
timeout: Duration::from_secs_f32(1.0),
|
timeout: Duration::from_secs_f32(1.0),
|
||||||
owner: uid,
|
owner: uid,
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
_ => {},
|
item::Throwable::TrainingDummy => {
|
||||||
}
|
new_entity = new_entity
|
||||||
|
.with(comp::Stats::new(
|
||||||
|
"Training Dummy".to_string(),
|
||||||
|
comp::object::Body::TrainingDummy.into(),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
entity.build();
|
new_entity.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ impl StateExt for State {
|
|||||||
.with(comp::Vel(Vec3::zero()))
|
.with(comp::Vel(Vec3::zero()))
|
||||||
.with(comp::Ori::default())
|
.with(comp::Ori::default())
|
||||||
.with(comp::Body::Object(object))
|
.with(comp::Body::Object(object))
|
||||||
.with(comp::Mass(100.0))
|
.with(comp::Mass(5.0))
|
||||||
.with(comp::Collider::Box {
|
.with(comp::Collider::Box {
|
||||||
radius: 0.4,
|
radius: 0.4,
|
||||||
z_min: 0.0,
|
z_min: 0.0,
|
||||||
|
@ -31,9 +31,9 @@ pub type PersistenceScheduler = SysScheduler<persistence::Sys>;
|
|||||||
//const SUBSCRIPTION_SYS: &str = "server_subscription_sys";
|
//const SUBSCRIPTION_SYS: &str = "server_subscription_sys";
|
||||||
//const TERRAIN_SYNC_SYS: &str = "server_terrain_sync_sys";
|
//const TERRAIN_SYNC_SYS: &str = "server_terrain_sync_sys";
|
||||||
const TERRAIN_SYS: &str = "server_terrain_sys";
|
const TERRAIN_SYS: &str = "server_terrain_sys";
|
||||||
const WAYPOINT_SYS: &str = "waypoint_sys";
|
const WAYPOINT_SYS: &str = "server_waypoint_sys";
|
||||||
const PERSISTENCE_SYS: &str = "persistence_sys";
|
const PERSISTENCE_SYS: &str = "server_persistence_sys";
|
||||||
const OBJECT_SYS: &str = "object_sys";
|
const OBJECT_SYS: &str = "server_object_sys";
|
||||||
|
|
||||||
pub fn add_server_systems(dispatch_builder: &mut DispatcherBuilder) {
|
pub fn add_server_systems(dispatch_builder: &mut DispatcherBuilder) {
|
||||||
dispatch_builder.add(terrain::Sys, TERRAIN_SYS, &[]);
|
dispatch_builder.add(terrain::Sys, TERRAIN_SYS, &[]);
|
||||||
|
@ -6,7 +6,7 @@ use common::{
|
|||||||
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
|
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
/// This system is responsible for handling projectile effect triggers
|
/// This system is responsible for handling misc object behaviours
|
||||||
pub struct Sys;
|
pub struct Sys;
|
||||||
impl<'a> System<'a> for Sys {
|
impl<'a> System<'a> for Sys {
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
|
@ -346,8 +346,12 @@ impl<'a> System<'a> for Sys {
|
|||||||
stats,
|
stats,
|
||||||
loadout,
|
loadout,
|
||||||
body,
|
body,
|
||||||
|
agent: if entity.has_agency {
|
||||||
|
Some(comp::Agent::new(entity.pos, can_speak))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
alignment,
|
alignment,
|
||||||
agent: comp::Agent::new(entity.pos, can_speak),
|
|
||||||
scale: comp::Scale(scale),
|
scale: comp::Scale(scale),
|
||||||
drop_item: entity.loot_drop,
|
drop_item: entity.loot_drop,
|
||||||
})
|
})
|
||||||
|
@ -970,7 +970,7 @@ impl Hud {
|
|||||||
&pos,
|
&pos,
|
||||||
interpolated.maybe(),
|
interpolated.maybe(),
|
||||||
&stats,
|
&stats,
|
||||||
&energy,
|
energy.maybe(),
|
||||||
players.maybe(),
|
players.maybe(),
|
||||||
scales.maybe(),
|
scales.maybe(),
|
||||||
&bodies,
|
&bodies,
|
||||||
|
@ -54,7 +54,7 @@ pub struct Overhead<'a> {
|
|||||||
name: &'a str,
|
name: &'a str,
|
||||||
bubble: Option<&'a SpeechBubble>,
|
bubble: Option<&'a SpeechBubble>,
|
||||||
stats: &'a Stats,
|
stats: &'a Stats,
|
||||||
energy: &'a Energy,
|
energy: Option<&'a Energy>,
|
||||||
own_level: u32,
|
own_level: u32,
|
||||||
settings: &'a GameplaySettings,
|
settings: &'a GameplaySettings,
|
||||||
pulse: f32,
|
pulse: f32,
|
||||||
@ -71,7 +71,7 @@ impl<'a> Overhead<'a> {
|
|||||||
name: &'a str,
|
name: &'a str,
|
||||||
bubble: Option<&'a SpeechBubble>,
|
bubble: Option<&'a SpeechBubble>,
|
||||||
stats: &'a Stats,
|
stats: &'a Stats,
|
||||||
energy: &'a Energy,
|
energy: Option<&'a Energy>,
|
||||||
own_level: u32,
|
own_level: u32,
|
||||||
settings: &'a GameplaySettings,
|
settings: &'a GameplaySettings,
|
||||||
pulse: f32,
|
pulse: f32,
|
||||||
@ -297,7 +297,6 @@ impl<'a> Widget for Overhead<'a> {
|
|||||||
|
|
||||||
let hp_percentage =
|
let hp_percentage =
|
||||||
self.stats.health.current() as f64 / self.stats.health.maximum() as f64 * 100.0;
|
self.stats.health.current() as f64 / self.stats.health.maximum() as f64 * 100.0;
|
||||||
let energy_percentage = self.energy.current() as f64 / self.energy.maximum() as f64 * 100.0;
|
|
||||||
let hp_ani = (self.pulse * 4.0/* speed factor */).cos() * 0.5 + 1.0; //Animation timer
|
let hp_ani = (self.pulse * 4.0/* speed factor */).cos() * 0.5 + 1.0; //Animation timer
|
||||||
let crit_hp_color: Color = Color::Rgba(0.79, 0.19, 0.17, hp_ani);
|
let crit_hp_color: Color = Color::Rgba(0.79, 0.19, 0.17, hp_ani);
|
||||||
|
|
||||||
@ -325,20 +324,25 @@ impl<'a> Widget for Overhead<'a> {
|
|||||||
}))
|
}))
|
||||||
.parent(id)
|
.parent(id)
|
||||||
.set(state.ids.health_bar, ui);
|
.set(state.ids.health_bar, ui);
|
||||||
|
|
||||||
// % Mana Filling
|
// % Mana Filling
|
||||||
Rectangle::fill_with(
|
if let Some(energy) = self.energy {
|
||||||
[
|
let energy_factor = energy.current() as f64 / energy.maximum() as f64;
|
||||||
72.0 * (self.energy.current() as f64 / self.energy.maximum() as f64) * BARSIZE,
|
|
||||||
MANA_BAR_HEIGHT,
|
Rectangle::fill_with(
|
||||||
],
|
[
|
||||||
MANA_COLOR,
|
72.0 * energy_factor * BARSIZE,
|
||||||
)
|
MANA_BAR_HEIGHT,
|
||||||
.x_y(
|
],
|
||||||
((3.5 + (energy_percentage / 100.0 * 36.5)) - 36.45) * BARSIZE,
|
MANA_COLOR,
|
||||||
MANA_BAR_Y, //-32.0,
|
)
|
||||||
)
|
.x_y(
|
||||||
.parent(id)
|
((3.5 + (energy_factor * 36.5)) - 36.45) * BARSIZE,
|
||||||
.set(state.ids.mana_bar, ui);
|
MANA_BAR_Y, //-32.0,
|
||||||
|
)
|
||||||
|
.parent(id)
|
||||||
|
.set(state.ids.mana_bar, ui);
|
||||||
|
}
|
||||||
|
|
||||||
// Foreground
|
// Foreground
|
||||||
Image::new(self.imgs.enemy_health)
|
Image::new(self.imgs.enemy_health)
|
||||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
use common::{
|
use common::{
|
||||||
assets,
|
assets,
|
||||||
astar::Astar,
|
astar::Astar,
|
||||||
comp::{self, bird_medium, humanoid, quadruped_small},
|
comp::{self, bird_medium, humanoid, quadruped_small, object},
|
||||||
generation::{ChunkSupplement, EntityInfo},
|
generation::{ChunkSupplement, EntityInfo},
|
||||||
path::Path,
|
path::Path,
|
||||||
spiral::Spiral2d,
|
spiral::Spiral2d,
|
||||||
@ -789,8 +789,13 @@ impl Settlement {
|
|||||||
&& RandomField::new(self.seed).chance(Vec3::from(wpos2d), 1.0 / (50.0 * 50.0))
|
&& RandomField::new(self.seed).chance(Vec3::from(wpos2d), 1.0 / (50.0 * 50.0))
|
||||||
{
|
{
|
||||||
let is_human: bool;
|
let is_human: bool;
|
||||||
|
let is_dummy = RandomField::new(self.seed + 1).chance(Vec3::from(wpos2d), 1.0 / 15.0);
|
||||||
let entity = EntityInfo::at(entity_wpos)
|
let entity = EntityInfo::at(entity_wpos)
|
||||||
.with_body(match rng.gen_range(0, 4) {
|
.with_body(match rng.gen_range(0, 4) {
|
||||||
|
_ if is_dummy => {
|
||||||
|
is_human = false;
|
||||||
|
object::Body::TrainingDummy.into()
|
||||||
|
},
|
||||||
0 => {
|
0 => {
|
||||||
let species = match rng.gen_range(0, 3) {
|
let species = match rng.gen_range(0, 3) {
|
||||||
0 => quadruped_small::Species::Pig,
|
0 => quadruped_small::Species::Pig,
|
||||||
@ -819,7 +824,10 @@ impl Settlement {
|
|||||||
comp::Body::Humanoid(humanoid::Body::random())
|
comp::Body::Humanoid(humanoid::Body::random())
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.with_alignment(if is_human {
|
.with_agency(!is_dummy)
|
||||||
|
.with_alignment(if is_dummy {
|
||||||
|
comp::Alignment::Wild
|
||||||
|
} else if is_human {
|
||||||
comp::Alignment::Npc
|
comp::Alignment::Npc
|
||||||
} else {
|
} else {
|
||||||
comp::Alignment::Tame
|
comp::Alignment::Tame
|
||||||
@ -838,7 +846,8 @@ impl Settlement {
|
|||||||
},
|
},
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.with_automatic_name();
|
.do_if(is_dummy, |e| e.with_name("Training Dummy"))
|
||||||
|
.do_if(!is_dummy, |e| e.with_automatic_name());
|
||||||
|
|
||||||
supplement.add_entity(entity);
|
supplement.add_entity(entity);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user