mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added bosses, improved secret object spawn rates
This commit is contained in:
@ -10,10 +10,20 @@ pub enum Agent {
|
|||||||
offset: Vec2<f32>,
|
offset: Vec2<f32>,
|
||||||
},
|
},
|
||||||
Enemy {
|
Enemy {
|
||||||
|
bearing: Vec2<f32>,
|
||||||
target: Option<EcsEntity>,
|
target: Option<EcsEntity>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Agent {
|
||||||
|
pub fn enemy() -> Self {
|
||||||
|
Agent::Enemy {
|
||||||
|
bearing: Vec2::zero(),
|
||||||
|
target: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Component for Agent {
|
impl Component for Agent {
|
||||||
type Storage = IDVStorage<Self>;
|
type Storage = IDVStorage<Self>;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ pub use inputs::{
|
|||||||
};
|
};
|
||||||
pub use inventory::{item, Inventory, InventoryUpdate, Item};
|
pub use inventory::{item, Inventory, InventoryUpdate, Item};
|
||||||
pub use last::Last;
|
pub use last::Last;
|
||||||
pub use phys::{ForceUpdate, Ori, Pos, Vel};
|
pub use phys::{ForceUpdate, Ori, Pos, Scale, Vel};
|
||||||
pub use player::Player;
|
pub use player::Player;
|
||||||
pub use stats::{Dying, Exp, HealthSource, Level, Stats};
|
pub use stats::{Dying, Exp, HealthSource, Level, Stats};
|
||||||
pub use visual::LightEmitter;
|
pub use visual::LightEmitter;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use specs::{Component, NullStorage};
|
use specs::{Component, FlaggedStorage, NullStorage};
|
||||||
use specs_idvs::IDVStorage;
|
use specs_idvs::IDVStorage;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
@ -26,6 +26,14 @@ impl Component for Ori {
|
|||||||
type Storage = IDVStorage<Self>;
|
type Storage = IDVStorage<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scale
|
||||||
|
#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Scale(pub f32);
|
||||||
|
|
||||||
|
impl Component for Scale {
|
||||||
|
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
|
||||||
|
}
|
||||||
|
|
||||||
// ForceUpdate
|
// ForceUpdate
|
||||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct ForceUpdate;
|
pub struct ForceUpdate;
|
||||||
|
@ -34,18 +34,26 @@ impl Health {
|
|||||||
pub fn current(&self) -> u32 {
|
pub fn current(&self) -> u32 {
|
||||||
self.current
|
self.current
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maximum(&self) -> u32 {
|
pub fn maximum(&self) -> u32 {
|
||||||
self.maximum
|
self.maximum
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_to(&mut self, amount: u32, cause: HealthSource) {
|
pub fn set_to(&mut self, amount: u32, cause: HealthSource) {
|
||||||
let amount = amount.min(self.maximum);
|
let amount = amount.min(self.maximum);
|
||||||
self.last_change = Some((amount as i32 - self.current as i32, 0.0, cause));
|
self.last_change = Some((amount as i32 - self.current as i32, 0.0, cause));
|
||||||
self.current = amount;
|
self.current = amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_by(&mut self, amount: i32, cause: HealthSource) {
|
pub fn change_by(&mut self, amount: i32, cause: HealthSource) {
|
||||||
self.current = ((self.current as i32 + amount).max(0) as u32).min(self.maximum);
|
self.current = ((self.current as i32 + amount).max(0) as u32).min(self.maximum);
|
||||||
self.last_change = Some((amount, 0.0, cause));
|
self.last_change = Some((amount, 0.0, cause));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_current(&mut self, amount: u32) {
|
||||||
|
self.current = amount.min(self.maximum);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_maximum(&mut self, amount: u32) {
|
pub fn set_maximum(&mut self, amount: u32) {
|
||||||
self.maximum = amount;
|
self.maximum = amount;
|
||||||
self.current = self.current.min(self.maximum);
|
self.current = self.current.min(self.maximum);
|
||||||
|
@ -26,6 +26,7 @@ sphynx::sum_type! {
|
|||||||
Stats(comp::Stats),
|
Stats(comp::Stats),
|
||||||
LightEmitter(comp::LightEmitter),
|
LightEmitter(comp::LightEmitter),
|
||||||
Item(comp::Item),
|
Item(comp::Item),
|
||||||
|
Scale(comp::Scale),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Automatically derive From<T> for EcsCompPhantom
|
// Automatically derive From<T> for EcsCompPhantom
|
||||||
@ -42,6 +43,7 @@ sphynx::sum_type! {
|
|||||||
Stats(PhantomData<comp::Stats>),
|
Stats(PhantomData<comp::Stats>),
|
||||||
LightEmitter(PhantomData<comp::LightEmitter>),
|
LightEmitter(PhantomData<comp::LightEmitter>),
|
||||||
Item(PhantomData<comp::Item>),
|
Item(PhantomData<comp::Item>),
|
||||||
|
Scale(PhantomData<comp::Scale>),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl sphynx::CompPacket for EcsCompPacket {
|
impl sphynx::CompPacket for EcsCompPacket {
|
||||||
|
@ -132,6 +132,7 @@ impl State {
|
|||||||
ecs.register_synced::<comp::CanBuild>();
|
ecs.register_synced::<comp::CanBuild>();
|
||||||
ecs.register_synced::<comp::LightEmitter>();
|
ecs.register_synced::<comp::LightEmitter>();
|
||||||
ecs.register_synced::<comp::Item>();
|
ecs.register_synced::<comp::Item>();
|
||||||
|
ecs.register_synced::<comp::Scale>();
|
||||||
|
|
||||||
// Register components send from clients -> server
|
// Register components send from clients -> server
|
||||||
ecs.register::<comp::Controller>();
|
ecs.register::<comp::Controller>();
|
||||||
|
@ -58,7 +58,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
* 10.0;
|
* 10.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Agent::Enemy { target } => {
|
Agent::Enemy { bearing, target } => {
|
||||||
let choose_new = match target.map(|tgt| positions.get(tgt)).flatten() {
|
let choose_new = match target.map(|tgt| positions.get(tgt)).flatten() {
|
||||||
Some(tgt_pos) => {
|
Some(tgt_pos) => {
|
||||||
let dist = Vec2::<f32>::from(tgt_pos.0 - pos.0).magnitude();
|
let dist = Vec2::<f32>::from(tgt_pos.0 - pos.0).magnitude();
|
||||||
@ -80,7 +80,16 @@ impl<'a> System<'a> for Sys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
controller.move_dir = Vec2::one();
|
*bearing +=
|
||||||
|
Vec2::new(rand::random::<f32>() - 0.5, rand::random::<f32>() - 0.5)
|
||||||
|
* 0.1
|
||||||
|
- *bearing * 0.01;
|
||||||
|
|
||||||
|
controller.move_dir = if bearing.magnitude_squared() > 0.5 {
|
||||||
|
bearing.normalized()
|
||||||
|
} else {
|
||||||
|
Vec2::zero()
|
||||||
|
};
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -438,7 +438,7 @@ fn handle_help(server: &mut Server, entity: EcsEntity, _args: String, _action: &
|
|||||||
|
|
||||||
fn alignment_to_agent(alignment: &str, target: EcsEntity) -> Option<comp::Agent> {
|
fn alignment_to_agent(alignment: &str, target: EcsEntity) -> Option<comp::Agent> {
|
||||||
match alignment {
|
match alignment {
|
||||||
"hostile" => Some(comp::Agent::Enemy { target: None }),
|
"hostile" => Some(comp::Agent::enemy()),
|
||||||
"friendly" => Some(comp::Agent::Pet {
|
"friendly" => Some(comp::Agent::Pet {
|
||||||
target,
|
target,
|
||||||
offset: Vec2::zero(),
|
offset: Vec2::zero(),
|
||||||
|
@ -270,6 +270,17 @@ impl Server {
|
|||||||
|
|
||||||
// Handle chunk supplement
|
// Handle chunk supplement
|
||||||
for npc in supplement.npcs {
|
for npc in supplement.npcs {
|
||||||
|
let mut stats = comp::Stats::new("Test".to_string());
|
||||||
|
let mut body = comp::Body::QuadrupedMedium(comp::quadruped_medium::Body::random());
|
||||||
|
let mut scale = 1.0;
|
||||||
|
|
||||||
|
if npc.boss {
|
||||||
|
stats.health.set_maximum(400);
|
||||||
|
stats.health.set_current(400);
|
||||||
|
scale = 2.5;
|
||||||
|
body = comp::Body::Humanoid(comp::humanoid::Body::random());
|
||||||
|
}
|
||||||
|
|
||||||
self.state
|
self.state
|
||||||
.ecs_mut()
|
.ecs_mut()
|
||||||
.create_entity_synced()
|
.create_entity_synced()
|
||||||
@ -277,11 +288,11 @@ impl Server {
|
|||||||
.with(comp::Vel(Vec3::zero()))
|
.with(comp::Vel(Vec3::zero()))
|
||||||
.with(comp::Ori(Vec3::unit_y()))
|
.with(comp::Ori(Vec3::unit_y()))
|
||||||
.with(comp::Controller::default())
|
.with(comp::Controller::default())
|
||||||
.with(comp::Body::Humanoid(comp::humanoid::Body::random()))
|
.with(body)
|
||||||
.with(comp::Stats::new("Test".to_string()))
|
.with(stats)
|
||||||
.with(comp::ActionState::default())
|
.with(comp::ActionState::default())
|
||||||
.with(comp::Agent::Enemy { target: None })
|
.with(comp::Agent::enemy())
|
||||||
.with(comp::ForceUpdate)
|
.with(comp::Scale(scale))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,6 +124,7 @@ impl Scene {
|
|||||||
renderer,
|
renderer,
|
||||||
Vec3::zero(),
|
Vec3::zero(),
|
||||||
-Vec3::unit_y(),
|
-Vec3::unit_y(),
|
||||||
|
1.0,
|
||||||
Rgba::broadcast(1.0),
|
Rgba::broadcast(1.0),
|
||||||
1.0 / 60.0, // TODO: Use actual deltatime here?
|
1.0 / 60.0, // TODO: Use actual deltatime here?
|
||||||
);
|
);
|
||||||
|
@ -624,11 +624,12 @@ impl FigureMgr {
|
|||||||
.get(client.entity())
|
.get(client.entity())
|
||||||
.map_or(Vec3::zero(), |pos| pos.0);
|
.map_or(Vec3::zero(), |pos| pos.0);
|
||||||
|
|
||||||
for (entity, pos, vel, ori, body, animation_info, stats) in (
|
for (entity, pos, vel, ori, scale, body, animation_info, stats) in (
|
||||||
&ecs.entities(),
|
&ecs.entities(),
|
||||||
&ecs.read_storage::<comp::Pos>(),
|
&ecs.read_storage::<comp::Pos>(),
|
||||||
&ecs.read_storage::<comp::Vel>(),
|
&ecs.read_storage::<comp::Vel>(),
|
||||||
&ecs.read_storage::<comp::Ori>(),
|
&ecs.read_storage::<comp::Ori>(),
|
||||||
|
ecs.read_storage::<comp::Scale>().maybe(),
|
||||||
&ecs.read_storage::<comp::Body>(),
|
&ecs.read_storage::<comp::Body>(),
|
||||||
ecs.read_storage::<comp::AnimationInfo>().maybe(),
|
ecs.read_storage::<comp::AnimationInfo>().maybe(),
|
||||||
ecs.read_storage::<comp::Stats>().maybe(),
|
ecs.read_storage::<comp::Stats>().maybe(),
|
||||||
@ -671,6 +672,8 @@ impl FigureMgr {
|
|||||||
})
|
})
|
||||||
.unwrap_or(Rgba::broadcast(1.0));
|
.unwrap_or(Rgba::broadcast(1.0));
|
||||||
|
|
||||||
|
let scale = scale.map(|s| s.0).unwrap_or(1.0);
|
||||||
|
|
||||||
let skeleton_attr = &self
|
let skeleton_attr = &self
|
||||||
.model_cache
|
.model_cache
|
||||||
.get_or_create_model(renderer, *body, tick)
|
.get_or_create_model(renderer, *body, tick)
|
||||||
@ -750,7 +753,7 @@ impl FigureMgr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
state.skeleton.interpolate(&target_skeleton, dt);
|
state.skeleton.interpolate(&target_skeleton, dt);
|
||||||
state.update(renderer, pos.0, ori.0, col, dt);
|
state.update(renderer, pos.0, ori.0, scale, col, dt);
|
||||||
}
|
}
|
||||||
Body::Quadruped(_) => {
|
Body::Quadruped(_) => {
|
||||||
let state = self
|
let state = self
|
||||||
@ -788,7 +791,7 @@ impl FigureMgr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
state.skeleton.interpolate(&target_skeleton, dt);
|
state.skeleton.interpolate(&target_skeleton, dt);
|
||||||
state.update(renderer, pos.0, ori.0, col, dt);
|
state.update(renderer, pos.0, ori.0, scale, col, dt);
|
||||||
}
|
}
|
||||||
Body::QuadrupedMedium(_) => {
|
Body::QuadrupedMedium(_) => {
|
||||||
let state = self
|
let state = self
|
||||||
@ -834,7 +837,7 @@ impl FigureMgr {
|
|||||||
};
|
};
|
||||||
|
|
||||||
state.skeleton.interpolate(&target_skeleton, dt);
|
state.skeleton.interpolate(&target_skeleton, dt);
|
||||||
state.update(renderer, pos.0, ori.0, col, dt);
|
state.update(renderer, pos.0, ori.0, scale, col, dt);
|
||||||
}
|
}
|
||||||
Body::Object(_) => {
|
Body::Object(_) => {
|
||||||
let state = self
|
let state = self
|
||||||
@ -843,7 +846,7 @@ impl FigureMgr {
|
|||||||
.or_insert_with(|| FigureState::new(renderer, ObjectSkeleton::new()));
|
.or_insert_with(|| FigureState::new(renderer, ObjectSkeleton::new()));
|
||||||
|
|
||||||
state.skeleton = state.skeleton_mut().clone();
|
state.skeleton = state.skeleton_mut().clone();
|
||||||
state.update(renderer, pos.0, ori.0, col, dt);
|
state.update(renderer, pos.0, ori.0, scale, col, dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -967,6 +970,7 @@ impl<S: Skeleton> FigureState<S> {
|
|||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
pos: Vec3<f32>,
|
pos: Vec3<f32>,
|
||||||
ori: Vec3<f32>,
|
ori: Vec3<f32>,
|
||||||
|
scale: f32,
|
||||||
col: Rgba<f32>,
|
col: Rgba<f32>,
|
||||||
dt: f32,
|
dt: f32,
|
||||||
) {
|
) {
|
||||||
@ -982,7 +986,7 @@ impl<S: Skeleton> FigureState<S> {
|
|||||||
let mat = Mat4::<f32>::identity()
|
let mat = Mat4::<f32>::identity()
|
||||||
* Mat4::translation_3d(self.pos)
|
* Mat4::translation_3d(self.pos)
|
||||||
* Mat4::rotation_z(-ori.x.atan2(ori.y))
|
* Mat4::rotation_z(-ori.x.atan2(ori.y))
|
||||||
* Mat4::scaling_3d(Vec3::from(0.8));
|
* Mat4::scaling_3d(Vec3::from(0.8 * scale));
|
||||||
|
|
||||||
let locals = FigureLocals::new(mat, col);
|
let locals = FigureLocals::new(mat, col);
|
||||||
renderer.update_consts(&mut self.locals, &[locals]).unwrap();
|
renderer.update_consts(&mut self.locals, &[locals]).unwrap();
|
||||||
|
@ -43,7 +43,7 @@ pub fn structure_gen<'a>(
|
|||||||
let wheight = st_sample.alt.max(cliff_height);
|
let wheight = st_sample.alt.max(cliff_height);
|
||||||
let st_pos3d = Vec3::new(st_pos.x, st_pos.y, wheight as i32);
|
let st_pos3d = Vec3::new(st_pos.x, st_pos.y, wheight as i32);
|
||||||
|
|
||||||
let volumes: &'static [_] = if QUIRKY_RAND.get(st_seed) % 64 == 17 {
|
let volumes: &'static [_] = if QUIRKY_RAND.get(st_seed) % 512 == 17 {
|
||||||
if st_sample.temp > CONFIG.desert_temp {
|
if st_sample.temp > CONFIG.desert_temp {
|
||||||
&QUIRKY_DRY
|
&QUIRKY_DRY
|
||||||
} else {
|
} else {
|
||||||
|
@ -131,10 +131,12 @@ impl World {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const SPAWN_RATE: f32 = 0.1;
|
const SPAWN_RATE: f32 = 0.1;
|
||||||
|
const BOSS_RATE: f32 = 0.1;
|
||||||
let supplement = ChunkSupplement {
|
let supplement = ChunkSupplement {
|
||||||
npcs: if rand::thread_rng().gen::<f32>() < SPAWN_RATE && sim_chunk.chaos < 0.5 {
|
npcs: if rand::thread_rng().gen::<f32>() < SPAWN_RATE && sim_chunk.chaos < 0.5 {
|
||||||
vec![NpcInfo {
|
vec![NpcInfo {
|
||||||
pos: gen_entity_pos(),
|
pos: gen_entity_pos(),
|
||||||
|
boss: rand::thread_rng().gen::<f32>() < BOSS_RATE,
|
||||||
}]
|
}]
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
@ -147,6 +149,7 @@ impl World {
|
|||||||
|
|
||||||
pub struct NpcInfo {
|
pub struct NpcInfo {
|
||||||
pub pos: Vec3<f32>,
|
pub pos: Vec3<f32>,
|
||||||
|
pub boss: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ChunkSupplement {
|
pub struct ChunkSupplement {
|
||||||
|
Reference in New Issue
Block a user