mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
spawn wyverns
This commit is contained in:
parent
690385df96
commit
57fe2c4adb
@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- First version of multisalvage that allows to obtain more than one piece of material from salvage
|
||||
- Axe
|
||||
- Combat music toggle
|
||||
- Spawn rtsim wyverns that travel the world, providing dragon scale loot drops
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -724,42 +724,42 @@
|
||||
),
|
||||
Custom("Flame Wyvern"): (
|
||||
primary: Simple(None, "common.abilities.custom.flamewyvern.firebomb"),
|
||||
secondary: Simple(None, "common.abilities.custom.flamewyvern.fireshockwave"),
|
||||
secondary: Simple(None, "common.abilities.custom.flamewyvern.triplestrike"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.flamewyvern.triplestrike"),
|
||||
Simple(None, "common.abilities.custom.flamewyvern.fireshockwave"),
|
||||
Simple(None, "common.abilities.custom.flamewyvern.flamethrower"),
|
||||
],
|
||||
),
|
||||
Custom("Frost Wyvern"): (
|
||||
primary: Simple(None, "common.abilities.custom.frostwyvern.frostbomb"),
|
||||
secondary: Simple(None, "common.abilities.custom.frostwyvern.iceshockwave"),
|
||||
secondary: Simple(None, "common.abilities.custom.frostwyvern.triplestrike"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.frostwyvern.triplestrike"),
|
||||
Simple(None, "common.abilities.custom.frostwyvern.iceshockwave"),
|
||||
Simple(None, "common.abilities.custom.frostwyvern.frostthrower"),
|
||||
],
|
||||
),
|
||||
Custom("Cloud Wyvern"): (
|
||||
primary: Simple(None, "common.abilities.custom.cloudwyvern.windbomb"),
|
||||
secondary: Simple(None, "common.abilities.custom.cloudwyvern.windshockwave"),
|
||||
primary: Simple(None, "common.abilities.custom.cloudwyvern.lightningbomb"),
|
||||
secondary: Simple(None, "common.abilities.custom.cloudwyvern.triplestrike"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.cloudwyvern.triplestrike"),
|
||||
Simple(None, "common.abilities.custom.cloudwyvern.windthrower"),
|
||||
Simple(None, "common.abilities.custom.cloudwyvern.lightningshockwave"),
|
||||
Simple(None, "common.abilities.custom.cloudwyvern.lightningthrower"),
|
||||
],
|
||||
),
|
||||
Custom("Sea Wyvern"): (
|
||||
primary: Simple(None, "common.abilities.custom.seawyvern.seabomb"),
|
||||
secondary: Simple(None, "common.abilities.custom.seawyvern.seashockwave"),
|
||||
primary: Simple(None, "common.abilities.custom.seawyvern.inkbomb"),
|
||||
secondary: Simple(None, "common.abilities.custom.seawyvern.triplestrike"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.seawyvern.triplestrike"),
|
||||
Simple(None, "common.abilities.custom.seawyvern.bubblethrower"),
|
||||
Simple(None, "common.abilities.custom.seawyvern.inkshockwave"),
|
||||
Simple(None, "common.abilities.custom.seawyvern.inkthrower"),
|
||||
],
|
||||
),
|
||||
Custom("Weald Wyvern"): (
|
||||
primary: Simple(None, "common.abilities.custom.wealdwyvern.firebomb"),
|
||||
secondary: Simple(None, "common.abilities.custom.wealdwyvern.fireshockwave"),
|
||||
primary: Simple(None, "common.abilities.custom.wealdwyvern.poisonbomb"),
|
||||
secondary: Simple(None, "common.abilities.custom.wealdwyvern.triplestrike"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.wealdwyvern.triplestrike"),
|
||||
Simple(None, "common.abilities.custom.wealdwyvern.flamethrower"),
|
||||
Simple(None, "common.abilities.custom.wealdwyvern.poisonshockwave"),
|
||||
Simple(None, "common.abilities.custom.wealdwyvern.poisonthrower"),
|
||||
],
|
||||
),
|
||||
Custom("Bird Large Basic"): (
|
||||
|
@ -13,7 +13,7 @@ BasicRanged(
|
||||
col: (1.0, 0.75, 0.11).into(),
|
||||
..Default::default()
|
||||
}),*/
|
||||
projectile_speed: 260.0,
|
||||
projectile_speed: 25.0,
|
||||
num_projectiles: 1,
|
||||
projectile_spread: 0.3,
|
||||
move_efficiency: 0.3,
|
||||
|
@ -1,59 +1,66 @@
|
||||
ComboMelee(
|
||||
stage_data: [
|
||||
ComboMelee2(
|
||||
strikes: [
|
||||
(
|
||||
stage: 1,
|
||||
base_damage: 22.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 22,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 4.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 3.0,
|
||||
damage_kind: Crushing,
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(3.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 2,
|
||||
base_damage: 18.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 18,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 3.0,
|
||||
damage_kind: Crushing,
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(3.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 3,
|
||||
base_damage: 28.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 10.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 28,
|
||||
poise: 0,
|
||||
knockback: 10,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 1.3,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 1.3,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 3.5,
|
||||
damage_kind: Crushing,
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(3.5)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
],
|
||||
initial_energy_gain: 0,
|
||||
max_energy_gain: 0,
|
||||
energy_increase: 0,
|
||||
speed_increase: 0.0,
|
||||
max_speed_increase: 0.0,
|
||||
scales_from_combo: 0,
|
||||
ori_modifier: 0.7,
|
||||
energy_cost_per_strike: 0,
|
||||
auto_progress: true,
|
||||
)
|
@ -1,77 +1,66 @@
|
||||
ComboMelee(
|
||||
stage_data: [
|
||||
ComboMelee2(
|
||||
strikes: [
|
||||
(
|
||||
stage: 1,
|
||||
base_damage: 20.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 20,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 4.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 2.0,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(2.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 2,
|
||||
base_damage: 16.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 16,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 1.5,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(2.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 3,
|
||||
base_damage: 26.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 10.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 26,
|
||||
poise: 0,
|
||||
knockback: 10,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 1.3,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.4,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 1.5,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(1.5)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
],
|
||||
initial_energy_gain: 0,
|
||||
max_energy_gain: 0,
|
||||
energy_increase: 0,
|
||||
speed_increase: 0.0,
|
||||
max_speed_increase: 0.0,
|
||||
scales_from_combo: 0,
|
||||
ori_modifier: 0.7,
|
||||
energy_cost_per_strike: 0,
|
||||
auto_progress: true,
|
||||
)
|
@ -1,77 +1,66 @@
|
||||
ComboMelee(
|
||||
stage_data: [
|
||||
ComboMelee2(
|
||||
strikes: [
|
||||
(
|
||||
stage: 1,
|
||||
base_damage: 20.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 20,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 4.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 2.0,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(2.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 2,
|
||||
base_damage: 16.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 16,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 1.5,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(2.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 3,
|
||||
base_damage: 26.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 10.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 26,
|
||||
poise: 0,
|
||||
knockback: 10,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.375,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.4,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 1.5,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(1.5)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
],
|
||||
initial_energy_gain: 0,
|
||||
max_energy_gain: 0,
|
||||
energy_increase: 0,
|
||||
speed_increase: 0.0,
|
||||
max_speed_increase: 0.0,
|
||||
scales_from_combo: 0,
|
||||
ori_modifier: 0.7,
|
||||
energy_cost_per_strike: 0,
|
||||
auto_progress: true,
|
||||
)
|
18
assets/common/abilities/custom/cloudwyvern/lightningbomb.ron
Normal file
18
assets/common/abilities/custom/cloudwyvern/lightningbomb.ron
Normal file
@ -0,0 +1,18 @@
|
||||
BasicRanged(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.5,
|
||||
recover_duration: 1.5,
|
||||
projectile: LaserBeam(
|
||||
damage: 20.0,
|
||||
radius: 5.0,
|
||||
knockback: 5.0,
|
||||
energy_regen: 20.0,
|
||||
min_falloff: 0.1,
|
||||
),
|
||||
projectile_body: Object(LightningBolt),
|
||||
projectile_light: None,
|
||||
projectile_speed: 100.0,
|
||||
num_projectiles: 1,
|
||||
projectile_spread: 0.0,
|
||||
move_efficiency: 0.3,
|
||||
)
|
@ -0,0 +1,24 @@
|
||||
Shockwave(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.3,
|
||||
swing_duration: 0.3,
|
||||
recover_duration: 2.0,
|
||||
damage: 20.0,
|
||||
poise_damage: 10,
|
||||
knockback: (strength: 18.0, direction: Away),
|
||||
shockwave_angle: 360.0,
|
||||
shockwave_vertical_angle: 90.0,
|
||||
shockwave_speed: 15.0,
|
||||
shockwave_duration: 2.0,
|
||||
requires_ground: true,
|
||||
move_efficiency: 0.0,
|
||||
damage_kind: Crushing,
|
||||
specifier: Lightning,
|
||||
ori_rate: 1.0,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Crippled,
|
||||
dur_secs: 2.0,
|
||||
strength: Value(0.3),
|
||||
chance: 1.0,
|
||||
))),
|
||||
)
|
@ -0,0 +1,19 @@
|
||||
BasicBeam(
|
||||
buildup_duration: 0.3,
|
||||
recover_duration: 1.5,
|
||||
beam_duration: 2.0,
|
||||
damage: 22.5,
|
||||
tick_rate: 3.0,
|
||||
range: 22.0,
|
||||
max_angle: 22.5,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Crippled,
|
||||
dur_secs: 3.0,
|
||||
strength: Value(0.5),
|
||||
chance: 1.0,
|
||||
))),
|
||||
energy_regen: 2,
|
||||
energy_drain: 0,
|
||||
ori_rate: 0.5,
|
||||
specifier: Lightning,
|
||||
)
|
@ -1,77 +1,66 @@
|
||||
ComboMelee(
|
||||
stage_data: [
|
||||
ComboMelee2(
|
||||
strikes: [
|
||||
(
|
||||
stage: 1,
|
||||
base_damage: 20.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 20,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 4.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 2.0,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(2.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 2,
|
||||
base_damage: 16.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 16,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 1.5,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(2.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 3,
|
||||
base_damage: 26.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 10.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 26,
|
||||
poise: 0,
|
||||
knockback: 10,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.375,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.4,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 1.5,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(1.5)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
],
|
||||
initial_energy_gain: 0,
|
||||
max_energy_gain: 0,
|
||||
energy_increase: 0,
|
||||
speed_increase: 0.0,
|
||||
max_speed_increase: 0.0,
|
||||
scales_from_combo: 0,
|
||||
ori_modifier: 0.7,
|
||||
energy_cost_per_strike: 0,
|
||||
auto_progress: true,
|
||||
)
|
@ -1,20 +0,0 @@
|
||||
BasicRanged(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 1.0,
|
||||
recover_duration: 0.7,
|
||||
projectile: WindBomb(
|
||||
damage: 20.0,
|
||||
radius: 5.0,
|
||||
energy_regen: 5.0,
|
||||
min_falloff: 0.5,
|
||||
),
|
||||
projectile_body: Object(BoltFire),
|
||||
/*projectile_light: Some(LightEmitter {
|
||||
col: (1.0, 0.75, 0.11).into(),
|
||||
..Default::default()
|
||||
}),*/
|
||||
projectile_speed: 60.0,
|
||||
num_projectiles: 1,
|
||||
projectile_spread: 0.0,
|
||||
move_efficiency: 0.3,
|
||||
)
|
@ -1,18 +0,0 @@
|
||||
Shockwave(
|
||||
energy_cost: 60.0,
|
||||
buildup_duration: 1.4,
|
||||
swing_duration: 0.1,
|
||||
recover_duration: 0.4,
|
||||
damage: 40.0,
|
||||
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,
|
||||
damage_kind: Energy,
|
||||
specifier: Water,
|
||||
ori_rate: 1.0,
|
||||
)
|
@ -1,19 +0,0 @@
|
||||
BasicBeam(
|
||||
buildup_duration: 0.8,
|
||||
recover_duration: 0.5,
|
||||
beam_duration: 0.5,
|
||||
damage: 10.0,
|
||||
tick_rate: 3.0,
|
||||
range: 15.0,
|
||||
max_angle: 22.5,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Burning,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.5),
|
||||
chance: 0.25,
|
||||
))),
|
||||
energy_regen: 0,
|
||||
energy_drain: 0,
|
||||
ori_rate: 0.3,
|
||||
specifier: Bubbles,
|
||||
)
|
@ -1,19 +1,16 @@
|
||||
BasicRanged(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 1.0,
|
||||
recover_duration: 0.7,
|
||||
buildup_duration: 0.5,
|
||||
recover_duration: 1.5,
|
||||
projectile: Fireball(
|
||||
damage: 20.0,
|
||||
damage: 32.0,
|
||||
radius: 5.0,
|
||||
energy_regen: 5.0,
|
||||
min_falloff: 0.5,
|
||||
min_falloff: 0.1,
|
||||
),
|
||||
projectile_body: Object(BoltFire),
|
||||
/*projectile_light: Some(LightEmitter {
|
||||
col: (1.0, 0.75, 0.11).into(),
|
||||
..Default::default()
|
||||
}),*/
|
||||
projectile_speed: 60.0,
|
||||
projectile_light: None,
|
||||
projectile_speed: 100.0,
|
||||
num_projectiles: 1,
|
||||
projectile_spread: 0.0,
|
||||
move_efficiency: 0.3,
|
||||
|
@ -1,18 +1,24 @@
|
||||
Shockwave(
|
||||
energy_cost: 60.0,
|
||||
buildup_duration: 1.4,
|
||||
swing_duration: 0.1,
|
||||
recover_duration: 0.4,
|
||||
damage: 40.0,
|
||||
poise_damage: 0,
|
||||
knockback: ( strength: 25.0, direction: Away),
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.3,
|
||||
swing_duration: 0.3,
|
||||
recover_duration: 2.0,
|
||||
damage: 20.0,
|
||||
poise_damage: 10,
|
||||
knockback: (strength: 18.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,
|
||||
damage_kind: Energy,
|
||||
shockwave_speed: 15.0,
|
||||
shockwave_duration: 2.0,
|
||||
requires_ground: true,
|
||||
move_efficiency: 0.0,
|
||||
damage_kind: Crushing,
|
||||
specifier: Fire,
|
||||
ori_rate: 1.0,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Burning,
|
||||
dur_secs: 2.0,
|
||||
strength: DamageFraction(0.3),
|
||||
chance: 1.0,
|
||||
))),
|
||||
)
|
||||
|
@ -1,19 +1,19 @@
|
||||
BasicBeam(
|
||||
buildup_duration: 0.8,
|
||||
recover_duration: 0.5,
|
||||
beam_duration: 0.5,
|
||||
damage: 10.0,
|
||||
buildup_duration: 0.3,
|
||||
recover_duration: 1.5,
|
||||
beam_duration: 2.0,
|
||||
damage: 22.5,
|
||||
tick_rate: 3.0,
|
||||
range: 15.0,
|
||||
range: 22.0,
|
||||
max_angle: 22.5,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Burning,
|
||||
dur_secs: 10.0,
|
||||
dur_secs: 3.0,
|
||||
strength: DamageFraction(0.5),
|
||||
chance: 0.25,
|
||||
chance: 1.0,
|
||||
))),
|
||||
energy_regen: 0,
|
||||
energy_regen: 2,
|
||||
energy_drain: 0,
|
||||
ori_rate: 0.3,
|
||||
ori_rate: 0.5,
|
||||
specifier: Flamethrower,
|
||||
)
|
||||
|
@ -1,77 +1,66 @@
|
||||
ComboMelee(
|
||||
stage_data: [
|
||||
ComboMelee2(
|
||||
strikes: [
|
||||
(
|
||||
stage: 1,
|
||||
base_damage: 20.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 20,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 4.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 2.0,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(2.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 2,
|
||||
base_damage: 16.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 16,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 1.5,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(2.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 3,
|
||||
base_damage: 26.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 10.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 26,
|
||||
poise: 0,
|
||||
knockback: 10,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.375,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.4,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 1.5,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(1.5)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
],
|
||||
initial_energy_gain: 0,
|
||||
max_energy_gain: 0,
|
||||
energy_increase: 0,
|
||||
speed_increase: 0.0,
|
||||
max_speed_increase: 0.0,
|
||||
scales_from_combo: 0,
|
||||
ori_modifier: 0.7,
|
||||
energy_cost_per_strike: 0,
|
||||
auto_progress: true,
|
||||
)
|
@ -1,19 +1,16 @@
|
||||
BasicRanged(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 1.0,
|
||||
recover_duration: 0.7,
|
||||
buildup_duration: 0.5,
|
||||
recover_duration: 1.5,
|
||||
projectile: Frostball(
|
||||
damage: 20.0,
|
||||
damage: 32.0,
|
||||
radius: 5.0,
|
||||
energy_regen: 5.0,
|
||||
min_falloff: 0.5,
|
||||
min_falloff: 0.1,
|
||||
),
|
||||
projectile_body: Object(BoltNature),
|
||||
/*projectile_light: Some(LightEmitter {
|
||||
col: (1.0, 0.75, 0.11).into(),
|
||||
..Default::default()
|
||||
}),*/
|
||||
projectile_speed: 60.0,
|
||||
projectile_body: Object(SpearIcicle),
|
||||
projectile_light: None,
|
||||
projectile_speed: 100.0,
|
||||
num_projectiles: 1,
|
||||
projectile_spread: 0.0,
|
||||
move_efficiency: 0.3,
|
||||
|
@ -1,19 +1,19 @@
|
||||
BasicBeam(
|
||||
buildup_duration: 0.8,
|
||||
recover_duration: 0.5,
|
||||
beam_duration: 0.5,
|
||||
damage: 10.0,
|
||||
buildup_duration: 0.3,
|
||||
recover_duration: 1.5,
|
||||
beam_duration: 2.0,
|
||||
damage: 22.5,
|
||||
tick_rate: 3.0,
|
||||
range: 15.0,
|
||||
range: 22.0,
|
||||
max_angle: 22.5,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Burning,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.5),
|
||||
chance: 0.25,
|
||||
kind: Frigid,
|
||||
dur_secs: 3.0,
|
||||
strength: Value(0.5),
|
||||
chance: 1.0,
|
||||
))),
|
||||
energy_regen: 0,
|
||||
energy_regen: 2,
|
||||
energy_drain: 0,
|
||||
ori_rate: 0.3,
|
||||
ori_rate: 0.5,
|
||||
specifier: Frost,
|
||||
)
|
||||
|
@ -1,18 +1,24 @@
|
||||
Shockwave(
|
||||
energy_cost: 60.0,
|
||||
buildup_duration: 1.4,
|
||||
swing_duration: 0.1,
|
||||
recover_duration: 0.4,
|
||||
damage: 40.0,
|
||||
poise_damage: 0,
|
||||
knockback: ( strength: 25.0, direction: Away),
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.3,
|
||||
swing_duration: 0.3,
|
||||
recover_duration: 2.0,
|
||||
damage: 20.0,
|
||||
poise_damage: 10,
|
||||
knockback: (strength: 18.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,
|
||||
damage_kind: Energy,
|
||||
specifier: IceSpikes,
|
||||
shockwave_speed: 15.0,
|
||||
shockwave_duration: 2.0,
|
||||
requires_ground: true,
|
||||
move_efficiency: 0.0,
|
||||
damage_kind: Crushing,
|
||||
specifier: Ice,
|
||||
ori_rate: 1.0,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Frozen,
|
||||
dur_secs: 2.0,
|
||||
strength: Value(0.3),
|
||||
chance: 1.0,
|
||||
))),
|
||||
)
|
||||
|
@ -1,77 +1,66 @@
|
||||
ComboMelee(
|
||||
stage_data: [
|
||||
ComboMelee2(
|
||||
strikes: [
|
||||
(
|
||||
stage: 1,
|
||||
base_damage: 20.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 20,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 4.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 2.0,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(2.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 2,
|
||||
base_damage: 16.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 16,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 1.5,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(2.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 3,
|
||||
base_damage: 26.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 10.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 26,
|
||||
poise: 0,
|
||||
knockback: 10,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.375,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.4,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 1.5,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(1.5)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
],
|
||||
initial_energy_gain: 0,
|
||||
max_energy_gain: 0,
|
||||
energy_increase: 0,
|
||||
speed_increase: 0.0,
|
||||
max_speed_increase: 0.0,
|
||||
scales_from_combo: 0,
|
||||
ori_modifier: 0.7,
|
||||
energy_cost_per_strike: 0,
|
||||
auto_progress: true,
|
||||
)
|
@ -1,19 +0,0 @@
|
||||
BasicBeam(
|
||||
buildup_duration: 0.8,
|
||||
recover_duration: 0.5,
|
||||
beam_duration: 0.5,
|
||||
damage: 10.0,
|
||||
tick_rate: 3.0,
|
||||
range: 15.0,
|
||||
max_angle: 22.5,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Burning,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.5),
|
||||
chance: 0.25,
|
||||
))),
|
||||
energy_regen: 0,
|
||||
energy_drain: 0,
|
||||
ori_rate: 0.3,
|
||||
specifier: Bubbles,
|
||||
)
|
17
assets/common/abilities/custom/seawyvern/inkbomb.ron
Normal file
17
assets/common/abilities/custom/seawyvern/inkbomb.ron
Normal file
@ -0,0 +1,17 @@
|
||||
BasicRanged(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.5,
|
||||
recover_duration: 1.5,
|
||||
projectile: InkBomb(
|
||||
damage: 32.0,
|
||||
radius: 5.0,
|
||||
energy_regen: 5.0,
|
||||
min_falloff: 0.1,
|
||||
),
|
||||
projectile_body: Object(SpitPoison),
|
||||
projectile_light: None,
|
||||
projectile_speed: 100.0,
|
||||
num_projectiles: 1,
|
||||
projectile_spread: 0.0,
|
||||
move_efficiency: 0.3,
|
||||
)
|
25
assets/common/abilities/custom/seawyvern/inkshockwave.ron
Normal file
25
assets/common/abilities/custom/seawyvern/inkshockwave.ron
Normal file
@ -0,0 +1,25 @@
|
||||
Shockwave(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.3,
|
||||
swing_duration: 0.3,
|
||||
recover_duration: 2.0,
|
||||
damage: 20.0,
|
||||
poise_damage: 10,
|
||||
knockback: (strength: 18.0, direction: Away),
|
||||
shockwave_angle: 360.0,
|
||||
shockwave_vertical_angle: 90.0,
|
||||
shockwave_speed: 15.0,
|
||||
shockwave_duration: 2.0,
|
||||
requires_ground: true,
|
||||
move_efficiency: 0.0,
|
||||
damage_kind: Crushing,
|
||||
specifier: Ink,
|
||||
ori_rate: 1.0,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Wet,
|
||||
dur_secs: 8.0,
|
||||
strength: Value(0.3),
|
||||
chance: 1.0,
|
||||
))),
|
||||
)
|
||||
|
19
assets/common/abilities/custom/seawyvern/inkthrower.ron
Normal file
19
assets/common/abilities/custom/seawyvern/inkthrower.ron
Normal file
@ -0,0 +1,19 @@
|
||||
BasicBeam(
|
||||
buildup_duration: 0.3,
|
||||
recover_duration: 1.5,
|
||||
beam_duration: 2.0,
|
||||
damage: 22.5,
|
||||
tick_rate: 3.0,
|
||||
range: 22.0,
|
||||
max_angle: 22.5,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Wet,
|
||||
dur_secs: 8.0,
|
||||
strength: Value(1.5),
|
||||
chance: 1.0,
|
||||
))),
|
||||
energy_regen: 2,
|
||||
energy_drain: 0,
|
||||
ori_rate: 0.5,
|
||||
specifier: Ink,
|
||||
)
|
@ -1,20 +0,0 @@
|
||||
BasicRanged(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 1.0,
|
||||
recover_duration: 0.7,
|
||||
projectile: SeaBomb(
|
||||
damage: 20.0,
|
||||
radius: 5.0,
|
||||
energy_regen: 5.0,
|
||||
min_falloff: 0.5,
|
||||
),
|
||||
projectile_body: Object(BoltFire),
|
||||
/*projectile_light: Some(LightEmitter {
|
||||
col: (1.0, 0.75, 0.11).into(),
|
||||
..Default::default()
|
||||
}),*/
|
||||
projectile_speed: 60.0,
|
||||
num_projectiles: 1,
|
||||
projectile_spread: 0.0,
|
||||
move_efficiency: 0.3,
|
||||
)
|
@ -1,18 +0,0 @@
|
||||
Shockwave(
|
||||
energy_cost: 60.0,
|
||||
buildup_duration: 1.4,
|
||||
swing_duration: 0.1,
|
||||
recover_duration: 0.4,
|
||||
damage: 40.0,
|
||||
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,
|
||||
damage_kind: Energy,
|
||||
specifier: Water,
|
||||
ori_rate: 1.0,
|
||||
)
|
@ -1,77 +1,66 @@
|
||||
ComboMelee(
|
||||
stage_data: [
|
||||
ComboMelee2(
|
||||
strikes: [
|
||||
(
|
||||
stage: 1,
|
||||
base_damage: 20.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 20,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 4.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 2.0,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(2.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 2,
|
||||
base_damage: 16.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 16,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 1.5,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(2.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 3,
|
||||
base_damage: 26.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 10.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 26,
|
||||
poise: 0,
|
||||
knockback: 10,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.375,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.4,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 1.5,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(1.5)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
],
|
||||
initial_energy_gain: 0,
|
||||
max_energy_gain: 0,
|
||||
energy_increase: 0,
|
||||
speed_increase: 0.0,
|
||||
max_speed_increase: 0.0,
|
||||
scales_from_combo: 0,
|
||||
ori_modifier: 0.7,
|
||||
energy_cost_per_strike: 0,
|
||||
auto_progress: true,
|
||||
)
|
@ -1,20 +0,0 @@
|
||||
BasicRanged(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 1.0,
|
||||
recover_duration: 0.7,
|
||||
projectile: Fireball(
|
||||
damage: 20.0,
|
||||
radius: 5.0,
|
||||
energy_regen: 5.0,
|
||||
min_falloff: 0.5,
|
||||
),
|
||||
projectile_body: Object(BoltFire),
|
||||
/*projectile_light: Some(LightEmitter {
|
||||
col: (1.0, 0.75, 0.11).into(),
|
||||
..Default::default()
|
||||
}),*/
|
||||
projectile_speed: 60.0,
|
||||
num_projectiles: 1,
|
||||
projectile_spread: 0.0,
|
||||
move_efficiency: 0.3,
|
||||
)
|
@ -1,18 +0,0 @@
|
||||
Shockwave(
|
||||
energy_cost: 60.0,
|
||||
buildup_duration: 1.4,
|
||||
swing_duration: 0.1,
|
||||
recover_duration: 0.4,
|
||||
damage: 40.0,
|
||||
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,
|
||||
damage_kind: Energy,
|
||||
specifier: Fire,
|
||||
ori_rate: 1.0,
|
||||
)
|
@ -1,19 +0,0 @@
|
||||
BasicBeam(
|
||||
buildup_duration: 0.8,
|
||||
recover_duration: 0.5,
|
||||
beam_duration: 0.5,
|
||||
damage: 10.0,
|
||||
tick_rate: 3.0,
|
||||
range: 15.0,
|
||||
max_angle: 22.5,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Burning,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.5),
|
||||
chance: 0.25,
|
||||
))),
|
||||
energy_regen: 0,
|
||||
energy_drain: 0,
|
||||
ori_rate: 0.3,
|
||||
specifier: Flamethrower,
|
||||
)
|
17
assets/common/abilities/custom/wealdwyvern/poisonbomb.ron
Normal file
17
assets/common/abilities/custom/wealdwyvern/poisonbomb.ron
Normal file
@ -0,0 +1,17 @@
|
||||
BasicRanged(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.5,
|
||||
recover_duration: 1.5,
|
||||
projectile: Poisonball(
|
||||
damage: 32.0,
|
||||
radius: 5.0,
|
||||
energy_regen: 5.0,
|
||||
min_falloff: 0.1,
|
||||
),
|
||||
projectile_body: Object(SpitPoison),
|
||||
projectile_light: None,
|
||||
projectile_speed: 100.0,
|
||||
num_projectiles: 1,
|
||||
projectile_spread: 0.0,
|
||||
move_efficiency: 0.3,
|
||||
)
|
@ -0,0 +1,25 @@
|
||||
Shockwave(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.3,
|
||||
swing_duration: 0.3,
|
||||
recover_duration: 2.0,
|
||||
damage: 20.0,
|
||||
poise_damage: 10,
|
||||
knockback: (strength: 18.0, direction: Away),
|
||||
shockwave_angle: 360.0,
|
||||
shockwave_vertical_angle: 90.0,
|
||||
shockwave_speed: 15.0,
|
||||
shockwave_duration: 2.0,
|
||||
requires_ground: true,
|
||||
move_efficiency: 0.0,
|
||||
damage_kind: Crushing,
|
||||
specifier: Poison,
|
||||
ori_rate: 1.0,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Poisoned,
|
||||
dur_secs: 8.0,
|
||||
strength: DamageFraction(0.3),
|
||||
chance: 1.0,
|
||||
))),
|
||||
)
|
||||
|
19
assets/common/abilities/custom/wealdwyvern/poisonthrower.ron
Normal file
19
assets/common/abilities/custom/wealdwyvern/poisonthrower.ron
Normal file
@ -0,0 +1,19 @@
|
||||
BasicBeam(
|
||||
buildup_duration: 0.3,
|
||||
recover_duration: 1.5,
|
||||
beam_duration: 2.0,
|
||||
damage: 22.5,
|
||||
tick_rate: 3.0,
|
||||
range: 22.0,
|
||||
max_angle: 22.5,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Poisoned,
|
||||
dur_secs: 3.0,
|
||||
strength: DamageFraction(0.5),
|
||||
chance: 1.0,
|
||||
))),
|
||||
energy_regen: 2,
|
||||
energy_drain: 0,
|
||||
ori_rate: 0.5,
|
||||
specifier: Poison,
|
||||
)
|
@ -1,77 +1,66 @@
|
||||
ComboMelee(
|
||||
stage_data: [
|
||||
ComboMelee2(
|
||||
strikes: [
|
||||
(
|
||||
stage: 1,
|
||||
base_damage: 20.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 20,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 4.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 2.0,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(2.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 2,
|
||||
base_damage: 16.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 5.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 16,
|
||||
poise: 0,
|
||||
knockback: 5,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.8,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.8,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 1.5,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(2.0)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
(
|
||||
stage: 3,
|
||||
base_damage: 26.0,
|
||||
damage_increase: 0,
|
||||
base_poise_damage: 0,
|
||||
poise_damage_increase: 0,
|
||||
knockback: 10.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 26,
|
||||
poise: 0,
|
||||
knockback: 10,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 3.5,
|
||||
angle: 30.0,
|
||||
base_buildup_duration: 0.375,
|
||||
base_swing_duration: 0.1,
|
||||
),
|
||||
buildup_duration: 0.4,
|
||||
swing_duration: 0.1,
|
||||
hit_timing: 0.5,
|
||||
base_recover_duration: 0.6,
|
||||
forward_movement: 1.5,
|
||||
damage_kind: Slashing,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Bleeding,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(0.1),
|
||||
chance: 0.1,
|
||||
))),
|
||||
recover_duration: 0.6,
|
||||
movement: (
|
||||
swing: Some(Forward(1.5)),
|
||||
),
|
||||
ori_modifier: 0.7,
|
||||
),
|
||||
],
|
||||
initial_energy_gain: 0,
|
||||
max_energy_gain: 0,
|
||||
energy_increase: 0,
|
||||
speed_increase: 0.0,
|
||||
max_speed_increase: 0.0,
|
||||
scales_from_combo: 0,
|
||||
ori_modifier: 0.7,
|
||||
energy_cost_per_strike: 0,
|
||||
auto_progress: true,
|
||||
)
|
@ -3,7 +3,7 @@
|
||||
name: Automatic,
|
||||
body: RandomWith("wyvern_cloud"),
|
||||
alignment: Alignment(Enemy),
|
||||
loot: LootTable("common.loot_tables.creature.bird_large.wyvern"),
|
||||
loot: LootTable("common.loot_tables.creature.bird_large.cloudwyvern"),
|
||||
inventory: (
|
||||
loadout: FromBody,
|
||||
),
|
||||
|
@ -3,7 +3,7 @@
|
||||
name: Automatic,
|
||||
body: RandomWith("wyvern_flame"),
|
||||
alignment: Alignment(Enemy),
|
||||
loot: LootTable("common.loot_tables.creature.bird_large.wyvern"),
|
||||
loot: LootTable("common.loot_tables.creature.bird_large.flamewyvern"),
|
||||
inventory: (
|
||||
loadout: FromBody,
|
||||
),
|
||||
|
@ -3,7 +3,7 @@
|
||||
name: Automatic,
|
||||
body: RandomWith("wyvern_frost"),
|
||||
alignment: Alignment(Enemy),
|
||||
loot: LootTable("common.loot_tables.creature.bird_large.wyvern"),
|
||||
loot: LootTable("common.loot_tables.creature.bird_large.frostwyvern"),
|
||||
inventory: (
|
||||
loadout: FromBody,
|
||||
),
|
||||
|
@ -3,7 +3,7 @@
|
||||
name: Automatic,
|
||||
body: RandomWith("wyvern_sea"),
|
||||
alignment: Alignment(Enemy),
|
||||
loot: LootTable("common.loot_tables.creature.bird_large.wyvern"),
|
||||
loot: LootTable("common.loot_tables.creature.bird_large.seawyvern"),
|
||||
inventory: (
|
||||
loadout: FromBody,
|
||||
),
|
||||
|
@ -3,7 +3,7 @@
|
||||
name: Automatic,
|
||||
body: RandomWith("wyvern_weald"),
|
||||
alignment: Alignment(Enemy),
|
||||
loot: LootTable("common.loot_tables.creature.bird_large.wyvern"),
|
||||
loot: LootTable("common.loot_tables.creature.bird_large.wealdwyvern"),
|
||||
inventory: (
|
||||
loadout: FromBody,
|
||||
),
|
||||
|
@ -0,0 +1,7 @@
|
||||
[
|
||||
(1.0, MultiDrop(Item("common.items.mineral.gem.topaz"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.mineral.gem.amethyst"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.elegant_crest"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.claw"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 2, 6)),
|
||||
]
|
@ -0,0 +1,7 @@
|
||||
[
|
||||
(1.0, MultiDrop(Item("common.items.mineral.gem.topaz"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.mineral.gem.ruby"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.large_horn"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.sharp_fang"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 2, 6)),
|
||||
]
|
@ -0,0 +1,7 @@
|
||||
[
|
||||
(1.0, MultiDrop(Item("common.items.mineral.gem.topaz"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.mineral.gem.diamond"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.large_horn"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.claw"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 2, 6)),
|
||||
]
|
@ -0,0 +1,7 @@
|
||||
[
|
||||
(1.0, MultiDrop(Item("common.items.mineral.gem.topaz"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.mineral.gem.sapphire"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.sharp_fang"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.claw"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 2, 6)),
|
||||
]
|
@ -0,0 +1,7 @@
|
||||
[
|
||||
(1.0, MultiDrop(Item("common.items.mineral.gem.topaz"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.mineral.gem.emerald"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.elegant_crest"), 1, 3)),
|
||||
(1.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.large_horn"), 1, 3)),
|
||||
(5.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 2, 6)),
|
||||
]
|
@ -1,6 +0,0 @@
|
||||
[
|
||||
(1.0, MultiDrop(Item("common.items.food.meat.bird_large_raw"), 1, 2)),
|
||||
(1.0, MultiDrop(Item("common.items.food.meat.beast_large_raw"), 2, 2)),
|
||||
(2.0, MultiDrop(Item("common.items.crafting_ing.animal_misc.elegant_crest"), 1, 3)),
|
||||
(1.0, MultiDrop(Item("common.items.crafting_ing.hide.scales"), 2, 6)),
|
||||
]
|
@ -1,6 +1,5 @@
|
||||
[
|
||||
(1.0, MultiDrop(Item("common.items.crafting_ing.cloth.sunsilk"), 1, 3)),
|
||||
(1.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 3, 8)),
|
||||
(1.0, MultiDrop(Item("common.items.mineral.ingot.orichalcum"), 1, 3)),
|
||||
(1.0, MultiDrop(Item("common.items.log.eldwood"), 2, 6)),
|
||||
]
|
@ -8,6 +8,5 @@
|
||||
(1.0, LootTable("common.loot_tables.weapons.legendary_melee")),
|
||||
// Crafting material
|
||||
// Allow for DS and Eldwood to drop till entity droppers are implemented
|
||||
(1.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 3, 8)),
|
||||
(1.0, MultiDrop(Item("common.items.log.eldwood"), 2, 6)),
|
||||
]
|
||||
|
@ -13,6 +13,5 @@
|
||||
// Crafting material
|
||||
// Allow for DS and Eldwood to drop till entity droppers are implemented
|
||||
(1.0, Item("common.items.crafting_ing.mindflayer_bag_damaged")),
|
||||
(1.0, MultiDrop(Item("common.items.crafting_ing.hide.dragon_scale"), 3, 8)),
|
||||
(1.0, MultiDrop(Item("common.items.log.eldwood"), 2, 6)),
|
||||
]
|
||||
|
@ -1430,12 +1430,18 @@
|
||||
threshold: 1.25,
|
||||
subtitle: "subtitle-attack-laser_beam",
|
||||
),
|
||||
Woosh: (
|
||||
Whoosh: (
|
||||
files: [
|
||||
"voxygen.audio.sfx.abilities.woosh",
|
||||
"voxygen.audio.sfx.abilities.whoosh",
|
||||
],
|
||||
threshold: 0.4,
|
||||
),
|
||||
Swoosh: (
|
||||
files: [
|
||||
"voxygen.audio.sfx.abilities.swoosh",
|
||||
],
|
||||
threshold: 1.3,
|
||||
),
|
||||
CyclopsCharge: (
|
||||
files: [
|
||||
"voxygen.audio.sfx.abilities.cyclops_charge",
|
||||
@ -1518,6 +1524,13 @@
|
||||
threshold: 1.0,
|
||||
subtitle: "subtitle-utterance-bird-angry",
|
||||
),
|
||||
Utterance(Angry, Wyvern): (
|
||||
files: [
|
||||
"voxygen.audio.sfx.utterance.wyvern_angry",
|
||||
],
|
||||
threshold: 1.3,
|
||||
subtitle: "subtitle-utterance-wyvern-angry",
|
||||
),
|
||||
Utterance(Angry, Adlet): (
|
||||
files: [
|
||||
"voxygen.audio.sfx.utterance.adlet_angry1",
|
||||
@ -1719,6 +1732,13 @@
|
||||
threshold: 1.0,
|
||||
subtitle: "subtitle-utterance-asp-hurt",
|
||||
),
|
||||
Utterance(Hurt, Wyvern): (
|
||||
files: [
|
||||
"voxygen.audio.sfx.utterance.wyvern_hurt",
|
||||
],
|
||||
threshold: 1.2,
|
||||
subtitle: "subtitle-utterance-wyvern-hurt",
|
||||
),
|
||||
Utterance(Angry, Wendigo): (
|
||||
files: [
|
||||
"voxygen.audio.sfx.utterance.wendigo_angry1",
|
||||
|
BIN
assets/voxygen/audio/sfx/abilities/swoosh.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/sfx/abilities/swoosh.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/sfx/utterance/wyvern_angry.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/sfx/utterance/wyvern_angry.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/audio/sfx/utterance/wyvern_hurt.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/sfx/utterance/wyvern_hurt.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -149,3 +149,5 @@ subtitle-utterance-wendigo-angry = Wendigo screaming
|
||||
subtitle-utterance-wendigo-calm = Wendigo mumbling
|
||||
subtitle-utterance-wolf-angry = Wolf growling
|
||||
subtitle-utterance-wolf-hurt = Wolf whining
|
||||
subtitle-utterance-wyvern-angry = Wyvern roaring
|
||||
subtitle-utterance-wyvern-hurt = Wyvern hurting
|
@ -82,6 +82,7 @@ const int POTION_SICKNESS = 41;
|
||||
const int GIGA_SNOW = 42;
|
||||
const int CYCLOPS_CHARGE = 43;
|
||||
const int PORTAL_FIZZ = 45;
|
||||
const int INK = 46;
|
||||
|
||||
// meters per second squared (acceleration)
|
||||
const float earth_gravity = 9.807;
|
||||
@ -691,6 +692,17 @@ void main() {
|
||||
spin_in_axis(vec3(rand6, rand7, rand8), rand9 * 3 + lifetime * 5)
|
||||
);
|
||||
break;
|
||||
case INK:
|
||||
f_reflect = 0.0; // Magic water doesn't reflect light, it emits it
|
||||
float black_color = 0.3 + 0.2 * rand3 + 0.3 * max(floor(rand4 + 0.3), 0.0);
|
||||
float ink_size = 8.0 * (1 - slow_start(0.1)) * slow_end(0.15);
|
||||
attr = Attr(
|
||||
(inst_dir * slow_end(1.5)) + vec3(rand0, rand1, rand2) * (percent() + 2) * 0.1,
|
||||
vec3(ink_size),
|
||||
vec4(0.5 * black_color, 0.75 * black_color, black_color, 1),
|
||||
spin_in_axis(vec3(rand6, rand7, rand8), percent() * 10 + 3 * rand9)
|
||||
);
|
||||
break;
|
||||
default:
|
||||
attr = Attr(
|
||||
linear_motion(
|
||||
|
@ -939,6 +939,26 @@
|
||||
central: ("armor.empty"),
|
||||
)
|
||||
),
|
||||
LightningBolt: (
|
||||
bone0: (
|
||||
offset: (-4.5, -80.0, -3.0),
|
||||
central: ("weapon.projectile.lightning_bolt"),
|
||||
),
|
||||
bone1: (
|
||||
offset: (0.0, 0.0, 0.0),
|
||||
central: ("armor.empty"),
|
||||
)
|
||||
),
|
||||
SpearIcicle: (
|
||||
bone0: (
|
||||
offset: (-2.5, -30.0, -2.5),
|
||||
central: ("weapon.projectile.icicle-spear"),
|
||||
),
|
||||
bone1: (
|
||||
offset: (0.0, 0.0, 0.0),
|
||||
central: ("armor.empty"),
|
||||
)
|
||||
),
|
||||
AdletSpear: (
|
||||
bone0: (
|
||||
offset: (5.0, -22.0, -2.0),
|
||||
|
BIN
assets/voxygen/voxel/weapon/projectile/icicle-spear.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/weapon/projectile/icicle-spear.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/weapon/projectile/lightning_bolt.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/weapon/projectile/lightning_bolt.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -354,7 +354,7 @@ impl<'a> From<&'a Body> for Psyche {
|
||||
bird_medium::Species::Puffin => 0.8,
|
||||
bird_medium::Species::Toucan => 0.4,
|
||||
},
|
||||
Body::BirdLarge(_) => 0.1,
|
||||
Body::BirdLarge(_) => 0.0,
|
||||
Body::FishSmall(_) => 1.0,
|
||||
Body::FishMedium(_) => 0.75,
|
||||
Body::BipedLarge(_) => 0.0,
|
||||
@ -380,7 +380,10 @@ impl<'a> From<&'a Body> for Psyche {
|
||||
arthropod::Species::Emberfly => 0.1,
|
||||
},
|
||||
},
|
||||
sight_dist: 40.0,
|
||||
sight_dist: match body {
|
||||
Body::BirdLarge(_) => 80.0,
|
||||
_ => 40.0,
|
||||
},
|
||||
listen_dist: 30.0,
|
||||
aggro_dist: match body {
|
||||
Body::Humanoid(_) => Some(20.0),
|
||||
|
@ -55,4 +55,7 @@ pub enum FrontendSpecifier {
|
||||
Steam,
|
||||
Frost,
|
||||
WebStrand,
|
||||
Poison,
|
||||
Ink,
|
||||
Lightning,
|
||||
}
|
||||
|
@ -108,6 +108,8 @@ make_case_elim!(
|
||||
AdletTrap = 93,
|
||||
Flamethrower = 94,
|
||||
Mine = 95,
|
||||
LightningBolt = 96,
|
||||
SpearIcicle = 97,
|
||||
}
|
||||
);
|
||||
|
||||
@ -118,7 +120,7 @@ impl Body {
|
||||
}
|
||||
}
|
||||
|
||||
pub const ALL_OBJECTS: [Body; 96] = [
|
||||
pub const ALL_OBJECTS: [Body; 98] = [
|
||||
Body::Arrow,
|
||||
Body::Bomb,
|
||||
Body::Scarecrow,
|
||||
@ -215,6 +217,8 @@ pub const ALL_OBJECTS: [Body; 96] = [
|
||||
Body::AdletTrap,
|
||||
Body::Flamethrower,
|
||||
Body::Mine,
|
||||
Body::LightningBolt,
|
||||
Body::SpearIcicle,
|
||||
];
|
||||
|
||||
impl From<Body> for super::Body {
|
||||
@ -320,6 +324,8 @@ impl Body {
|
||||
Body::AdletTrap => "adlet_trap",
|
||||
Body::Flamethrower => "flamethrower",
|
||||
Body::Mine => "mine",
|
||||
Body::LightningBolt => "lightning_bolt",
|
||||
Body::SpearIcicle => "spear_icicle",
|
||||
}
|
||||
}
|
||||
|
||||
@ -372,11 +378,8 @@ impl Body {
|
||||
Body::BedBlue => 50.0,
|
||||
Body::Bedroll => 3.0,
|
||||
Body::Bench => 100.0,
|
||||
Body::BoltFire
|
||||
| Body::BoltFireBig
|
||||
| Body::BoltNature
|
||||
| Body::BoltIcicle
|
||||
| Body::SpitPoison => 1.0,
|
||||
Body::BoltFire | Body::BoltFireBig | Body::BoltNature | Body::BoltIcicle => 1.0,
|
||||
Body::SpitPoison => 100.0,
|
||||
Body::Bomb | Body::DagonBomb => {
|
||||
0.5 * IRON_DENSITY * std::f32::consts::PI / 6.0 * self.dimensions().x.powi(3)
|
||||
},
|
||||
@ -446,6 +449,7 @@ impl Body {
|
||||
Body::AdletSpear => 1.5,
|
||||
Body::AdletTrap => 10.0,
|
||||
Body::Mine => 100.0,
|
||||
Body::LightningBolt | Body::SpearIcicle => 20000.0,
|
||||
};
|
||||
|
||||
Mass(m)
|
||||
@ -477,6 +481,7 @@ impl Body {
|
||||
Body::IceBomb => Vec3::broadcast(2.5),
|
||||
Body::LaserBeam => Vec3::new(8.0, 8.0, 8.0),
|
||||
Body::Mine => Vec3::new(0.8, 0.8, 0.5),
|
||||
Body::LightningBolt | Body::SpearIcicle => Vec3::new(1.0, 1.0, 1.0),
|
||||
// FIXME: this *must* be exhaustive match
|
||||
_ => Vec3::broadcast(0.5),
|
||||
}
|
||||
|
@ -91,12 +91,7 @@ pub enum ProjectileConstructor {
|
||||
knockback: f32,
|
||||
min_falloff: f32,
|
||||
},
|
||||
SeaBomb {
|
||||
damage: f32,
|
||||
radius: f32,
|
||||
min_falloff: f32,
|
||||
},
|
||||
WindBomb {
|
||||
InkBomb {
|
||||
damage: f32,
|
||||
radius: f32,
|
||||
min_falloff: f32,
|
||||
@ -527,7 +522,7 @@ impl ProjectileConstructor {
|
||||
is_point: true,
|
||||
}
|
||||
},
|
||||
SeaBomb {
|
||||
InkBomb {
|
||||
damage,
|
||||
radius,
|
||||
min_falloff,
|
||||
@ -541,12 +536,27 @@ impl ProjectileConstructor {
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
instance,
|
||||
);
|
||||
let buff = AttackEffect::new(
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
CombatEffect::Buff(CombatBuff {
|
||||
kind: BuffKind::Wet,
|
||||
dur_secs: 8.0,
|
||||
strength: CombatBuffStrength::Value(0.5),
|
||||
chance: 1.0,
|
||||
})
|
||||
.adjusted_by_stats(tool_stats),
|
||||
)
|
||||
.with_requirement(CombatRequirement::AnyDamage);
|
||||
let attack = Attack::default()
|
||||
.with_damage(damage)
|
||||
.with_crit(crit_chance, crit_mult)
|
||||
.with_effect(buff)
|
||||
.with_combo_increment();
|
||||
let explosion = Explosion {
|
||||
effects: vec![RadiusEffect::Attack(attack)],
|
||||
effects: vec![
|
||||
RadiusEffect::Attack(attack),
|
||||
RadiusEffect::TerrainDestruction(18.0, Rgb::new(4.0, 7.0, 32.0)),
|
||||
],
|
||||
radius,
|
||||
reagent: Some(Reagent::Blue),
|
||||
min_falloff,
|
||||
@ -561,40 +571,6 @@ impl ProjectileConstructor {
|
||||
is_point: true,
|
||||
}
|
||||
},
|
||||
WindBomb {
|
||||
damage,
|
||||
radius,
|
||||
min_falloff,
|
||||
} => {
|
||||
let damage = AttackDamage::new(
|
||||
Damage {
|
||||
source: DamageSource::Explosion,
|
||||
kind: DamageKind::Energy,
|
||||
value: damage,
|
||||
},
|
||||
Some(GroupTarget::OutOfGroup),
|
||||
instance,
|
||||
);
|
||||
let attack = Attack::default()
|
||||
.with_damage(damage)
|
||||
.with_crit(crit_chance, crit_mult)
|
||||
.with_combo_increment();
|
||||
let explosion = Explosion {
|
||||
effects: vec![RadiusEffect::Attack(attack)],
|
||||
radius,
|
||||
reagent: Some(Reagent::White),
|
||||
min_falloff,
|
||||
};
|
||||
Projectile {
|
||||
hit_solid: vec![Effect::Explode(explosion.clone()), Effect::Vanish],
|
||||
hit_entity: vec![Effect::Explode(explosion), Effect::Vanish],
|
||||
time_left: Duration::from_secs(10),
|
||||
owner,
|
||||
ignore_group: true,
|
||||
is_sticky: true,
|
||||
is_point: true,
|
||||
}
|
||||
},
|
||||
Snowball {
|
||||
damage,
|
||||
radius,
|
||||
@ -982,15 +958,7 @@ impl ProjectileConstructor {
|
||||
*damage *= power;
|
||||
*radius *= range;
|
||||
},
|
||||
SeaBomb {
|
||||
ref mut damage,
|
||||
ref mut radius,
|
||||
..
|
||||
} => {
|
||||
*damage *= power;
|
||||
*radius *= range;
|
||||
},
|
||||
WindBomb {
|
||||
InkBomb {
|
||||
ref mut damage,
|
||||
ref mut radius,
|
||||
..
|
||||
@ -1068,8 +1036,7 @@ impl ProjectileConstructor {
|
||||
Snowball { .. } => true,
|
||||
ExplodingPumpkin { .. } => true,
|
||||
DagonBomb { .. } => true,
|
||||
SeaBomb { .. } => true,
|
||||
WindBomb { .. } => true,
|
||||
InkBomb { .. } => true,
|
||||
IceBomb { .. } => true,
|
||||
LaserBeam { .. } => true,
|
||||
Trap { .. } => false,
|
||||
|
@ -49,6 +49,10 @@ pub enum FrontendSpecifier {
|
||||
Ground,
|
||||
Fire,
|
||||
Water,
|
||||
Ice,
|
||||
IceSpikes,
|
||||
Steam,
|
||||
Poison,
|
||||
Ink,
|
||||
Lightning,
|
||||
}
|
||||
|
@ -128,7 +128,10 @@ pub enum Outcome {
|
||||
FailedSpriteUnlock {
|
||||
pos: Vec3<i32>,
|
||||
},
|
||||
Woosh {
|
||||
Whoosh {
|
||||
pos: Vec3<f32>,
|
||||
},
|
||||
Swoosh {
|
||||
pos: Vec3<f32>,
|
||||
},
|
||||
FireShockwave {
|
||||
@ -152,7 +155,8 @@ impl Outcome {
|
||||
| Outcome::PoiseChange { pos, .. }
|
||||
| Outcome::GroundSlam { pos }
|
||||
| Outcome::FlashFreeze { pos }
|
||||
| Outcome::Woosh { pos }
|
||||
| Outcome::Whoosh { pos }
|
||||
| Outcome::Swoosh { pos }
|
||||
| Outcome::IceSpikes { pos }
|
||||
| Outcome::Steam { pos }
|
||||
| Outcome::FireShockwave { pos }
|
||||
|
@ -75,7 +75,7 @@ impl CharacterBehavior for Data {
|
||||
});
|
||||
if let Some(FrontendSpecifier::ElderLeap) = self.static_data.specifier {
|
||||
// Send local event used for frontend shenanigans
|
||||
output_events.emit_local(LocalEvent::CreateOutcome(Outcome::Woosh {
|
||||
output_events.emit_local(LocalEvent::CreateOutcome(Outcome::Whoosh {
|
||||
pos: data.pos.0 + *data.ori.look_dir() * (data.body.max_radius()),
|
||||
}));
|
||||
}
|
||||
|
@ -173,7 +173,11 @@ impl CharacterBehavior for Data {
|
||||
},
|
||||
));
|
||||
},
|
||||
_ => {},
|
||||
_ => {
|
||||
output_events.emit_local(LocalEvent::CreateOutcome(Outcome::Swoosh {
|
||||
pos: data.pos.0 + *data.ori.look_dir() * (data.body.max_radius()),
|
||||
}));
|
||||
},
|
||||
}
|
||||
} else {
|
||||
// Transitions to recover
|
||||
|
@ -29,7 +29,7 @@ use std::{
|
||||
/// Note that this number does *not* need incrementing on every change: most
|
||||
/// field removals/additions are fine. This number should only be incremented
|
||||
/// when we wish to perform a *hard purge* of rtsim data.
|
||||
pub const CURRENT_VERSION: u32 = 3;
|
||||
pub const CURRENT_VERSION: u32 = 4;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct Data {
|
||||
|
@ -218,6 +218,11 @@ impl Data {
|
||||
comp::body::bird_large::Species::Phoenix,
|
||||
comp::body::bird_large::Species::Cockatrice,
|
||||
comp::body::bird_large::Species::Roc,
|
||||
comp::body::bird_large::Species::FlameWyvern,
|
||||
comp::body::bird_large::Species::CloudWyvern,
|
||||
comp::body::bird_large::Species::FrostWyvern,
|
||||
comp::body::bird_large::Species::SeaWyvern,
|
||||
comp::body::bird_large::Species::WealdWyvern,
|
||||
]
|
||||
.choose(&mut rng)
|
||||
.unwrap();
|
||||
|
@ -1147,45 +1147,74 @@ fn humanoid() -> impl Action<DefaultState> {
|
||||
}
|
||||
|
||||
fn bird_large() -> impl Action<DefaultState> {
|
||||
choose(|ctx, _| {
|
||||
let data = ctx.state.data();
|
||||
if let Some(home) = ctx.npc.home {
|
||||
let is_home = ctx.npc.current_site.map_or(false, |site| home == site);
|
||||
let goto = |wpos| {
|
||||
casual(goto_2d_flying(
|
||||
wpos,
|
||||
1.0,
|
||||
20.0,
|
||||
32.0,
|
||||
22.0,
|
||||
ctx.npc.body.flying_height(),
|
||||
))
|
||||
now(|ctx, bearing: &mut Vec2<f32>| {
|
||||
*bearing = bearing
|
||||
.map(|e| e + ctx.rng.gen_range(-0.1..0.1))
|
||||
.try_normalized()
|
||||
.unwrap_or_default();
|
||||
let bearing_dist = 24.0;
|
||||
let mut pos = ctx.npc.wpos.xy() + *bearing * bearing_dist;
|
||||
let is_deep_water = ctx
|
||||
.world
|
||||
.sim()
|
||||
.get_interpolated(pos.as_(), |c| c.alt - c.water_alt)
|
||||
.unwrap_or(f32::NEG_INFINITY)
|
||||
< -120.0
|
||||
&& ctx
|
||||
.world
|
||||
.sim()
|
||||
.get(pos.as_().wpos_to_cpos())
|
||||
.map_or(false, |c| c.river.is_ocean() || c.river.is_lake());
|
||||
// when high tree_density fly high, otherwise fly low-mid
|
||||
let npc_pos = ctx.npc.wpos.xy();
|
||||
let tree_density = ctx
|
||||
.world
|
||||
.sim()
|
||||
.get_interpolated(npc_pos.as_(), |c| c.tree_density)
|
||||
.unwrap_or(1.0);
|
||||
let height_factor = if tree_density > 0.1 {
|
||||
2.0
|
||||
} else {
|
||||
ctx.rng.gen_range(0.1..0.5)
|
||||
};
|
||||
if is_home {
|
||||
if let Some((_, site)) = data
|
||||
.sites
|
||||
.iter()
|
||||
.filter(|(id, site)| {
|
||||
*id != home
|
||||
&& site.world_site.map_or(false, |site| {
|
||||
matches!(ctx.index.sites.get(site).kind, SiteKind::Dungeon(_))
|
||||
if !is_deep_water {
|
||||
goto_2d_flying(
|
||||
pos,
|
||||
0.2,
|
||||
bearing_dist,
|
||||
8.0,
|
||||
8.0,
|
||||
ctx.npc.body.flying_height() * height_factor,
|
||||
)
|
||||
|
||||
} else {
|
||||
*bearing *= -1.0;
|
||||
|
||||
pos = ctx.npc.wpos.xy() + *bearing * 24.0;
|
||||
|
||||
goto_2d_flying(
|
||||
pos,
|
||||
0.2,
|
||||
bearing_dist,
|
||||
8.0,
|
||||
8.0,
|
||||
ctx.npc.body.flying_height() * height_factor,
|
||||
)
|
||||
}
|
||||
// If we are too far away from our goal position we can stop since we aren't going to a specific place.
|
||||
.stop_if(move |ctx: &mut NpcCtx| {
|
||||
ctx.npc.wpos.xy().distance_squared(pos) > (bearing_dist + 5.0).powi(2)
|
||||
})
|
||||
// If goal position wasn't reached within 20 seconds we're probably stuck and need to find a new goal position.
|
||||
.stop_if(timeout(10.0))
|
||||
.debug({
|
||||
let bearing = *bearing;
|
||||
move || format!("Moving with a bearing of {:?}", bearing)
|
||||
})
|
||||
})
|
||||
.choose(&mut ctx.rng)
|
||||
{
|
||||
goto(site.wpos.as_::<f32>())
|
||||
} else {
|
||||
casual(idle())
|
||||
}
|
||||
} else if let Some(site) = data.sites.get(home) {
|
||||
goto(site.wpos.as_::<f32>())
|
||||
} else {
|
||||
casual(idle())
|
||||
}
|
||||
} else {
|
||||
casual(idle())
|
||||
}
|
||||
})
|
||||
.repeat()
|
||||
.with_state(Vec2::<f32>::zero())
|
||||
.map(|_, _| ())
|
||||
}
|
||||
|
||||
fn monster() -> impl Action<DefaultState> {
|
||||
|
@ -106,68 +106,6 @@ impl<'a> AgentData<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_wyvern_attack(
|
||||
&self,
|
||||
_agent: &mut Agent,
|
||||
controller: &mut Controller,
|
||||
attack_data: &AttackData,
|
||||
tgt_data: &TargetData,
|
||||
read_data: &ReadData,
|
||||
_rng: &mut impl Rng,
|
||||
) {
|
||||
// Fly to target
|
||||
let dir_to_target = ((tgt_data.pos.0 + Vec3::unit_z() * 1.5) - self.pos.0)
|
||||
.try_normalized()
|
||||
.unwrap_or_else(Vec3::zero);
|
||||
let speed = 1.0;
|
||||
controller.inputs.move_dir = dir_to_target.xy() * speed;
|
||||
|
||||
// Always fly! If the floor can't touch you, it can't hurt you...
|
||||
controller.push_basic_input(InputKind::Fly);
|
||||
// Flee from the ground! The internet told me it was lava!
|
||||
// If on the ground, jump with every last ounce of energy, holding onto all that
|
||||
// is dear in life and straining for the wide open skies.
|
||||
if self.physics_state.on_ground.is_some() {
|
||||
controller.push_basic_input(InputKind::Jump);
|
||||
} else {
|
||||
// Only fly down if close enough to target in the xy plane
|
||||
// Otherwise fly towards the target bouncing around a 5 block altitude
|
||||
let mut maintain_altitude = |altitude| {
|
||||
if read_data
|
||||
.terrain
|
||||
.ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * altitude))
|
||||
.until(Block::is_solid)
|
||||
.cast()
|
||||
.1
|
||||
.map_or(true, |b| b.is_some())
|
||||
{
|
||||
// Fly up
|
||||
controller.inputs.move_z = 1.0;
|
||||
} else {
|
||||
// Fly down
|
||||
controller.inputs.move_z = -1.0;
|
||||
}
|
||||
};
|
||||
if (tgt_data.pos.0 - self.pos.0).xy().magnitude_squared() > (30.0_f32).powi(2) {
|
||||
// If above 30 blocks, fly down and attack
|
||||
maintain_altitude(30.0);
|
||||
// Shoot bombs
|
||||
controller.push_basic_input(InputKind::Primary);
|
||||
} else {
|
||||
maintain_altitude(2.0);
|
||||
|
||||
// Attack if in range
|
||||
if attack_data.dist_sqrd < 6.0_f32.powi(2) && attack_data.angle < 150.0 {
|
||||
controller.push_basic_input(InputKind::Ability(0));
|
||||
} else if attack_data.dist_sqrd < 8.0_f32.powi(2) && attack_data.angle < 150.0 {
|
||||
controller.push_basic_input(InputKind::Ability(1));
|
||||
} else if attack_data.dist_sqrd < 12.0_f32.powi(2) && attack_data.angle < 150.0 {
|
||||
controller.push_basic_input(InputKind::Secondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Intended for any agent that has one attack, that attack is a melee attack,
|
||||
// the agent is able to freely walk around, and the agent is trying to attack
|
||||
// from behind its target
|
||||
@ -3034,13 +2972,15 @@ impl<'a> AgentData<'a> {
|
||||
attack_data: &AttackData,
|
||||
tgt_data: &TargetData,
|
||||
read_data: &ReadData,
|
||||
rng: &mut impl Rng,
|
||||
_rng: &mut impl Rng,
|
||||
) {
|
||||
enum ActionStateTimers {
|
||||
AttackTimer = 0,
|
||||
}
|
||||
// Set fly to false
|
||||
controller.push_cancel_input(InputKind::Fly);
|
||||
if attack_data.dist_sqrd > 30.0_f32.powi(2) {
|
||||
let small_chance = rng.gen_bool(0.05);
|
||||
|
||||
if small_chance
|
||||
&& entities_have_line_of_sight(
|
||||
if entities_have_line_of_sight(
|
||||
self.pos,
|
||||
self.body,
|
||||
self.scale,
|
||||
@ -3048,13 +2988,10 @@ impl<'a> AgentData<'a> {
|
||||
tgt_data.body,
|
||||
tgt_data.scale,
|
||||
read_data,
|
||||
)
|
||||
&& attack_data.angle < 15.0
|
||||
) && attack_data.angle < 15.0
|
||||
{
|
||||
// Fireball
|
||||
controller.push_basic_input(InputKind::Primary);
|
||||
}
|
||||
// If some target
|
||||
if let Some((bearing, speed)) = agent.chaser.chase(
|
||||
&*read_data.terrain,
|
||||
self.pos.0,
|
||||
@ -3065,23 +3002,14 @@ impl<'a> AgentData<'a> {
|
||||
..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_data.pos.0.z) < 20.0 {
|
||||
// Fly upward
|
||||
controller.push_basic_input(InputKind::Fly);
|
||||
controller.inputs.move_z = 1.0;
|
||||
} else {
|
||||
// Jump
|
||||
self.jump_if(bearing.z > 1.5, controller);
|
||||
controller.inputs.move_z = bearing.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If higher than 2 blocks
|
||||
else if !read_data
|
||||
} else if !read_data
|
||||
.terrain
|
||||
.ray(self.pos.0, self.pos.0 - (Vec3::unit_z() * 2.0))
|
||||
.until(Block::is_solid)
|
||||
@ -3092,41 +3020,52 @@ impl<'a> AgentData<'a> {
|
||||
// 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.push_basic_input(InputKind::Fly);
|
||||
let move_dir = tgt_data.pos.0 - self.pos.0;
|
||||
controller.inputs.move_dir =
|
||||
move_dir.xy().try_normalized().unwrap_or_else(Vec2::zero) * 2.0;
|
||||
controller.inputs.move_z = move_dir.z - 0.5;
|
||||
// If further than 4 blocks and random chance
|
||||
if rng.gen_bool(0.05)
|
||||
&& attack_data.dist_sqrd > (4.0 * attack_data.min_attack_dist).powi(2)
|
||||
if attack_data.dist_sqrd > (4.0 * attack_data.min_attack_dist).powi(2)
|
||||
&& attack_data.angle < 15.0
|
||||
{
|
||||
// Fireball
|
||||
controller.push_basic_input(InputKind::Primary);
|
||||
}
|
||||
}
|
||||
// If further than 4 blocks and random chance
|
||||
else if rng.gen_bool(0.05)
|
||||
&& attack_data.dist_sqrd > (4.0 * attack_data.min_attack_dist).powi(2)
|
||||
} else if attack_data.dist_sqrd > (3.0 * attack_data.min_attack_dist).powi(2) {
|
||||
self.path_toward_target(
|
||||
agent,
|
||||
controller,
|
||||
tgt_data.pos.0,
|
||||
read_data,
|
||||
Path::Separate,
|
||||
None,
|
||||
);
|
||||
} else if self.energy.current() > 60.0
|
||||
&& agent.action_state.timers[ActionStateTimers::AttackTimer as usize] < 3.0
|
||||
&& attack_data.angle < 15.0
|
||||
{
|
||||
// Fireball
|
||||
controller.push_basic_input(InputKind::Primary);
|
||||
}
|
||||
// If random chance and less than 20 blocks higher than target and further than 4
|
||||
// blocks
|
||||
else if rng.gen_bool(0.5)
|
||||
&& (self.pos.0.z - tgt_data.pos.0.z) < 15.0
|
||||
&& attack_data.dist_sqrd > (4.0 * attack_data.min_attack_dist).powi(2)
|
||||
// Shockwave
|
||||
controller.push_basic_input(InputKind::Ability(0));
|
||||
// Move towards the target slowly
|
||||
self.path_toward_target(
|
||||
agent,
|
||||
controller,
|
||||
tgt_data.pos.0,
|
||||
read_data,
|
||||
Path::Separate,
|
||||
Some(0.5),
|
||||
);
|
||||
agent.action_state.timers[ActionStateTimers::AttackTimer as usize] += read_data.dt.0;
|
||||
} else if agent.action_state.timers[ActionStateTimers::AttackTimer as usize] < 6.0
|
||||
&& attack_data.angle < 90.0
|
||||
&& attack_data.in_min_range()
|
||||
{
|
||||
controller.push_basic_input(InputKind::Fly);
|
||||
controller.inputs.move_z = 1.0;
|
||||
}
|
||||
// If further than 2.5 blocks and random chance
|
||||
else if attack_data.dist_sqrd > (2.5 * attack_data.min_attack_dist).powi(2) {
|
||||
// Walk to target
|
||||
// Triple strike
|
||||
controller.push_basic_input(InputKind::Secondary);
|
||||
agent.action_state.timers[ActionStateTimers::AttackTimer as usize] += read_data.dt.0;
|
||||
} else {
|
||||
// Reset timer
|
||||
agent.action_state.timers[ActionStateTimers::AttackTimer as usize] = 0.0;
|
||||
// Target is behind us or the timer needs to be reset. Chase target
|
||||
self.path_toward_target(
|
||||
agent,
|
||||
controller,
|
||||
@ -3136,15 +3075,113 @@ impl<'a> AgentData<'a> {
|
||||
None,
|
||||
);
|
||||
}
|
||||
// If energy higher than 600 and random chance
|
||||
else if self.energy.current() > 60.0 && rng.gen_bool(0.4) {
|
||||
// Shockwave
|
||||
}
|
||||
|
||||
pub fn handle_wyvern_attack(
|
||||
&self,
|
||||
agent: &mut Agent,
|
||||
controller: &mut Controller,
|
||||
attack_data: &AttackData,
|
||||
tgt_data: &TargetData,
|
||||
read_data: &ReadData,
|
||||
_rng: &mut impl Rng,
|
||||
) {
|
||||
enum ActionStateTimers {
|
||||
AttackTimer = 0,
|
||||
}
|
||||
// Set fly to false
|
||||
controller.push_cancel_input(InputKind::Fly);
|
||||
if attack_data.dist_sqrd > 30.0_f32.powi(2) {
|
||||
if entities_have_line_of_sight(
|
||||
self.pos,
|
||||
self.body,
|
||||
self.scale,
|
||||
tgt_data.pos,
|
||||
tgt_data.body,
|
||||
tgt_data.scale,
|
||||
read_data,
|
||||
) && attack_data.angle < 15.0
|
||||
{
|
||||
controller.push_basic_input(InputKind::Primary);
|
||||
}
|
||||
if let Some((bearing, speed)) = agent.chaser.chase(
|
||||
&*read_data.terrain,
|
||||
self.pos.0,
|
||||
self.vel.0,
|
||||
tgt_data.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_data.pos.0.z) < 35.0 {
|
||||
controller.push_basic_input(InputKind::Fly);
|
||||
controller.inputs.move_z = 1.0;
|
||||
}
|
||||
}
|
||||
} 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.push_basic_input(InputKind::Fly);
|
||||
let move_dir = tgt_data.pos.0 - self.pos.0;
|
||||
controller.inputs.move_dir =
|
||||
move_dir.xy().try_normalized().unwrap_or_else(Vec2::zero) * 2.0;
|
||||
controller.inputs.move_z = move_dir.z - 0.5;
|
||||
if attack_data.dist_sqrd > (4.0 * attack_data.min_attack_dist).powi(2)
|
||||
&& attack_data.angle < 15.0
|
||||
{
|
||||
controller.push_basic_input(InputKind::Primary);
|
||||
}
|
||||
} else if attack_data.dist_sqrd > (3.0 * attack_data.min_attack_dist).powi(2) {
|
||||
self.path_toward_target(
|
||||
agent,
|
||||
controller,
|
||||
tgt_data.pos.0,
|
||||
read_data,
|
||||
Path::Separate,
|
||||
None,
|
||||
);
|
||||
} else if attack_data.angle < 15.0 {
|
||||
if agent.action_state.timers[ActionStateTimers::AttackTimer as usize] < 5.0 {
|
||||
// beam
|
||||
controller.push_basic_input(InputKind::Ability(1));
|
||||
} else if agent.action_state.timers[ActionStateTimers::AttackTimer as usize] < 9.0 {
|
||||
// shockwave
|
||||
controller.push_basic_input(InputKind::Ability(0));
|
||||
} else if attack_data.angle < 90.0 {
|
||||
} else {
|
||||
agent.action_state.timers[ActionStateTimers::AttackTimer as usize] = 0.0;
|
||||
}
|
||||
// Move towards the target slowly
|
||||
self.path_toward_target(
|
||||
agent,
|
||||
controller,
|
||||
tgt_data.pos.0,
|
||||
read_data,
|
||||
Path::Separate,
|
||||
Some(0.5),
|
||||
);
|
||||
agent.action_state.timers[ActionStateTimers::AttackTimer as usize] += read_data.dt.0;
|
||||
} else if agent.action_state.timers[ActionStateTimers::AttackTimer as usize] < 9.0
|
||||
&& attack_data.angle < 90.0
|
||||
&& attack_data.in_min_range()
|
||||
{
|
||||
// Triple strike
|
||||
controller.push_basic_input(InputKind::Secondary);
|
||||
agent.action_state.timers[ActionStateTimers::AttackTimer as usize] += read_data.dt.0;
|
||||
} else {
|
||||
// Target is behind us. Turn around and chase target
|
||||
// Reset timer
|
||||
agent.action_state.timers[ActionStateTimers::AttackTimer as usize] = 0.0;
|
||||
// Target is behind us or the timer needs to be reset. Chase target
|
||||
self.path_toward_target(
|
||||
agent,
|
||||
controller,
|
||||
@ -3201,9 +3238,6 @@ impl<'a> AgentData<'a> {
|
||||
if (self.pos.0.z - tgt_data.pos.0.z) < 20.0 {
|
||||
controller.push_basic_input(InputKind::Fly);
|
||||
controller.inputs.move_z = 1.0;
|
||||
} else {
|
||||
self.jump_if(bearing.z > 1.5, controller);
|
||||
controller.inputs.move_z = bearing.z;
|
||||
}
|
||||
}
|
||||
} else if !read_data
|
||||
@ -3311,22 +3345,7 @@ impl<'a> AgentData<'a> {
|
||||
// Increase action timer
|
||||
agent.action_state.timers[ActionStateTimers::TimerBirdLargeBasic as usize] +=
|
||||
read_data.dt.0;
|
||||
// If higher than 2 blocks
|
||||
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())
|
||||
{
|
||||
// Fly to target and land
|
||||
controller.push_basic_input(InputKind::Fly);
|
||||
let move_dir = tgt_data.pos.0 - self.pos.0;
|
||||
controller.inputs.move_dir =
|
||||
move_dir.xy().try_normalized().unwrap_or_else(Vec2::zero) * 2.0;
|
||||
controller.inputs.move_z = move_dir.z - 0.5;
|
||||
} else if agent.action_state.timers[ActionStateTimers::TimerBirdLargeBasic as usize] > 8.0 {
|
||||
if agent.action_state.timers[ActionStateTimers::TimerBirdLargeBasic as usize] > 8.0 {
|
||||
// If action timer higher than 8, make bird summon tornadoes
|
||||
controller.push_basic_input(InputKind::Secondary);
|
||||
if matches!(self.char_state, CharacterState::BasicSummon(c) if matches!(c.stage_section, StageSection::Recover))
|
||||
|
@ -165,9 +165,19 @@ fn get_npc_entity_info(npc: &Npc, sites: &Sites, index: IndexRef) -> EntityInfo
|
||||
comp::bird_large::Species::Phoenix => "common.entity.wild.peaceful.phoenix",
|
||||
comp::bird_large::Species::Cockatrice => "common.entity.wild.aggressive.cockatrice",
|
||||
comp::bird_large::Species::Roc => "common.entity.wild.aggressive.roc",
|
||||
// Wildcard match used here as there is an array above
|
||||
// which limits what species are used
|
||||
_ => unimplemented!(),
|
||||
comp::bird_large::Species::CloudWyvern => {
|
||||
"common.entity.wild.aggressive.cloudwyvern"
|
||||
},
|
||||
comp::bird_large::Species::FlameWyvern => {
|
||||
"common.entity.wild.aggressive.flamewyvern"
|
||||
},
|
||||
comp::bird_large::Species::FrostWyvern => {
|
||||
"common.entity.wild.aggressive.frostwyvern"
|
||||
},
|
||||
comp::bird_large::Species::SeaWyvern => "common.entity.wild.aggressive.seawyvern",
|
||||
comp::bird_large::Species::WealdWyvern => {
|
||||
"common.entity.wild.aggressive.wealdwyvern"
|
||||
},
|
||||
},
|
||||
Body::BipedLarge(body) => match body.species {
|
||||
comp::biped_large::Species::Ogre => "common.entity.wild.aggressive.ogre",
|
||||
|
149
voxygen/anim/src/bird_large/combomelee.rs
Normal file
149
voxygen/anim/src/bird_large/combomelee.rs
Normal file
@ -0,0 +1,149 @@
|
||||
use super::{
|
||||
super::{vek::*, Animation},
|
||||
BirdLargeSkeleton, SkeletonAttr,
|
||||
};
|
||||
use common::states::utils::StageSection;
|
||||
|
||||
pub struct ComboAnimation;
|
||||
impl Animation for ComboAnimation {
|
||||
type Dependency<'a> = (
|
||||
Option<&'a str>,
|
||||
Option<StageSection>,
|
||||
usize,
|
||||
f32,
|
||||
f32,
|
||||
Vec3<f32>,
|
||||
Vec3<f32>,
|
||||
bool,
|
||||
);
|
||||
type Skeleton = BirdLargeSkeleton;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
const UPDATE_FN: &'static [u8] = b"bird_large_combo\0";
|
||||
|
||||
#[cfg_attr(feature = "be-dyn-lib", export_name = "bird_large_combo")]
|
||||
fn update_skeleton_inner(
|
||||
skeleton: &Self::Skeleton,
|
||||
(
|
||||
_ability_id,
|
||||
stage_section,
|
||||
current_strike,
|
||||
global_time,
|
||||
timer,
|
||||
orientation,
|
||||
last_ori,
|
||||
on_ground,
|
||||
): Self::Dependency<'_>,
|
||||
anim_time: f32,
|
||||
rate: &mut f32,
|
||||
s_a: &SkeletonAttr,
|
||||
) -> Self::Skeleton {
|
||||
*rate = 1.0;
|
||||
let mut next = (*skeleton).clone();
|
||||
|
||||
let multi_strike_pullback = 1.0
|
||||
- if matches!(stage_section, Some(StageSection::Recover)) {
|
||||
anim_time.powi(4)
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
let (move1base, move2base, _move3) = match stage_section {
|
||||
Some(StageSection::Buildup) => (anim_time.powf(0.25), 0.0, 0.0),
|
||||
Some(StageSection::Action) => (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 subtract = global_time - timer;
|
||||
let check = subtract - subtract.trunc();
|
||||
let mirror = (check - 0.5).signum();
|
||||
|
||||
let move1 = move1base * multi_strike_pullback;
|
||||
let move2 = move2base * multi_strike_pullback;
|
||||
let move1mirror = move1base * multi_strike_pullback * mirror;
|
||||
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;
|
||||
|
||||
for strike in 0..=current_strike {
|
||||
match strike {
|
||||
0..=2 => {
|
||||
next.chest.position = Vec3::new(
|
||||
0.0,
|
||||
s_a.chest.0,
|
||||
s_a.chest.1 + wave_slow_cos * 0.06 + move2 * -6.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.4)
|
||||
* Quaternion::rotation_z(move1 * tilt * 1.5)
|
||||
* Quaternion::rotation_y(move1mirror * 0.3);
|
||||
|
||||
next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1);
|
||||
next.head.orientation = Quaternion::rotation_x(move1 * -0.2 - move2 * 0.2)
|
||||
* Quaternion::rotation_y(move1mirror * 0.5);
|
||||
|
||||
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 + move1 * -0.5 + move2 * 0.5);
|
||||
|
||||
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 + move1 * 1.0 + move2 * 0.5,
|
||||
) * Quaternion::rotation_z(0.2);
|
||||
next.wing_in_r.orientation = Quaternion::rotation_y(
|
||||
1.0 - wave_slow_cos * 0.06 + move1 * -1.0 + move2 * -0.5,
|
||||
) * 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 + move1 * -0.5)
|
||||
* Quaternion::rotation_z(0.7 + move1 * -0.7);
|
||||
next.wing_mid_r.orientation = Quaternion::rotation_y(0.1 + move1 * 0.5)
|
||||
* Quaternion::rotation_z(-0.7 + move1 * 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 + move1 * -0.3)
|
||||
* Quaternion::rotation_z(0.2);
|
||||
next.wing_out_r.orientation = Quaternion::rotation_y(0.2 + move1 * 0.3)
|
||||
* Quaternion::rotation_z(-0.2);
|
||||
} else {
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
pub mod alpha;
|
||||
pub mod breathe;
|
||||
pub mod combomelee;
|
||||
pub mod dash;
|
||||
pub mod feed;
|
||||
pub mod fly;
|
||||
@ -13,9 +14,10 @@ pub mod swim;
|
||||
|
||||
// Reexports
|
||||
pub use self::{
|
||||
alpha::AlphaAnimation, breathe::BreatheAnimation, dash::DashAnimation, feed::FeedAnimation,
|
||||
fly::FlyAnimation, idle::IdleAnimation, run::RunAnimation, shockwave::ShockwaveAnimation,
|
||||
shoot::ShootAnimation, stunned::StunnedAnimation, summon::SummonAnimation, swim::SwimAnimation,
|
||||
alpha::AlphaAnimation, breathe::BreatheAnimation, combomelee::ComboAnimation,
|
||||
dash::DashAnimation, feed::FeedAnimation, fly::FlyAnimation, idle::IdleAnimation,
|
||||
run::RunAnimation, shockwave::ShockwaveAnimation, shoot::ShootAnimation,
|
||||
stunned::StunnedAnimation, summon::SummonAnimation, swim::SwimAnimation,
|
||||
};
|
||||
|
||||
use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton};
|
||||
|
@ -93,7 +93,7 @@ use client::Client;
|
||||
use common::{
|
||||
assets::{self, AssetExt, AssetHandle},
|
||||
comp::{
|
||||
beam, biped_large, biped_small, humanoid,
|
||||
beam, biped_large, biped_small, bird_large, humanoid,
|
||||
item::{AbilitySpec, ItemDefinitionId, ItemKind, ToolKind},
|
||||
object,
|
||||
poise::PoiseState,
|
||||
@ -178,9 +178,10 @@ pub enum SfxEvent {
|
||||
Yeet,
|
||||
Klonk,
|
||||
SmashKlonk,
|
||||
Woosh,
|
||||
FireShockwave,
|
||||
DeepLaugh,
|
||||
Whoosh,
|
||||
Swoosh,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Deserialize, Hash, Eq)]
|
||||
@ -213,6 +214,7 @@ pub enum VoiceKind {
|
||||
Fungome,
|
||||
Truffler,
|
||||
Wolf,
|
||||
Wyvern,
|
||||
}
|
||||
|
||||
fn body_to_voice(body: &Body) -> Option<VoiceKind> {
|
||||
@ -261,7 +263,15 @@ fn body_to_voice(body: &Body) -> Option<VoiceKind> {
|
||||
quadruped_medium::Species::Antelope => VoiceKind::Antelope,
|
||||
_ => return None,
|
||||
},
|
||||
Body::BirdMedium(_) | Body::BirdLarge(_) => VoiceKind::Bird,
|
||||
Body::BirdMedium(_) => VoiceKind::Bird,
|
||||
Body::BirdLarge(body) => match body.species {
|
||||
bird_large::Species::CloudWyvern
|
||||
| bird_large::Species::FlameWyvern
|
||||
| bird_large::Species::FrostWyvern
|
||||
| bird_large::Species::SeaWyvern
|
||||
| bird_large::Species::WealdWyvern => VoiceKind::Wyvern,
|
||||
_ => VoiceKind::Bird,
|
||||
},
|
||||
Body::BipedSmall(body) => match body.species {
|
||||
biped_small::Species::Adlet => VoiceKind::Adlet,
|
||||
biped_small::Species::Mandragora => VoiceKind::Mandragora,
|
||||
@ -510,12 +520,16 @@ impl SfxMgr {
|
||||
Body::Object(
|
||||
object::Body::BoltFire
|
||||
| object::Body::BoltFireBig
|
||||
| object::Body::BoltNature,
|
||||
| object::Body::BoltNature
|
||||
| object::Body::BoltIcicle
|
||||
| object::Body::SpearIcicle
|
||||
| object::Body::SpitPoison,
|
||||
) => {
|
||||
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::FireShot);
|
||||
audio.emit_sfx(sfx_trigger_item, *pos, None, underwater);
|
||||
},
|
||||
Body::Object(object::Body::LaserBeam) => {
|
||||
Body::Object(object::Body::LaserBeam)
|
||||
| Body::Object(object::Body::LightningBolt) => {
|
||||
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::LaserBeam);
|
||||
audio.emit_sfx(sfx_trigger_item, *pos, None, underwater);
|
||||
},
|
||||
@ -589,6 +603,10 @@ impl SfxMgr {
|
||||
Outcome::Beam { pos, specifier } => match specifier {
|
||||
beam::FrontendSpecifier::LifestealBeam
|
||||
| beam::FrontendSpecifier::Steam
|
||||
| beam::FrontendSpecifier::Poison
|
||||
| beam::FrontendSpecifier::Ink
|
||||
| beam::FrontendSpecifier::Lightning
|
||||
| beam::FrontendSpecifier::Frost
|
||||
| beam::FrontendSpecifier::Bubbles => {
|
||||
if thread_rng().gen_bool(0.5) {
|
||||
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::SceptreBeam);
|
||||
@ -601,9 +619,7 @@ impl SfxMgr {
|
||||
audio.emit_sfx(sfx_trigger_item, *pos, None, underwater);
|
||||
}
|
||||
},
|
||||
beam::FrontendSpecifier::ClayGolem
|
||||
| beam::FrontendSpecifier::Frost
|
||||
| beam::FrontendSpecifier::WebStrand => {},
|
||||
beam::FrontendSpecifier::ClayGolem | beam::FrontendSpecifier::WebStrand => {},
|
||||
},
|
||||
Outcome::SpriteUnlocked { pos } => {
|
||||
// TODO: Dedicated sound effect!
|
||||
@ -719,8 +735,17 @@ impl SfxMgr {
|
||||
_ => {},
|
||||
};
|
||||
},
|
||||
Outcome::Woosh { pos, .. } => {
|
||||
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Woosh);
|
||||
Outcome::Whoosh { pos, .. } => {
|
||||
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Whoosh);
|
||||
audio.emit_sfx(
|
||||
sfx_trigger_item,
|
||||
pos.map(|e| e + 0.5),
|
||||
Some(3.0),
|
||||
underwater,
|
||||
);
|
||||
},
|
||||
Outcome::Swoosh { pos, .. } => {
|
||||
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Swoosh);
|
||||
audio.emit_sfx(
|
||||
sfx_trigger_item,
|
||||
pos.map(|e| e + 0.5),
|
||||
|
@ -97,6 +97,7 @@ pub enum ParticleMode {
|
||||
CyclopsCharge = 43,
|
||||
SnowStorm = 44,
|
||||
PortalFizz = 45,
|
||||
Ink = 46,
|
||||
}
|
||||
|
||||
impl ParticleMode {
|
||||
|
@ -4944,38 +4944,36 @@ impl FigureMgr {
|
||||
skeleton_attr,
|
||||
)
|
||||
},
|
||||
CharacterState::ComboMelee(s) => {
|
||||
let stage_index = (s.stage - 1) as usize;
|
||||
let stage_time = s.timer.as_secs_f32();
|
||||
let stage_progress =
|
||||
if let Some(stage) = s.static_data.stage_data.get(stage_index) {
|
||||
match s.stage_section {
|
||||
CharacterState::ComboMelee2(s) => {
|
||||
let timer = s.timer.as_secs_f32();
|
||||
let current_strike = s.completed_strikes % s.static_data.strikes.len();
|
||||
let strike_data = s.static_data.strikes[current_strike];
|
||||
let progress = match s.stage_section {
|
||||
StageSection::Buildup => {
|
||||
stage_time / stage.base_buildup_duration.as_secs_f32()
|
||||
timer / strike_data.buildup_duration.as_secs_f32()
|
||||
},
|
||||
StageSection::Action => {
|
||||
stage_time / stage.base_swing_duration.as_secs_f32()
|
||||
timer / strike_data.swing_duration.as_secs_f32()
|
||||
},
|
||||
StageSection::Recover => {
|
||||
stage_time / stage.base_recover_duration.as_secs_f32()
|
||||
timer / strike_data.recover_duration.as_secs_f32()
|
||||
},
|
||||
_ => 0.0,
|
||||
}
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
anim::bird_large::AlphaAnimation::update_skeleton(
|
||||
anim::bird_large::ComboAnimation::update_skeleton(
|
||||
&target_base,
|
||||
(
|
||||
ability_id,
|
||||
Some(s.stage_section),
|
||||
current_strike,
|
||||
time,
|
||||
state.state_time,
|
||||
ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||
state.last_ori * anim::vek::Vec3::<f32>::unit_y(),
|
||||
physics.on_ground.is_some(),
|
||||
),
|
||||
stage_progress,
|
||||
progress,
|
||||
&mut state_animation_rate,
|
||||
skeleton_attr,
|
||||
)
|
||||
|
@ -397,7 +397,8 @@ impl ParticleMgr {
|
||||
| Outcome::IceSpikes { .. }
|
||||
| Outcome::IceCrack { .. }
|
||||
| Outcome::Glider { .. }
|
||||
| Outcome::Woosh { .. }
|
||||
| Outcome::Whoosh { .. }
|
||||
| Outcome::Swoosh { .. }
|
||||
| Outcome::Steam { .. }
|
||||
| Outcome::FireShockwave { .. }
|
||||
| Outcome::LaserBeam { .. } => {},
|
||||
@ -1071,6 +1072,56 @@ impl ParticleMgr {
|
||||
},
|
||||
);
|
||||
},
|
||||
beam::FrontendSpecifier::Poison => {
|
||||
let mut rng = thread_rng();
|
||||
let (from, to) = (Vec3::<f32>::unit_z(), *ori.look_dir());
|
||||
let m = Mat3::<f32>::rotation_from_to_3d(from, to);
|
||||
self.particles.resize_with(
|
||||
self.particles.len() + usize::from(beam_tick_count) / 15,
|
||||
|| {
|
||||
let phi: f32 = rng.gen_range(0.0..beam.properties.angle);
|
||||
let theta: f32 = rng.gen_range(0.0..2.0 * PI);
|
||||
let offset_z = Vec3::new(
|
||||
phi.sin() * theta.cos(),
|
||||
phi.sin() * theta.sin(),
|
||||
phi.cos(),
|
||||
);
|
||||
let random_ori = offset_z * m * Vec3::new(-1.0, -1.0, 1.0);
|
||||
Particle::new_directed(
|
||||
beam.properties.duration,
|
||||
time,
|
||||
ParticleMode::CultistFlame,
|
||||
pos,
|
||||
pos + random_ori * range,
|
||||
)
|
||||
},
|
||||
);
|
||||
},
|
||||
beam::FrontendSpecifier::Ink => {
|
||||
let mut rng = thread_rng();
|
||||
let (from, to) = (Vec3::<f32>::unit_z(), *ori.look_dir());
|
||||
let m = Mat3::<f32>::rotation_from_to_3d(from, to);
|
||||
self.particles.resize_with(
|
||||
self.particles.len() + usize::from(beam_tick_count) / 15,
|
||||
|| {
|
||||
let phi: f32 = rng.gen_range(0.0..beam.properties.angle);
|
||||
let theta: f32 = rng.gen_range(0.0..2.0 * PI);
|
||||
let offset_z = Vec3::new(
|
||||
phi.sin() * theta.cos(),
|
||||
phi.sin() * theta.sin(),
|
||||
phi.cos(),
|
||||
);
|
||||
let random_ori = offset_z * m * Vec3::new(-1.0, -1.0, 1.0);
|
||||
Particle::new_directed(
|
||||
beam.properties.duration,
|
||||
time,
|
||||
ParticleMode::Ink,
|
||||
pos,
|
||||
pos + random_ori * range,
|
||||
)
|
||||
},
|
||||
);
|
||||
},
|
||||
beam::FrontendSpecifier::Steam => {
|
||||
let mut rng = thread_rng();
|
||||
let (from, to) = (Vec3::<f32>::unit_z(), *ori.look_dir());
|
||||
@ -1096,6 +1147,17 @@ impl ParticleMgr {
|
||||
},
|
||||
);
|
||||
},
|
||||
beam::FrontendSpecifier::Lightning => {
|
||||
self.particles.resize_with(self.particles.len() + 2, || {
|
||||
Particle::new_directed(
|
||||
beam.properties.duration,
|
||||
time,
|
||||
ParticleMode::Lightning,
|
||||
pos,
|
||||
pos + *ori.look_dir() * range,
|
||||
)
|
||||
})
|
||||
},
|
||||
beam::FrontendSpecifier::Frost => {
|
||||
let mut rng = thread_rng();
|
||||
let (from, to) = (Vec3::<f32>::unit_z(), *ori.look_dir());
|
||||
@ -1943,6 +2005,41 @@ impl ParticleMgr {
|
||||
}
|
||||
}
|
||||
},
|
||||
FrontendSpecifier::Lightning => {
|
||||
// 1 particle per unit length of arc
|
||||
let particles_per_length = arc_length as usize;
|
||||
let dtheta = radians / particles_per_length as f32;
|
||||
// Scales number of desired heartbeats from speed - thicker arc = higher speed =
|
||||
// lower duration = more particles
|
||||
let heartbeats = self
|
||||
.scheduler
|
||||
.heartbeats(Duration::from_secs_f32(1.0 / speed));
|
||||
|
||||
// Reserves capacity for new particles
|
||||
let new_particle_count = particles_per_length * heartbeats as usize;
|
||||
self.particles.reserve(new_particle_count);
|
||||
|
||||
for i in 0..particles_per_length {
|
||||
let angle = dtheta * i as f32;
|
||||
let direction = Vec3::new(angle.cos(), angle.sin(), 0.0);
|
||||
for j in 0..heartbeats {
|
||||
// Sub tick dt
|
||||
let dt = (j as f32 / heartbeats as f32) * dt;
|
||||
let distance = distance + speed * dt;
|
||||
let pos1 = pos + distance * direction - Vec3::unit_z();
|
||||
let pos2 = pos1 + (Vec3::unit_z() + direction) * 3.0;
|
||||
let time = time + dt as f64;
|
||||
|
||||
self.particles.push(Particle::new_directed(
|
||||
Duration::from_secs_f32(0.5),
|
||||
time,
|
||||
ParticleMode::Lightning,
|
||||
pos1,
|
||||
pos2,
|
||||
));
|
||||
}
|
||||
}
|
||||
},
|
||||
FrontendSpecifier::Steam => {
|
||||
// 1 particle per unit length of arc
|
||||
let particles_per_length = arc_length as usize;
|
||||
@ -1978,7 +2075,77 @@ impl ParticleMgr {
|
||||
}
|
||||
}
|
||||
},
|
||||
FrontendSpecifier::IceSpikes => {
|
||||
FrontendSpecifier::Poison => {
|
||||
// 1 particle per unit length of arc
|
||||
let particles_per_length = arc_length as usize;
|
||||
let dtheta = radians / particles_per_length as f32;
|
||||
// Scales number of desired heartbeats from speed - thicker arc = higher speed =
|
||||
// lower duration = more particles
|
||||
let heartbeats = self
|
||||
.scheduler
|
||||
.heartbeats(Duration::from_secs_f32(1.0 / speed));
|
||||
|
||||
// Reserves capacity for new particles
|
||||
let new_particle_count = particles_per_length * heartbeats as usize;
|
||||
self.particles.reserve(new_particle_count);
|
||||
|
||||
for i in 0..particles_per_length {
|
||||
let angle = dtheta * i as f32;
|
||||
let direction = Vec3::new(angle.cos(), angle.sin(), 0.0);
|
||||
for j in 0..heartbeats {
|
||||
// Sub tick dt
|
||||
let dt = (j as f32 / heartbeats as f32) * dt;
|
||||
let distance = distance + speed * dt;
|
||||
let pos1 = pos + distance * direction - Vec3::unit_z();
|
||||
let pos2 = pos1 + (Vec3::unit_z() + direction) * 3.0;
|
||||
let time = time + dt as f64;
|
||||
|
||||
self.particles.push(Particle::new_directed(
|
||||
Duration::from_secs_f32(0.5),
|
||||
time,
|
||||
ParticleMode::CultistFlame,
|
||||
pos1,
|
||||
pos2,
|
||||
));
|
||||
}
|
||||
}
|
||||
},
|
||||
FrontendSpecifier::Ink => {
|
||||
// 1 particle per unit length of arc
|
||||
let particles_per_length = arc_length as usize;
|
||||
let dtheta = radians / particles_per_length as f32;
|
||||
// Scales number of desired heartbeats from speed - thicker arc = higher speed =
|
||||
// lower duration = more particles
|
||||
let heartbeats = self
|
||||
.scheduler
|
||||
.heartbeats(Duration::from_secs_f32(1.0 / speed));
|
||||
|
||||
// Reserves capacity for new particles
|
||||
let new_particle_count = particles_per_length * heartbeats as usize;
|
||||
self.particles.reserve(new_particle_count);
|
||||
|
||||
for i in 0..particles_per_length {
|
||||
let angle = dtheta * i as f32;
|
||||
let direction = Vec3::new(angle.cos(), angle.sin(), 0.0);
|
||||
for j in 0..heartbeats {
|
||||
// Sub tick dt
|
||||
let dt = (j as f32 / heartbeats as f32) * dt;
|
||||
let distance = distance + speed * dt;
|
||||
let pos1 = pos + distance * direction - Vec3::unit_z();
|
||||
let pos2 = pos1 + (Vec3::unit_z() + direction) * 3.0;
|
||||
let time = time + dt as f64;
|
||||
|
||||
self.particles.push(Particle::new_directed(
|
||||
Duration::from_secs_f32(0.5),
|
||||
time,
|
||||
ParticleMode::Ink,
|
||||
pos1,
|
||||
pos2,
|
||||
));
|
||||
}
|
||||
}
|
||||
},
|
||||
FrontendSpecifier::IceSpikes | FrontendSpecifier::Ice => {
|
||||
// 1 / 3 the size of terrain voxel
|
||||
let scale = 1.0 / 3.0;
|
||||
let scaled_distance = distance / scale;
|
||||
|
Loading…
Reference in New Issue
Block a user