mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'snowram/bird-large' into 'master'
Large bird skeleton See merge request veloren/veloren!2121
This commit is contained in:
commit
79cb7a5826
@ -45,6 +45,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Drag is now calculated based on physical properties
|
||||
- Terrain chunks are now deflate-compressed when sent over the network.
|
||||
- Missing translations can be displayed in English.
|
||||
- New large birds npcs
|
||||
- Day period dependant wildlife spawns
|
||||
|
||||
### Changed
|
||||
|
||||
|
17
assets/common/abilities/unique/birdlargebreathe/firebomb.ron
Normal file
17
assets/common/abilities/unique/birdlargebreathe/firebomb.ron
Normal file
@ -0,0 +1,17 @@
|
||||
BasicRanged(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.5,
|
||||
recover_duration: 0.35,
|
||||
projectile: Fireball(
|
||||
damage: 100.0,
|
||||
radius: 5.0,
|
||||
energy_regen: 50,
|
||||
),
|
||||
projectile_body: Object(BoltFire),
|
||||
/*projectile_light: Some(LightEmitter {
|
||||
col: (1.0, 0.75, 0.11).into(),
|
||||
..Default::default()
|
||||
}),*/
|
||||
projectile_gravity: Some(Gravity(0.15)),
|
||||
projectile_speed: 60.0,
|
||||
)
|
@ -0,0 +1,14 @@
|
||||
BasicBeam(
|
||||
buildup_duration: 0.4,
|
||||
recover_duration: 0.25,
|
||||
beam_duration: 0.5,
|
||||
damage: 50,
|
||||
tick_rate: 3.0,
|
||||
range: 15.0,
|
||||
max_angle: 22.5,
|
||||
damage_effect: None,
|
||||
energy_regen: 0,
|
||||
energy_drain: 0,
|
||||
orientation_behavior: Normal,
|
||||
specifier: Flamethrower,
|
||||
)
|
@ -0,0 +1,53 @@
|
||||
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,
|
||||
),
|
||||
(
|
||||
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,
|
||||
),
|
||||
(
|
||||
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,
|
||||
),
|
||||
],
|
||||
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,
|
||||
)
|
17
assets/common/abilities/unique/birdlargefire/firebomb.ron
Normal file
17
assets/common/abilities/unique/birdlargefire/firebomb.ron
Normal file
@ -0,0 +1,17 @@
|
||||
BasicRanged(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.5,
|
||||
recover_duration: 0.35,
|
||||
projectile: Fireball(
|
||||
damage: 100.0,
|
||||
radius: 5.0,
|
||||
energy_regen: 50,
|
||||
),
|
||||
projectile_body: Object(BoltFire),
|
||||
/*projectile_light: Some(LightEmitter {
|
||||
col: (1.0, 0.75, 0.11).into(),
|
||||
..Default::default()
|
||||
}),*/
|
||||
projectile_gravity: Some(Gravity(0.15)),
|
||||
projectile_speed: 60.0,
|
||||
)
|
@ -0,0 +1,15 @@
|
||||
Shockwave(
|
||||
energy_cost: 600,
|
||||
buildup_duration: 0.7,
|
||||
swing_duration: 0.1,
|
||||
recover_duration: 0.2,
|
||||
damage: 200,
|
||||
poise_damage: 0,
|
||||
knockback: ( strength: 25.0, direction: Away),
|
||||
shockwave_angle: 360.0,
|
||||
shockwave_vertical_angle: 90.0,
|
||||
shockwave_speed: 20.0,
|
||||
shockwave_duration: 0.5,
|
||||
requires_ground: false,
|
||||
move_efficiency: 0.1,
|
||||
)
|
@ -0,0 +1,14 @@
|
||||
BasicBeam(
|
||||
buildup_duration: 0.4,
|
||||
recover_duration: 0.25,
|
||||
beam_duration: 0.5,
|
||||
damage: 50,
|
||||
tick_rate: 3.0,
|
||||
range: 15.0,
|
||||
max_angle: 22.5,
|
||||
damage_effect: None,
|
||||
energy_regen: 0,
|
||||
energy_drain: 0,
|
||||
orientation_behavior: Normal,
|
||||
specifier: Flamethrower,
|
||||
)
|
@ -0,0 +1,53 @@
|
||||
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,
|
||||
),
|
||||
(
|
||||
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,
|
||||
),
|
||||
(
|
||||
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,
|
||||
),
|
||||
],
|
||||
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,
|
||||
)
|
@ -207,6 +207,20 @@
|
||||
(None, "common.abilities.unique.mindflayer.summonminions"),
|
||||
],
|
||||
),
|
||||
Unique(BirdLargeBreathe): (
|
||||
primary: "common.abilities.unique.birdlargebreathe.firebomb",
|
||||
secondary: "common.abilities.unique.birdlargebreathe.triplestrike",
|
||||
abilities: [
|
||||
(None, "common.abilities.unique.birdlargebreathe.flamethrower"),
|
||||
],
|
||||
),
|
||||
Unique(BirdLargeFire): (
|
||||
primary: "common.abilities.unique.birdlargefire.firebomb",
|
||||
secondary: "common.abilities.unique.birdlargefire.triplestrike",
|
||||
abilities: [
|
||||
(None, "common.abilities.unique.birdlargefire.fireshockwave"),
|
||||
],
|
||||
),
|
||||
Debug: (
|
||||
primary: "common.abilities.debug.forwardboost",
|
||||
secondary: "common.abilities.debug.upboost",
|
||||
|
18
assets/common/items/npc_weapons/unique/birdlargebreathe.ron
Normal file
18
assets/common/items/npc_weapons/unique/birdlargebreathe.ron
Normal file
@ -0,0 +1,18 @@
|
||||
ItemDef(
|
||||
name: "Bird Large Breathe",
|
||||
description: "testing123",
|
||||
kind: Tool((
|
||||
kind: Unique(BirdLargeBreathe),
|
||||
hands: Two,
|
||||
stats: Direct((
|
||||
equip_time_secs: 0.01,
|
||||
power: 1.0,
|
||||
poise_strength: 1.0,
|
||||
speed: 1.0,
|
||||
crit_chance: 0.0625,
|
||||
crit_mult: 1.9142857,
|
||||
)),
|
||||
)),
|
||||
quality: Low,
|
||||
tags: [],
|
||||
)
|
18
assets/common/items/npc_weapons/unique/birdlargefire.ron
Normal file
18
assets/common/items/npc_weapons/unique/birdlargefire.ron
Normal file
@ -0,0 +1,18 @@
|
||||
ItemDef(
|
||||
name: "Bird Large Fire",
|
||||
description: "testing123",
|
||||
kind: Tool((
|
||||
kind: Unique(BirdLargeFire),
|
||||
hands: Two,
|
||||
stats: Direct((
|
||||
equip_time_secs: 0.01,
|
||||
power: 1.0,
|
||||
poise_strength: 1.0,
|
||||
speed: 1.0,
|
||||
crit_chance: 0.0625,
|
||||
crit_mult: 1.9142857,
|
||||
)),
|
||||
)),
|
||||
quality: Low,
|
||||
tags: [],
|
||||
)
|
@ -804,10 +804,6 @@
|
||||
keyword: "parrot",
|
||||
generic: "Parrot"
|
||||
),
|
||||
cockatrice: (
|
||||
keyword: "cockatrice",
|
||||
generic: "Cockatrice"
|
||||
)
|
||||
)
|
||||
),
|
||||
biped_large: (
|
||||
@ -1068,12 +1064,23 @@
|
||||
)
|
||||
)
|
||||
),
|
||||
bird_small: (
|
||||
bird_large: (
|
||||
body: (
|
||||
keyword: "bird_small",
|
||||
names_0: []
|
||||
keyword: "bird_large",
|
||||
names_0: [
|
||||
"Aitvaras"
|
||||
]
|
||||
),
|
||||
species: ()
|
||||
species: (
|
||||
phoenix: (
|
||||
keyword: "phoenix",
|
||||
generic: "Phoenix"
|
||||
),
|
||||
cockatrice: (
|
||||
keyword: "cockatrice",
|
||||
generic: "Cockatrice"
|
||||
),
|
||||
)
|
||||
),
|
||||
quadruped_low: (
|
||||
body: (
|
||||
|
106
assets/voxygen/voxel/bird_large_central_manifest.ron
Normal file
106
assets/voxygen/voxel/bird_large_central_manifest.ron
Normal file
@ -0,0 +1,106 @@
|
||||
({
|
||||
(Phoenix, Male): (
|
||||
head: (
|
||||
offset: (-4.0, -4.0, 0.0),
|
||||
central: ("npc.phoenix.male.head"),
|
||||
),
|
||||
beak: (
|
||||
offset: (-2.0, 0.0, -3.0),
|
||||
central: ("npc.phoenix.male.beak"),
|
||||
),
|
||||
neck: (
|
||||
offset: (-4.0, 0.0, 0.0),
|
||||
central: ("npc.phoenix.male.neck"),
|
||||
),
|
||||
chest: (
|
||||
offset: (-6.0, -9.5, -7.5),
|
||||
central: ("npc.phoenix.male.chest"),
|
||||
),
|
||||
tail_front: (
|
||||
offset: (-10.0, -14.0, -3.0),
|
||||
central: ("npc.phoenix.male.tail_front"),
|
||||
),
|
||||
tail_rear: (
|
||||
offset: (-9.0, -30.0, -2.0),
|
||||
central: ("npc.phoenix.male.tail_rear"),
|
||||
)
|
||||
),
|
||||
(Phoenix, Female): (
|
||||
head: (
|
||||
offset: (-4.0, -4.0, 0.0),
|
||||
central: ("npc.phoenix.male.head"),
|
||||
),
|
||||
beak: (
|
||||
offset: (-2.0, 0.0, -3.0),
|
||||
central: ("npc.phoenix.male.beak"),
|
||||
),
|
||||
neck: (
|
||||
offset: (-4.0, 0.0, 0.0),
|
||||
central: ("npc.phoenix.male.neck"),
|
||||
),
|
||||
chest: (
|
||||
offset: (-6.0, -9.5, -7.5),
|
||||
central: ("npc.phoenix.male.chest"),
|
||||
),
|
||||
tail_front: (
|
||||
offset: (-10.0, -14.0, -3.0),
|
||||
central: ("npc.phoenix.male.tail_front"),
|
||||
),
|
||||
tail_rear: (
|
||||
offset: (-9.0, -30.0, -2.0),
|
||||
central: ("npc.phoenix.male.tail_rear"),
|
||||
)
|
||||
),
|
||||
(Cockatrice, Male): (
|
||||
head: (
|
||||
offset: (-4.5, -6.0, -3.5),
|
||||
central: ("npc.cockatrice.male.head"),
|
||||
),
|
||||
beak: (
|
||||
offset: (-1.5, 0.0, -1.5),
|
||||
central: ("npc.cockatrice.male.beak"),
|
||||
),
|
||||
neck: (
|
||||
offset: (-3.5, 0.0, -6.0),
|
||||
central: ("npc.cockatrice.male.neck"),
|
||||
),
|
||||
chest: (
|
||||
offset: (-5.5, -10.0, -9.5),
|
||||
central: ("npc.cockatrice.male.chest"),
|
||||
),
|
||||
tail_front: (
|
||||
offset: (-2.5, -9.0, -6.0),
|
||||
central: ("npc.cockatrice.male.tail_front"),
|
||||
),
|
||||
tail_rear: (
|
||||
offset: (-2.5, -13.0, -3.0),
|
||||
central: ("npc.cockatrice.male.tail_rear"),
|
||||
)
|
||||
),
|
||||
(Cockatrice, Female): (
|
||||
head: (
|
||||
offset: (-4.5, -6.0, -3.5),
|
||||
central: ("npc.cockatrice.male.head"),
|
||||
),
|
||||
beak: (
|
||||
offset: (-1.5, 0.0, -1.5),
|
||||
central: ("npc.cockatrice.male.beak"),
|
||||
),
|
||||
neck: (
|
||||
offset: (-3.5, 0.0, -6.0),
|
||||
central: ("npc.cockatrice.male.neck"),
|
||||
),
|
||||
chest: (
|
||||
offset: (-5.5, -10.0, -9.5),
|
||||
central: ("npc.cockatrice.male.chest"),
|
||||
),
|
||||
tail_front: (
|
||||
offset: (-2.5, -9.0, -6.0),
|
||||
central: ("npc.cockatrice.male.tail_front"),
|
||||
),
|
||||
tail_rear: (
|
||||
offset: (-2.5, -13.0, -3.0),
|
||||
central: ("npc.cockatrice.male.tail_rear"),
|
||||
)
|
||||
),
|
||||
})
|
170
assets/voxygen/voxel/bird_large_lateral_manifest.ron
Normal file
170
assets/voxygen/voxel/bird_large_lateral_manifest.ron
Normal file
@ -0,0 +1,170 @@
|
||||
({
|
||||
(Phoenix, Male): (
|
||||
wing_in_l: (
|
||||
offset: (-10.0, -12.0, -1.5),
|
||||
lateral: ("npc.phoenix.male.wing_in_r"),
|
||||
),
|
||||
wing_in_r: (
|
||||
offset: (0.0, -12.0, -1.5),
|
||||
lateral: ("npc.phoenix.male.wing_in_r"),
|
||||
),
|
||||
wing_mid_l: (
|
||||
offset: (-7.0, -15.0, -0.5),
|
||||
lateral: ("npc.phoenix.male.wing_mid_r"),
|
||||
),
|
||||
wing_mid_r: (
|
||||
offset: (0.0, -15.0, -0.5),
|
||||
lateral: ("npc.phoenix.male.wing_mid_r"),
|
||||
),
|
||||
wing_out_l: (
|
||||
offset: (-18.0, -18.0, -2.0),
|
||||
lateral: ("npc.phoenix.male.wing_out_r"),
|
||||
),
|
||||
wing_out_r: (
|
||||
offset: (0.0, -18.0, -2.0),
|
||||
lateral: ("npc.phoenix.male.wing_out_r"),
|
||||
),
|
||||
leg_l: (
|
||||
offset: (-4.0, -5.0, -4.5),
|
||||
lateral: ("npc.phoenix.male.leg_r"),
|
||||
),
|
||||
leg_r: (
|
||||
offset: (-4.0, -5.0, -4.5),
|
||||
lateral: ("npc.phoenix.male.leg_r"),
|
||||
),
|
||||
foot_l: (
|
||||
offset: (-3.5, -4.5, -9.0),
|
||||
lateral: ("npc.phoenix.male.foot_r"),
|
||||
),
|
||||
foot_r: (
|
||||
offset: (-3.5, -4.5, -9.0),
|
||||
lateral: ("npc.phoenix.male.foot_r"),
|
||||
)
|
||||
),
|
||||
(Phoenix, Female): (
|
||||
wing_in_l: (
|
||||
offset: (-10.0, -12.0, -1.5),
|
||||
lateral: ("npc.phoenix.male.wing_in_r"),
|
||||
),
|
||||
wing_in_r: (
|
||||
offset: (0.0, -12.0, -1.5),
|
||||
lateral: ("npc.phoenix.male.wing_in_r"),
|
||||
),
|
||||
wing_mid_l: (
|
||||
offset: (-7.0, -15.0, -0.5),
|
||||
lateral: ("npc.phoenix.male.wing_mid_r"),
|
||||
),
|
||||
wing_mid_r: (
|
||||
offset: (0.0, -15.0, -0.5),
|
||||
lateral: ("npc.phoenix.male.wing_mid_r"),
|
||||
),
|
||||
wing_out_l: (
|
||||
offset: (-18.0, -18.0, -2.0),
|
||||
lateral: ("npc.phoenix.male.wing_out_r"),
|
||||
),
|
||||
wing_out_r: (
|
||||
offset: (0.0, -18.0, -2.0),
|
||||
lateral: ("npc.phoenix.male.wing_out_r"),
|
||||
),
|
||||
leg_l: (
|
||||
offset: (-4.0, -5.0, -4.5),
|
||||
lateral: ("npc.phoenix.male.leg_r"),
|
||||
),
|
||||
leg_r: (
|
||||
offset: (-4.0, -5.0, -4.5),
|
||||
lateral: ("npc.phoenix.male.leg_r"),
|
||||
),
|
||||
foot_l: (
|
||||
offset: (-3.5, -4.5, -9.0),
|
||||
lateral: ("npc.phoenix.male.foot_r"),
|
||||
),
|
||||
foot_r: (
|
||||
offset: (-3.5, -4.5, -9.0),
|
||||
lateral: ("npc.phoenix.male.foot_r"),
|
||||
)
|
||||
),
|
||||
(Cockatrice, Male): (
|
||||
wing_in_l: (
|
||||
offset: (-7.0, -8.0, -2.0),
|
||||
lateral: ("npc.cockatrice.male.wing_in_r"),
|
||||
),
|
||||
wing_in_r: (
|
||||
offset: (0.0, -8.0, -2.0),
|
||||
lateral: ("npc.cockatrice.male.wing_in_r"),
|
||||
),
|
||||
wing_mid_l: (
|
||||
offset: (-5.0, -9.0, -2.0),
|
||||
lateral: ("npc.cockatrice.male.wing_mid_r"),
|
||||
),
|
||||
wing_mid_r: (
|
||||
offset: (0.0, -9.0, -2.0),
|
||||
lateral: ("npc.cockatrice.male.wing_mid_r"),
|
||||
),
|
||||
wing_out_l: (
|
||||
offset: (-10.0, -11.0, -2.0),
|
||||
lateral: ("npc.cockatrice.male.wing_out_r"),
|
||||
),
|
||||
wing_out_r: (
|
||||
offset: (0.0, -11.0, -2.0),
|
||||
lateral: ("npc.cockatrice.male.wing_out_r"),
|
||||
),
|
||||
leg_l: (
|
||||
offset: (-3.0, -4.5, -4.0),
|
||||
lateral: ("npc.cockatrice.male.leg_r"),
|
||||
),
|
||||
leg_r: (
|
||||
offset: (-3.0, -4.5, -4.0),
|
||||
lateral: ("npc.cockatrice.male.leg_r"),
|
||||
),
|
||||
foot_l: (
|
||||
offset: (-3.5, -5.5, -10.0),
|
||||
lateral: ("npc.cockatrice.male.foot_r"),
|
||||
),
|
||||
foot_r: (
|
||||
offset: (-3.5, -5.5, -10.0),
|
||||
lateral: ("npc.cockatrice.male.foot_r"),
|
||||
)
|
||||
),
|
||||
(Cockatrice, Female): (
|
||||
wing_in_l: (
|
||||
offset: (-7.0, -8.0, -2.0),
|
||||
lateral: ("npc.cockatrice.male.wing_in_r"),
|
||||
),
|
||||
wing_in_r: (
|
||||
offset: (0.0, -8.0, -2.0),
|
||||
lateral: ("npc.cockatrice.male.wing_in_r"),
|
||||
),
|
||||
wing_mid_l: (
|
||||
offset: (-5.0, -9.0, -2.0),
|
||||
lateral: ("npc.cockatrice.male.wing_mid_r"),
|
||||
),
|
||||
wing_mid_r: (
|
||||
offset: (0.0, -9.0, -2.0),
|
||||
lateral: ("npc.cockatrice.male.wing_mid_r"),
|
||||
),
|
||||
wing_out_l: (
|
||||
offset: (-10.0, -11.0, -2.0),
|
||||
lateral: ("npc.cockatrice.male.wing_out_r"),
|
||||
),
|
||||
wing_out_r: (
|
||||
offset: (0.0, -11.0, -2.0),
|
||||
lateral: ("npc.cockatrice.male.wing_out_r"),
|
||||
),
|
||||
leg_l: (
|
||||
offset: (-3.0, -4.5, -4.0),
|
||||
lateral: ("npc.cockatrice.male.leg_r"),
|
||||
),
|
||||
leg_r: (
|
||||
offset: (-3.0, -4.5, -4.0),
|
||||
lateral: ("npc.cockatrice.male.leg_r"),
|
||||
),
|
||||
foot_l: (
|
||||
offset: (-3.5, -5.5, -10.0),
|
||||
lateral: ("npc.cockatrice.male.foot_r"),
|
||||
),
|
||||
foot_r: (
|
||||
offset: (-3.5, -5.5, -10.0),
|
||||
lateral: ("npc.cockatrice.male.foot_r"),
|
||||
)
|
||||
),
|
||||
})
|
@ -195,32 +195,4 @@
|
||||
central: ("npc.parrot.male.tail"),
|
||||
)
|
||||
),
|
||||
(Cockatrice, Male): (
|
||||
head: (
|
||||
offset: (-2.5, 0.0, -8.0),
|
||||
central: ("npc.cockatrice.male.head"),
|
||||
),
|
||||
torso: (
|
||||
offset: (-3.5, -6.5, -7.5),
|
||||
central: ("npc.cockatrice.male.torso"),
|
||||
),
|
||||
tail: (
|
||||
offset: (-1.5, -3.5, -4.0),
|
||||
central: ("npc.cockatrice.male.tail"),
|
||||
)
|
||||
),
|
||||
(Cockatrice, Female): (
|
||||
head: (
|
||||
offset: (-2.5, 0.0, -8.0),
|
||||
central: ("npc.cockatrice.male.head"),
|
||||
),
|
||||
torso: (
|
||||
offset: (-3.5, -6.5, -7.5),
|
||||
central: ("npc.cockatrice.male.torso"),
|
||||
),
|
||||
tail: (
|
||||
offset: (-1.5, -3.5, -4.0),
|
||||
central: ("npc.cockatrice.male.tail"),
|
||||
)
|
||||
),
|
||||
})
|
@ -251,40 +251,4 @@
|
||||
lateral: ("npc.parrot.male.leg_r"),
|
||||
)
|
||||
),
|
||||
(Cockatrice, Male): (
|
||||
wing_l: (
|
||||
offset: (-2.0, -3.0, -9.0),
|
||||
lateral: ("npc.cockatrice.male.wing_r"),
|
||||
),
|
||||
wing_r: (
|
||||
offset: (-2.0, -3.0, -9.0),
|
||||
lateral: ("npc.cockatrice.male.wing_r"),
|
||||
),
|
||||
foot_l: (
|
||||
offset: (-2.5, 0.0, -12.0),
|
||||
lateral: ("npc.cockatrice.male.leg_r"),
|
||||
),
|
||||
foot_r: (
|
||||
offset: (-2.5, 0.0, -12.0),
|
||||
lateral: ("npc.cockatrice.male.leg_r"),
|
||||
)
|
||||
),
|
||||
(Cockatrice, Female): (
|
||||
wing_l: (
|
||||
offset: (-2.0, -3.0, -9.0),
|
||||
lateral: ("npc.cockatrice.male.wing_r"),
|
||||
),
|
||||
wing_r: (
|
||||
offset: (-2.0, -3.0, -9.0),
|
||||
lateral: ("npc.cockatrice.male.wing_r"),
|
||||
),
|
||||
foot_l: (
|
||||
offset: (-2.5, 0.0, -12.0),
|
||||
lateral: ("npc.cockatrice.male.leg_r"),
|
||||
),
|
||||
foot_r: (
|
||||
offset: (-2.5, 0.0, -12.0),
|
||||
lateral: ("npc.cockatrice.male.leg_r"),
|
||||
)
|
||||
),
|
||||
})
|
BIN
assets/voxygen/voxel/npc/cockatrice/male/beak.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/cockatrice/male/beak.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/cockatrice/male/chest.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/cockatrice/male/chest.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/cockatrice/male/foot_r.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/cockatrice/male/foot_r.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/cockatrice/male/head.vox
(Stored with Git LFS)
BIN
assets/voxygen/voxel/npc/cockatrice/male/head.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/voxel/npc/cockatrice/male/leg_r.vox
(Stored with Git LFS)
BIN
assets/voxygen/voxel/npc/cockatrice/male/leg_r.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/voxel/npc/cockatrice/male/neck.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/cockatrice/male/neck.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/cockatrice/male/tail.vox
(Stored with Git LFS)
BIN
assets/voxygen/voxel/npc/cockatrice/male/tail.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/voxel/npc/cockatrice/male/tail_front.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/cockatrice/male/tail_front.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/cockatrice/male/tail_rear.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/cockatrice/male/tail_rear.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/cockatrice/male/torso.vox
(Stored with Git LFS)
BIN
assets/voxygen/voxel/npc/cockatrice/male/torso.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/voxel/npc/cockatrice/male/wing_in_r.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/cockatrice/male/wing_in_r.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/cockatrice/male/wing_mid_r.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/cockatrice/male/wing_mid_r.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/cockatrice/male/wing_out_r.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/cockatrice/male/wing_out_r.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/cockatrice/male/wing_r.vox
(Stored with Git LFS)
BIN
assets/voxygen/voxel/npc/cockatrice/male/wing_r.vox
(Stored with Git LFS)
Binary file not shown.
BIN
assets/voxygen/voxel/npc/phoenix/male/beak.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/phoenix/male/beak.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/phoenix/male/chest.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/phoenix/male/chest.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/phoenix/male/foot_r.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/phoenix/male/foot_r.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/phoenix/male/head.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/phoenix/male/head.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/phoenix/male/leg_r.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/phoenix/male/leg_r.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/phoenix/male/neck.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/phoenix/male/neck.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/phoenix/male/tail_front.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/phoenix/male/tail_front.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/phoenix/male/tail_rear.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/phoenix/male/tail_rear.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/phoenix/male/wing_in_r.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/phoenix/male/wing_in_r.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/phoenix/male/wing_mid_r.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/phoenix/male/wing_mid_r.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/npc/phoenix/male/wing_out_r.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/npc/phoenix/male/wing_out_r.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -38,6 +38,8 @@ pub enum Tactic {
|
||||
FixedTurret,
|
||||
RotatingTurret,
|
||||
Mindflayer,
|
||||
BirdLargeBreathe,
|
||||
BirdLargeFire,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
@ -247,7 +249,7 @@ impl<'a> From<&'a Body> for Psyche {
|
||||
},
|
||||
Body::BipedSmall(_) => 0.5,
|
||||
Body::BirdMedium(_) => 0.5,
|
||||
Body::BirdSmall(_) => 0.4,
|
||||
Body::BirdLarge(_) => 0.9,
|
||||
Body::FishMedium(_) => 0.15,
|
||||
Body::FishSmall(_) => 0.0,
|
||||
Body::BipedLarge(_) => 1.0,
|
||||
|
@ -1,7 +1,7 @@
|
||||
pub mod biped_large;
|
||||
pub mod biped_small;
|
||||
pub mod bird_large;
|
||||
pub mod bird_medium;
|
||||
pub mod bird_small;
|
||||
pub mod dragon;
|
||||
pub mod fish_medium;
|
||||
pub mod fish_small;
|
||||
@ -38,7 +38,7 @@ make_case_elim!(
|
||||
BirdMedium(body: bird_medium::Body) = 3,
|
||||
FishMedium(body: fish_medium::Body) = 4,
|
||||
Dragon(body: dragon::Body) = 5,
|
||||
BirdSmall(body: bird_small::Body) = 6,
|
||||
BirdLarge(body: bird_large::Body) = 6,
|
||||
FishSmall(body: fish_small::Body) = 7,
|
||||
BipedLarge(body: biped_large::Body)= 8,
|
||||
BipedSmall(body: biped_small::Body)= 9,
|
||||
@ -73,7 +73,7 @@ pub struct AllBodies<BodyMeta, SpeciesMeta> {
|
||||
pub bird_medium: BodyData<BodyMeta, bird_medium::AllSpecies<SpeciesMeta>>,
|
||||
pub fish_medium: BodyData<BodyMeta, fish_medium::AllSpecies<SpeciesMeta>>,
|
||||
pub dragon: BodyData<BodyMeta, dragon::AllSpecies<SpeciesMeta>>,
|
||||
pub bird_small: BodyData<BodyMeta, ()>,
|
||||
pub bird_large: BodyData<BodyMeta, bird_large::AllSpecies<SpeciesMeta>>,
|
||||
pub fish_small: BodyData<BodyMeta, fish_small::AllSpecies<SpeciesMeta>>,
|
||||
pub biped_large: BodyData<BodyMeta, biped_large::AllSpecies<SpeciesMeta>>,
|
||||
pub biped_small: BodyData<BodyMeta, biped_small::AllSpecies<SpeciesMeta>>,
|
||||
@ -95,6 +95,7 @@ impl<BodyMeta, SpeciesMeta> core::ops::Index<NpcKind> for AllBodies<BodyMeta, Sp
|
||||
NpcKind::Pig => &self.quadruped_small.body,
|
||||
NpcKind::Wolf => &self.quadruped_medium.body,
|
||||
NpcKind::Duck => &self.bird_medium.body,
|
||||
NpcKind::Phoenix => &self.bird_large.body,
|
||||
NpcKind::Marlin => &self.fish_medium.body,
|
||||
NpcKind::Clownfish => &self.fish_small.body,
|
||||
NpcKind::Ogre => &self.biped_large.body,
|
||||
@ -118,9 +119,9 @@ impl<'a, BodyMeta, SpeciesMeta> core::ops::Index<&'a Body> for AllBodies<BodyMet
|
||||
Body::QuadrupedSmall(_) => &self.quadruped_small.body,
|
||||
Body::QuadrupedMedium(_) => &self.quadruped_medium.body,
|
||||
Body::BirdMedium(_) => &self.bird_medium.body,
|
||||
Body::BirdLarge(_) => &self.bird_large.body,
|
||||
Body::FishMedium(_) => &self.fish_medium.body,
|
||||
Body::Dragon(_) => &self.dragon.body,
|
||||
Body::BirdSmall(_) => &self.bird_small.body,
|
||||
Body::FishSmall(_) => &self.fish_small.body,
|
||||
Body::BipedLarge(_) => &self.biped_large.body,
|
||||
Body::BipedSmall(_) => &self.biped_small.body,
|
||||
@ -152,7 +153,7 @@ impl Body {
|
||||
let d = match self {
|
||||
// based on a house sparrow (Passer domesticus)
|
||||
Body::BirdMedium(_) => 700.0,
|
||||
Body::BirdSmall(_) => 700.0,
|
||||
Body::BirdLarge(_) => 2_200.0,
|
||||
|
||||
// based on its mass divided by the volume of a bird scaled up to the size of the dragon
|
||||
Body::Dragon(_) => 3_700.0,
|
||||
@ -183,8 +184,7 @@ impl Body {
|
||||
|
||||
// ravens are 0.69-2 kg, crows are 0.51 kg on average
|
||||
Body::BirdMedium(_) => 1.0,
|
||||
// australian magpies are around 0.22-0.35 kg
|
||||
Body::BirdSmall(_) => 0.3,
|
||||
Body::BirdLarge(_) => 200.0,
|
||||
|
||||
Body::Dragon(_) => 20_000.0,
|
||||
Body::FishMedium(_) => 2.5,
|
||||
@ -281,11 +281,8 @@ impl Body {
|
||||
_ => Vec3::new(4.6, 3.0, 6.0),
|
||||
},
|
||||
Body::BipedSmall(_) => Vec3::new(1.0, 0.75, 1.4),
|
||||
Body::BirdMedium(body) => match body.species {
|
||||
bird_medium::Species::Cockatrice => Vec3::new(2.0, 1.0, 1.8),
|
||||
_ => Vec3::new(2.0, 1.0, 1.1),
|
||||
},
|
||||
Body::BirdSmall(_) => Vec3::new(1.2, 0.6, 1.1),
|
||||
Body::BirdMedium(_) => Vec3::new(2.0, 1.0, 1.1),
|
||||
Body::BirdLarge(_) => Vec3::new(2.0, 5.0, 2.4),
|
||||
Body::Dragon(_) => Vec3::new(16.0, 10.0, 16.0),
|
||||
Body::FishMedium(_) => Vec3::new(0.5, 2.0, 0.8),
|
||||
Body::FishSmall(_) => Vec3::new(0.3, 1.2, 0.6),
|
||||
@ -374,6 +371,10 @@ impl Body {
|
||||
biped_large::Species::Dullahan => 4000,
|
||||
_ => 3000,
|
||||
},
|
||||
Body::BirdLarge(body) => match body.species {
|
||||
bird_large::Species::Cockatrice => 4000,
|
||||
bird_large::Species::Phoenix => 6000,
|
||||
},
|
||||
Body::Humanoid(_) => 750,
|
||||
_ => 1000,
|
||||
}
|
||||
@ -429,13 +430,12 @@ impl Body {
|
||||
bird_medium::Species::Goose => 60,
|
||||
bird_medium::Species::Parrot => 60,
|
||||
bird_medium::Species::Peacock => 60,
|
||||
bird_medium::Species::Cockatrice => 400,
|
||||
bird_medium::Species::Eagle => 400,
|
||||
_ => 100,
|
||||
},
|
||||
Body::FishMedium(_) => 50,
|
||||
Body::Dragon(_) => 5000,
|
||||
Body::BirdSmall(_) => 50,
|
||||
Body::BirdLarge(_) => 3000,
|
||||
Body::FishSmall(_) => 20,
|
||||
Body::BipedLarge(biped_large) => match biped_large.species {
|
||||
biped_large::Species::Ogre => 2500,
|
||||
@ -542,13 +542,12 @@ impl Body {
|
||||
bird_medium::Species::Goose => 10,
|
||||
bird_medium::Species::Parrot => 10,
|
||||
bird_medium::Species::Peacock => 10,
|
||||
bird_medium::Species::Cockatrice => 10,
|
||||
bird_medium::Species::Eagle => 10,
|
||||
_ => 20,
|
||||
},
|
||||
Body::FishMedium(_) => 10,
|
||||
Body::Dragon(_) => 500,
|
||||
Body::BirdSmall(_) => 10,
|
||||
Body::BirdLarge(_) => 120,
|
||||
Body::FishSmall(_) => 10,
|
||||
Body::BipedLarge(biped_large) => match biped_large.species {
|
||||
biped_large::Species::Ogre => 70,
|
||||
@ -587,7 +586,7 @@ impl Body {
|
||||
|
||||
pub fn flying_height(&self) -> f32 {
|
||||
match self {
|
||||
Body::BirdSmall(_) => 30.0,
|
||||
Body::BirdLarge(_) => 50.0,
|
||||
Body::BirdMedium(_) => 40.0,
|
||||
Body::Dragon(_) => 60.0,
|
||||
Body::Ship(ship::Body::DefaultAirship) => 60.0,
|
||||
|
82
common/src/comp/body/bird_large.rs
Normal file
82
common/src/comp/body/bird_large.rs
Normal file
@ -0,0 +1,82 @@
|
||||
use crate::{make_case_elim, make_proj_elim};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub species: Species,
|
||||
pub body_type: BodyType,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
let mut rng = thread_rng();
|
||||
let species = *(&ALL_SPECIES).choose(&mut rng).unwrap();
|
||||
Self::random_with(&mut rng, &species)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn random_with(rng: &mut impl rand::Rng, &species: &Species) -> Self {
|
||||
let body_type = *(&ALL_BODY_TYPES).choose(rng).unwrap();
|
||||
Self { species, body_type }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Body> for super::Body {
|
||||
fn from(body: Body) -> Self { super::Body::BirdLarge(body) }
|
||||
}
|
||||
|
||||
make_case_elim!(
|
||||
species,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Species {
|
||||
Phoenix = 0,
|
||||
Cockatrice = 1,
|
||||
}
|
||||
);
|
||||
|
||||
/// Data representing per-species generic data.
|
||||
///
|
||||
/// NOTE: Deliberately don't (yet?) implement serialize.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct AllSpecies<SpeciesMeta> {
|
||||
pub phoenix: SpeciesMeta,
|
||||
pub cockatrice: SpeciesMeta,
|
||||
}
|
||||
|
||||
impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta> {
|
||||
type Output = SpeciesMeta;
|
||||
|
||||
#[inline]
|
||||
fn index(&self, &index: &'a Species) -> &Self::Output {
|
||||
match index {
|
||||
Species::Phoenix => &self.phoenix,
|
||||
Species::Cockatrice => &self.cockatrice,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const ALL_SPECIES: [Species; 2] = [Species::Phoenix, Species::Cockatrice];
|
||||
|
||||
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
type IntoIter = std::iter::Copied<std::slice::Iter<'static, Self::Item>>;
|
||||
type Item = Species;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter { ALL_SPECIES.iter().copied() }
|
||||
}
|
||||
|
||||
make_case_elim!(
|
||||
body_type,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum BodyType {
|
||||
Female = 0,
|
||||
Male = 1,
|
||||
}
|
||||
);
|
||||
|
||||
pub const ALL_BODY_TYPES: [BodyType; 2] = [BodyType::Female, BodyType::Male];
|
@ -41,7 +41,6 @@ make_case_elim!(
|
||||
Eagle = 4,
|
||||
Owl = 5,
|
||||
Parrot = 6,
|
||||
Cockatrice = 7,
|
||||
}
|
||||
);
|
||||
|
||||
@ -57,7 +56,6 @@ pub struct AllSpecies<SpeciesMeta> {
|
||||
pub eagle: SpeciesMeta,
|
||||
pub owl: SpeciesMeta,
|
||||
pub parrot: SpeciesMeta,
|
||||
pub cockatrice: SpeciesMeta,
|
||||
}
|
||||
|
||||
impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta> {
|
||||
@ -73,12 +71,11 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies<SpeciesMeta>
|
||||
Species::Eagle => &self.eagle,
|
||||
Species::Owl => &self.owl,
|
||||
Species::Parrot => &self.parrot,
|
||||
Species::Cockatrice => &self.cockatrice,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const ALL_SPECIES: [Species; 8] = [
|
||||
pub const ALL_SPECIES: [Species; 7] = [
|
||||
Species::Duck,
|
||||
Species::Chicken,
|
||||
Species::Goose,
|
||||
@ -86,7 +83,6 @@ pub const ALL_SPECIES: [Species; 8] = [
|
||||
Species::Eagle,
|
||||
Species::Owl,
|
||||
Species::Parrot,
|
||||
Species::Cockatrice,
|
||||
];
|
||||
|
||||
impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies<SpeciesMeta> {
|
||||
|
@ -1,66 +0,0 @@
|
||||
use crate::{make_case_elim, make_proj_elim};
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
make_proj_elim!(
|
||||
body,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Body {
|
||||
pub head: Head,
|
||||
pub torso: Torso,
|
||||
pub wing_l: WingL,
|
||||
pub wing_r: WingR,
|
||||
}
|
||||
);
|
||||
|
||||
impl Body {
|
||||
pub fn random() -> Self {
|
||||
let mut rng = thread_rng();
|
||||
Self {
|
||||
head: *(&ALL_HEADS).choose(&mut rng).unwrap(),
|
||||
torso: *(&ALL_TORSOS).choose(&mut rng).unwrap(),
|
||||
wing_l: *(&ALL_WING_LS).choose(&mut rng).unwrap(),
|
||||
wing_r: *(&ALL_WING_RS).choose(&mut rng).unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
make_case_elim!(
|
||||
head,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Head {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_HEADS: [Head; 1] = [Head::Default];
|
||||
|
||||
make_case_elim!(
|
||||
torso,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum Torso {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_TORSOS: [Torso; 1] = [Torso::Default];
|
||||
|
||||
make_case_elim!(
|
||||
wing_l,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum WingL {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_WING_LS: [WingL; 1] = [WingL::Default];
|
||||
|
||||
make_case_elim!(
|
||||
wing_r,
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[repr(u32)]
|
||||
pub enum WingR {
|
||||
Default = 0,
|
||||
}
|
||||
);
|
||||
const ALL_WING_RS: [WingR; 1] = [WingR::Default];
|
@ -129,11 +129,11 @@ impl Body {
|
||||
},
|
||||
|
||||
// Cross-section, zero-lift angle; exclude the wings (width * 0.2)
|
||||
Body::BirdMedium(_) | Body::BirdSmall(_) | Body::Dragon(_) => {
|
||||
Body::BirdMedium(_) | Body::BirdLarge(_) | Body::Dragon(_) => {
|
||||
let dim = self.dimensions().map(|a| a * 0.5);
|
||||
let cd = match self {
|
||||
Body::BirdMedium(_) => 0.2,
|
||||
Body::BirdSmall(_) => 0.4,
|
||||
Body::BirdLarge(_) => 0.4,
|
||||
_ => 0.7,
|
||||
};
|
||||
cd * std::f32::consts::PI * dim.x * 0.2 * dim.z
|
||||
|
@ -441,4 +441,6 @@ pub enum UniqueKind {
|
||||
ObjectTurret,
|
||||
WoodenSpear,
|
||||
MindflayerStaff,
|
||||
BirdLargeBreathe,
|
||||
BirdLargeFire,
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
biped_large, biped_small, golem,
|
||||
biped_large, biped_small, bird_large, golem,
|
||||
inventory::{
|
||||
loadout::Loadout,
|
||||
slot::{ArmorSlot, EquipSlot},
|
||||
@ -333,6 +333,18 @@ impl LoadoutBuilder {
|
||||
));
|
||||
},
|
||||
},
|
||||
Body::BirdLarge(bird_large) => match (bird_large.species, bird_large.body_type) {
|
||||
(bird_large::Species::Cockatrice, _) => {
|
||||
main_tool = Some(Item::new_from_asset_expect(
|
||||
"common.items.npc_weapons.unique.birdlargebreathe",
|
||||
));
|
||||
},
|
||||
(bird_large::Species::Phoenix, _) => {
|
||||
main_tool = Some(Item::new_from_asset_expect(
|
||||
"common.items.npc_weapons.unique.birdlargefire",
|
||||
));
|
||||
},
|
||||
},
|
||||
_ => {},
|
||||
};
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ pub use self::{
|
||||
aura::{Aura, AuraChange, AuraKind, Auras},
|
||||
beam::{Beam, BeamSegment},
|
||||
body::{
|
||||
biped_large, biped_small, bird_medium, bird_small, dragon, fish_medium, fish_small, golem,
|
||||
biped_large, biped_small, bird_large, bird_medium, dragon, fish_medium, fish_small, golem,
|
||||
humanoid, object, quadruped_low, quadruped_medium, quadruped_small, ship, theropod,
|
||||
AllBodies, Body, BodyData,
|
||||
},
|
||||
|
@ -135,6 +135,7 @@ impl EntityInfo {
|
||||
Some(get_npc_name(&npc_names.quadruped_medium, body.species))
|
||||
},
|
||||
Body::BirdMedium(body) => Some(get_npc_name(&npc_names.bird_medium, body.species)),
|
||||
Body::BirdLarge(body) => Some(get_npc_name(&npc_names.bird_large, body.species)),
|
||||
Body::FishSmall(body) => Some(get_npc_name(&npc_names.fish_small, body.species)),
|
||||
Body::FishMedium(body) => Some(get_npc_name(&npc_names.fish_medium, body.species)),
|
||||
Body::Theropod(body) => Some(get_npc_name(&npc_names.theropod, body.species)),
|
||||
|
@ -13,6 +13,7 @@ pub enum NpcKind {
|
||||
Wolf,
|
||||
Pig,
|
||||
Duck,
|
||||
Phoenix,
|
||||
Clownfish,
|
||||
Marlin,
|
||||
Ogre,
|
||||
@ -23,11 +24,12 @@ pub enum NpcKind {
|
||||
Crocodile,
|
||||
}
|
||||
|
||||
pub const ALL_NPCS: [NpcKind; 12] = [
|
||||
pub const ALL_NPCS: [NpcKind; 13] = [
|
||||
NpcKind::Humanoid,
|
||||
NpcKind::Wolf,
|
||||
NpcKind::Pig,
|
||||
NpcKind::Duck,
|
||||
NpcKind::Phoenix,
|
||||
NpcKind::Clownfish,
|
||||
NpcKind::Marlin,
|
||||
NpcKind::Ogre,
|
||||
@ -122,6 +124,7 @@ pub fn kind_to_body(kind: NpcKind) -> Body {
|
||||
NpcKind::Pig => comp::quadruped_small::Body::random().into(),
|
||||
NpcKind::Wolf => comp::quadruped_medium::Body::random().into(),
|
||||
NpcKind::Duck => comp::bird_medium::Body::random().into(),
|
||||
NpcKind::Phoenix => comp::bird_large::Body::random().into(),
|
||||
NpcKind::Clownfish => comp::fish_small::Body::random().into(),
|
||||
NpcKind::Marlin => comp::fish_medium::Body::random().into(),
|
||||
NpcKind::Ogre => comp::biped_large::Body::random().into(),
|
||||
@ -228,6 +231,14 @@ impl NpcBody {
|
||||
comp::bird_medium::Body::random_with,
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
parse(
|
||||
s,
|
||||
NpcKind::Phoenix,
|
||||
&npc_names.bird_large,
|
||||
comp::bird_large::Body::random_with,
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
parse(
|
||||
s,
|
||||
|
@ -3,7 +3,7 @@ use crate::{
|
||||
Attack, AttackDamage, AttackEffect, CombatEffect, CombatRequirement, Damage, DamageSource,
|
||||
GroupTarget,
|
||||
},
|
||||
comp::{beam, CharacterState, EnergyChange, EnergySource, Ori, Pos, StateUpdate},
|
||||
comp::{beam, Body, CharacterState, EnergyChange, EnergySource, Ori, Pos, StateUpdate},
|
||||
event::ServerEvent,
|
||||
states::{
|
||||
behavior::{CharacterBehavior, JoinData},
|
||||
@ -136,11 +136,15 @@ impl CharacterBehavior for Data {
|
||||
owner: Some(*data.uid),
|
||||
specifier: self.static_data.specifier,
|
||||
};
|
||||
let body_offsets_z = match data.body {
|
||||
Body::BirdLarge(_) => data.body.height() * 0.9,
|
||||
_ => data.body.height() * 0.5,
|
||||
};
|
||||
// Gets offsets
|
||||
let body_offsets = Vec3::new(
|
||||
(data.body.radius() + 0.2) * data.inputs.look_dir.x,
|
||||
(data.body.radius() + 0.2) * data.inputs.look_dir.y,
|
||||
data.body.eye_height() * 0.6,
|
||||
(data.body.radius() + 1.0) * data.inputs.look_dir.x,
|
||||
(data.body.radius() + 1.0) * data.inputs.look_dir.y,
|
||||
body_offsets_z,
|
||||
);
|
||||
let pos = Pos(data.pos.0 + body_offsets);
|
||||
// Create beam segment
|
||||
|
@ -77,7 +77,7 @@ impl Body {
|
||||
Body::BirdMedium(_) => 80.0,
|
||||
Body::FishMedium(_) => 80.0,
|
||||
Body::Dragon(_) => 250.0,
|
||||
Body::BirdSmall(_) => 75.0,
|
||||
Body::BirdLarge(_) => 110.0,
|
||||
Body::FishSmall(_) => 60.0,
|
||||
Body::BipedSmall(biped_small) => match biped_small.species {
|
||||
biped_small::Species::Haniwa => 65.0,
|
||||
@ -133,7 +133,7 @@ impl Body {
|
||||
Body::BirdMedium(_) => 6.0,
|
||||
Body::FishMedium(_) => 6.0,
|
||||
Body::Dragon(_) => 1.0,
|
||||
Body::BirdSmall(_) => 7.0,
|
||||
Body::BirdLarge(_) => 7.0,
|
||||
Body::FishSmall(_) => 7.0,
|
||||
Body::BipedLarge(_) => 1.6,
|
||||
Body::BipedSmall(_) => 2.4,
|
||||
@ -165,7 +165,7 @@ impl Body {
|
||||
Body::BipedLarge(_) | Body::Golem(_) => Some(200.0 * self.mass().0),
|
||||
Body::BipedSmall(_) => Some(100.0 * self.mass().0),
|
||||
Body::BirdMedium(_) => Some(50.0 * self.mass().0),
|
||||
Body::BirdSmall(_) => Some(50.0 * self.mass().0),
|
||||
Body::BirdLarge(_) => Some(50.0 * self.mass().0),
|
||||
Body::FishMedium(_) => Some(50.0 * self.mass().0),
|
||||
Body::FishSmall(_) => Some(50.0 * self.mass().0),
|
||||
Body::Dragon(_) => Some(200.0 * self.mass().0),
|
||||
@ -188,7 +188,7 @@ impl Body {
|
||||
pub fn fly_thrust(&self) -> Option<f32> {
|
||||
match self {
|
||||
Body::BirdMedium(_) => Some(GRAVITY * self.mass().0 * 2.0),
|
||||
Body::BirdSmall(_) => Some(GRAVITY * self.mass().0 * 2.0),
|
||||
Body::BirdLarge(_) => Some(GRAVITY * self.mass().0 * 0.5),
|
||||
Body::Dragon(_) => Some(200_000.0),
|
||||
Body::Ship(ship::Body::DefaultAirship) => Some(300_000.0),
|
||||
_ => None,
|
||||
@ -377,7 +377,7 @@ pub fn fly_move(data: &JoinData, update: &mut StateUpdate, efficiency: f32) -> b
|
||||
// Elevation control
|
||||
match data.body {
|
||||
// flappy flappy
|
||||
Body::Dragon(_) | Body::BirdMedium(_) | Body::BirdSmall(_) => {
|
||||
Body::Dragon(_) | Body::BirdMedium(_) | Body::BirdLarge(_) => {
|
||||
let anti_grav = GRAVITY * (1.0 + data.inputs.move_z.min(0.0));
|
||||
update.vel.0.z += data.dt.0 * (anti_grav + accel * data.inputs.move_z.max(0.0));
|
||||
},
|
||||
|
@ -1,4 +1,4 @@
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum DayPeriod {
|
||||
Night,
|
||||
Morning,
|
||||
|
@ -1,7 +1,9 @@
|
||||
use crate::metrics::ChunkGenMetrics;
|
||||
#[cfg(not(feature = "worldgen"))]
|
||||
use crate::test_world::{IndexOwned, World};
|
||||
use common::{generation::ChunkSupplement, slowjob::SlowJobPool, terrain::TerrainChunk};
|
||||
use common::{
|
||||
generation::ChunkSupplement, resources::TimeOfDay, slowjob::SlowJobPool, terrain::TerrainChunk,
|
||||
};
|
||||
use hashbrown::{hash_map::Entry, HashMap};
|
||||
use specs::Entity as EcsEntity;
|
||||
use std::sync::{
|
||||
@ -42,6 +44,7 @@ impl ChunkGenerator {
|
||||
slowjob_pool: &SlowJobPool,
|
||||
world: Arc<World>,
|
||||
index: IndexOwned,
|
||||
time: TimeOfDay,
|
||||
) {
|
||||
let v = if let Entry::Vacant(v) = self.pending_chunks.entry(key) {
|
||||
v
|
||||
@ -55,7 +58,7 @@ impl ChunkGenerator {
|
||||
slowjob_pool.spawn("CHUNK_GENERATOR", move || {
|
||||
let index = index.as_index_ref();
|
||||
let payload = world
|
||||
.generate_chunk(index, key, || cancel.load(Ordering::Relaxed))
|
||||
.generate_chunk(index, key, || cancel.load(Ordering::Relaxed), Some(time))
|
||||
.map_err(|_| entity);
|
||||
let _ = chunk_tx.send((key, payload));
|
||||
});
|
||||
|
@ -725,6 +725,7 @@ impl Server {
|
||||
&slow_jobs,
|
||||
Arc::clone(&world),
|
||||
index.clone(),
|
||||
*ecs.read_resource::<TimeOfDay>(),
|
||||
);
|
||||
});
|
||||
}
|
||||
@ -930,6 +931,7 @@ impl Server {
|
||||
&slow_jobs,
|
||||
Arc::clone(&self.world),
|
||||
self.index.clone(),
|
||||
*ecs.read_resource::<TimeOfDay>(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -38,12 +38,18 @@ impl Entity {
|
||||
match self.rng(PERM_GENUS).gen::<f32>() {
|
||||
// we want 5% airships, 45% birds, 50% humans
|
||||
x if x < 0.05 => comp::Body::Ship(comp::ship::Body::DefaultAirship),
|
||||
x if x < 0.50 => {
|
||||
x if x < 0.45 => {
|
||||
let species = *(&comp::bird_medium::ALL_SPECIES)
|
||||
.choose(&mut self.rng(PERM_SPECIES))
|
||||
.unwrap();
|
||||
comp::bird_medium::Body::random_with(&mut self.rng(PERM_BODY), &species).into()
|
||||
},
|
||||
x if x < 0.50 => {
|
||||
let species = *(&comp::bird_large::ALL_SPECIES)
|
||||
.choose(&mut self.rng(PERM_SPECIES))
|
||||
.unwrap();
|
||||
comp::bird_large::Body::random_with(&mut self.rng(PERM_BODY), &species).into()
|
||||
},
|
||||
_ => {
|
||||
let species = *(&comp::humanoid::ALL_SPECIES)
|
||||
.choose(&mut self.rng(PERM_SPECIES))
|
||||
@ -60,7 +66,7 @@ impl Entity {
|
||||
comp::Body::BirdMedium(b) => {
|
||||
get_npc_name(&npc_names.bird_medium, b.species).to_string()
|
||||
},
|
||||
comp::Body::BirdSmall(_) => "Warbler".to_string(),
|
||||
comp::Body::BirdLarge(b) => get_npc_name(&npc_names.bird_large, b.species).to_string(),
|
||||
comp::Body::Dragon(b) => get_npc_name(&npc_names.dragon, b.species).to_string(),
|
||||
comp::Body::Humanoid(b) => get_npc_name(&npc_names.humanoid, b.species).to_string(),
|
||||
comp::Body::Ship(_) => "Veloren Air".to_string(),
|
||||
|
@ -11,6 +11,7 @@ use common::{
|
||||
Group, Inventory,
|
||||
},
|
||||
effect::Effect,
|
||||
resources::TimeOfDay,
|
||||
slowjob::SlowJobPool,
|
||||
uid::{Uid, UidAllocator},
|
||||
};
|
||||
@ -382,7 +383,7 @@ impl StateExt for State {
|
||||
.for_each(|chunk_key| {
|
||||
#[cfg(feature = "worldgen")]
|
||||
{
|
||||
chunk_generator.generate_chunk(None, chunk_key, &slow_jobs, Arc::clone(world), index.clone());
|
||||
chunk_generator.generate_chunk(None, chunk_key, &slow_jobs, Arc::clone(world), index.clone(), *ecs.read_resource::<TimeOfDay>());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1538,6 +1538,8 @@ impl<'a> AgentData<'a> {
|
||||
Some(ToolKind::Unique(UniqueKind::TheropodBird)) => Tactic::Theropod,
|
||||
Some(ToolKind::Unique(UniqueKind::ObjectTurret)) => Tactic::Turret,
|
||||
Some(ToolKind::Unique(UniqueKind::MindflayerStaff)) => Tactic::Mindflayer,
|
||||
Some(ToolKind::Unique(UniqueKind::BirdLargeBreathe)) => Tactic::BirdLargeBreathe,
|
||||
Some(ToolKind::Unique(UniqueKind::BirdLargeFire)) => Tactic::BirdLargeFire,
|
||||
_ => Tactic::Melee,
|
||||
};
|
||||
|
||||
@ -2587,6 +2589,244 @@ impl<'a> AgentData<'a> {
|
||||
controller.inputs.move_z = bearing.z;
|
||||
}
|
||||
},
|
||||
Tactic::BirdLargeFire => {
|
||||
// Set fly to false
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::CancelInput(InputKind::Fly));
|
||||
// If further than 30 blocks
|
||||
if dist_sqrd > 30.0_f32.powi(2) {
|
||||
// If random chance and can see target
|
||||
if thread_rng().gen_bool(0.05)
|
||||
&& can_see_tgt(&*terrain, self.pos, tgt_pos, dist_sqrd)
|
||||
{
|
||||
// Fireball
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Primary));
|
||||
}
|
||||
// If some target
|
||||
if let Some((bearing, speed)) = agent.chaser.chase(
|
||||
&*terrain,
|
||||
self.pos.0,
|
||||
self.vel.0,
|
||||
tgt_pos.0,
|
||||
TraversalConfig {
|
||||
min_tgt_dist: 1.25,
|
||||
..self.traversal_config
|
||||
},
|
||||
) {
|
||||
// Walk to target
|
||||
controller.inputs.move_dir =
|
||||
bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed;
|
||||
// If less than 20 blocks higher than target
|
||||
if (self.pos.0.z - tgt_pos.0.z) < 20.0 {
|
||||
// Fly upward
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Fly));
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Jump));
|
||||
controller.inputs.move_z = 1.0;
|
||||
} else {
|
||||
// Jump
|
||||
self.jump_if(controller, bearing.z > 1.5);
|
||||
controller.inputs.move_z = bearing.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If higher than 2 blocks
|
||||
else if !read_data
|
||||
.terrain
|
||||
.ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * 2.0))
|
||||
.until(Block::is_solid)
|
||||
.cast()
|
||||
.1
|
||||
.map_or(true, |b| b.is_some())
|
||||
{
|
||||
// Do not increment the timer during this movement
|
||||
// The next stage shouldn't trigger until the entity
|
||||
// is on the ground
|
||||
// Fly to target
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Fly));
|
||||
let move_dir = tgt_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;
|
||||
// If further than 4 blocks and random chance
|
||||
if thread_rng().gen_bool(0.05) && dist_sqrd > (4.0 * min_attack_dist).powi(2) {
|
||||
// Fireball
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Primary));
|
||||
}
|
||||
}
|
||||
// If further than 4 blocks and random chance
|
||||
else if thread_rng().gen_bool(0.05) && dist_sqrd > (4.0 * min_attack_dist).powi(2)
|
||||
{
|
||||
// Fireball
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Primary));
|
||||
}
|
||||
// If random chance and less than 20 blocks higher than target and further than 4
|
||||
// blocks
|
||||
else if thread_rng().gen_bool(0.5)
|
||||
&& (self.pos.0.z - tgt_pos.0.z) < 15.0
|
||||
&& dist_sqrd > (4.0 * min_attack_dist).powi(2)
|
||||
{
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Fly));
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Jump));
|
||||
controller.inputs.move_z = 1.0;
|
||||
}
|
||||
// If further than 2.5 blocks and random chance
|
||||
else if dist_sqrd > (2.5 * min_attack_dist).powi(2) {
|
||||
// If some target
|
||||
if let Some((bearing, speed)) = agent.chaser.chase(
|
||||
&*terrain,
|
||||
self.pos.0,
|
||||
self.vel.0,
|
||||
tgt_pos.0,
|
||||
TraversalConfig {
|
||||
min_tgt_dist: 1.25,
|
||||
..self.traversal_config
|
||||
},
|
||||
) {
|
||||
// Walk to target
|
||||
controller.inputs.move_dir =
|
||||
bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed;
|
||||
self.jump_if(controller, bearing.z > 1.5);
|
||||
controller.inputs.move_z = bearing.z;
|
||||
}
|
||||
}
|
||||
// If energy higher than 600 and random chance
|
||||
else if self.energy.current() > 600 && thread_rng().gen_bool(0.4) {
|
||||
// Shockwave
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Ability(0)));
|
||||
} else {
|
||||
// Triple strike
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Secondary));
|
||||
}
|
||||
},
|
||||
// Mostly identical to BirdLargeFire but tweaked for flamethrower instead of shockwave
|
||||
Tactic::BirdLargeBreathe => {
|
||||
// Set fly to false
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::CancelInput(InputKind::Fly));
|
||||
if dist_sqrd > 30.0_f32.powi(2) {
|
||||
if thread_rng().gen_bool(0.05)
|
||||
&& can_see_tgt(&*terrain, self.pos, tgt_pos, dist_sqrd)
|
||||
{
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Primary));
|
||||
}
|
||||
if let Some((bearing, speed)) = agent.chaser.chase(
|
||||
&*terrain,
|
||||
self.pos.0,
|
||||
self.vel.0,
|
||||
tgt_pos.0,
|
||||
TraversalConfig {
|
||||
min_tgt_dist: 1.25,
|
||||
..self.traversal_config
|
||||
},
|
||||
) {
|
||||
controller.inputs.move_dir =
|
||||
bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed;
|
||||
if (self.pos.0.z - tgt_pos.0.z) < 20.0 {
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Fly));
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Jump));
|
||||
controller.inputs.move_z = 1.0;
|
||||
} else {
|
||||
self.jump_if(controller, bearing.z > 1.5);
|
||||
controller.inputs.move_z = bearing.z;
|
||||
}
|
||||
}
|
||||
} else if !read_data
|
||||
.terrain
|
||||
.ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * 2.0))
|
||||
.until(Block::is_solid)
|
||||
.cast()
|
||||
.1
|
||||
.map_or(true, |b| b.is_some())
|
||||
{
|
||||
// Do not increment the timer during this movement
|
||||
// The next stage shouldn't trigger until the entity
|
||||
// is on the ground
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Fly));
|
||||
let move_dir = tgt_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;
|
||||
if thread_rng().gen_bool(0.05) && dist_sqrd > (4.0 * min_attack_dist).powi(2) {
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Primary));
|
||||
}
|
||||
} else if thread_rng().gen_bool(0.05) && dist_sqrd > (4.0 * min_attack_dist).powi(2)
|
||||
{
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Primary));
|
||||
} else if thread_rng().gen_bool(0.5)
|
||||
&& (self.pos.0.z - tgt_pos.0.z) < 15.0
|
||||
&& dist_sqrd > (4.0 * min_attack_dist).powi(2)
|
||||
{
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Fly));
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Jump));
|
||||
controller.inputs.move_z = 1.0;
|
||||
} else if dist_sqrd > (3.0 * min_attack_dist).powi(2) {
|
||||
if let Some((bearing, speed)) = agent.chaser.chase(
|
||||
&*terrain,
|
||||
self.pos.0,
|
||||
self.vel.0,
|
||||
tgt_pos.0,
|
||||
TraversalConfig {
|
||||
min_tgt_dist: 1.25,
|
||||
..self.traversal_config
|
||||
},
|
||||
) {
|
||||
controller.inputs.move_dir =
|
||||
bearing.xy().try_normalized().unwrap_or_else(Vec2::zero) * speed;
|
||||
self.jump_if(controller, bearing.z > 1.5);
|
||||
controller.inputs.move_z = bearing.z;
|
||||
}
|
||||
} else if self.energy.current() > 600 && agent.action_timer < 3.0 {
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Ability(0)));
|
||||
agent.action_timer += dt.0;
|
||||
} else if agent.action_timer < 6.0 {
|
||||
controller
|
||||
.actions
|
||||
.push(ControlAction::basic_input(InputKind::Secondary));
|
||||
agent.action_timer += dt.0;
|
||||
} else {
|
||||
agent.action_timer = 0.0;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
108
voxygen/anim/src/bird_large/alpha.rs
Normal file
108
voxygen/anim/src/bird_large/alpha.rs
Normal file
@ -0,0 +1,108 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
BirdLargeSkeleton, SkeletonAttr,
|
||||
};
|
||||
use common::states::utils::StageSection;
|
||||
|
||||
pub struct AlphaAnimation;
|
||||
|
||||
impl Animation for AlphaAnimation {
|
||||
type Dependency = (Option<StageSection>, Vec3<f32>, Vec3<f32>, bool);
|
||||
type Skeleton = BirdLargeSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"bird_large_alpha\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_alpha")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
(stage_section, orientation, last_ori, on_ground): Self::Dependency,
|
||||
anim_time: f32,
|
||||
_rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let (move1base, move2base, move3) = match stage_section {
|
||||
Some(StageSection::Buildup) => (anim_time.powf(0.25), 0.0, 0.0),
|
||||
Some(StageSection::Swing) => (1.0, anim_time, 0.0),
|
||||
Some(StageSection::Recover) => (1.0, 1.0, anim_time.powf(4.0)),
|
||||
_ => (0.0, 0.0, 0.0),
|
||||
};
|
||||
|
||||
let wave_slow_cos = (anim_time * 4.5).cos();
|
||||
|
||||
let pullback = 1.0 - move3;
|
||||
|
||||
let move1 = move1base * pullback;
|
||||
let move2 = move2base * pullback;
|
||||
|
||||
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.chest.position =
|
||||
Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + wave_slow_cos * 0.06) * s_a.scaler / 8.0;
|
||||
next.chest.orientation = Quaternion::rotation_x(move1 * 0.5 - move2 * 0.8);
|
||||
|
||||
next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1);
|
||||
next.neck.orientation = Quaternion::rotation_x(move1 * 0.5 - move2 * 0.8)
|
||||
* Quaternion::rotation_z(move1 * tilt * 1.5);
|
||||
|
||||
next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
|
||||
next.head.orientation = Quaternion::rotation_x(move1 * 0.5 - move2 * 0.8);
|
||||
|
||||
next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1);
|
||||
next.beak.orientation = Quaternion::rotation_x(wave_slow_cos * -0.02 - 0.02);
|
||||
|
||||
if on_ground {
|
||||
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(-move1 * 0.2);
|
||||
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.0);
|
||||
|
||||
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(-1.0 + wave_slow_cos * 0.06) * Quaternion::rotation_z(0.2);
|
||||
next.wing_in_r.orientation =
|
||||
Quaternion::rotation_y(1.0 - wave_slow_cos * 0.06) * Quaternion::rotation_z(-0.2);
|
||||
|
||||
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) * Quaternion::rotation_z(0.2);
|
||||
next.wing_out_r.orientation =
|
||||
Quaternion::rotation_y(0.2) * Quaternion::rotation_z(-0.2);
|
||||
} else {
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
}
|
135
voxygen/anim/src/bird_large/breathe.rs
Normal file
135
voxygen/anim/src/bird_large/breathe.rs
Normal file
@ -0,0 +1,135 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
BirdLargeSkeleton, SkeletonAttr,
|
||||
};
|
||||
use common::{states::utils::StageSection, util::Dir};
|
||||
|
||||
pub struct BreatheAnimation;
|
||||
|
||||
type BreatheAnimationDependency = (
|
||||
f32,
|
||||
Vec3<f32>,
|
||||
Vec3<f32>,
|
||||
Option<StageSection>,
|
||||
f32,
|
||||
Dir,
|
||||
bool,
|
||||
);
|
||||
|
||||
impl Animation for BreatheAnimation {
|
||||
type Dependency = BreatheAnimationDependency;
|
||||
type Skeleton = BirdLargeSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"bird_large_breathe\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_breathe")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
(global_time, orientation, last_ori, stage_section, timer, look_dir, on_ground): Self::Dependency,
|
||||
anim_time: f32,
|
||||
_rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
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, 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.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.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
|
||||
next.head.orientation =
|
||||
Quaternion::rotation_x(movement1abs * 0.5 - movement2abs * 0.5 + 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.chest.orientation =
|
||||
Quaternion::rotation_x(movement1abs * 0.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_y(-1.0 + movement1abs * 0.8 - movement2abs * 0.4)
|
||||
* Quaternion::rotation_z(0.2 - movement1abs * 0.8 + movement2abs * 0.4);
|
||||
next.wing_in_r.orientation =
|
||||
Quaternion::rotation_y(1.0 - movement1abs * 0.8 + movement2abs * 0.4)
|
||||
* Quaternion::rotation_z(-0.2 + movement1abs * 0.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) * 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) * Quaternion::rotation_z(0.2);
|
||||
next.wing_out_r.orientation =
|
||||
Quaternion::rotation_y(0.2) * 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 {
|
||||
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.chest.orientation =
|
||||
Quaternion::rotation_x(movement1abs * 0.1 - movement2abs * 0.1)
|
||||
* Quaternion::rotation_y(tilt * 1.8);
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
}
|
100
voxygen/anim/src/bird_large/feed.rs
Normal file
100
voxygen/anim/src/bird_large/feed.rs
Normal file
@ -0,0 +1,100 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
BirdLargeSkeleton, SkeletonAttr,
|
||||
};
|
||||
use std::ops::Mul;
|
||||
|
||||
pub struct FeedAnimation;
|
||||
|
||||
impl Animation for FeedAnimation {
|
||||
type Dependency = f32;
|
||||
type Skeleton = BirdLargeSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"bird_large_feed\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_feed")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
global_time: Self::Dependency,
|
||||
anim_time: f32,
|
||||
_rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let duck_head_look = Vec2::new(
|
||||
(global_time / 2.0 + anim_time / 8.0)
|
||||
.floor()
|
||||
.mul(7331.0)
|
||||
.sin()
|
||||
* 0.5,
|
||||
(global_time / 2.0 + anim_time / 8.0)
|
||||
.floor()
|
||||
.mul(1337.0)
|
||||
.sin()
|
||||
* 0.25,
|
||||
);
|
||||
let wave_slow_cos = (anim_time * 4.5).cos();
|
||||
let wave_fast = (anim_time * 9.0).cos();
|
||||
let beak = (anim_time * 16.0).sin();
|
||||
|
||||
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 - 1.8)
|
||||
* s_a.scaler
|
||||
/ 8.0;
|
||||
next.chest.orientation = Quaternion::rotation_x(s_a.feed);
|
||||
|
||||
next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1);
|
||||
next.neck.orientation = Quaternion::rotation_x(-0.2);
|
||||
|
||||
next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
|
||||
next.head.orientation = Quaternion::rotation_z(duck_head_look.x)
|
||||
* Quaternion::rotation_x(-0.2 - duck_head_look.y.abs() + wave_slow_cos * 0.01);
|
||||
|
||||
next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1);
|
||||
next.beak.orientation = Quaternion::rotation_x(beak * -0.1 - 0.1);
|
||||
|
||||
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.0);
|
||||
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.0);
|
||||
|
||||
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.7 + wave_fast * 0.08) * Quaternion::rotation_z(0.2);
|
||||
next.wing_in_r.orientation =
|
||||
Quaternion::rotation_y(0.7 - wave_fast * 0.08) * Quaternion::rotation_z(-0.2);
|
||||
|
||||
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) * Quaternion::rotation_z(0.2);
|
||||
next.wing_out_r.orientation = Quaternion::rotation_y(0.2) * Quaternion::rotation_z(-0.2);
|
||||
|
||||
next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0;
|
||||
next.leg_l.orientation = Quaternion::rotation_x(0.0);
|
||||
next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0;
|
||||
next.leg_r.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
next.foot_l.orientation = Quaternion::rotation_x(0.0);
|
||||
next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
next.foot_r.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
next
|
||||
}
|
||||
}
|
177
voxygen/anim/src/bird_large/fly.rs
Normal file
177
voxygen/anim/src/bird_large/fly.rs
Normal file
@ -0,0 +1,177 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
BirdLargeSkeleton, SkeletonAttr,
|
||||
};
|
||||
|
||||
pub struct FlyAnimation;
|
||||
|
||||
impl Animation for FlyAnimation {
|
||||
type Dependency = (Vec3<f32>, Vec3<f32>, Vec3<f32>);
|
||||
type Skeleton = BirdLargeSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"bird_large_fly\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_fly")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
(velocity, orientation, last_ori): Self::Dependency,
|
||||
anim_time: f32,
|
||||
_rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let slow = (anim_time * 2.0).sin();
|
||||
let fast = (anim_time * 4.0).sin();
|
||||
|
||||
// Harmonic series hack to get a sine/saw mix
|
||||
let freq = 8.0;
|
||||
let off1 = 0.0;
|
||||
let off2 = -1.7;
|
||||
let off3 = -2.0;
|
||||
let off4 = -2.4;
|
||||
let flap1 = 7.0 / 16.0 * (freq * anim_time + off1).sin()
|
||||
+ 7.0 / 64.0 * (freq * 2.0 * anim_time + off1).sin()
|
||||
+ 1.0 / 48.0 * (freq * 3.0 * anim_time + off1).sin();
|
||||
let flap2 = 7.0 / 16.0 * (freq * anim_time + off2).sin()
|
||||
+ 7.0 / 64.0 * (freq * 2.0 * anim_time + off2).sin()
|
||||
+ 1.0 / 48.0 * (freq * 3.0 * anim_time + off2).sin();
|
||||
let flap3 = 7.0 / 16.0 * (freq * anim_time + off3).sin()
|
||||
+ 7.0 / 64.0 * (freq * 2.0 * anim_time + off3).sin()
|
||||
+ 1.0 / 48.0 * (freq * 3.0 * anim_time + off3).sin();
|
||||
let flap4 = 7.0 / 16.0 * (freq * anim_time + off4).sin()
|
||||
+ 7.0 / 64.0 * (freq * 2.0 * anim_time + off4).sin()
|
||||
+ 1.0 / 48.0 * (freq * 3.0 * anim_time + off4).sin();
|
||||
|
||||
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.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1);
|
||||
next.neck.orientation =
|
||||
Quaternion::rotation_x((-0.4 + 0.2 * velocity.xy().magnitude() / 5.0).min(0.15));
|
||||
|
||||
next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
|
||||
|
||||
next.head.orientation = Quaternion::rotation_x(
|
||||
(-0.5 + 0.2 * velocity.xy().magnitude() / 5.0).min(-0.3) + fast * 0.05,
|
||||
);
|
||||
|
||||
next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1);
|
||||
|
||||
if velocity.z > 2.0 || velocity.xy().magnitude() < 12.0 {
|
||||
next.chest.position =
|
||||
Vec3::new(0.0, s_a.chest.0, s_a.chest.1 - flap4 * 1.5) * s_a.scaler / 8.0;
|
||||
next.chest.orientation = Quaternion::rotation_x(
|
||||
(0.8 - 0.8 * velocity.xy().magnitude() / 5.0).max(-0.2) - flap1 * 0.2,
|
||||
) * Quaternion::rotation_y(tilt * 1.8 + fast * 0.01);
|
||||
|
||||
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(-flap1 * 1.9 + 0.2) * Quaternion::rotation_x(0.4);
|
||||
next.wing_in_r.orientation =
|
||||
Quaternion::rotation_y(flap1 * 1.9 - 0.2) * Quaternion::rotation_x(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(-flap2 * 1.4 - 0.2);
|
||||
next.wing_mid_r.orientation = Quaternion::rotation_y(flap2 * 1.4 + 0.2);
|
||||
|
||||
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(-flap3 * 1.2 - 0.3);
|
||||
next.wing_out_r.orientation = Quaternion::rotation_y(flap3 * 1.2 + 0.3);
|
||||
|
||||
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(-flap2 * 0.2 + 0.1) * Quaternion::rotation_z(-tilt * 1.0);
|
||||
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(-flap3 * 0.3 + 0.15) * Quaternion::rotation_z(-tilt * 0.8);
|
||||
|
||||
next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2 - flap4 * 1.5) / 8.0;
|
||||
next.leg_l.orientation = Quaternion::rotation_x(
|
||||
(-1.0 * velocity.xy().magnitude() / 5.0).max(-1.2) + flap1 * -0.1,
|
||||
) * Quaternion::rotation_y(tilt * 1.6 + fast * 0.01);
|
||||
next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2 - flap4 * 1.5) / 8.0;
|
||||
next.leg_r.orientation = Quaternion::rotation_x(
|
||||
(-1.0 * velocity.xy().magnitude() / 5.0).max(-1.2) + flap1 * -0.1,
|
||||
) * Quaternion::rotation_y(tilt * 1.6 + fast * 0.01);
|
||||
|
||||
next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
next.foot_l.orientation = Quaternion::rotation_x(flap1 * -0.1);
|
||||
next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
next.foot_r.orientation = Quaternion::rotation_x(flap1 * -0.1);
|
||||
} else {
|
||||
next.chest.position =
|
||||
Vec3::new(0.0, s_a.chest.0, s_a.chest.1 + slow * 0.05) * s_a.scaler / 8.0;
|
||||
next.chest.orientation =
|
||||
Quaternion::rotation_x(-0.2 + slow * 0.05 + (0.8 * velocity.z / 80.0).min(0.8))
|
||||
* Quaternion::rotation_y(tilt * 1.8 + fast * 0.01);
|
||||
|
||||
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.1 + slow * 0.04 + (0.8 * velocity.z / 80.0).min(0.8))
|
||||
* Quaternion::rotation_x(0.4);
|
||||
next.wing_in_r.orientation =
|
||||
Quaternion::rotation_y(-0.1 + slow * -0.04 - (0.8 * velocity.z / 80.0).min(0.8))
|
||||
* Quaternion::rotation_x(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 + slow * 0.04);
|
||||
next.wing_mid_r.orientation = Quaternion::rotation_y(-0.1 + slow * -0.04);
|
||||
|
||||
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.1 + slow * 0.04 + (0.4 * velocity.z / 80.0).min(0.2));
|
||||
next.wing_out_r.orientation =
|
||||
Quaternion::rotation_y(-0.1 + slow * -0.04 - (0.4 * velocity.z / 80.0).min(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(0.04 - slow * 0.04) * Quaternion::rotation_z(-tilt * 1.0);
|
||||
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(slow * 0.08) * Quaternion::rotation_z(-tilt * 0.8);
|
||||
|
||||
next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2 + slow * 0.05) / 8.0;
|
||||
next.leg_l.orientation = Quaternion::rotation_x(-1.2 + slow * -0.05)
|
||||
* Quaternion::rotation_y(tilt * 1.6 + fast * 0.01);
|
||||
next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2 + slow * 0.05) / 8.0;
|
||||
next.leg_r.orientation = Quaternion::rotation_x(-1.2 + slow * -0.05)
|
||||
* Quaternion::rotation_y(tilt * 1.6 + fast * 0.01);
|
||||
|
||||
next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
next.foot_l.orientation = Quaternion::rotation_x(slow * -0.05);
|
||||
next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
next.foot_r.orientation = Quaternion::rotation_x(slow * -0.05);
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
}
|
98
voxygen/anim/src/bird_large/idle.rs
Normal file
98
voxygen/anim/src/bird_large/idle.rs
Normal file
@ -0,0 +1,98 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
BirdLargeSkeleton, SkeletonAttr,
|
||||
};
|
||||
use std::ops::Mul;
|
||||
|
||||
pub struct IdleAnimation;
|
||||
|
||||
impl Animation for IdleAnimation {
|
||||
type Dependency = f32;
|
||||
type Skeleton = BirdLargeSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"bird_large_idle\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_idle")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
global_time: Self::Dependency,
|
||||
anim_time: f32,
|
||||
_rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let duck_head_look = Vec2::new(
|
||||
(global_time / 2.0 + anim_time / 8.0)
|
||||
.floor()
|
||||
.mul(7331.0)
|
||||
.sin()
|
||||
* 0.5,
|
||||
(global_time / 2.0 + anim_time / 8.0)
|
||||
.floor()
|
||||
.mul(1337.0)
|
||||
.sin()
|
||||
* 0.25,
|
||||
);
|
||||
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 + 1.5)
|
||||
* s_a.scaler
|
||||
/ 8.0;
|
||||
next.chest.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1);
|
||||
next.neck.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
|
||||
next.head.orientation = Quaternion::rotation_z(duck_head_look.x)
|
||||
* Quaternion::rotation_x(-duck_head_look.y.abs() + wave_slow_cos * 0.01);
|
||||
|
||||
next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1);
|
||||
next.beak.orientation = Quaternion::rotation_x(wave_slow_cos * -0.02 - 0.02);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
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 + wave_slow_cos * 0.06) * Quaternion::rotation_z(0.2);
|
||||
next.wing_in_r.orientation =
|
||||
Quaternion::rotation_y(0.8 - wave_slow_cos * 0.06) * Quaternion::rotation_z(-0.2);
|
||||
|
||||
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.4) * Quaternion::rotation_z(0.2);
|
||||
next.wing_out_r.orientation = Quaternion::rotation_y(0.4) * Quaternion::rotation_z(-0.2);
|
||||
|
||||
next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0;
|
||||
next.leg_l.orientation = Quaternion::rotation_x(0.0);
|
||||
next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0;
|
||||
next.leg_r.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
next.foot_l.orientation = Quaternion::rotation_x(0.0);
|
||||
next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
next.foot_r.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
next
|
||||
}
|
||||
}
|
203
voxygen/anim/src/bird_large/mod.rs
Normal file
203
voxygen/anim/src/bird_large/mod.rs
Normal file
@ -0,0 +1,203 @@
|
||||
pub mod alpha;
|
||||
pub mod breathe;
|
||||
pub mod feed;
|
||||
pub mod fly;
|
||||
pub mod idle;
|
||||
pub mod run;
|
||||
pub mod shockwave;
|
||||
pub mod shoot;
|
||||
pub mod stunned;
|
||||
pub mod swim;
|
||||
|
||||
// Reexports
|
||||
pub use self::{
|
||||
alpha::AlphaAnimation, breathe::BreatheAnimation, feed::FeedAnimation, fly::FlyAnimation,
|
||||
idle::IdleAnimation, run::RunAnimation, shockwave::ShockwaveAnimation, shoot::ShootAnimation,
|
||||
stunned::StunnedAnimation, swim::SwimAnimation,
|
||||
};
|
||||
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::bird_large::Body;
|
||||
|
||||
skeleton_impls!(struct BirdLargeSkeleton {
|
||||
+ head,
|
||||
+ beak,
|
||||
+ neck,
|
||||
+ chest,
|
||||
+ tail_front,
|
||||
+ tail_rear,
|
||||
+ wing_in_l,
|
||||
+ wing_in_r,
|
||||
+ wing_mid_l,
|
||||
+ wing_mid_r,
|
||||
+ wing_out_l,
|
||||
+ wing_out_r,
|
||||
+ leg_l,
|
||||
+ leg_r,
|
||||
+ foot_l,
|
||||
+ foot_r,
|
||||
});
|
||||
|
||||
impl Skeleton for BirdLargeSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 16;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const COMPUTE_FN: &'static [u8] = b"bird_large_compute_mats\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_compute_mats")]
|
||||
|
||||
fn compute_matrices_inner(
|
||||
&self,
|
||||
base_mat: Mat4<f32>,
|
||||
buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
|
||||
) -> Vec3<f32> {
|
||||
let chest_mat = base_mat * Mat4::<f32>::from(self.chest);
|
||||
let neck_mat = chest_mat * Mat4::<f32>::from(self.neck);
|
||||
let head_mat = neck_mat * Mat4::<f32>::from(self.head);
|
||||
let beak_mat = head_mat * Mat4::<f32>::from(self.beak);
|
||||
let tail_front_mat = chest_mat * Mat4::<f32>::from(self.tail_front);
|
||||
let tail_rear_mat = tail_front_mat * Mat4::<f32>::from(self.tail_rear);
|
||||
let wing_in_l_mat = chest_mat * Mat4::<f32>::from(self.wing_in_l);
|
||||
let wing_in_r_mat = chest_mat * Mat4::<f32>::from(self.wing_in_r);
|
||||
let wing_mid_l_mat = wing_in_l_mat * Mat4::<f32>::from(self.wing_mid_l);
|
||||
let wing_mid_r_mat = wing_in_r_mat * Mat4::<f32>::from(self.wing_mid_r);
|
||||
let wing_out_l_mat = wing_mid_l_mat * Mat4::<f32>::from(self.wing_out_l);
|
||||
let wing_out_r_mat = wing_mid_r_mat * Mat4::<f32>::from(self.wing_out_r);
|
||||
let leg_l_mat = base_mat * Mat4::<f32>::from(self.leg_l);
|
||||
let leg_r_mat = base_mat * Mat4::<f32>::from(self.leg_r);
|
||||
let foot_l_mat = leg_l_mat * Mat4::<f32>::from(self.foot_l);
|
||||
let foot_r_mat = leg_r_mat * Mat4::<f32>::from(self.foot_r);
|
||||
|
||||
*(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
|
||||
make_bone(head_mat),
|
||||
make_bone(beak_mat),
|
||||
make_bone(neck_mat),
|
||||
make_bone(chest_mat),
|
||||
make_bone(tail_front_mat),
|
||||
make_bone(tail_rear_mat),
|
||||
make_bone(wing_in_l_mat),
|
||||
make_bone(wing_in_r_mat),
|
||||
make_bone(wing_mid_l_mat),
|
||||
make_bone(wing_mid_r_mat),
|
||||
make_bone(wing_out_l_mat),
|
||||
make_bone(wing_out_r_mat),
|
||||
make_bone(leg_l_mat),
|
||||
make_bone(leg_r_mat),
|
||||
make_bone(foot_l_mat),
|
||||
make_bone(foot_r_mat),
|
||||
];
|
||||
Vec3::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SkeletonAttr {
|
||||
chest: (f32, f32),
|
||||
neck: (f32, f32),
|
||||
head: (f32, f32),
|
||||
beak: (f32, f32),
|
||||
tail_front: (f32, f32),
|
||||
tail_rear: (f32, f32),
|
||||
wing_in: (f32, f32, f32),
|
||||
wing_mid: (f32, f32, f32),
|
||||
wing_out: (f32, f32, f32),
|
||||
leg: (f32, f32, f32),
|
||||
foot: (f32, f32, f32),
|
||||
scaler: f32,
|
||||
feed: f32,
|
||||
}
|
||||
|
||||
impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
|
||||
match body {
|
||||
comp::Body::BirdLarge(body) => Ok(SkeletonAttr::from(body)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SkeletonAttr {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
chest: (0.0, 0.0),
|
||||
neck: (0.0, 0.0),
|
||||
head: (0.0, 0.0),
|
||||
beak: (0.0, 0.0),
|
||||
tail_front: (0.0, 0.0),
|
||||
tail_rear: (0.0, 0.0),
|
||||
wing_in: (0.0, 0.0, 0.0),
|
||||
wing_mid: (0.0, 0.0, 0.0),
|
||||
wing_out: (0.0, 0.0, 0.0),
|
||||
leg: (0.0, 0.0, 0.0),
|
||||
foot: (0.0, 0.0, 0.0),
|
||||
scaler: 0.0,
|
||||
feed: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(body: &'a Body) -> Self {
|
||||
use comp::bird_large::Species::*;
|
||||
Self {
|
||||
chest: match (body.species, body.body_type) {
|
||||
(Phoenix, _) => (2.5, 16.0),
|
||||
(Cockatrice, _) => (2.5, 16.0),
|
||||
},
|
||||
neck: match (body.species, body.body_type) {
|
||||
(Phoenix, _) => (2.5, -5.5),
|
||||
(Cockatrice, _) => (5.0, -1.5),
|
||||
},
|
||||
head: match (body.species, body.body_type) {
|
||||
(Phoenix, _) => (6.0, 12.0),
|
||||
(Cockatrice, _) => (8.0, 4.5),
|
||||
},
|
||||
beak: match (body.species, body.body_type) {
|
||||
(Phoenix, _) => (5.0, 3.0),
|
||||
(Cockatrice, _) => (2.0, -3.0),
|
||||
},
|
||||
tail_front: match (body.species, body.body_type) {
|
||||
(Phoenix, _) => (-9.5, -1.0),
|
||||
(Cockatrice, _) => (-5.0, -2.5),
|
||||
},
|
||||
tail_rear: match (body.species, body.body_type) {
|
||||
(Phoenix, _) => (-11.0, 0.0),
|
||||
(Cockatrice, _) => (-8.0, -3.0),
|
||||
},
|
||||
wing_in: match (body.species, body.body_type) {
|
||||
(Phoenix, _) => (3.0, 2.5, 2.0),
|
||||
(Cockatrice, _) => (3.5, 7.0, 3.5),
|
||||
},
|
||||
wing_mid: match (body.species, body.body_type) {
|
||||
(Phoenix, _) => (10.0, 1.0, 0.0),
|
||||
(Cockatrice, _) => (6.0, 0.0, 0.0),
|
||||
},
|
||||
wing_out: match (body.species, body.body_type) {
|
||||
(Phoenix, _) => (7.0, 2.0, 1.5),
|
||||
(Cockatrice, _) => (4.0, -1.0, 1.0),
|
||||
},
|
||||
leg: match (body.species, body.body_type) {
|
||||
(Phoenix, _) => (4.0, 1.5, 12.0),
|
||||
(Cockatrice, _) => (3.5, 2.5, 13.0),
|
||||
},
|
||||
foot: match (body.species, body.body_type) {
|
||||
(Phoenix, _) => (0.5, -0.5, -2.5),
|
||||
(Cockatrice, _) => (0.5, -3.0, -3.0),
|
||||
},
|
||||
scaler: match (body.species, body.body_type) {
|
||||
(Phoenix, _) => (1.0),
|
||||
(Cockatrice, _) => (1.0),
|
||||
},
|
||||
feed: match (body.species, body.body_type) {
|
||||
(Phoenix, _) => (-0.65),
|
||||
(Cockatrice, _) => (-0.5),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
159
voxygen/anim/src/bird_large/run.rs
Normal file
159
voxygen/anim/src/bird_large/run.rs
Normal file
@ -0,0 +1,159 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
BirdLargeSkeleton, SkeletonAttr,
|
||||
};
|
||||
use std::f32::consts::PI;
|
||||
|
||||
pub struct RunAnimation;
|
||||
|
||||
impl Animation for RunAnimation {
|
||||
type Dependency = (Vec3<f32>, Vec3<f32>, Vec3<f32>, f32);
|
||||
type Skeleton = BirdLargeSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"bird_large_run\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_run")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
(velocity, orientation, last_ori, acc_vel): Self::Dependency,
|
||||
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 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;
|
||||
|
||||
//FL
|
||||
let foot1a = (mixed_vel * 1.0 * lab * speedmult + 0.0 + PI).sin() * speednorm; //1.5
|
||||
let foot1b = (mixed_vel * 1.0 * lab * speedmult + 1.57 + PI).sin() * speednorm; //1.9
|
||||
//FR
|
||||
let foot2a = (mixed_vel * 1.0 * lab * speedmult).sin() * speednorm; //1.2
|
||||
let foot2b = (mixed_vel * 1.0 * lab * speedmult + 1.57).sin() * speednorm; //1.6
|
||||
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)
|
||||
* 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);
|
||||
|
||||
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)
|
||||
* 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);
|
||||
|
||||
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) * Quaternion::rotation_z(0.2);
|
||||
next.wing_in_r.orientation = Quaternion::rotation_y(0.8) * Quaternion::rotation_z(-0.2);
|
||||
|
||||
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);
|
||||
|
||||
next.leg_l.position = Vec3::new(
|
||||
-s_a.leg.0 + speednorm * 1.5,
|
||||
s_a.leg.1 + foot1b * -2.3,
|
||||
s_a.leg.2,
|
||||
) / 8.0;
|
||||
next.leg_l.orientation = Quaternion::rotation_x(-0.2 * speednorm + foot1a * 0.15)
|
||||
* Quaternion::rotation_y(tilt * 0.5);
|
||||
|
||||
next.leg_r.position = Vec3::new(
|
||||
s_a.leg.0 + speednorm * -1.5,
|
||||
s_a.leg.1 + foot2b * -2.3,
|
||||
s_a.leg.2,
|
||||
) / 8.0;
|
||||
next.leg_r.orientation = Quaternion::rotation_x(-0.2 * speednorm + foot2a * 0.15)
|
||||
* Quaternion::rotation_y(tilt * 0.5);
|
||||
|
||||
next.foot_l.position = Vec3::new(
|
||||
-s_a.foot.0,
|
||||
s_a.foot.1 + foot1b * -1.0,
|
||||
s_a.foot.2 + (foot1a * 1.5).max(0.0),
|
||||
);
|
||||
next.foot_l.orientation = Quaternion::rotation_x(0.2 * speednorm + foot1b * -0.5 + 0.1)
|
||||
* Quaternion::rotation_y(tilt * -1.0)
|
||||
* Quaternion::rotation_z(tilt * -0.5);
|
||||
|
||||
next.foot_r.position = Vec3::new(
|
||||
s_a.foot.0,
|
||||
s_a.foot.1 + foot2b * -1.0,
|
||||
s_a.foot.2 + (foot2a * 1.5).max(0.0),
|
||||
);
|
||||
next.foot_r.orientation = Quaternion::rotation_x(0.2 * speednorm + foot2b * -0.5 + 0.1)
|
||||
* Quaternion::rotation_y(tilt * -1.0)
|
||||
* Quaternion::rotation_z(tilt * -0.5);
|
||||
|
||||
next
|
||||
}
|
||||
}
|
106
voxygen/anim/src/bird_large/shockwave.rs
Normal file
106
voxygen/anim/src/bird_large/shockwave.rs
Normal file
@ -0,0 +1,106 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
BirdLargeSkeleton, SkeletonAttr,
|
||||
};
|
||||
use common::states::utils::StageSection;
|
||||
|
||||
pub struct ShockwaveAnimation;
|
||||
|
||||
impl Animation for ShockwaveAnimation {
|
||||
#[allow(clippy::type_complexity)]
|
||||
type Dependency = (Option<StageSection>, bool);
|
||||
type Skeleton = BirdLargeSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"bird_large_shockwave\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_shockwave")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
(stage_section, on_ground): Self::Dependency,
|
||||
anim_time: f32,
|
||||
_rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let (movement1base, movement2base, movement3, _twitch) = match stage_section {
|
||||
Some(StageSection::Buildup) => (anim_time.powf(0.5), 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, 1.0),
|
||||
_ => (0.0, 0.0, 0.0, 0.0),
|
||||
};
|
||||
|
||||
let pullback = 1.0 - movement3;
|
||||
|
||||
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 + movement1abs * 1.5) * s_a.scaler / 8.0;
|
||||
next.chest.orientation = Quaternion::rotation_x(movement1abs * 1.0 + movement2abs * -1.0);
|
||||
|
||||
next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1);
|
||||
next.neck.orientation = Quaternion::rotation_x(-0.2);
|
||||
|
||||
next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
|
||||
next.head.orientation = Quaternion::rotation_x(wave_slow_cos * 0.01);
|
||||
|
||||
next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1);
|
||||
next.beak.orientation = Quaternion::rotation_x(wave_slow_cos * -0.02 - 0.02);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
if on_ground {
|
||||
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.6 + movement2abs * -1.6)
|
||||
* Quaternion::rotation_z(0.2 + movement1abs * -0.8);
|
||||
next.wing_in_r.orientation =
|
||||
Quaternion::rotation_y(0.8 + movement1abs * -1.6 + movement2abs * 1.6)
|
||||
* Quaternion::rotation_z(-0.2 + movement1abs * 0.8);
|
||||
|
||||
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.4) * Quaternion::rotation_z(0.2);
|
||||
next.wing_out_r.orientation =
|
||||
Quaternion::rotation_y(0.4) * Quaternion::rotation_z(-0.2);
|
||||
|
||||
next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0;
|
||||
next.leg_l.orientation = Quaternion::rotation_x(0.0);
|
||||
next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0;
|
||||
next.leg_r.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
next.foot_l.orientation = Quaternion::rotation_x(0.0);
|
||||
next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
next.foot_r.orientation = Quaternion::rotation_x(0.0);
|
||||
} else {
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
}
|
110
voxygen/anim/src/bird_large/shoot.rs
Normal file
110
voxygen/anim/src/bird_large/shoot.rs
Normal file
@ -0,0 +1,110 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
BirdLargeSkeleton, SkeletonAttr,
|
||||
};
|
||||
use common::{states::utils::StageSection, util::Dir};
|
||||
|
||||
pub struct ShootAnimation;
|
||||
|
||||
type ShootAnimationDependency = (f32, Option<StageSection>, f32, Dir, bool);
|
||||
|
||||
impl Animation for ShootAnimation {
|
||||
type Dependency = ShootAnimationDependency;
|
||||
type Skeleton = BirdLargeSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"bird_large_shoot\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_shoot")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
(global_time, stage_section, timer, look_dir, on_ground): Self::Dependency,
|
||||
anim_time: f32,
|
||||
_rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
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, 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 * 0.5 - movement2abs * 0.5 + 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 * 0.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_y(-1.0 + movement1abs * 0.8 - movement2abs * 0.4)
|
||||
* Quaternion::rotation_z(0.2 - movement1abs * 0.8 + movement2abs * 0.4);
|
||||
next.wing_in_r.orientation =
|
||||
Quaternion::rotation_y(1.0 - movement1abs * 0.8 + movement2abs * 0.4)
|
||||
* Quaternion::rotation_z(-0.2 + movement1abs * 0.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) * 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) * Quaternion::rotation_z(0.2);
|
||||
next.wing_out_r.orientation =
|
||||
Quaternion::rotation_y(0.2) * 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
|
||||
}
|
||||
}
|
91
voxygen/anim/src/bird_large/stunned.rs
Normal file
91
voxygen/anim/src/bird_large/stunned.rs
Normal file
@ -0,0 +1,91 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
BirdLargeSkeleton, SkeletonAttr,
|
||||
};
|
||||
use common::states::utils::StageSection;
|
||||
|
||||
pub struct StunnedAnimation;
|
||||
|
||||
impl Animation for StunnedAnimation {
|
||||
type Dependency = (f32, Option<StageSection>, f32);
|
||||
type Skeleton = BirdLargeSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"bird_large_stunned\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_stunned")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
(global_time, stage_section, timer): Self::Dependency,
|
||||
anim_time: f32,
|
||||
_rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let wave_slow_cos = (anim_time * 4.5).cos();
|
||||
|
||||
let (movement1base, movement2, twitch) = match stage_section {
|
||||
Some(StageSection::Buildup) => (anim_time.powf(0.1), 0.0, anim_time),
|
||||
Some(StageSection::Recover) => (1.0, anim_time.powf(4.0), 1.0),
|
||||
_ => (0.0, 0.0, 0.0),
|
||||
};
|
||||
let pullback = 1.0 - movement2;
|
||||
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;
|
||||
|
||||
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) * s_a.scaler / 8.0;
|
||||
next.chest.orientation = Quaternion::rotation_x(movement1base * 0.5);
|
||||
|
||||
next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1);
|
||||
|
||||
next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
|
||||
next.head.orientation =
|
||||
Quaternion::rotation_z(twitch2 * 0.8) * Quaternion::rotation_x(wave_slow_cos * 0.01);
|
||||
|
||||
next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1);
|
||||
next.beak.orientation = Quaternion::rotation_x(-movement1abs * 0.8);
|
||||
|
||||
next.tail_front.position = Vec3::new(0.0, s_a.tail_front.0, s_a.tail_front.1);
|
||||
next.tail_rear.position = Vec3::new(0.0, s_a.tail_rear.0, s_a.tail_rear.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(wave_slow_cos * 0.06 + twitch2 * 0.8)
|
||||
* Quaternion::rotation_z(0.2 - movement1abs);
|
||||
next.wing_in_r.orientation = Quaternion::rotation_y(wave_slow_cos * 0.06 - twitch2 * 0.8)
|
||||
* Quaternion::rotation_z(-0.2 + movement1abs);
|
||||
|
||||
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) * Quaternion::rotation_z(0.2);
|
||||
next.wing_out_r.orientation = Quaternion::rotation_y(0.2) * Quaternion::rotation_z(-0.2);
|
||||
|
||||
next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0;
|
||||
next.leg_l.orientation = Quaternion::rotation_x(movement1abs * 0.8);
|
||||
next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0;
|
||||
|
||||
next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
|
||||
next
|
||||
}
|
||||
}
|
102
voxygen/anim/src/bird_large/swim.rs
Normal file
102
voxygen/anim/src/bird_large/swim.rs
Normal file
@ -0,0 +1,102 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
BirdLargeSkeleton, SkeletonAttr,
|
||||
};
|
||||
use std::ops::Mul;
|
||||
|
||||
pub struct SwimAnimation;
|
||||
|
||||
impl Animation for SwimAnimation {
|
||||
#[allow(clippy::type_complexity)]
|
||||
type Dependency = f32;
|
||||
type Skeleton = BirdLargeSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"bird_large_swim\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_swim")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
global_time: Self::Dependency,
|
||||
anim_time: f32,
|
||||
_rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let duck_head_look = Vec2::new(
|
||||
(global_time / 2.0 + anim_time / 8.0)
|
||||
.floor()
|
||||
.mul(7331.0)
|
||||
.sin()
|
||||
* 0.5,
|
||||
(global_time / 2.0 + anim_time / 8.0)
|
||||
.floor()
|
||||
.mul(1337.0)
|
||||
.sin()
|
||||
* 0.25,
|
||||
);
|
||||
let wave_slow_cos = (anim_time * 4.5).cos();
|
||||
|
||||
let wave_fast = (anim_time * 6.0).sin();
|
||||
let wave_fast_cos = (anim_time * 6.0).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 + 1.5)
|
||||
* s_a.scaler
|
||||
/ 8.0;
|
||||
next.chest.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
next.neck.position = Vec3::new(0.0, s_a.neck.0, s_a.neck.1);
|
||||
next.neck.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
|
||||
next.head.orientation = Quaternion::rotation_z(duck_head_look.x)
|
||||
* Quaternion::rotation_x(-duck_head_look.y.abs() + wave_slow_cos * 0.01);
|
||||
|
||||
next.beak.position = Vec3::new(0.0, s_a.beak.0, s_a.beak.1);
|
||||
next.beak.orientation = Quaternion::rotation_x(wave_slow_cos * -0.02 - 0.02);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
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 + wave_slow_cos * 0.06) * Quaternion::rotation_z(0.2);
|
||||
next.wing_in_r.orientation =
|
||||
Quaternion::rotation_y(0.8 - wave_slow_cos * 0.06) * Quaternion::rotation_z(-0.2);
|
||||
|
||||
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.4) * Quaternion::rotation_z(0.2);
|
||||
next.wing_out_r.orientation = Quaternion::rotation_y(0.4) * Quaternion::rotation_z(-0.2);
|
||||
|
||||
next.leg_l.position = Vec3::new(-s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0;
|
||||
next.leg_l.orientation = Quaternion::rotation_x(-0.8 + wave_fast * 0.5);
|
||||
next.leg_r.position = Vec3::new(s_a.leg.0, s_a.leg.1, s_a.leg.2) / 8.0;
|
||||
next.leg_r.orientation = Quaternion::rotation_x(-0.8 + wave_fast_cos * 0.5);
|
||||
|
||||
next.foot_l.position = Vec3::new(-s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
next.foot_l.orientation = Quaternion::rotation_x(0.0);
|
||||
next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1, s_a.foot.2);
|
||||
next.foot_r.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
next
|
||||
}
|
||||
}
|
@ -99,7 +99,6 @@ impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
(Owl, Male) => (2.5, 5.0),
|
||||
(Owl, Female) => (2.5, 7.0),
|
||||
(Parrot, _) => (0.5, 4.5),
|
||||
(Cockatrice, _) => (0.0, 4.0),
|
||||
},
|
||||
chest: match (body.species, body.body_type) {
|
||||
(Duck, _) => (0.0, 5.0),
|
||||
@ -111,7 +110,6 @@ impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
(Owl, Male) => (0.0, 4.5),
|
||||
(Owl, Female) => (0.0, 4.5),
|
||||
(Parrot, _) => (0.0, 5.0),
|
||||
(Cockatrice, _) => (0.0, 12.5),
|
||||
},
|
||||
tail: match (body.species, body.body_type) {
|
||||
(Duck, _) => (-3.0, 1.5),
|
||||
@ -123,7 +121,6 @@ impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
(Owl, Male) => (-6.0, -2.0),
|
||||
(Owl, Female) => (-6.0, -2.5),
|
||||
(Parrot, _) => (-8.0, -2.0),
|
||||
(Cockatrice, _) => (-10.0, -2.5),
|
||||
},
|
||||
wing: match (body.species, body.body_type) {
|
||||
(Duck, _) => (2.75, 0.0, 1.0),
|
||||
@ -135,7 +132,6 @@ impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
(Owl, Male) => (3.5, -5.5, 4.0),
|
||||
(Owl, Female) => (3.5, -6.0, 3.5),
|
||||
(Parrot, _) => (2.0, -4.5, 3.0),
|
||||
(Cockatrice, _) => (4.5, -2.5, 1.5),
|
||||
},
|
||||
foot: match (body.species, body.body_type) {
|
||||
(Duck, _) => (2.0, -1.5, 4.0),
|
||||
@ -147,7 +143,6 @@ impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
(Owl, Male) => (1.5, -2.5, 7.0),
|
||||
(Owl, Female) => (1.5, -3.0, 6.5),
|
||||
(Parrot, _) => (1.5, -3.0, 3.0),
|
||||
(Cockatrice, _) => (4.0, -3.5, 12.0),
|
||||
},
|
||||
feed: match (body.species, body.body_type) {
|
||||
(Chicken, _) => 1.2,
|
||||
@ -155,7 +150,6 @@ impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
(Peacock, _) => 1.6,
|
||||
(Eagle, _) => 1.2,
|
||||
(Parrot, _) => 1.2,
|
||||
(Cockatrice, _) => 1.3,
|
||||
_ => 1.0,
|
||||
},
|
||||
}
|
||||
|
@ -1,42 +0,0 @@
|
||||
use super::{super::Animation, BirdSmallSkeleton, SkeletonAttr};
|
||||
//use std::{f32::consts::PI, ops::Mul};
|
||||
use super::super::vek::*;
|
||||
|
||||
pub struct IdleAnimation;
|
||||
|
||||
impl Animation for IdleAnimation {
|
||||
type Dependency = f32;
|
||||
type Skeleton = BirdSmallSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"bird_small_idle\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_small_idle")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
_global_time: Self::Dependency,
|
||||
_anim_time: f32,
|
||||
_rate: &mut f32,
|
||||
_skeleton_attr: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
next.head.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.head.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.head.scale = Vec3::one() / 10.88;
|
||||
|
||||
next.torso.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.torso.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.torso.scale = Vec3::one() / 10.88;
|
||||
|
||||
next.wing_l.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.wing_l.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.wing_l.scale = Vec3::one() / 10.88;
|
||||
|
||||
next.wing_r.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.wing_r.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.wing_r.scale = Vec3::one() / 10.88;
|
||||
|
||||
next
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
use super::{super::Animation, BirdSmallSkeleton, SkeletonAttr};
|
||||
//use std::f32::consts::PI;
|
||||
use super::super::vek::*;
|
||||
|
||||
pub struct JumpAnimation;
|
||||
|
||||
impl Animation for JumpAnimation {
|
||||
type Dependency = (f32, f32);
|
||||
type Skeleton = BirdSmallSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"bird_small_jump\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_small_jump")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
_global_time: Self::Dependency,
|
||||
_anim_time: f32,
|
||||
_rate: &mut f32,
|
||||
_skeleton_attr: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
next.head.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.head.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.head.scale = Vec3::one() / 10.88;
|
||||
|
||||
next.torso.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.torso.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.torso.scale = Vec3::one() / 10.88;
|
||||
|
||||
next.wing_l.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.wing_l.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.wing_l.scale = Vec3::one() / 10.88;
|
||||
|
||||
next.wing_r.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.wing_r.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.wing_r.scale = Vec3::one() / 10.88;
|
||||
|
||||
next
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
pub mod idle;
|
||||
pub mod jump;
|
||||
pub mod run;
|
||||
|
||||
// Reexports
|
||||
pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
||||
|
||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||
use common::comp::{self};
|
||||
use core::convert::TryFrom;
|
||||
|
||||
pub type Body = comp::bird_small::Body;
|
||||
|
||||
skeleton_impls!(struct BirdSmallSkeleton {
|
||||
+ head,
|
||||
+ torso,
|
||||
+ wing_l,
|
||||
+ wing_r,
|
||||
});
|
||||
|
||||
impl Skeleton for BirdSmallSkeleton {
|
||||
type Attr = SkeletonAttr;
|
||||
type Body = Body;
|
||||
|
||||
const BONE_COUNT: usize = 4;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const COMPUTE_FN: &'static [u8] = b"bird_small_compute_mats\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_small_compute_mats")]
|
||||
|
||||
fn compute_matrices_inner(
|
||||
&self,
|
||||
base_mat: Mat4<f32>,
|
||||
buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
|
||||
) -> Vec3<f32> {
|
||||
let torso_mat = base_mat * Mat4::<f32>::from(self.torso);
|
||||
|
||||
*(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
|
||||
make_bone(torso_mat * Mat4::<f32>::from(self.head)),
|
||||
make_bone(torso_mat),
|
||||
make_bone(torso_mat * Mat4::<f32>::from(self.wing_l)),
|
||||
make_bone(torso_mat * Mat4::<f32>::from(self.wing_r)),
|
||||
];
|
||||
Vec3::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SkeletonAttr;
|
||||
|
||||
impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
|
||||
match body {
|
||||
comp::Body::BirdSmall(body) => Ok(SkeletonAttr::from(body)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SkeletonAttr {
|
||||
fn default() -> Self { Self }
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||
fn from(_body: &'a Body) -> Self { Self }
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
use super::{super::Animation, BirdSmallSkeleton, SkeletonAttr};
|
||||
//use std::{f32::consts::PI, ops::Mul};
|
||||
use super::super::vek::*;
|
||||
|
||||
pub struct RunAnimation;
|
||||
|
||||
impl Animation for RunAnimation {
|
||||
type Dependency = (f32, f32);
|
||||
type Skeleton = BirdSmallSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"bird_small_run\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_small_run")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
(_velocity, _global_time): Self::Dependency,
|
||||
_anim_time: f32,
|
||||
_rate: &mut f32,
|
||||
_skeleton_attr: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
next.head.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.head.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.head.scale = Vec3::one() / 10.88;
|
||||
|
||||
next.torso.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.torso.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.torso.scale = Vec3::one() / 10.88;
|
||||
|
||||
next.wing_l.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.wing_l.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.wing_l.scale = Vec3::one() / 10.88;
|
||||
|
||||
next.wing_r.position = Vec3::new(0.0, 7.5, 15.0) / 11.0;
|
||||
next.wing_r.orientation = Quaternion::rotation_z(0.0) * Quaternion::rotation_x(0.0);
|
||||
next.wing_r.scale = Vec3::one() / 10.88;
|
||||
|
||||
next
|
||||
}
|
||||
}
|
@ -50,8 +50,8 @@ macro_rules! skeleton_impls {
|
||||
|
||||
pub mod biped_large;
|
||||
pub mod biped_small;
|
||||
pub mod bird_large;
|
||||
pub mod bird_medium;
|
||||
pub mod bird_small;
|
||||
pub mod character;
|
||||
pub mod dragon;
|
||||
#[cfg(feature = "use-dyn-lib")] pub mod dyn_lib;
|
||||
|
@ -27,7 +27,12 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
||||
(0..GEN_SIZE)
|
||||
.flat_map(|x| (0..GEN_SIZE).map(move |y| Vec2::new(x, y)))
|
||||
.map(|offset| offset + CENTER)
|
||||
.map(|pos| (pos, world.generate_chunk(index, pos, || false).unwrap()))
|
||||
.map(|pos| {
|
||||
(
|
||||
pos,
|
||||
world.generate_chunk(index, pos, || false, None).unwrap(),
|
||||
)
|
||||
})
|
||||
.for_each(|(key, chunk)| {
|
||||
terrain.insert(key, Arc::new(chunk.0));
|
||||
});
|
||||
|
@ -93,7 +93,7 @@ impl EventMapper for MovementEventMapper {
|
||||
Body::QuadrupedMedium(_) | Body::QuadrupedSmall(_) | Body::QuadrupedLow(_) => {
|
||||
Self::map_quadruped_movement_event(physics, vel.0, underfoot_block_kind)
|
||||
},
|
||||
Body::BirdMedium(_) | Body::BirdSmall(_) | Body::BipedLarge(_) => {
|
||||
Body::BirdMedium(_) | Body::BirdLarge(_) | Body::BipedLarge(_) => {
|
||||
Self::map_non_humanoid_movement_event(physics, vel.0, underfoot_block_kind)
|
||||
},
|
||||
_ => SfxEvent::Idle, // Ignore fish, etc...
|
||||
@ -281,7 +281,7 @@ impl MovementEventMapper {
|
||||
Body::QuadrupedMedium(_) => 0.7,
|
||||
Body::QuadrupedLow(_) => 0.7,
|
||||
Body::BirdMedium(_) => 0.3,
|
||||
Body::BirdSmall(_) => 0.2,
|
||||
Body::BirdLarge(_) => 0.2,
|
||||
Body::BipedLarge(_) => 1.0,
|
||||
_ => 0.9,
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use super::*;
|
||||
use crate::audio::sfx::SfxEvent;
|
||||
use common::{
|
||||
comp::{
|
||||
bird_small, humanoid, quadruped_medium, quadruped_small, Body, CharacterState, InputKind,
|
||||
bird_large, humanoid, quadruped_medium, quadruped_small, Body, CharacterState, InputKind,
|
||||
PhysicsState,
|
||||
},
|
||||
states,
|
||||
@ -340,12 +340,12 @@ fn determines_relative_volumes() {
|
||||
quadruped_small::Body::random(),
|
||||
));
|
||||
|
||||
let bird_small =
|
||||
MovementEventMapper::get_volume_for_body_type(&Body::BirdSmall(bird_small::Body::random()));
|
||||
let bird_large =
|
||||
MovementEventMapper::get_volume_for_body_type(&Body::BirdLarge(bird_large::Body::random()));
|
||||
|
||||
assert!(quadruped_medium < human);
|
||||
assert!(quadruped_small < quadruped_medium);
|
||||
assert!(bird_small < quadruped_small);
|
||||
assert!(bird_large < quadruped_small);
|
||||
}
|
||||
|
||||
fn empty_ability_info() -> states::utils::AbilityInfo {
|
||||
|
@ -4,8 +4,8 @@ use common::{
|
||||
comp::{
|
||||
biped_large::{self, BodyType as BLBodyType, Species as BLSpecies},
|
||||
biped_small,
|
||||
bird_large::{self, BodyType as BLABodyType, Species as BLASpecies},
|
||||
bird_medium::{self, BodyType as BMBodyType, Species as BMSpecies},
|
||||
bird_small,
|
||||
dragon::{self, BodyType as DBodyType, Species as DSpecies},
|
||||
fish_medium::{self, BodyType as FMBodyType, Species as FMSpecies},
|
||||
fish_small::{self, BodyType as FSBodyType, Species as FSSpecies},
|
||||
@ -3109,65 +3109,379 @@ impl DragonLateralSpec {
|
||||
}
|
||||
|
||||
////
|
||||
#[derive(Deserialize)]
|
||||
struct BirdLargeCentralSpec(HashMap<(BLASpecies, BLABodyType), SidedBLACentralVoxSpec>);
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct SidedBLACentralVoxSpec {
|
||||
head: BirdLargeCentralSubSpec,
|
||||
beak: BirdLargeCentralSubSpec,
|
||||
neck: BirdLargeCentralSubSpec,
|
||||
chest: BirdLargeCentralSubSpec,
|
||||
tail_front: BirdLargeCentralSubSpec,
|
||||
tail_rear: BirdLargeCentralSubSpec,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
struct BirdLargeCentralSubSpec {
|
||||
offset: [f32; 3], // Should be relative to initial origin
|
||||
central: VoxSimple,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct BirdLargeLateralSpec(HashMap<(BLASpecies, BLABodyType), SidedBLALateralVoxSpec>);
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct SidedBLALateralVoxSpec {
|
||||
wing_in_l: BirdLargeLateralSubSpec,
|
||||
wing_in_r: BirdLargeLateralSubSpec,
|
||||
wing_mid_l: BirdLargeLateralSubSpec,
|
||||
wing_mid_r: BirdLargeLateralSubSpec,
|
||||
wing_out_l: BirdLargeLateralSubSpec,
|
||||
wing_out_r: BirdLargeLateralSubSpec,
|
||||
leg_l: BirdLargeLateralSubSpec,
|
||||
leg_r: BirdLargeLateralSubSpec,
|
||||
foot_l: BirdLargeLateralSubSpec,
|
||||
foot_r: BirdLargeLateralSubSpec,
|
||||
}
|
||||
#[derive(Deserialize)]
|
||||
struct BirdLargeLateralSubSpec {
|
||||
offset: [f32; 3], // Should be relative to initial origin
|
||||
lateral: VoxSimple,
|
||||
}
|
||||
|
||||
make_vox_spec!(
|
||||
bird_small::Body,
|
||||
struct BirdSmallSpec {},
|
||||
|FigureKey { body, .. }, _spec| {
|
||||
bird_large::Body,
|
||||
struct BirdLargeSpec {
|
||||
central: BirdLargeCentralSpec = "voxygen.voxel.bird_large_central_manifest",
|
||||
lateral: BirdLargeLateralSpec = "voxygen.voxel.bird_large_lateral_manifest",
|
||||
},
|
||||
|FigureKey { body, .. }, spec| {
|
||||
[
|
||||
Some(mesh_bird_small_head(body.head)),
|
||||
Some(mesh_bird_small_torso(body.torso)),
|
||||
Some(mesh_bird_small_wing_l(body.wing_l)),
|
||||
Some(mesh_bird_small_wing_r(body.wing_r)),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(spec.central.read().0.mesh_head(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.central.read().0.mesh_beak(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.central.read().0.mesh_neck(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.central.read().0.mesh_chest(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.central.read().0.mesh_tail_front(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.central.read().0.mesh_tail_rear(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.read().0.mesh_wing_in_l(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.read().0.mesh_wing_in_r(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.read().0.mesh_wing_mid_l(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.read().0.mesh_wing_mid_r(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.read().0.mesh_wing_out_l(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.read().0.mesh_wing_out_r(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.read().0.mesh_leg_l(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.read().0.mesh_leg_r(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.read().0.mesh_foot_l(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
Some(spec.lateral.read().0.mesh_foot_r(
|
||||
body.species,
|
||||
body.body_type,
|
||||
)),
|
||||
]
|
||||
},
|
||||
);
|
||||
|
||||
fn mesh_bird_small_head(head: bird_small::Head) -> BoneMeshes {
|
||||
load_mesh(
|
||||
match head {
|
||||
bird_small::Head::Default => "npc.crow.head",
|
||||
},
|
||||
Vec3::new(-7.0, -6.0, -6.0),
|
||||
)
|
||||
}
|
||||
impl BirdLargeCentralSpec {
|
||||
fn mesh_head(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No head specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let central = graceful_load_segment(&spec.head.central.0);
|
||||
|
||||
fn mesh_bird_small_torso(torso: bird_small::Torso) -> BoneMeshes {
|
||||
load_mesh(
|
||||
match torso {
|
||||
bird_small::Torso::Default => "npc.crow.torso",
|
||||
},
|
||||
Vec3::new(-7.0, -6.0, -6.0),
|
||||
)
|
||||
}
|
||||
(central, Vec3::from(spec.head.offset))
|
||||
}
|
||||
|
||||
fn mesh_bird_small_wing_l(wing_l: bird_small::WingL) -> BoneMeshes {
|
||||
load_mesh(
|
||||
match wing_l {
|
||||
bird_small::WingL::Default => "npc.crow.wing_l",
|
||||
},
|
||||
Vec3::new(-7.0, -6.0, -6.0),
|
||||
)
|
||||
}
|
||||
fn mesh_beak(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No beak specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let central = graceful_load_segment(&spec.beak.central.0);
|
||||
|
||||
fn mesh_bird_small_wing_r(wing_r: bird_small::WingR) -> BoneMeshes {
|
||||
load_mesh(
|
||||
match wing_r {
|
||||
bird_small::WingR::Default => "npc.crow.wing_r",
|
||||
},
|
||||
Vec3::new(-7.0, -6.0, -6.0),
|
||||
)
|
||||
(central, Vec3::from(spec.beak.offset))
|
||||
}
|
||||
|
||||
fn mesh_neck(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No neck specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let central = graceful_load_segment(&spec.neck.central.0);
|
||||
|
||||
(central, Vec3::from(spec.neck.offset))
|
||||
}
|
||||
|
||||
fn mesh_chest(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No chest specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let central = graceful_load_segment(&spec.chest.central.0);
|
||||
|
||||
(central, Vec3::from(spec.chest.offset))
|
||||
}
|
||||
|
||||
fn mesh_tail_front(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No tail front specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let central = graceful_load_segment(&spec.tail_front.central.0);
|
||||
|
||||
(central, Vec3::from(spec.tail_front.offset))
|
||||
}
|
||||
|
||||
fn mesh_tail_rear(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No tail rear specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let central = graceful_load_segment(&spec.tail_rear.central.0);
|
||||
|
||||
(central, Vec3::from(spec.tail_rear.offset))
|
||||
}
|
||||
}
|
||||
impl BirdLargeLateralSpec {
|
||||
fn mesh_wing_in_l(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No wing in in left specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let lateral = graceful_load_segment_flipped(&spec.wing_in_l.lateral.0, true);
|
||||
|
||||
(lateral, Vec3::from(spec.wing_in_l.offset))
|
||||
}
|
||||
|
||||
fn mesh_wing_in_r(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No wing in right specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let lateral = graceful_load_segment(&spec.wing_in_r.lateral.0);
|
||||
|
||||
(lateral, Vec3::from(spec.wing_in_r.offset))
|
||||
}
|
||||
|
||||
fn mesh_wing_mid_l(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No wing mid specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let lateral = graceful_load_segment_flipped(&spec.wing_mid_l.lateral.0, true);
|
||||
|
||||
(lateral, Vec3::from(spec.wing_mid_l.offset))
|
||||
}
|
||||
|
||||
fn mesh_wing_mid_r(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No wing mid specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let lateral = graceful_load_segment(&spec.wing_mid_r.lateral.0);
|
||||
|
||||
(lateral, Vec3::from(spec.wing_mid_r.offset))
|
||||
}
|
||||
|
||||
fn mesh_wing_out_l(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No wing out specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let lateral = graceful_load_segment_flipped(&spec.wing_out_l.lateral.0, true);
|
||||
|
||||
(lateral, Vec3::from(spec.wing_out_l.offset))
|
||||
}
|
||||
|
||||
fn mesh_wing_out_r(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No wing out specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let lateral = graceful_load_segment(&spec.wing_out_r.lateral.0);
|
||||
|
||||
(lateral, Vec3::from(spec.wing_out_r.offset))
|
||||
}
|
||||
|
||||
fn mesh_leg_l(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No leg specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let lateral = graceful_load_segment_flipped(&spec.leg_l.lateral.0, true);
|
||||
|
||||
(lateral, Vec3::from(spec.leg_l.offset))
|
||||
}
|
||||
|
||||
fn mesh_leg_r(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No leg specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let lateral = graceful_load_segment(&spec.leg_r.lateral.0);
|
||||
|
||||
(lateral, Vec3::from(spec.leg_r.offset))
|
||||
}
|
||||
|
||||
fn mesh_foot_l(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No foot specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let lateral = graceful_load_segment_flipped(&spec.foot_l.lateral.0, true);
|
||||
|
||||
(lateral, Vec3::from(spec.foot_l.offset))
|
||||
}
|
||||
|
||||
fn mesh_foot_r(&self, species: BLASpecies, body_type: BLABodyType) -> BoneMeshes {
|
||||
let spec = match self.0.get(&(species, body_type)) {
|
||||
Some(spec) => spec,
|
||||
None => {
|
||||
error!(
|
||||
"No foot specification exists for the combination of {:?} and {:?}",
|
||||
species, body_type
|
||||
);
|
||||
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||
},
|
||||
};
|
||||
let lateral = graceful_load_segment(&spec.foot_r.lateral.0);
|
||||
|
||||
(lateral, Vec3::from(spec.foot_r.offset))
|
||||
}
|
||||
}
|
||||
|
||||
////
|
||||
|
@ -19,7 +19,7 @@ use crate::{
|
||||
};
|
||||
use anim::{
|
||||
biped_large::BipedLargeSkeleton, biped_small::BipedSmallSkeleton,
|
||||
bird_medium::BirdMediumSkeleton, bird_small::BirdSmallSkeleton, character::CharacterSkeleton,
|
||||
bird_large::BirdLargeSkeleton, bird_medium::BirdMediumSkeleton, character::CharacterSkeleton,
|
||||
dragon::DragonSkeleton, fish_medium::FishMediumSkeleton, fish_small::FishSmallSkeleton,
|
||||
golem::GolemSkeleton, object::ObjectSkeleton, quadruped_low::QuadrupedLowSkeleton,
|
||||
quadruped_medium::QuadrupedMediumSkeleton, quadruped_small::QuadrupedSmallSkeleton,
|
||||
@ -95,7 +95,7 @@ struct FigureMgrStates {
|
||||
fish_medium_states: HashMap<EcsEntity, FigureState<FishMediumSkeleton>>,
|
||||
theropod_states: HashMap<EcsEntity, FigureState<TheropodSkeleton>>,
|
||||
dragon_states: HashMap<EcsEntity, FigureState<DragonSkeleton>>,
|
||||
bird_small_states: HashMap<EcsEntity, FigureState<BirdSmallSkeleton>>,
|
||||
bird_large_states: HashMap<EcsEntity, FigureState<BirdLargeSkeleton>>,
|
||||
fish_small_states: HashMap<EcsEntity, FigureState<FishSmallSkeleton>>,
|
||||
biped_large_states: HashMap<EcsEntity, FigureState<BipedLargeSkeleton>>,
|
||||
biped_small_states: HashMap<EcsEntity, FigureState<BipedSmallSkeleton>>,
|
||||
@ -115,7 +115,7 @@ impl FigureMgrStates {
|
||||
fish_medium_states: HashMap::new(),
|
||||
theropod_states: HashMap::new(),
|
||||
dragon_states: HashMap::new(),
|
||||
bird_small_states: HashMap::new(),
|
||||
bird_large_states: HashMap::new(),
|
||||
fish_small_states: HashMap::new(),
|
||||
biped_large_states: HashMap::new(),
|
||||
biped_small_states: HashMap::new(),
|
||||
@ -164,8 +164,8 @@ impl FigureMgrStates {
|
||||
.get_mut(&entity)
|
||||
.map(DerefMut::deref_mut),
|
||||
Body::Dragon(_) => self.dragon_states.get_mut(&entity).map(DerefMut::deref_mut),
|
||||
Body::BirdSmall(_) => self
|
||||
.bird_small_states
|
||||
Body::BirdLarge(_) => self
|
||||
.bird_large_states
|
||||
.get_mut(&entity)
|
||||
.map(DerefMut::deref_mut),
|
||||
Body::FishSmall(_) => self
|
||||
@ -202,7 +202,7 @@ impl FigureMgrStates {
|
||||
Body::FishMedium(_) => self.fish_medium_states.remove(&entity).map(|e| e.meta),
|
||||
Body::Theropod(_) => self.theropod_states.remove(&entity).map(|e| e.meta),
|
||||
Body::Dragon(_) => self.dragon_states.remove(&entity).map(|e| e.meta),
|
||||
Body::BirdSmall(_) => self.bird_small_states.remove(&entity).map(|e| e.meta),
|
||||
Body::BirdLarge(_) => self.bird_large_states.remove(&entity).map(|e| e.meta),
|
||||
Body::FishSmall(_) => self.fish_small_states.remove(&entity).map(|e| e.meta),
|
||||
Body::BipedLarge(_) => self.biped_large_states.remove(&entity).map(|e| e.meta),
|
||||
Body::BipedSmall(_) => self.biped_small_states.remove(&entity).map(|e| e.meta),
|
||||
@ -222,7 +222,7 @@ impl FigureMgrStates {
|
||||
self.fish_medium_states.retain(|k, v| f(k, &mut *v));
|
||||
self.theropod_states.retain(|k, v| f(k, &mut *v));
|
||||
self.dragon_states.retain(|k, v| f(k, &mut *v));
|
||||
self.bird_small_states.retain(|k, v| f(k, &mut *v));
|
||||
self.bird_large_states.retain(|k, v| f(k, &mut *v));
|
||||
self.fish_small_states.retain(|k, v| f(k, &mut *v));
|
||||
self.biped_large_states.retain(|k, v| f(k, &mut *v));
|
||||
self.biped_small_states.retain(|k, v| f(k, &mut *v));
|
||||
@ -241,7 +241,7 @@ impl FigureMgrStates {
|
||||
+ self.fish_medium_states.len()
|
||||
+ self.theropod_states.len()
|
||||
+ self.dragon_states.len()
|
||||
+ self.bird_small_states.len()
|
||||
+ self.bird_large_states.len()
|
||||
+ self.fish_small_states.len()
|
||||
+ self.biped_large_states.len()
|
||||
+ self.biped_small_states.len()
|
||||
@ -291,7 +291,7 @@ impl FigureMgrStates {
|
||||
.filter(|(_, c)| c.visible())
|
||||
.count()
|
||||
+ self
|
||||
.bird_small_states
|
||||
.bird_large_states
|
||||
.iter()
|
||||
.filter(|(_, c)| c.visible())
|
||||
.count()
|
||||
@ -332,7 +332,7 @@ pub struct FigureMgr {
|
||||
quadruped_medium_model_cache: FigureModelCache<QuadrupedMediumSkeleton>,
|
||||
quadruped_low_model_cache: FigureModelCache<QuadrupedLowSkeleton>,
|
||||
bird_medium_model_cache: FigureModelCache<BirdMediumSkeleton>,
|
||||
bird_small_model_cache: FigureModelCache<BirdSmallSkeleton>,
|
||||
bird_large_model_cache: FigureModelCache<BirdLargeSkeleton>,
|
||||
dragon_model_cache: FigureModelCache<DragonSkeleton>,
|
||||
fish_medium_model_cache: FigureModelCache<FishMediumSkeleton>,
|
||||
fish_small_model_cache: FigureModelCache<FishSmallSkeleton>,
|
||||
@ -354,7 +354,7 @@ impl FigureMgr {
|
||||
quadruped_medium_model_cache: FigureModelCache::new(),
|
||||
quadruped_low_model_cache: FigureModelCache::new(),
|
||||
bird_medium_model_cache: FigureModelCache::new(),
|
||||
bird_small_model_cache: FigureModelCache::new(),
|
||||
bird_large_model_cache: FigureModelCache::new(),
|
||||
dragon_model_cache: FigureModelCache::new(),
|
||||
fish_medium_model_cache: FigureModelCache::new(),
|
||||
fish_small_model_cache: FigureModelCache::new(),
|
||||
@ -381,7 +381,7 @@ impl FigureMgr {
|
||||
.clean(&mut self.col_lights, tick);
|
||||
self.bird_medium_model_cache
|
||||
.clean(&mut self.col_lights, tick);
|
||||
self.bird_small_model_cache
|
||||
self.bird_large_model_cache
|
||||
.clean(&mut self.col_lights, tick);
|
||||
self.dragon_model_cache.clean(&mut self.col_lights, tick);
|
||||
self.fish_medium_model_cache
|
||||
@ -3263,8 +3263,8 @@ impl FigureMgr {
|
||||
physics.ground_vel,
|
||||
);
|
||||
},
|
||||
Body::BirdSmall(body) => {
|
||||
let (model, skeleton_attr) = self.bird_small_model_cache.get_or_create_model(
|
||||
Body::BirdLarge(body) => {
|
||||
let (model, skeleton_attr) = self.bird_large_model_cache.get_or_create_model(
|
||||
renderer,
|
||||
&mut self.col_lights,
|
||||
*body,
|
||||
@ -3277,15 +3277,12 @@ impl FigureMgr {
|
||||
|
||||
let state = self
|
||||
.states
|
||||
.bird_small_states
|
||||
.bird_large_states
|
||||
.entry(entity)
|
||||
.or_insert_with(|| {
|
||||
FigureState::new(renderer, BirdSmallSkeleton::default())
|
||||
FigureState::new(renderer, BirdLargeSkeleton::default())
|
||||
});
|
||||
|
||||
// Average velocity relative to the current ground
|
||||
let _rel_avg_vel = state.avg_vel - physics.ground_vel;
|
||||
|
||||
let (character, last_character) = match (character, last_character) {
|
||||
(Some(c), Some(l)) => (c, l),
|
||||
_ => continue,
|
||||
@ -3301,41 +3298,214 @@ impl FigureMgr {
|
||||
physics.in_liquid().is_some(), // In water
|
||||
) {
|
||||
// Standing
|
||||
(true, false, false) => anim::bird_small::IdleAnimation::update_skeleton(
|
||||
&BirdSmallSkeleton::default(),
|
||||
(true, false, false) => anim::bird_large::IdleAnimation::update_skeleton(
|
||||
&BirdLargeSkeleton::default(),
|
||||
time,
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
// Running
|
||||
(true, true, false) => anim::bird_small::RunAnimation::update_skeleton(
|
||||
&BirdSmallSkeleton::default(),
|
||||
(rel_vel.magnitude(), time),
|
||||
(true, true, false) => anim::bird_large::RunAnimation::update_skeleton(
|
||||
&BirdLargeSkeleton::default(),
|
||||
(
|
||||
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,
|
||||
),
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
// In air
|
||||
(false, _, false) => anim::bird_small::JumpAnimation::update_skeleton(
|
||||
&BirdSmallSkeleton::default(),
|
||||
(rel_vel.magnitude(), time),
|
||||
(false, _, false) => anim::bird_large::FlyAnimation::update_skeleton(
|
||||
&BirdLargeSkeleton::default(),
|
||||
(
|
||||
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.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
// Swim
|
||||
(_, true, _) => anim::bird_large::SwimAnimation::update_skeleton(
|
||||
&BirdLargeSkeleton::default(),
|
||||
time,
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
|
||||
// TODO!
|
||||
_ => anim::bird_small::IdleAnimation::update_skeleton(
|
||||
&BirdSmallSkeleton::default(),
|
||||
_ => anim::bird_large::IdleAnimation::update_skeleton(
|
||||
&BirdLargeSkeleton::default(),
|
||||
time,
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
),
|
||||
};
|
||||
let target_bones = match &character {
|
||||
CharacterState::Sit { .. } => {
|
||||
anim::bird_large::FeedAnimation::update_skeleton(
|
||||
&target_base,
|
||||
time,
|
||||
state.state_time,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
},
|
||||
CharacterState::BasicBeam(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 => s.timer.as_secs_f32(),
|
||||
StageSection::Recover => {
|
||||
stage_time / s.static_data.recover_duration.as_secs_f32()
|
||||
},
|
||||
_ => 0.0,
|
||||
};
|
||||
anim::bird_large::BreatheAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(
|
||||
time,
|
||||
ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||
state.last_ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||
Some(s.stage_section),
|
||||
state.state_time,
|
||||
look_dir,
|
||||
physics.on_ground,
|
||||
),
|
||||
stage_progress,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
},
|
||||
CharacterState::ComboMelee(s) => {
|
||||
let stage_index = (s.stage - 1) as usize;
|
||||
let stage_time = s.timer.as_secs_f32();
|
||||
let stage_progress = match s.stage_section {
|
||||
StageSection::Buildup => {
|
||||
stage_time
|
||||
/ s.static_data.stage_data[stage_index]
|
||||
.base_buildup_duration
|
||||
.as_secs_f32()
|
||||
},
|
||||
StageSection::Swing => {
|
||||
stage_time
|
||||
/ s.static_data.stage_data[stage_index]
|
||||
.base_swing_duration
|
||||
.as_secs_f32()
|
||||
},
|
||||
StageSection::Recover => {
|
||||
stage_time
|
||||
/ s.static_data.stage_data[stage_index]
|
||||
.base_recover_duration
|
||||
.as_secs_f32()
|
||||
},
|
||||
_ => 0.0,
|
||||
};
|
||||
|
||||
state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_base, dt_lerp);
|
||||
anim::bird_large::AlphaAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(
|
||||
Some(s.stage_section),
|
||||
ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||
state.last_ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||
physics.on_ground,
|
||||
),
|
||||
stage_progress,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
},
|
||||
CharacterState::BasicRanged(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::Recover => {
|
||||
stage_time / s.static_data.recover_duration.as_secs_f32()
|
||||
},
|
||||
|
||||
_ => 0.0,
|
||||
};
|
||||
anim::bird_large::ShootAnimation::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::Shockwave(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::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::ShockwaveAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(Some(s.stage_section), physics.on_ground),
|
||||
stage_progress,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
},
|
||||
CharacterState::Stunned(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::Recover => {
|
||||
stage_time / s.static_data.recover_duration.as_secs_f32()
|
||||
},
|
||||
_ => 0.0,
|
||||
};
|
||||
match s.static_data.poise_state {
|
||||
PoiseState::Normal
|
||||
| PoiseState::Interrupted
|
||||
| PoiseState::Stunned
|
||||
| PoiseState::Dazed
|
||||
| PoiseState::KnockedDown => {
|
||||
anim::bird_large::StunnedAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(time, Some(s.stage_section), state.state_time),
|
||||
stage_progress,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
},
|
||||
}
|
||||
},
|
||||
// TODO!
|
||||
_ => target_base,
|
||||
};
|
||||
|
||||
state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt_lerp);
|
||||
state.update(
|
||||
renderer,
|
||||
pos.0,
|
||||
@ -4572,7 +4742,7 @@ impl FigureMgr {
|
||||
quadruped_medium_model_cache,
|
||||
quadruped_low_model_cache,
|
||||
bird_medium_model_cache,
|
||||
bird_small_model_cache,
|
||||
bird_large_model_cache,
|
||||
dragon_model_cache,
|
||||
fish_medium_model_cache,
|
||||
fish_small_model_cache,
|
||||
@ -4591,7 +4761,7 @@ impl FigureMgr {
|
||||
fish_medium_states,
|
||||
theropod_states,
|
||||
dragon_states,
|
||||
bird_small_states,
|
||||
bird_large_states,
|
||||
fish_small_states,
|
||||
biped_large_states,
|
||||
biped_small_states,
|
||||
@ -4738,14 +4908,14 @@ impl FigureMgr {
|
||||
),
|
||||
)
|
||||
}),
|
||||
Body::BirdSmall(body) => bird_small_states
|
||||
Body::BirdLarge(body) => bird_large_states
|
||||
.get(&entity)
|
||||
.filter(|state| filter_state(&*state))
|
||||
.map(move |state| {
|
||||
(
|
||||
state.locals(),
|
||||
state.bone_consts(),
|
||||
bird_small_model_cache.get_model(
|
||||
bird_large_model_cache.get_model(
|
||||
col_lights,
|
||||
*body,
|
||||
inventory,
|
||||
|
@ -1058,7 +1058,7 @@ impl<'a> Widget for ItemTooltip<'a> {
|
||||
.w(text_w)
|
||||
.get_h(ui)
|
||||
.unwrap_or(0.0)
|
||||
+ V_PAD
|
||||
+ V_PAD * 2.0
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
@ -282,7 +282,7 @@ pub fn apply_caves_supplement<'a>(
|
||||
},
|
||||
_ => {
|
||||
is_hostile = true;
|
||||
let species = match dynamic_rng.gen_range(0..4) {
|
||||
let species = match dynamic_rng.gen_range(0..5) {
|
||||
0 => comp::biped_large::Species::Ogre,
|
||||
1 => comp::biped_large::Species::Cyclops,
|
||||
2 => comp::biped_large::Species::Wendigo,
|
||||
|
@ -1,11 +1,13 @@
|
||||
use crate::{column::ColumnSample, sim::SimChunk, IndexRef, CONFIG};
|
||||
use common::{
|
||||
comp::{
|
||||
biped_large, bird_medium, fish_medium, fish_small, quadruped_low, quadruped_medium,
|
||||
quadruped_small, theropod, Alignment,
|
||||
biped_large, bird_large, bird_medium, fish_medium, fish_small, quadruped_low,
|
||||
quadruped_medium, quadruped_small, theropod, Alignment,
|
||||
},
|
||||
generation::{ChunkSupplement, EntityInfo},
|
||||
resources::TimeOfDay,
|
||||
terrain::Block,
|
||||
time::DayPeriod::{self, Evening, Morning, Night, Noon},
|
||||
vol::{BaseVol, ReadVol, RectSizedVol, WriteVol},
|
||||
};
|
||||
use rand::prelude::*;
|
||||
@ -28,11 +30,13 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
_index: IndexRef,
|
||||
chunk: &SimChunk,
|
||||
supplement: &mut ChunkSupplement,
|
||||
time: Option<TimeOfDay>,
|
||||
) {
|
||||
struct Entry<R> {
|
||||
make_entity: fn(Vec3<f32>, &mut R) -> EntityInfo, // Entity
|
||||
group_size: Range<usize>, // Group size range
|
||||
is_underwater: bool, // Underwater?
|
||||
day_period: Vec<DayPeriod>, // Period of the day
|
||||
get_density: fn(&SimChunk, &ColumnSample) -> f32, // Density
|
||||
}
|
||||
|
||||
@ -60,6 +64,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..4,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, col| {
|
||||
close(c.temp, CONFIG.snow_temp, 0.3)
|
||||
* BASE_DENSITY
|
||||
@ -91,6 +96,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, col| {
|
||||
close(c.temp, CONFIG.snow_temp, 0.3) * col.tree_density * BASE_DENSITY * 1.4
|
||||
},
|
||||
@ -106,6 +112,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, _col| close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * 0.5,
|
||||
},
|
||||
// Tundra rarer solitary ennemies
|
||||
@ -119,6 +126,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, _col| close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * 0.1,
|
||||
},
|
||||
// Tundra rock solitary ennemies
|
||||
@ -133,6 +141,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, col| {
|
||||
close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * col.rock * 1.0
|
||||
},
|
||||
@ -154,6 +163,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, col| {
|
||||
close(c.temp, CONFIG.snow_temp + 0.2, 0.2) * col.tree_density * BASE_DENSITY * 0.4
|
||||
},
|
||||
@ -170,6 +180,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 3..8,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, col| {
|
||||
close(c.temp, CONFIG.snow_temp + 0.2, 0.6) * col.tree_density * BASE_DENSITY * 0.9
|
||||
},
|
||||
@ -199,6 +210,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..4,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, _col| close(c.temp, CONFIG.snow_temp + 0.2, 0.2) * BASE_DENSITY * 1.0,
|
||||
},
|
||||
// Taiga solitary wild
|
||||
@ -237,6 +249,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, _col| close(c.temp, CONFIG.snow_temp + 0.2, 0.6) * BASE_DENSITY * 5.0,
|
||||
},
|
||||
// Temperate solitary ennemies
|
||||
@ -271,6 +284,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, col| {
|
||||
close(c.temp, CONFIG.temperate_temp + 0.1, 0.5)
|
||||
* col.tree_density
|
||||
@ -341,6 +355,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..8,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.temperate_temp + 0.1, 0.6)
|
||||
* close(c.humidity, CONFIG.forest_hum, 0.6)
|
||||
@ -352,7 +367,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
Entry {
|
||||
make_entity: |pos, rng| {
|
||||
EntityInfo::at(pos)
|
||||
.with_body(match rng.gen_range(0..11) {
|
||||
.with_body(match rng.gen_range(0..10) {
|
||||
0 => quadruped_small::Body {
|
||||
species: quadruped_small::Species::Fox,
|
||||
body_type: quadruped_small::BodyType::Male,
|
||||
@ -393,14 +408,9 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
&quadruped_medium::Species::Hirdrasil,
|
||||
)
|
||||
.into(),
|
||||
9 => quadruped_small::Body::random_with(
|
||||
rng,
|
||||
&quadruped_small::Species::Truffler,
|
||||
)
|
||||
.into(),
|
||||
_ => quadruped_small::Body::random_with(
|
||||
rng,
|
||||
&quadruped_small::Species::Batfox,
|
||||
&quadruped_small::Species::Truffler,
|
||||
)
|
||||
.into(),
|
||||
})
|
||||
@ -408,6 +418,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.temperate_temp + 0.1, 0.6)
|
||||
* BASE_DENSITY
|
||||
@ -415,6 +426,26 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
* 8.0
|
||||
},
|
||||
},
|
||||
// Temperate solitary wild night
|
||||
Entry {
|
||||
make_entity: |pos, rng| {
|
||||
EntityInfo::at(pos)
|
||||
.with_body(
|
||||
quadruped_small::Body::random_with(rng, &quadruped_small::Species::Batfox)
|
||||
.into(),
|
||||
)
|
||||
.with_alignment(Alignment::Enemy)
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night],
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.temperate_temp + 0.1, 0.6)
|
||||
* BASE_DENSITY
|
||||
* close(c.humidity, CONFIG.forest_hum, 0.6)
|
||||
* 0.8
|
||||
},
|
||||
},
|
||||
// Rare temperate solitary enemies
|
||||
Entry {
|
||||
make_entity: |pos, rng| {
|
||||
@ -433,6 +464,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, _col| close(c.temp, CONFIG.temperate_temp, 0.8) * BASE_DENSITY * 0.08,
|
||||
},
|
||||
// Temperate river wildlife
|
||||
@ -463,6 +495,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |_c, col| {
|
||||
close(col.temp, CONFIG.temperate_temp, 0.6)
|
||||
* if col.water_dist.map(|d| d < 10.0).unwrap_or(false) {
|
||||
@ -487,6 +520,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |_c, col| {
|
||||
close(col.temp, CONFIG.temperate_temp, 0.6)
|
||||
* if col.water_dist.map(|d| d < 10.0).unwrap_or(false) {
|
||||
@ -508,6 +542,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |_c, col| {
|
||||
close(col.temp, CONFIG.temperate_temp, 0.6)
|
||||
* if col.water_dist.map(|d| d < 10.0).unwrap_or(false) {
|
||||
@ -532,6 +567,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, col| {
|
||||
close(c.temp, CONFIG.tropical_temp + 0.1, 0.5) * col.rock * BASE_DENSITY * 5.0
|
||||
},
|
||||
@ -557,14 +593,34 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.tropical_temp + 0.2, 0.2)
|
||||
* close(c.humidity, CONFIG.jungle_hum, 0.2)
|
||||
* BASE_DENSITY
|
||||
* 3.0
|
||||
* 2.8
|
||||
},
|
||||
},
|
||||
// Jungle rare solitary wild
|
||||
// Jungle solitary ennemies day
|
||||
Entry {
|
||||
make_entity: |pos, rng| {
|
||||
EntityInfo::at(pos)
|
||||
.with_body(
|
||||
theropod::Body::random_with(rng, &theropod::Species::Sunlizard).into(),
|
||||
)
|
||||
.with_alignment(Alignment::Enemy)
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Morning, Noon, Evening],
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.tropical_temp + 0.2, 0.2)
|
||||
* close(c.humidity, CONFIG.jungle_hum, 0.2)
|
||||
* BASE_DENSITY
|
||||
* 0.5
|
||||
},
|
||||
},
|
||||
// Jungle rare solitary wild day
|
||||
Entry {
|
||||
make_entity: |pos, rng| {
|
||||
EntityInfo::at(pos)
|
||||
@ -585,6 +641,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Morning, Noon, Evening],
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.tropical_temp + 0.2, 0.2)
|
||||
* close(c.humidity, CONFIG.jungle_hum, 0.2)
|
||||
@ -596,16 +653,12 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
Entry {
|
||||
make_entity: |pos, rng| {
|
||||
EntityInfo::at(pos)
|
||||
.with_body(match rng.gen_range(0..5) {
|
||||
.with_body(match rng.gen_range(0..4) {
|
||||
0 => bird_medium::Body::random_with(rng, &bird_medium::Species::Parrot)
|
||||
.into(),
|
||||
1 => {
|
||||
quadruped_low::Body::random_with(rng, &quadruped_low::Species::Monitor)
|
||||
.into()
|
||||
},
|
||||
2 => bird_medium::Body::random_with(rng, &bird_medium::Species::Cockatrice)
|
||||
1 => bird_large::Body::random_with(rng, &bird_large::Species::Cockatrice)
|
||||
.into(),
|
||||
3 => quadruped_small::Body::random_with(
|
||||
2 => quadruped_small::Body::random_with(
|
||||
rng,
|
||||
&quadruped_small::Species::Quokka,
|
||||
)
|
||||
@ -619,6 +672,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.tropical_temp + 0.2, 0.3)
|
||||
* close(c.humidity, CONFIG.jungle_hum, 0.2)
|
||||
@ -626,6 +680,26 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
* 8.0
|
||||
},
|
||||
},
|
||||
// Jungle solitary wild day
|
||||
Entry {
|
||||
make_entity: |pos, rng| {
|
||||
EntityInfo::at(pos)
|
||||
.with_body(
|
||||
quadruped_low::Body::random_with(rng, &quadruped_low::Species::Monitor)
|
||||
.into(),
|
||||
)
|
||||
.with_alignment(Alignment::Enemy)
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Morning, Noon, Evening],
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.tropical_temp + 0.2, 0.3)
|
||||
* close(c.humidity, CONFIG.jungle_hum, 0.2)
|
||||
* BASE_DENSITY
|
||||
* 2.0
|
||||
},
|
||||
},
|
||||
// Tropical rare river enemy
|
||||
Entry {
|
||||
make_entity: |pos, rng| {
|
||||
@ -638,6 +712,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..3,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |_c, col| {
|
||||
close(col.temp, CONFIG.tropical_temp + 0.2, 0.5)
|
||||
* if col.water_dist.map(|d| d < 10.0).unwrap_or(false) {
|
||||
@ -671,6 +746,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..3,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |_c, col| {
|
||||
close(col.temp, CONFIG.tropical_temp, 0.5)
|
||||
* if col.water_dist.map(|d| d < 10.0).unwrap_or(false) {
|
||||
@ -700,6 +776,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..3,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.tropical_temp + 0.1, 0.4)
|
||||
* close(c.humidity, CONFIG.desert_hum, 0.4)
|
||||
@ -727,6 +804,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 3..7,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.tropical_temp + 0.1, 0.4)
|
||||
* close(c.humidity, CONFIG.desert_hum, 0.4)
|
||||
@ -757,6 +835,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.desert_temp + 0.2, 0.3)
|
||||
* close(c.humidity, CONFIG.desert_hum, 0.5)
|
||||
@ -781,6 +860,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.desert_temp + 0.2, 0.3)
|
||||
* close(c.humidity, CONFIG.desert_hum, 0.5)
|
||||
@ -800,6 +880,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..3,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |_c, col| {
|
||||
close(col.temp, CONFIG.desert_temp + 0.2, 0.3)
|
||||
* if col.water_dist.map(|d| d < 10.0).unwrap_or(false) {
|
||||
@ -824,6 +905,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..3,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.desert_temp + 0.2, 0.3)
|
||||
* close(c.humidity, CONFIG.desert_hum, 0.5)
|
||||
@ -835,7 +917,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
Entry {
|
||||
make_entity: |pos, rng| {
|
||||
EntityInfo::at(pos)
|
||||
.with_body(match rng.gen_range(0..7) {
|
||||
.with_body(match rng.gen_range(0..4) {
|
||||
0 => quadruped_small::Body::random_with(
|
||||
rng,
|
||||
&quadruped_small::Species::Holladon,
|
||||
@ -850,21 +932,36 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
&quadruped_medium::Species::Camel,
|
||||
)
|
||||
.into(),
|
||||
3 => quadruped_low::Body {
|
||||
species: quadruped_low::Species::Salamander,
|
||||
body_type: quadruped_low::BodyType::Male,
|
||||
}
|
||||
.into(),
|
||||
4 => quadruped_small::Body::random_with(
|
||||
3 => quadruped_small::Body::random_with(
|
||||
rng,
|
||||
&quadruped_small::Species::Porcupine,
|
||||
)
|
||||
.into(),
|
||||
5 => quadruped_small::Body {
|
||||
_ => quadruped_small::Body {
|
||||
species: quadruped_small::Species::Hare,
|
||||
body_type: quadruped_small::BodyType::Male,
|
||||
}
|
||||
.into(),
|
||||
})
|
||||
.with_alignment(Alignment::Wild)
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.desert_temp + 0.2, 0.3) * BASE_DENSITY * 3.8
|
||||
},
|
||||
},
|
||||
// Desert solitary wild day
|
||||
Entry {
|
||||
make_entity: |pos, rng| {
|
||||
EntityInfo::at(pos)
|
||||
.with_body(match rng.gen_range(0..3) {
|
||||
1 => quadruped_low::Body {
|
||||
species: quadruped_low::Species::Salamander,
|
||||
body_type: quadruped_low::BodyType::Male,
|
||||
}
|
||||
.into(),
|
||||
_ => quadruped_small::Body::random_with(
|
||||
rng,
|
||||
&quadruped_small::Species::Gecko,
|
||||
@ -875,8 +972,9 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..2,
|
||||
is_underwater: false,
|
||||
day_period: vec![Morning, Noon, Evening],
|
||||
get_density: |c, _col| {
|
||||
close(c.temp, CONFIG.desert_temp + 0.2, 0.3) * BASE_DENSITY * 5.0
|
||||
close(c.temp, CONFIG.desert_temp + 0.2, 0.3) * BASE_DENSITY * 1.0
|
||||
},
|
||||
},
|
||||
// Underwater temperate
|
||||
@ -896,6 +994,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 3..5,
|
||||
is_underwater: true,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, col| {
|
||||
close(c.temp, CONFIG.temperate_temp, 1.0) * col.tree_density * BASE_DENSITY * 5.0
|
||||
},
|
||||
@ -911,6 +1010,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
},
|
||||
group_size: 1..3,
|
||||
is_underwater: true,
|
||||
day_period: vec![Night, Morning, Noon, Evening],
|
||||
get_density: |c, col| {
|
||||
close(c.temp, CONFIG.snow_temp, 0.15) * col.tree_density * BASE_DENSITY * 5.0
|
||||
},
|
||||
@ -931,6 +1031,12 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
};
|
||||
|
||||
let underwater = col_sample.water_level > col_sample.alt;
|
||||
let current_day_period;
|
||||
if let Some(time) = time {
|
||||
current_day_period = DayPeriod::from(time.0)
|
||||
} else {
|
||||
current_day_period = Noon
|
||||
}
|
||||
|
||||
let entity_group = scatter.iter().enumerate().find_map(
|
||||
|(
|
||||
@ -939,6 +1045,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
make_entity,
|
||||
group_size,
|
||||
is_underwater,
|
||||
day_period,
|
||||
get_density,
|
||||
},
|
||||
)| {
|
||||
@ -946,6 +1053,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>(
|
||||
if density > 0.0
|
||||
&& dynamic_rng.gen::<f32>() < density * col_sample.spawn_rate
|
||||
&& underwater == *is_underwater
|
||||
&& day_period.contains(¤t_day_period)
|
||||
&& col_sample.gradient < Some(1.3)
|
||||
{
|
||||
Some((make_entity, group_size.clone()))
|
||||
|
@ -50,6 +50,7 @@ use crate::{
|
||||
use common::{
|
||||
assets,
|
||||
generation::{ChunkSupplement, EntityInfo},
|
||||
resources::TimeOfDay,
|
||||
terrain::{Block, BlockKind, SpriteKind, TerrainChunk, TerrainChunkMeta, TerrainChunkSize},
|
||||
vol::{ReadVol, RectVolSize, WriteVol},
|
||||
};
|
||||
@ -171,7 +172,9 @@ impl World {
|
||||
|
||||
// Unwrapping because generate_chunk only returns err when should_continue evals
|
||||
// to true
|
||||
let (tc, _cs) = self.generate_chunk(index, chunk_pos, || false).unwrap();
|
||||
let (tc, _cs) = self
|
||||
.generate_chunk(index, chunk_pos, || false, None)
|
||||
.unwrap();
|
||||
let min_z = tc.get_min_z();
|
||||
let max_z = tc.get_max_z();
|
||||
|
||||
@ -209,6 +212,7 @@ impl World {
|
||||
chunk_pos: Vec2<i32>,
|
||||
// TODO: misleading name
|
||||
mut should_continue: impl FnMut() -> bool,
|
||||
time: Option<TimeOfDay>,
|
||||
) -> Result<(TerrainChunk, ChunkSupplement), ()> {
|
||||
let mut sampler = self.sample_blocks();
|
||||
|
||||
@ -390,6 +394,7 @@ impl World {
|
||||
index,
|
||||
sim_chunk,
|
||||
&mut supplement,
|
||||
time,
|
||||
);
|
||||
|
||||
// Apply site supplementary information
|
||||
|
Loading…
Reference in New Issue
Block a user