mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Make tornado (and empty models in general) work on WGPU.
This commit is contained in:
parent
3ba0500b90
commit
cb0566299a
assets/common/abilities
ability_set_manifest.ron
custom
common/src/comp
server/src
voxygen
anim/src
src
world/src/layer
@ -265,8 +265,8 @@
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
Custom("Bird Large Basic"): (
|
Custom("Bird Large Basic"): (
|
||||||
primary: "common.abilities.custom.birdlargebreathe.firebomb",
|
primary: "common.abilities.custom.birdlargebasic.dash",
|
||||||
secondary: "common.abilities.custom.birdlargebreathe.triplestrike",
|
secondary: "common.abilities.custom.birdlargebasic.triplestrike",
|
||||||
abilities: [
|
abilities: [
|
||||||
(None, "common.abilities.custom.birdlargebasic.summontornadoes"),
|
(None, "common.abilities.custom.birdlargebasic.summontornadoes"),
|
||||||
],
|
],
|
||||||
|
20
assets/common/abilities/custom/birdlargebasic/dash.ron
Normal file
20
assets/common/abilities/custom/birdlargebasic/dash.ron
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
DashMelee(
|
||||||
|
energy_cost: 0,
|
||||||
|
base_damage: 70,
|
||||||
|
scaled_damage: 150,
|
||||||
|
base_poise_damage: 50,
|
||||||
|
scaled_poise_damage: 100,
|
||||||
|
base_knockback: 12.0,
|
||||||
|
scaled_knockback: 17.0,
|
||||||
|
range: 6.0,
|
||||||
|
angle: 20.0,
|
||||||
|
energy_drain: 0,
|
||||||
|
forward_speed: 1.5,
|
||||||
|
buildup_duration: 0.5,
|
||||||
|
charge_duration: 1.2,
|
||||||
|
swing_duration: 0.1,
|
||||||
|
recover_duration: 1.1,
|
||||||
|
charge_through: true,
|
||||||
|
is_interruptible: false,
|
||||||
|
damage_kind: Crushing,
|
||||||
|
)
|
@ -1,9 +1,9 @@
|
|||||||
BasicSummon(
|
BasicSummon(
|
||||||
buildup_duration: 0.5,
|
buildup_duration: 0.5,
|
||||||
cast_duration: 1.0,
|
cast_duration: 0.2,
|
||||||
recover_duration: 0.5,
|
recover_duration: 0.2,
|
||||||
summon_amount: 6,
|
summon_amount: 6,
|
||||||
summon_distance: (1, 5),
|
summon_distance: (1, 3),
|
||||||
summon_info: (
|
summon_info: (
|
||||||
body: Object(Tornado),
|
body: Object(Tornado),
|
||||||
scale: None,
|
scale: None,
|
||||||
@ -12,7 +12,7 @@ BasicSummon(
|
|||||||
skillset_config: None,
|
skillset_config: None,
|
||||||
),
|
),
|
||||||
duration: Some((
|
duration: Some((
|
||||||
secs: 5,
|
secs: 10,
|
||||||
nanos: 0,
|
nanos: 0,
|
||||||
)),
|
)),
|
||||||
)
|
)
|
@ -0,0 +1,57 @@
|
|||||||
|
ComboMelee(
|
||||||
|
stage_data: [
|
||||||
|
(
|
||||||
|
stage: 1,
|
||||||
|
base_damage: 100,
|
||||||
|
damage_increase: 0,
|
||||||
|
base_poise_damage: 0,
|
||||||
|
poise_damage_increase: 0,
|
||||||
|
knockback: 5.0,
|
||||||
|
range: 4.5,
|
||||||
|
angle: 30.0,
|
||||||
|
base_buildup_duration: 0.4,
|
||||||
|
base_swing_duration: 0.1,
|
||||||
|
base_recover_duration: 0.3,
|
||||||
|
forward_movement: 2.0,
|
||||||
|
damage_kind: Slashing,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
stage: 2,
|
||||||
|
base_damage: 80,
|
||||||
|
damage_increase: 0,
|
||||||
|
base_poise_damage: 0,
|
||||||
|
poise_damage_increase: 0,
|
||||||
|
knockback: 5.0,
|
||||||
|
range: 3.5,
|
||||||
|
angle: 30.0,
|
||||||
|
base_buildup_duration: 0.4,
|
||||||
|
base_swing_duration: 0.1,
|
||||||
|
base_recover_duration: 0.3,
|
||||||
|
forward_movement: 1.5,
|
||||||
|
damage_kind: Slashing,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
stage: 3,
|
||||||
|
base_damage: 130,
|
||||||
|
damage_increase: 0,
|
||||||
|
base_poise_damage: 0,
|
||||||
|
poise_damage_increase: 0,
|
||||||
|
knockback: 10.0,
|
||||||
|
range: 3.5,
|
||||||
|
angle: 30.0,
|
||||||
|
base_buildup_duration: 0.65,
|
||||||
|
base_swing_duration: 0.1,
|
||||||
|
base_recover_duration: 0.3,
|
||||||
|
forward_movement: 1.5,
|
||||||
|
damage_kind: Slashing,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
initial_energy_gain: 0,
|
||||||
|
max_energy_gain: 0,
|
||||||
|
energy_increase: 0,
|
||||||
|
speed_increase: 0.0,
|
||||||
|
max_speed_increase: 0.0,
|
||||||
|
scales_from_combo: 0,
|
||||||
|
is_interruptible: false,
|
||||||
|
ori_modifier: 0.7,
|
||||||
|
)
|
@ -2,9 +2,9 @@ SpinMelee(
|
|||||||
buildup_duration: 0.0,
|
buildup_duration: 0.0,
|
||||||
swing_duration: 0.5,
|
swing_duration: 0.5,
|
||||||
recover_duration: 0.0,
|
recover_duration: 0.0,
|
||||||
base_damage: 15000,
|
base_damage: 50,
|
||||||
base_poise_damage: 200,
|
base_poise_damage: 100,
|
||||||
knockback: ( strength: 200.0, direction: Away),
|
knockback: ( strength: 50.0, direction: Away),
|
||||||
range: 3.5,
|
range: 3.5,
|
||||||
damage_effect: None,
|
damage_effect: None,
|
||||||
energy_cost: 0,
|
energy_cost: 0,
|
||||||
|
@ -472,7 +472,10 @@ impl Body {
|
|||||||
},
|
},
|
||||||
Body::FishMedium(_) => 250,
|
Body::FishMedium(_) => 250,
|
||||||
Body::Dragon(_) => 5000,
|
Body::Dragon(_) => 5000,
|
||||||
Body::BirdLarge(_) => 3000,
|
Body::BirdLarge(bird_large) => match bird_large.species {
|
||||||
|
bird_large::Species::Roc => 2400,
|
||||||
|
_ => 3000,
|
||||||
|
},
|
||||||
Body::FishSmall(_) => 20,
|
Body::FishSmall(_) => 20,
|
||||||
Body::BipedLarge(biped_large) => match biped_large.species {
|
Body::BipedLarge(biped_large) => match biped_large.species {
|
||||||
biped_large::Species::Ogre => 3200,
|
biped_large::Species::Ogre => 3200,
|
||||||
@ -591,7 +594,10 @@ impl Body {
|
|||||||
},
|
},
|
||||||
Body::FishMedium(_) => 10,
|
Body::FishMedium(_) => 10,
|
||||||
Body::Dragon(_) => 500,
|
Body::Dragon(_) => 500,
|
||||||
Body::BirdLarge(_) => 120,
|
Body::BirdLarge(bird_large) => match bird_large.species {
|
||||||
|
bird_large::Species::Roc => 100,
|
||||||
|
_ => 120,
|
||||||
|
},
|
||||||
Body::FishSmall(_) => 10,
|
Body::FishSmall(_) => 10,
|
||||||
Body::BipedLarge(biped_large) => match biped_large.species {
|
Body::BipedLarge(biped_large) => match biped_large.species {
|
||||||
biped_large::Species::Ogre => 70,
|
biped_large::Species::Ogre => 70,
|
||||||
|
@ -376,6 +376,7 @@ impl Body {
|
|||||||
Body::HaniwaSentry => Vec3::new(0.8, 0.8, 1.4),
|
Body::HaniwaSentry => Vec3::new(0.8, 0.8, 1.4),
|
||||||
Body::SeaLantern => Vec3::new(0.5, 0.5, 1.0),
|
Body::SeaLantern => Vec3::new(0.5, 0.5, 1.0),
|
||||||
Body::Snowball => Vec3::broadcast(2.5),
|
Body::Snowball => Vec3::broadcast(2.5),
|
||||||
|
Body::Tornado => Vec3::new(2.0, 2.0, 3.4),
|
||||||
_ => Vec3::broadcast(0.5),
|
_ => Vec3::broadcast(0.5),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,13 +253,12 @@ fn default_main_tool(body: &Body) -> Item {
|
|||||||
(biped_large::Species::Ogre, biped_large::BodyType::Female) => Some(
|
(biped_large::Species::Ogre, biped_large::BodyType::Female) => Some(
|
||||||
Item::new_from_asset_expect("common.items.npc_weapons.staff.ogre_staff"),
|
Item::new_from_asset_expect("common.items.npc_weapons.staff.ogre_staff"),
|
||||||
),
|
),
|
||||||
(biped_large::Species::Cavetroll, _) => Some(Item::new_from_asset_expect(
|
(
|
||||||
"common.items.npc_weapons.hammer.troll_hammer",
|
biped_large::Species::Mountaintroll
|
||||||
)),
|
| biped_large::Species::Swamptroll
|
||||||
(biped_large::Species::Mountaintroll, _) => Some(Item::new_from_asset_expect(
|
| biped_large::Species::Cavetroll,
|
||||||
"common.items.npc_weapons.hammer.troll_hammer",
|
_,
|
||||||
)),
|
) => Some(Item::new_from_asset_expect(
|
||||||
(biped_large::Species::Swamptroll, _) => Some(Item::new_from_asset_expect(
|
|
||||||
"common.items.npc_weapons.hammer.troll_hammer",
|
"common.items.npc_weapons.hammer.troll_hammer",
|
||||||
)),
|
)),
|
||||||
(biped_large::Species::Wendigo, _) => Some(Item::new_from_asset_expect(
|
(biped_large::Species::Wendigo, _) => Some(Item::new_from_asset_expect(
|
||||||
|
@ -137,6 +137,11 @@ impl<'a> System<'a> for Sys {
|
|||||||
agent,
|
agent,
|
||||||
alignment: match body {
|
alignment: match body {
|
||||||
comp::Body::Humanoid(_) => comp::Alignment::Npc,
|
comp::Body::Humanoid(_) => comp::Alignment::Npc,
|
||||||
|
comp::Body::BirdLarge(bird_large) => match bird_large.species {
|
||||||
|
comp::bird_large::Species::Roc => comp::Alignment::Enemy,
|
||||||
|
comp::bird_large::Species::Cockatrice => comp::Alignment::Enemy,
|
||||||
|
_ => comp::Alignment::Wild,
|
||||||
|
},
|
||||||
_ => comp::Alignment::Wild,
|
_ => comp::Alignment::Wild,
|
||||||
},
|
},
|
||||||
scale: match body {
|
scale: match body {
|
||||||
|
@ -3286,18 +3286,57 @@ impl<'a> AgentData<'a> {
|
|||||||
tgt_data: &TargetData,
|
tgt_data: &TargetData,
|
||||||
read_data: &ReadData,
|
read_data: &ReadData,
|
||||||
) {
|
) {
|
||||||
if can_see_tgt(
|
if !read_data
|
||||||
&*read_data.terrain,
|
.terrain
|
||||||
self.pos,
|
.ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * 2.0))
|
||||||
tgt_data.pos,
|
.until(Block::is_solid)
|
||||||
attack_data.dist_sqrd,
|
.cast()
|
||||||
) && attack_data.angle < 15.0
|
.1
|
||||||
|
.map_or(true, |b| b.is_some())
|
||||||
|
{
|
||||||
|
// Fly to target
|
||||||
|
controller
|
||||||
|
.actions
|
||||||
|
.push(ControlAction::basic_input(InputKind::Fly));
|
||||||
|
let move_dir = tgt_data.pos.0 - self.pos.0;
|
||||||
|
controller.inputs.move_dir =
|
||||||
|
move_dir.xy().try_normalized().unwrap_or_else(Vec2::zero) * 2.0;
|
||||||
|
controller.inputs.move_z = move_dir.z - 0.5;
|
||||||
|
} else if agent.action_state.timer > 7.0 {
|
||||||
|
controller
|
||||||
|
.actions
|
||||||
|
.push(ControlAction::basic_input(InputKind::Ability(0)));
|
||||||
|
// Reset timer
|
||||||
|
agent.action_state.timer = 0.0;
|
||||||
|
} else if attack_data.angle < 90.0
|
||||||
|
&& attack_data.dist_sqrd < (1.5 * attack_data.min_attack_dist).powi(2)
|
||||||
|
&& agent.action_state.timer < 6.0
|
||||||
|
{
|
||||||
|
controller.inputs.move_dir = Vec2::zero();
|
||||||
|
controller
|
||||||
|
.actions
|
||||||
|
.push(ControlAction::basic_input(InputKind::Secondary));
|
||||||
|
agent.action_state.timer += read_data.dt.0;
|
||||||
|
} else if attack_data.dist_sqrd < (3.0 * attack_data.min_attack_dist).powi(2)
|
||||||
|
&& attack_data.dist_sqrd > (2.0 * attack_data.min_attack_dist).powi(2)
|
||||||
|
&& attack_data.angle < 90.0
|
||||||
|
&& agent.action_state.timer < 6.0
|
||||||
{
|
{
|
||||||
controller
|
controller
|
||||||
.actions
|
.actions
|
||||||
.push(ControlAction::basic_input(InputKind::Primary));
|
.push(ControlAction::basic_input(InputKind::Primary));
|
||||||
|
controller.inputs.move_dir = (tgt_data.pos.0 - self.pos.0)
|
||||||
|
.xy()
|
||||||
|
.rotated_z(-0.47 * PI)
|
||||||
|
.try_normalized()
|
||||||
|
.unwrap_or_else(Vec2::unit_y);
|
||||||
|
agent.action_state.timer += read_data.dt.0;
|
||||||
|
} else if attack_data.dist_sqrd < MAX_PATH_DIST.powi(2) {
|
||||||
|
self.path_toward_target(agent, controller, tgt_data, read_data, true, None);
|
||||||
|
agent.action_state.timer += read_data.dt.0;
|
||||||
} else {
|
} else {
|
||||||
agent.target = None;
|
self.path_toward_target(agent, controller, tgt_data, read_data, false, None);
|
||||||
|
agent.action_state.timer += read_data.dt.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,7 +419,7 @@ impl<'a> From<&'a Body> for SkeletonAttr {
|
|||||||
(Wendigo, _) => (15.0, 0.0),
|
(Wendigo, _) => (15.0, 0.0),
|
||||||
(Cavetroll, _) => (13.0, 1.5),
|
(Cavetroll, _) => (13.0, 1.5),
|
||||||
(Mountaintroll, _) => (13.0, 1.5),
|
(Mountaintroll, _) => (13.0, 1.5),
|
||||||
(Swamptroll, _) => (13.0, 1.5),
|
(Swamptroll, _) => (15.0, 0.5),
|
||||||
(Dullahan, _) => (15.0, 0.0),
|
(Dullahan, _) => (15.0, 0.0),
|
||||||
(Werewolf, _) => (13.0, 0.0),
|
(Werewolf, _) => (13.0, 0.0),
|
||||||
(Occultsaurok, _) => (10.0, 0.0),
|
(Occultsaurok, _) => (10.0, 0.0),
|
||||||
|
177
voxygen/anim/src/bird_large/dash.rs
Normal file
177
voxygen/anim/src/bird_large/dash.rs
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
use super::{
|
||||||
|
super::{vek::*, Animation},
|
||||||
|
BirdLargeSkeleton, SkeletonAttr,
|
||||||
|
};
|
||||||
|
use common::states::utils::StageSection;
|
||||||
|
use std::f32::consts::PI;
|
||||||
|
|
||||||
|
pub struct DashAnimation;
|
||||||
|
type DashAnimationDependency<'a> = (
|
||||||
|
Vec3<f32>,
|
||||||
|
Vec3<f32>,
|
||||||
|
Vec3<f32>,
|
||||||
|
f32,
|
||||||
|
Option<StageSection>,
|
||||||
|
f32,
|
||||||
|
f32,
|
||||||
|
);
|
||||||
|
|
||||||
|
impl Animation for DashAnimation {
|
||||||
|
type Dependency<'a> = DashAnimationDependency<'a>;
|
||||||
|
type Skeleton = BirdLargeSkeleton;
|
||||||
|
|
||||||
|
#[cfg(feature = "use-dyn-lib")]
|
||||||
|
const UPDATE_FN: &'static [u8] = b"bird_large_dash\0";
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_dash")]
|
||||||
|
fn update_skeleton_inner<'a>(
|
||||||
|
skeleton: &Self::Skeleton,
|
||||||
|
(velocity, orientation, last_ori, acc_vel, stage_section, global_time, timer): Self::Dependency<'a>,
|
||||||
|
anim_time: f32,
|
||||||
|
rate: &mut f32,
|
||||||
|
s_a: &SkeletonAttr,
|
||||||
|
) -> Self::Skeleton {
|
||||||
|
let mut next = (*skeleton).clone();
|
||||||
|
let speed = (Vec2::<f32>::from(velocity).magnitude()).min(22.0);
|
||||||
|
*rate = 1.0;
|
||||||
|
|
||||||
|
let (movement1base, chargemovementbase, movement2base, movement3, legtell) =
|
||||||
|
match stage_section {
|
||||||
|
Some(StageSection::Buildup) => (anim_time.sqrt(), 0.0, 0.0, 0.0, anim_time),
|
||||||
|
Some(StageSection::Charge) => (1.0, 1.0, 0.0, 0.0, 0.0),
|
||||||
|
Some(StageSection::Swing) => (1.0, 0.0, anim_time.powi(4), 0.0, 1.0),
|
||||||
|
Some(StageSection::Recover) => (1.0, 0.0, 1.0, anim_time, 1.0),
|
||||||
|
_ => (0.0, 0.0, 0.0, 0.0, 0.0),
|
||||||
|
};
|
||||||
|
let pullback = 1.0 - movement3;
|
||||||
|
let subtract = global_time - timer;
|
||||||
|
let check = subtract - subtract.trunc();
|
||||||
|
let mirror = (check - 0.5).signum();
|
||||||
|
let movement1abs = movement1base * pullback;
|
||||||
|
let movement2abs = movement2base * pullback;
|
||||||
|
let legtwitch = (legtell * 6.0).sin() * pullback;
|
||||||
|
let legswing = legtell * pullback;
|
||||||
|
let chargeanim = (chargemovementbase * anim_time * 15.0).sin();
|
||||||
|
|
||||||
|
//let speednorm = speed / 13.0;
|
||||||
|
let speednorm = (speed / 13.0).powf(0.25);
|
||||||
|
|
||||||
|
let speedmult = 0.8;
|
||||||
|
let lab: f32 = 0.6; //6
|
||||||
|
|
||||||
|
// acc_vel and anim_time mix to make sure phase lenght isn't starting at
|
||||||
|
// +infinite
|
||||||
|
let mixed_vel = acc_vel + anim_time * 5.0; //sets run frequency using speed, with anim_time setting a floor
|
||||||
|
|
||||||
|
let short = ((1.0
|
||||||
|
/ (0.72
|
||||||
|
+ 0.28 * ((mixed_vel * 1.0 * lab * speedmult + PI * -0.15 - 0.5).sin()).powi(2)))
|
||||||
|
.sqrt())
|
||||||
|
* ((mixed_vel * 1.0 * lab * speedmult + PI * -0.15 - 0.5).sin())
|
||||||
|
* speednorm;
|
||||||
|
|
||||||
|
//
|
||||||
|
let shortalt = (mixed_vel * 1.0 * lab * speedmult + PI * 3.0 / 8.0 - 0.5).sin() * speednorm;
|
||||||
|
|
||||||
|
let ori: Vec2<f32> = Vec2::from(orientation);
|
||||||
|
let last_ori = Vec2::from(last_ori);
|
||||||
|
let tilt = if ::vek::Vec2::new(ori, last_ori)
|
||||||
|
.map(|o| o.magnitude_squared())
|
||||||
|
.map(|m| m > 0.001 && m.is_finite())
|
||||||
|
.reduce_and()
|
||||||
|
&& ori.angle_between(last_ori).is_finite()
|
||||||
|
{
|
||||||
|
ori.angle_between(last_ori).min(0.2)
|
||||||
|
* last_ori.determine_side(Vec2::zero(), ori).signum()
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
} * 1.3;
|
||||||
|
|
||||||
|
next.head.scale = Vec3::one() * 0.98;
|
||||||
|
next.neck.scale = Vec3::one() * 1.02;
|
||||||
|
next.leg_l.scale = Vec3::one() / 8.0 * 0.98;
|
||||||
|
next.leg_r.scale = Vec3::one() / 8.0 * 0.98;
|
||||||
|
next.foot_l.scale = Vec3::one() * 1.02;
|
||||||
|
next.foot_r.scale = Vec3::one() * 1.02;
|
||||||
|
next.chest.scale = Vec3::one() * s_a.scaler / 8.0;
|
||||||
|
|
||||||
|
next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
|
||||||
|
next.head.orientation = Quaternion::rotation_x(
|
||||||
|
-0.1 * speednorm + short * -0.05 + movement1abs * -0.8 + movement2abs * 0.2,
|
||||||
|
) * Quaternion::rotation_y(tilt * 0.2)
|
||||||
|
* Quaternion::rotation_z(shortalt * -0.05 - tilt * 1.5);
|
||||||
|
|
||||||
|
next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1);
|
||||||
|
next.beak.orientation =
|
||||||
|
Quaternion::rotation_x(short * -0.02 - 0.02 + movement1abs * -0.4 + movement2abs * 0.4);
|
||||||
|
|
||||||
|
next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1);
|
||||||
|
next.neck.orientation = Quaternion::rotation_x(-0.1 * speednorm + short * -0.04)
|
||||||
|
* Quaternion::rotation_y(tilt * 0.1)
|
||||||
|
* Quaternion::rotation_z(shortalt * -0.1 - tilt * 0.5);
|
||||||
|
|
||||||
|
next.chest.position = Vec3::new(
|
||||||
|
0.0,
|
||||||
|
s_a.chest.0,
|
||||||
|
s_a.chest.1 + short * 0.5 + 0.5 * speednorm,
|
||||||
|
) * s_a.scaler
|
||||||
|
/ 8.0;
|
||||||
|
next.chest.orientation =
|
||||||
|
Quaternion::rotation_x(short * 0.07 + movement1abs * 0.8 + movement2abs * -1.2)
|
||||||
|
* Quaternion::rotation_y(tilt * 0.8)
|
||||||
|
* Quaternion::rotation_z(shortalt * 0.10);
|
||||||
|
|
||||||
|
next.tail_front.position = Vec3::new(0.0, s_a.tail_front.0, s_a.tail_front.1);
|
||||||
|
next.tail_front.orientation =
|
||||||
|
Quaternion::rotation_x(0.6 + short * -0.02 + movement1abs * -0.8 + movement2abs * 0.8);
|
||||||
|
|
||||||
|
next.tail_rear.position = Vec3::new(0.0, s_a.tail_rear.0, s_a.tail_rear.1);
|
||||||
|
next.tail_rear.orientation = Quaternion::rotation_x(-0.2 + short * -0.1);
|
||||||
|
|
||||||
|
next.wing_in_l.position = Vec3::new(-s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2);
|
||||||
|
next.wing_in_r.position = Vec3::new(s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2);
|
||||||
|
|
||||||
|
next.wing_in_l.orientation =
|
||||||
|
Quaternion::rotation_y(
|
||||||
|
-0.8 + movement1abs * 1.0 + chargeanim * 0.2 - movement2abs * 0.6,
|
||||||
|
) * Quaternion::rotation_z(0.2 - movement1abs * 0.6 - movement2abs * 0.6);
|
||||||
|
next.wing_in_r.orientation =
|
||||||
|
Quaternion::rotation_y(
|
||||||
|
0.8 - movement1abs * 1.0 - chargeanim * 0.2 + movement2abs * 0.6,
|
||||||
|
) * Quaternion::rotation_z(-0.2 + movement1abs * 0.6 + movement2abs * 0.6);
|
||||||
|
|
||||||
|
next.wing_mid_l.position = Vec3::new(-s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2);
|
||||||
|
next.wing_mid_r.position = Vec3::new(s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2);
|
||||||
|
next.wing_mid_l.orientation = Quaternion::rotation_y(-0.1) * Quaternion::rotation_z(0.7);
|
||||||
|
next.wing_mid_r.orientation = Quaternion::rotation_y(0.1) * Quaternion::rotation_z(-0.7);
|
||||||
|
|
||||||
|
next.wing_out_l.position = Vec3::new(-s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2);
|
||||||
|
next.wing_out_r.position = Vec3::new(s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2);
|
||||||
|
next.wing_out_l.orientation =
|
||||||
|
Quaternion::rotation_y(-0.2 + short * 0.05) * Quaternion::rotation_z(0.2);
|
||||||
|
next.wing_out_r.orientation =
|
||||||
|
Quaternion::rotation_y(0.2 + short * -0.05) * Quaternion::rotation_z(-0.2);
|
||||||
|
|
||||||
|
if legtell > 0.0 {
|
||||||
|
if mirror.is_sign_positive() {
|
||||||
|
next.leg_l.orientation = Quaternion::rotation_x(legswing * 1.1);
|
||||||
|
|
||||||
|
next.foot_l.orientation = Quaternion::rotation_x(legswing * -1.1 + legtwitch * 0.5);
|
||||||
|
|
||||||
|
next.leg_r.orientation = Quaternion::rotation_x(0.0);
|
||||||
|
|
||||||
|
next.foot_r.orientation = Quaternion::rotation_x(0.0);
|
||||||
|
} else {
|
||||||
|
next.leg_l.orientation = Quaternion::rotation_x(0.0);
|
||||||
|
|
||||||
|
next.foot_l.orientation = Quaternion::rotation_x(0.0);
|
||||||
|
|
||||||
|
next.leg_r.orientation = Quaternion::rotation_x(legswing * 1.1);
|
||||||
|
|
||||||
|
next.foot_r.orientation = Quaternion::rotation_x(legswing * -1.1 + legtwitch * 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
next
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
pub mod alpha;
|
pub mod alpha;
|
||||||
pub mod breathe;
|
pub mod breathe;
|
||||||
|
pub mod dash;
|
||||||
pub mod feed;
|
pub mod feed;
|
||||||
pub mod fly;
|
pub mod fly;
|
||||||
pub mod idle;
|
pub mod idle;
|
||||||
@ -7,13 +8,14 @@ pub mod run;
|
|||||||
pub mod shockwave;
|
pub mod shockwave;
|
||||||
pub mod shoot;
|
pub mod shoot;
|
||||||
pub mod stunned;
|
pub mod stunned;
|
||||||
|
pub mod summon;
|
||||||
pub mod swim;
|
pub mod swim;
|
||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
pub use self::{
|
pub use self::{
|
||||||
alpha::AlphaAnimation, breathe::BreatheAnimation, feed::FeedAnimation, fly::FlyAnimation,
|
alpha::AlphaAnimation, breathe::BreatheAnimation, dash::DashAnimation, feed::FeedAnimation,
|
||||||
idle::IdleAnimation, run::RunAnimation, shockwave::ShockwaveAnimation, shoot::ShootAnimation,
|
fly::FlyAnimation, idle::IdleAnimation, run::RunAnimation, shockwave::ShockwaveAnimation,
|
||||||
stunned::StunnedAnimation, swim::SwimAnimation,
|
shoot::ShootAnimation, stunned::StunnedAnimation, summon::SummonAnimation, swim::SwimAnimation,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||||
|
114
voxygen/anim/src/bird_large/summon.rs
Normal file
114
voxygen/anim/src/bird_large/summon.rs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
use super::{
|
||||||
|
super::{vek::*, Animation},
|
||||||
|
BirdLargeSkeleton, SkeletonAttr,
|
||||||
|
};
|
||||||
|
use common::{states::utils::StageSection, util::Dir};
|
||||||
|
|
||||||
|
pub struct SummonAnimation;
|
||||||
|
|
||||||
|
type SummonAnimationDependency = (f32, Option<StageSection>, f32, Dir, bool);
|
||||||
|
|
||||||
|
impl Animation for SummonAnimation {
|
||||||
|
type Dependency<'a> = SummonAnimationDependency;
|
||||||
|
type Skeleton = BirdLargeSkeleton;
|
||||||
|
|
||||||
|
#[cfg(feature = "use-dyn-lib")]
|
||||||
|
const UPDATE_FN: &'static [u8] = b"bird_large_summon\0";
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_summon")]
|
||||||
|
#[allow(clippy::approx_constant)] // TODO: Pending review in #587
|
||||||
|
fn update_skeleton_inner<'a>(
|
||||||
|
skeleton: &Self::Skeleton,
|
||||||
|
(global_time, stage_section, timer, look_dir, on_ground): Self::Dependency<'a>,
|
||||||
|
anim_time: f32,
|
||||||
|
rate: &mut f32,
|
||||||
|
s_a: &SkeletonAttr,
|
||||||
|
) -> Self::Skeleton {
|
||||||
|
*rate = 1.0;
|
||||||
|
let mut next = (*skeleton).clone();
|
||||||
|
|
||||||
|
let (movement1base, movement2base, movement3, twitch) = match stage_section {
|
||||||
|
Some(StageSection::Buildup) => (anim_time.powf(0.25), 0.0, 0.0, 0.0),
|
||||||
|
Some(StageSection::Cast) => (1.0, anim_time.min(1.0).powf(0.1), 0.0, anim_time),
|
||||||
|
Some(StageSection::Recover) => (1.0, 1.0, anim_time.min(1.0).powi(2), 1.0),
|
||||||
|
_ => (0.0, 0.0, 0.0, 0.0),
|
||||||
|
};
|
||||||
|
|
||||||
|
let pullback = 1.0 - movement3;
|
||||||
|
let subtract = global_time - timer;
|
||||||
|
let check = subtract - subtract.trunc();
|
||||||
|
let mirror = (check - 0.5).signum();
|
||||||
|
let twitch2 = mirror * (twitch * 20.0).sin() * pullback;
|
||||||
|
|
||||||
|
let movement1abs = movement1base * pullback;
|
||||||
|
let movement2abs = movement2base * pullback;
|
||||||
|
|
||||||
|
let wave_slow_cos = (anim_time * 4.5).cos();
|
||||||
|
|
||||||
|
next.head.scale = Vec3::one() * 0.98;
|
||||||
|
next.neck.scale = Vec3::one() * 1.02;
|
||||||
|
next.leg_l.scale = Vec3::one() / 8.0 * 0.98;
|
||||||
|
next.leg_r.scale = Vec3::one() / 8.0 * 0.98;
|
||||||
|
next.foot_l.scale = Vec3::one() * 1.02;
|
||||||
|
next.foot_r.scale = Vec3::one() * 1.02;
|
||||||
|
next.chest.scale = Vec3::one() * s_a.scaler / 8.0;
|
||||||
|
|
||||||
|
next.chest.position = Vec3::new(
|
||||||
|
0.0,
|
||||||
|
s_a.chest.0,
|
||||||
|
s_a.chest.1 + wave_slow_cos * 0.06 + twitch2 * 0.1,
|
||||||
|
) * s_a.scaler
|
||||||
|
/ 8.0;
|
||||||
|
|
||||||
|
next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
|
||||||
|
next.head.orientation =
|
||||||
|
Quaternion::rotation_x(movement1abs * -1.0 - movement2abs * 0.1 + look_dir.z * 0.4);
|
||||||
|
|
||||||
|
next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1);
|
||||||
|
next.beak.orientation = Quaternion::rotation_x(movement1abs * -0.7 + twitch2 * 0.1);
|
||||||
|
|
||||||
|
if on_ground {
|
||||||
|
next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1);
|
||||||
|
next.neck.orientation = Quaternion::rotation_x(movement1abs * 0.5 - movement2abs * 0.5);
|
||||||
|
|
||||||
|
next.chest.orientation =
|
||||||
|
Quaternion::rotation_x(movement1abs * 1.1 - movement2abs * 0.1);
|
||||||
|
|
||||||
|
next.wing_in_l.position = Vec3::new(-s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2);
|
||||||
|
next.wing_in_r.position = Vec3::new(s_a.wing_in.0, s_a.wing_in.1, s_a.wing_in.2);
|
||||||
|
|
||||||
|
next.wing_in_l.orientation =
|
||||||
|
Quaternion::rotation_x(movement1abs * 0.4 - movement2abs * 0.4)
|
||||||
|
* Quaternion::rotation_y(-1.0 + movement1abs * 1.6 - movement2abs * 1.8)
|
||||||
|
* Quaternion::rotation_z(0.2 - movement1abs * 1.8 + movement2abs * 0.4);
|
||||||
|
next.wing_in_r.orientation =
|
||||||
|
Quaternion::rotation_x(movement1abs * 0.4 - movement2abs * 0.4)
|
||||||
|
* Quaternion::rotation_y(1.0 - movement1abs * 1.6 + movement2abs * 1.8)
|
||||||
|
* Quaternion::rotation_z(-0.2 + movement1abs * 1.8 - movement2abs * 0.4);
|
||||||
|
|
||||||
|
next.wing_mid_l.position = Vec3::new(-s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2);
|
||||||
|
next.wing_mid_r.position = Vec3::new(s_a.wing_mid.0, s_a.wing_mid.1, s_a.wing_mid.2);
|
||||||
|
next.wing_mid_l.orientation =
|
||||||
|
Quaternion::rotation_y(-0.1 - movement2abs * 0.4) * Quaternion::rotation_z(0.7);
|
||||||
|
next.wing_mid_r.orientation =
|
||||||
|
Quaternion::rotation_y(0.1 + movement2abs * 0.4) * Quaternion::rotation_z(-0.7);
|
||||||
|
|
||||||
|
next.wing_out_l.position = Vec3::new(-s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2);
|
||||||
|
next.wing_out_r.position = Vec3::new(s_a.wing_out.0, s_a.wing_out.1, s_a.wing_out.2);
|
||||||
|
next.wing_out_l.orientation =
|
||||||
|
Quaternion::rotation_y(-0.2 - movement2abs * 0.4) * Quaternion::rotation_z(0.2);
|
||||||
|
next.wing_out_r.orientation =
|
||||||
|
Quaternion::rotation_y(0.2 + movement2abs * 0.4) * Quaternion::rotation_z(-0.2);
|
||||||
|
|
||||||
|
next.tail_front.position = Vec3::new(0.0, s_a.tail_front.0, s_a.tail_front.1);
|
||||||
|
next.tail_front.orientation =
|
||||||
|
Quaternion::rotation_x(-movement1abs * 0.1 + movement2abs * 0.1 + twitch2 * 0.02);
|
||||||
|
next.tail_rear.position = Vec3::new(0.0, s_a.tail_rear.0, s_a.tail_rear.1);
|
||||||
|
next.tail_rear.orientation =
|
||||||
|
Quaternion::rotation_x(-movement1abs * 0.1 + movement2abs * 0.1 + twitch2 * 0.02);
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
|
next
|
||||||
|
}
|
||||||
|
}
|
@ -80,7 +80,7 @@ impl Default for BoneData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct FigureModel {
|
pub struct FigureModel {
|
||||||
pub opaque: Model<Vertex>,
|
pub opaque: Option<Model<Vertex>>,
|
||||||
/* TODO: Consider using mipmaps instead of storing multiple texture atlases for different
|
/* TODO: Consider using mipmaps instead of storing multiple texture atlases for different
|
||||||
* LOD levels. */
|
* LOD levels. */
|
||||||
}
|
}
|
||||||
|
@ -88,11 +88,12 @@ pub struct FigureModelEntry<const N: usize> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<const N: usize> FigureModelEntry<N> {
|
impl<const N: usize> FigureModelEntry<N> {
|
||||||
pub fn lod_model(&self, lod: usize) -> SubModel<TerrainVertex> {
|
pub fn lod_model(&self, lod: usize) -> Option<SubModel<TerrainVertex>> {
|
||||||
// Note: Range doesn't impl Copy even for trivially Cloneable things
|
// Note: Range doesn't impl Copy even for trivially Cloneable things
|
||||||
self.model
|
self.model
|
||||||
.opaque
|
.opaque
|
||||||
.submodel(self.lod_vertex_ranges[lod].clone())
|
.as_ref()
|
||||||
|
.map(|m| m.submodel(self.lod_vertex_ranges[lod].clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3480,6 +3481,70 @@ impl FigureMgr {
|
|||||||
skeleton_attr,
|
skeleton_attr,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
CharacterState::BasicSummon(s) => {
|
||||||
|
let stage_time = s.timer.as_secs_f32();
|
||||||
|
let stage_progress = match s.stage_section {
|
||||||
|
StageSection::Buildup => {
|
||||||
|
stage_time / s.static_data.buildup_duration.as_secs_f32()
|
||||||
|
},
|
||||||
|
|
||||||
|
StageSection::Cast => {
|
||||||
|
stage_time / s.static_data.cast_duration.as_secs_f32()
|
||||||
|
},
|
||||||
|
StageSection::Recover => {
|
||||||
|
stage_time / s.static_data.recover_duration.as_secs_f32()
|
||||||
|
},
|
||||||
|
_ => 0.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
anim::bird_large::SummonAnimation::update_skeleton(
|
||||||
|
&target_base,
|
||||||
|
(
|
||||||
|
time,
|
||||||
|
Some(s.stage_section),
|
||||||
|
state.state_time,
|
||||||
|
look_dir,
|
||||||
|
physics.on_ground,
|
||||||
|
),
|
||||||
|
stage_progress,
|
||||||
|
&mut state_animation_rate,
|
||||||
|
skeleton_attr,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
CharacterState::DashMelee(s) => {
|
||||||
|
let stage_time = s.timer.as_secs_f32();
|
||||||
|
let stage_progress = match s.stage_section {
|
||||||
|
StageSection::Buildup => {
|
||||||
|
stage_time / s.static_data.buildup_duration.as_secs_f32()
|
||||||
|
},
|
||||||
|
StageSection::Charge => {
|
||||||
|
stage_time / s.static_data.charge_duration.as_secs_f32()
|
||||||
|
},
|
||||||
|
StageSection::Swing => {
|
||||||
|
stage_time / s.static_data.swing_duration.as_secs_f32()
|
||||||
|
},
|
||||||
|
StageSection::Recover => {
|
||||||
|
stage_time / s.static_data.recover_duration.as_secs_f32()
|
||||||
|
},
|
||||||
|
_ => 0.0,
|
||||||
|
};
|
||||||
|
anim::bird_large::DashAnimation::update_skeleton(
|
||||||
|
&target_base,
|
||||||
|
(
|
||||||
|
rel_vel,
|
||||||
|
// TODO: Update to use the quaternion.
|
||||||
|
ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||||
|
state.last_ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||||
|
state.acc_vel,
|
||||||
|
Some(s.stage_section),
|
||||||
|
time,
|
||||||
|
state.state_time,
|
||||||
|
),
|
||||||
|
stage_progress,
|
||||||
|
&mut state_animation_rate,
|
||||||
|
skeleton_attr,
|
||||||
|
)
|
||||||
|
},
|
||||||
CharacterState::Stunned(s) => {
|
CharacterState::Stunned(s) => {
|
||||||
let stage_time = s.timer.as_secs_f32();
|
let stage_time = s.timer.as_secs_f32();
|
||||||
let stage_progress = match s.stage_section {
|
let stage_progress = match s.stage_section {
|
||||||
@ -5163,7 +5228,7 @@ impl FigureMgr {
|
|||||||
model_entry.lod_model(0)
|
model_entry.lod_model(0)
|
||||||
};
|
};
|
||||||
|
|
||||||
Some((bound, model, col_lights_.texture(model_entry)))
|
Some((bound, model?, col_lights_.texture(model_entry)))
|
||||||
} else {
|
} else {
|
||||||
// trace!("Body has no saved figure");
|
// trace!("Body has no saved figure");
|
||||||
None
|
None
|
||||||
@ -5221,9 +5286,7 @@ impl FigureColLights {
|
|||||||
let col_lights = renderer.figure_bind_col_light(col_lights);
|
let col_lights = renderer.figure_bind_col_light(col_lights);
|
||||||
let model_len = u32::try_from(opaque.vertices().len())
|
let model_len = u32::try_from(opaque.vertices().len())
|
||||||
.expect("The model size for this figure does not fit in a u32!");
|
.expect("The model size for this figure does not fit in a u32!");
|
||||||
let model = renderer
|
let model = renderer.create_model(&opaque);
|
||||||
.create_model(&opaque)
|
|
||||||
.expect("The model contains no vertices!");
|
|
||||||
|
|
||||||
vertex_ranges.iter().for_each(|range| {
|
vertex_ranges.iter().for_each(|range| {
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -366,20 +366,20 @@ impl Scene {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if let Some(model) = model {
|
if let Some(model) = model {
|
||||||
figure_drawer.draw(
|
if let Some(lod) = model.lod_model(0) {
|
||||||
model.lod_model(0),
|
figure_drawer.draw(
|
||||||
self.figure_state.bound(),
|
lod,
|
||||||
&self.col_lights.texture(model),
|
self.figure_state.bound(),
|
||||||
);
|
&self.col_lights.texture(model),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((model, state)) = &self.backdrop {
|
if let Some((model, state)) = &self.backdrop {
|
||||||
figure_drawer.draw(
|
if let Some(lod) = model.lod_model(0) {
|
||||||
model.lod_model(0),
|
figure_drawer.draw(lod, state.bound(), &self.col_lights.texture(model));
|
||||||
state.bound(),
|
}
|
||||||
&self.col_lights.texture(model),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
drop(figure_drawer);
|
drop(figure_drawer);
|
||||||
|
|
||||||
|
@ -119,9 +119,15 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
|||||||
Entry {
|
Entry {
|
||||||
make_entity: |pos, rng| {
|
make_entity: |pos, rng| {
|
||||||
EntityInfo::at(pos)
|
EntityInfo::at(pos)
|
||||||
.with_body(
|
.with_body(match rng.gen_range(0..2) {
|
||||||
biped_large::Body::random_with(rng, &biped_large::Species::Wendigo).into(),
|
0 => biped_large::Body::random_with(rng, &biped_large::Species::Wendigo)
|
||||||
)
|
.into(),
|
||||||
|
_ => biped_large::Body::random_with(
|
||||||
|
rng,
|
||||||
|
&biped_large::Species::Mountaintroll,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
})
|
||||||
.with_alignment(Alignment::Enemy)
|
.with_alignment(Alignment::Enemy)
|
||||||
},
|
},
|
||||||
group_size: 1..2,
|
group_size: 1..2,
|
||||||
@ -623,7 +629,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
|||||||
Entry {
|
Entry {
|
||||||
make_entity: |pos, rng| {
|
make_entity: |pos, rng| {
|
||||||
EntityInfo::at(pos)
|
EntityInfo::at(pos)
|
||||||
.with_body(match rng.gen_range(0..4) {
|
.with_body(match rng.gen_range(0..5) {
|
||||||
0 => theropod::Body::random_with(rng, &theropod::Species::Odonto).into(),
|
0 => theropod::Body::random_with(rng, &theropod::Species::Odonto).into(),
|
||||||
1 => {
|
1 => {
|
||||||
biped_large::Body::random_with(rng, &biped_large::Species::Mightysaurok)
|
biped_large::Body::random_with(rng, &biped_large::Species::Mightysaurok)
|
||||||
@ -633,6 +639,8 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
|||||||
biped_large::Body::random_with(rng, &biped_large::Species::Occultsaurok)
|
biped_large::Body::random_with(rng, &biped_large::Species::Occultsaurok)
|
||||||
.into()
|
.into()
|
||||||
},
|
},
|
||||||
|
3 => bird_large::Body::random_with(rng, &bird_large::Species::Cockatrice)
|
||||||
|
.into(),
|
||||||
_ => biped_large::Body::random_with(rng, &biped_large::Species::Slysaurok)
|
_ => biped_large::Body::random_with(rng, &biped_large::Species::Slysaurok)
|
||||||
.into(),
|
.into(),
|
||||||
})
|
})
|
||||||
@ -652,12 +660,11 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
|||||||
Entry {
|
Entry {
|
||||||
make_entity: |pos, rng| {
|
make_entity: |pos, rng| {
|
||||||
EntityInfo::at(pos)
|
EntityInfo::at(pos)
|
||||||
.with_body(match rng.gen_range(0..4) {
|
.with_body(match rng.gen_range(0..3) {
|
||||||
0 => bird_medium::Body::random_with(rng, &bird_medium::Species::Parrot)
|
0 => bird_medium::Body::random_with(rng, &bird_medium::Species::Parrot)
|
||||||
.into(),
|
.into(),
|
||||||
1 => bird_large::Body::random_with(rng, &bird_large::Species::Cockatrice)
|
|
||||||
.into(),
|
1 => quadruped_small::Body::random_with(
|
||||||
2 => quadruped_small::Body::random_with(
|
|
||||||
rng,
|
rng,
|
||||||
&quadruped_small::Species::Quokka,
|
&quadruped_small::Species::Quokka,
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user