mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'snowram/turret' into 'master'
Object animation, beam fixes, turret implementation See merge request veloren/veloren!1805
This commit is contained in:
commit
14c252d8b2
@ -11,4 +11,5 @@ BasicBeam(
|
|||||||
energy_regen: 25,
|
energy_regen: 25,
|
||||||
energy_cost: 50,
|
energy_cost: 50,
|
||||||
energy_drain: 0,
|
energy_drain: 0,
|
||||||
|
orientation_behavior: Normal,
|
||||||
)
|
)
|
@ -11,4 +11,5 @@ BasicBeam(
|
|||||||
energy_regen: 0,
|
energy_regen: 0,
|
||||||
energy_cost: 1,
|
energy_cost: 1,
|
||||||
energy_drain: 350,
|
energy_drain: 350,
|
||||||
|
orientation_behavior: Normal,
|
||||||
)
|
)
|
@ -11,4 +11,5 @@ BasicBeam(
|
|||||||
energy_regen: 0,
|
energy_regen: 0,
|
||||||
energy_cost: 0,
|
energy_cost: 0,
|
||||||
energy_drain: 0,
|
energy_drain: 0,
|
||||||
|
orientation_behavior: Normal,
|
||||||
)
|
)
|
15
assets/common/abilities/unique/turret/arrows.ron
Normal file
15
assets/common/abilities/unique/turret/arrows.ron
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
BasicRanged(
|
||||||
|
energy_cost: 0,
|
||||||
|
buildup_duration: 1.0,
|
||||||
|
recover_duration: 0.3,
|
||||||
|
projectile: Arrow(
|
||||||
|
damage: 200.0,
|
||||||
|
knockback: 5.0,
|
||||||
|
energy_regen: 100,
|
||||||
|
),
|
||||||
|
projectile_body: Object(ArrowTurret),
|
||||||
|
projectile_light: None,
|
||||||
|
projectile_gravity: Some(Gravity(0.1)),
|
||||||
|
projectile_speed: 100.0,
|
||||||
|
can_continue: true,
|
||||||
|
)
|
15
assets/common/abilities/unique/turret/flamethrower.ron
Normal file
15
assets/common/abilities/unique/turret/flamethrower.ron
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
BasicBeam(
|
||||||
|
buildup_duration: 0.25,
|
||||||
|
recover_duration: 0.25,
|
||||||
|
beam_duration: 0.5,
|
||||||
|
base_hps: 0,
|
||||||
|
base_dps: 9001,
|
||||||
|
tick_rate: 3.0,
|
||||||
|
range: 30.0,
|
||||||
|
max_angle: 1.0,
|
||||||
|
lifesteal_eff: 0.0,
|
||||||
|
energy_regen: 0,
|
||||||
|
energy_cost: 0,
|
||||||
|
energy_drain: 0,
|
||||||
|
orientation_behavior: Turret,
|
||||||
|
)
|
@ -132,6 +132,11 @@
|
|||||||
secondary: "common.abilities.unique.theropodbird.triplestrike",
|
secondary: "common.abilities.unique.theropodbird.triplestrike",
|
||||||
abilities: [],
|
abilities: [],
|
||||||
),
|
),
|
||||||
|
Unique(ObjectTurret): (
|
||||||
|
primary: "common.abilities.unique.turret.arrows",
|
||||||
|
secondary: "common.abilities.unique.turret.arrows",
|
||||||
|
abilities: [],
|
||||||
|
),
|
||||||
Debug: (
|
Debug: (
|
||||||
primary: "common.abilities.debug.forwardboost",
|
primary: "common.abilities.debug.forwardboost",
|
||||||
secondary: "common.abilities.debug.upboost",
|
secondary: "common.abilities.debug.upboost",
|
||||||
|
18
assets/common/items/npc_weapons/unique/turret.ron
Normal file
18
assets/common/items/npc_weapons/unique/turret.ron
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
ItemDef(
|
||||||
|
name: "Turret",
|
||||||
|
description: "Turret weapon",
|
||||||
|
kind: Tool(
|
||||||
|
(
|
||||||
|
kind: Unique(ObjectTurret),
|
||||||
|
hands: Two,
|
||||||
|
stats: Direct((
|
||||||
|
equip_time_millis: 10,
|
||||||
|
power: 1.00,
|
||||||
|
poise_strength: 1.00,
|
||||||
|
speed: 1.00,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
quality: Low,
|
||||||
|
tags: [],
|
||||||
|
)
|
BIN
assets/voxygen/voxel/object/crossbow/bone0.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/object/crossbow/bone0.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/voxygen/voxel/object/crossbow/bone1.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/object/crossbow/bone1.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -3,378 +3,650 @@
|
|||||||
bone0: (
|
bone0: (
|
||||||
offset: (-0.5, -6.0, -1.5),
|
offset: (-0.5, -6.0, -1.5),
|
||||||
central: ("weapon.projectile.simple-arrow"),
|
central: ("weapon.projectile.simple-arrow"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Bomb: (
|
Bomb: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-5.5, -5.5, 0.0),
|
offset: (-5.5, -5.5, 0.0),
|
||||||
central: ("object.bomb"),
|
central: ("object.bomb"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
FireworkBlue: (
|
FireworkBlue: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (0.0, 0.0, 0.0),
|
offset: (0.0, 0.0, 0.0),
|
||||||
central: ("weapon.projectile.fireworks_blue-0"),
|
central: ("weapon.projectile.fireworks_blue-0"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
FireworkGreen: (
|
FireworkGreen: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (0.0, 0.0, 0.0),
|
offset: (0.0, 0.0, 0.0),
|
||||||
central: ("weapon.projectile.fireworks_green-0"),
|
central: ("weapon.projectile.fireworks_green-0"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
FireworkPurple: (
|
FireworkPurple: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (0.0, 0.0, 0.0),
|
offset: (0.0, 0.0, 0.0),
|
||||||
central: ("weapon.projectile.fireworks_purple-0"),
|
central: ("weapon.projectile.fireworks_purple-0"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
FireworkRed: (
|
FireworkRed: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (0.0, 0.0, 0.0),
|
offset: (0.0, 0.0, 0.0),
|
||||||
central: ("weapon.projectile.fireworks_red-0"),
|
central: ("weapon.projectile.fireworks_red-0"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
FireworkYellow: (
|
FireworkYellow: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (0.0, 0.0, 0.0),
|
offset: (0.0, 0.0, 0.0),
|
||||||
central: ("weapon.projectile.fireworks_yellow-0"),
|
central: ("weapon.projectile.fireworks_yellow-0"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Scarecrow: (
|
Scarecrow: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-9.5, -4.0, 0.0),
|
offset: (-9.5, -4.0, 0.0),
|
||||||
central: ("object.scarecrow"),
|
central: ("object.scarecrow"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Cauldron: (
|
Cauldron: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-10.0, -10.0, 0.0),
|
offset: (-10.0, -10.0, 0.0),
|
||||||
central: ("object.cauldron"),
|
central: ("object.cauldron"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
ChestVines: (
|
ChestVines: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-7.5, -6.0, 0.0),
|
offset: (-7.5, -6.0, 0.0),
|
||||||
central: ("object.chest_vines"),
|
central: ("object.chest_vines"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Chest: (
|
Chest: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-7.5, -6.0, 0.0),
|
offset: (-7.5, -6.0, 0.0),
|
||||||
central: ("object.chest"),
|
central: ("object.chest"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
ChestDark: (
|
ChestDark: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-7.5, -6.0, 0.0),
|
offset: (-7.5, -6.0, 0.0),
|
||||||
central: ("object.chest_dark"),
|
central: ("object.chest_dark"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
ChestDemon: (
|
ChestDemon: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-7.5, -6.0, 0.0),
|
offset: (-7.5, -6.0, 0.0),
|
||||||
central: ("object.chest_demon"),
|
central: ("object.chest_demon"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
ChestGold: (
|
ChestGold: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-7.5, -6.0, 0.0),
|
offset: (-7.5, -6.0, 0.0),
|
||||||
central: ("object.chest_gold"),
|
central: ("object.chest_gold"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
ChestLight: (
|
ChestLight: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-7.5, -6.0, 0.0),
|
offset: (-7.5, -6.0, 0.0),
|
||||||
central: ("object.chest_light"),
|
central: ("object.chest_light"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
ChestOpen: (
|
ChestOpen: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-7.5, -6.0, 0.0),
|
offset: (-7.5, -6.0, 0.0),
|
||||||
central: ("object.chest_open"),
|
central: ("object.chest_open"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
ChestSkull: (
|
ChestSkull: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-7.5, -6.0, 0.0),
|
offset: (-7.5, -6.0, 0.0),
|
||||||
central: ("object.chest_skull"),
|
central: ("object.chest_skull"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Pumpkin: (
|
Pumpkin: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-5.5, -4.0, 0.0),
|
offset: (-5.5, -4.0, 0.0),
|
||||||
central: ("object.pumpkin"),
|
central: ("object.pumpkin"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Pumpkin2: (
|
Pumpkin2: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-5.0, -4.0, 0.0),
|
offset: (-5.0, -4.0, 0.0),
|
||||||
central: ("object.pumpkin_2"),
|
central: ("object.pumpkin_2"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Pumpkin3: (
|
Pumpkin3: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-5.0, -4.0, 0.0),
|
offset: (-5.0, -4.0, 0.0),
|
||||||
central: ("object.pumpkin_3"),
|
central: ("object.pumpkin_3"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Pumpkin4: (
|
Pumpkin4: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-5.0, -4.0, 0.0),
|
offset: (-5.0, -4.0, 0.0),
|
||||||
central: ("object.pumpkin_4"),
|
central: ("object.pumpkin_4"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Pumpkin5: (
|
Pumpkin5: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-4.0, -5.0, 0.0),
|
offset: (-4.0, -5.0, 0.0),
|
||||||
central: ("object.pumpkin_5"),
|
central: ("object.pumpkin_5"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Campfire: (
|
Campfire: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-9.0, -10.0, 0.0),
|
offset: (-9.0, -10.0, 0.0),
|
||||||
central: ("object.campfire"),
|
central: ("object.campfire"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
CampfireLit: (
|
CampfireLit: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-9.0, -10.0, 0.0),
|
offset: (-9.0, -10.0, 0.0),
|
||||||
central: ("object.campfire_lit"),
|
central: ("object.campfire_lit"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
LanternGround: (
|
LanternGround: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-3.5, -3.5, 0.0),
|
offset: (-3.5, -3.5, 0.0),
|
||||||
central: ("object.lantern_ground"),
|
central: ("object.lantern_ground"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
LanternGroundOpen: (
|
LanternGroundOpen: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-3.5, -3.5, 0.0),
|
offset: (-3.5, -3.5, 0.0),
|
||||||
central: ("object.lantern_ground_open"),
|
central: ("object.lantern_ground_open"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
LanternStanding: (
|
LanternStanding: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-7.5, -3.5, 0.0),
|
offset: (-7.5, -3.5, 0.0),
|
||||||
central: ("object.lantern_standing"),
|
central: ("object.lantern_standing"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
LanternStanding2: (
|
LanternStanding2: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-11.5, -3.5, 0.0),
|
offset: (-11.5, -3.5, 0.0),
|
||||||
central: ("object.lantern_standing_2"),
|
central: ("object.lantern_standing_2"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
PotionRed: (
|
PotionRed: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-2.0, -2.0, 0.0),
|
offset: (-2.0, -2.0, 0.0),
|
||||||
central: ("object.potion_red"),
|
central: ("object.potion_red"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
PotionBlue: (
|
PotionBlue: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-2.0, -2.0, 0.0),
|
offset: (-2.0, -2.0, 0.0),
|
||||||
central: ("object.potion_blue"),
|
central: ("object.potion_blue"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
PotionGreen: (
|
PotionGreen: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-2.0, -2.0, 0.0),
|
offset: (-2.0, -2.0, 0.0),
|
||||||
central: ("object.potion_green"),
|
central: ("object.potion_green"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Crate: (
|
Crate: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-7.0, -7.0, 0.0),
|
offset: (-7.0, -7.0, 0.0),
|
||||||
central: ("object.crate"),
|
central: ("object.crate"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Tent: (
|
Tent: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-18.5, -19.5, 0.0),
|
offset: (-18.5, -19.5, 0.0),
|
||||||
central: ("object.tent"),
|
central: ("object.tent"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
WindowSpooky: (
|
WindowSpooky: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-15.0, -1.5, -1.0),
|
offset: (-15.0, -1.5, -1.0),
|
||||||
central: ("object.window_spooky"),
|
central: ("object.window_spooky"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
DoorSpooky: (
|
DoorSpooky: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-15.0, -4.5, 0.0),
|
offset: (-15.0, -4.5, 0.0),
|
||||||
central: ("object.door_spooky"),
|
central: ("object.door_spooky"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Table: (
|
Table: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-12.0, -8.0, 0.0),
|
offset: (-12.0, -8.0, 0.0),
|
||||||
central: ("object.table"),
|
central: ("object.table"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Table2: (
|
Table2: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-8.0, -8.0, 0.0),
|
offset: (-8.0, -8.0, 0.0),
|
||||||
central: ("object.table_2"),
|
central: ("object.table_2"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Table3: (
|
Table3: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-10.0, -10.0, 0.0),
|
offset: (-10.0, -10.0, 0.0),
|
||||||
central: ("object.table_3"),
|
central: ("object.table_3"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Drawer: (
|
Drawer: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-11.0, -7.5, 0.0),
|
offset: (-11.0, -7.5, 0.0),
|
||||||
central: ("object.drawer"),
|
central: ("object.drawer"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
BedBlue: (
|
BedBlue: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-11.0, -15.0, 0.0),
|
offset: (-11.0, -15.0, 0.0),
|
||||||
central: ("object.bed_human_blue"),
|
central: ("object.bed_human_blue"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Anvil: (
|
Anvil: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-3.0, -7.0, 0.0),
|
offset: (-3.0, -7.0, 0.0),
|
||||||
central: ("object.anvil"),
|
central: ("object.anvil"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Gravestone: (
|
Gravestone: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-5.0, -2.0, 0.0),
|
offset: (-5.0, -2.0, 0.0),
|
||||||
central: ("object.gravestone"),
|
central: ("object.gravestone"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Gravestone2: (
|
Gravestone2: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-8.5, -3.0, 0.0),
|
offset: (-8.5, -3.0, 0.0),
|
||||||
central: ("object.gravestone_2"),
|
central: ("object.gravestone_2"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Chair: (
|
Chair: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-5.0, -4.5, 0.0),
|
offset: (-5.0, -4.5, 0.0),
|
||||||
central: ("object.chair"),
|
central: ("object.chair"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Chair2: (
|
Chair2: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-5.0, -4.5, 0.0),
|
offset: (-5.0, -4.5, 0.0),
|
||||||
central: ("object.chair_2"),
|
central: ("object.chair_2"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Chair3: (
|
Chair3: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-5.0, -4.5, 0.0),
|
offset: (-5.0, -4.5, 0.0),
|
||||||
central: ("object.chair_3"),
|
central: ("object.chair_3"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Bench: (
|
Bench: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-8.8, -5.0, 0.0),
|
offset: (-8.8, -5.0, 0.0),
|
||||||
central: ("object.bench"),
|
central: ("object.bench"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Carpet: (
|
Carpet: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-14.0, -14.0, -0.5),
|
offset: (-14.0, -14.0, -0.5),
|
||||||
central: ("object.carpet"),
|
central: ("object.carpet"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Bedroll: (
|
Bedroll: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-11.0, -19.5, -0.5),
|
offset: (-11.0, -19.5, -0.5),
|
||||||
central: ("object.bedroll"),
|
central: ("object.bedroll"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
CarpetHumanRound: (
|
CarpetHumanRound: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-14.0, -14.0, -0.5),
|
offset: (-14.0, -14.0, -0.5),
|
||||||
central: ("object.carpet_human_round"),
|
central: ("object.carpet_human_round"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
CarpetHumanSquare: (
|
CarpetHumanSquare: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-13.5, -14.0, -0.5),
|
offset: (-13.5, -14.0, -0.5),
|
||||||
central: ("object.carpet_human_square"),
|
central: ("object.carpet_human_square"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
CarpetHumanSquare2: (
|
CarpetHumanSquare2: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-13.5, -14.0, -0.5),
|
offset: (-13.5, -14.0, -0.5),
|
||||||
central: ("object.carpet_human_square_2"),
|
central: ("object.carpet_human_square_2"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
CarpetHumanSquircle: (
|
CarpetHumanSquircle: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-21.0, -21.0, -0.5),
|
offset: (-21.0, -21.0, -0.5),
|
||||||
central: ("object.carpet_human_squircle"),
|
central: ("object.carpet_human_squircle"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Pouch: (
|
Pouch: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-5.5, -4.5, 0.0),
|
offset: (-5.5, -4.5, 0.0),
|
||||||
central: ("object.pouch"),
|
central: ("object.pouch"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
CraftingBench: (
|
CraftingBench: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-9.5, -7.0, 0.0),
|
offset: (-9.5, -7.0, 0.0),
|
||||||
central: ("object.crafting_bench"),
|
central: ("object.crafting_bench"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
ArrowSnake: (
|
ArrowSnake: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-1.5, -6.5, 0.0),
|
offset: (-1.5, -6.5, 0.0),
|
||||||
central: ("weapon.projectile.snake-arrow"),
|
central: ("weapon.projectile.snake-arrow"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
BoltFire: (
|
BoltFire: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-3.0, -5.5, -3.0),
|
offset: (-3.0, -5.5, -3.0),
|
||||||
central: ("weapon.projectile.fire-bolt-0"),
|
central: ("weapon.projectile.fire-bolt-0"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
BoltFireBig: (
|
BoltFireBig: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-6.0, -6.0, -6.0),
|
offset: (-6.0, -6.0, -6.0),
|
||||||
central: ("weapon.projectile.fire-bolt-1"),
|
central: ("weapon.projectile.fire-bolt-1"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
TrainingDummy: (
|
TrainingDummy: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-7.0, -5.0, 0.0),
|
offset: (-7.0, -5.0, 0.0),
|
||||||
central: ("object.training_dummy"),
|
central: ("object.training_dummy"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
MultiArrow: (
|
MultiArrow: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-4.0, -9.5, -5.0),
|
offset: (-4.0, -9.5, -5.0),
|
||||||
central: ("weapon.projectile.multi-arrow"),
|
central: ("weapon.projectile.multi-arrow"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
BoltNature: (
|
BoltNature: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-6.0, -6.0, -6.0),
|
offset: (-6.0, -6.0, -6.0),
|
||||||
central: ("weapon.projectile.nature-bolt"),
|
central: ("weapon.projectile.nature-bolt"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
MeatDrop: (
|
MeatDrop: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-3.5, -8.0, 0.0),
|
offset: (-3.5, -8.0, 0.0),
|
||||||
central: ("object.meat_drop"),
|
central: ("object.meat_drop"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Steak: (
|
Steak: (
|
||||||
bone0: (
|
bone0: (
|
||||||
offset: (-3.5, -6.0, 0.0),
|
offset: (-3.5, -6.0, 0.0),
|
||||||
central: ("object.steak"),
|
central: ("object.steak"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Crossbow: (
|
||||||
|
bone0: (
|
||||||
|
offset: (-18.0, -15.5, -8.0),
|
||||||
|
central: ("object.crossbow.bone0"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (-9.0, -7.0, -5.0 ),
|
||||||
|
central: ("object.crossbow.bone1"),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
ArrowTurret: (
|
||||||
|
bone0: (
|
||||||
|
offset: (-1.5, -6.5, -1.5),
|
||||||
|
central: ("weapon.projectile.turret-arrow"),
|
||||||
|
),
|
||||||
|
bone1: (
|
||||||
|
offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("armor.empty"),
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
})
|
})
|
BIN
assets/voxygen/voxel/weapon/projectile/turret-arrow.vox
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/voxel/weapon/projectile/turret-arrow.vox
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -225,6 +225,7 @@ pub enum CharacterAbility {
|
|||||||
energy_regen: f32,
|
energy_regen: f32,
|
||||||
energy_cost: f32,
|
energy_cost: f32,
|
||||||
energy_drain: f32,
|
energy_drain: f32,
|
||||||
|
orientation_behavior: basic_beam::MovementBehavior,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1445,6 +1446,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
|
|||||||
energy_regen,
|
energy_regen,
|
||||||
energy_cost,
|
energy_cost,
|
||||||
energy_drain,
|
energy_drain,
|
||||||
|
orientation_behavior,
|
||||||
} => CharacterState::BasicBeam(basic_beam::Data {
|
} => CharacterState::BasicBeam(basic_beam::Data {
|
||||||
static_data: basic_beam::StaticData {
|
static_data: basic_beam::StaticData {
|
||||||
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
buildup_duration: Duration::from_secs_f32(*buildup_duration),
|
||||||
@ -1460,10 +1462,10 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
|
|||||||
energy_cost: *energy_cost,
|
energy_cost: *energy_cost,
|
||||||
energy_drain: *energy_drain,
|
energy_drain: *energy_drain,
|
||||||
ability_info,
|
ability_info,
|
||||||
|
orientation_behavior: *orientation_behavior,
|
||||||
},
|
},
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
stage_section: StageSection::Buildup,
|
stage_section: StageSection::Buildup,
|
||||||
particle_ori: None::<Vec3<f32>>,
|
|
||||||
offset: Vec3::zero(),
|
offset: Vec3::zero(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,9 @@ pub enum Tactic {
|
|||||||
QuadMedBasic,
|
QuadMedBasic,
|
||||||
Lavadrake,
|
Lavadrake,
|
||||||
Theropod,
|
Theropod,
|
||||||
|
Turret,
|
||||||
|
FixedTurret,
|
||||||
|
RotatingTurret,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
@ -262,7 +262,10 @@ impl Body {
|
|||||||
_ => 4.6,
|
_ => 4.6,
|
||||||
},
|
},
|
||||||
Body::Golem(_) => 5.0,
|
Body::Golem(_) => 5.0,
|
||||||
Body::Object(_) => 1.0,
|
Body::Object(object) => match object {
|
||||||
|
object::Body::Crossbow => 1.7,
|
||||||
|
_ => 1.0,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,7 +339,11 @@ impl Body {
|
|||||||
biped_large::Species::Mindflayer => 8000,
|
biped_large::Species::Mindflayer => 8000,
|
||||||
_ => 1000,
|
_ => 1000,
|
||||||
},
|
},
|
||||||
Body::Object(_) => 10000,
|
Body::Object(object) => match object {
|
||||||
|
object::Body::TrainingDummy => 10000,
|
||||||
|
object::Body::Crossbow => 800,
|
||||||
|
_ => 10000,
|
||||||
|
},
|
||||||
Body::Golem(_) => 2740,
|
Body::Golem(_) => 2740,
|
||||||
Body::Theropod(theropod) => match theropod.species {
|
Body::Theropod(theropod) => match theropod.species {
|
||||||
theropod::Species::Archaeos => 3000,
|
theropod::Species::Archaeos => 3000,
|
||||||
|
@ -70,6 +70,8 @@ make_case_elim!(
|
|||||||
BoltNature = 60,
|
BoltNature = 60,
|
||||||
MeatDrop = 61,
|
MeatDrop = 61,
|
||||||
Steak = 62,
|
Steak = 62,
|
||||||
|
Crossbow = 63,
|
||||||
|
ArrowTurret = 64,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -80,7 +82,7 @@ impl Body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ALL_OBJECTS: [Body; 63] = [
|
pub const ALL_OBJECTS: [Body; 65] = [
|
||||||
Body::Arrow,
|
Body::Arrow,
|
||||||
Body::Bomb,
|
Body::Bomb,
|
||||||
Body::Scarecrow,
|
Body::Scarecrow,
|
||||||
@ -144,6 +146,8 @@ pub const ALL_OBJECTS: [Body; 63] = [
|
|||||||
Body::BoltNature,
|
Body::BoltNature,
|
||||||
Body::MeatDrop,
|
Body::MeatDrop,
|
||||||
Body::Steak,
|
Body::Steak,
|
||||||
|
Body::Crossbow,
|
||||||
|
Body::ArrowTurret,
|
||||||
];
|
];
|
||||||
|
|
||||||
impl From<Body> for super::Body {
|
impl From<Body> for super::Body {
|
||||||
@ -216,6 +220,8 @@ impl Body {
|
|||||||
Body::BoltNature => "bolt_nature",
|
Body::BoltNature => "bolt_nature",
|
||||||
Body::MeatDrop => "meat_drop",
|
Body::MeatDrop => "meat_drop",
|
||||||
Body::Steak => "steak",
|
Body::Steak => "steak",
|
||||||
|
Body::Crossbow => "crossbow",
|
||||||
|
Body::ArrowTurret => "arrow_turret",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,4 +295,5 @@ pub enum UniqueKind {
|
|||||||
QuadSmallBasic,
|
QuadSmallBasic,
|
||||||
TheropodBasic,
|
TheropodBasic,
|
||||||
TheropodBird,
|
TheropodBird,
|
||||||
|
ObjectTurret,
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use crate::comp::{
|
|||||||
slot::{ArmorSlot, EquipSlot},
|
slot::{ArmorSlot, EquipSlot},
|
||||||
},
|
},
|
||||||
item::{Item, ItemKind},
|
item::{Item, ItemKind},
|
||||||
quadruped_low, quadruped_medium, theropod, Body,
|
object, quadruped_low, quadruped_medium, theropod, Body,
|
||||||
};
|
};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
@ -227,6 +227,11 @@ impl LoadoutBuilder {
|
|||||||
));
|
));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Body::Object(object::Body::Crossbow) => {
|
||||||
|
main_tool = Some(Item::new_from_asset_expect(
|
||||||
|
"common.items.npc_weapons.unique.turret",
|
||||||
|
));
|
||||||
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use vek::Vec3;
|
use vek::*;
|
||||||
|
|
||||||
/// Separated out to condense update portions of character state
|
/// Separated out to condense update portions of character state
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
@ -43,6 +43,8 @@ pub struct StaticData {
|
|||||||
pub energy_cost: f32,
|
pub energy_cost: f32,
|
||||||
/// Energy drained per
|
/// Energy drained per
|
||||||
pub energy_drain: f32,
|
pub energy_drain: f32,
|
||||||
|
/// Used to dictate how orientation functions in this state
|
||||||
|
pub orientation_behavior: MovementBehavior,
|
||||||
/// What key is used to press ability
|
/// What key is used to press ability
|
||||||
pub ability_info: AbilityInfo,
|
pub ability_info: AbilityInfo,
|
||||||
}
|
}
|
||||||
@ -56,8 +58,6 @@ pub struct Data {
|
|||||||
pub timer: Duration,
|
pub timer: Duration,
|
||||||
/// What section the character stage is in
|
/// What section the character stage is in
|
||||||
pub stage_section: StageSection,
|
pub stage_section: StageSection,
|
||||||
/// Used for particle stuffs
|
|
||||||
pub particle_ori: Option<Vec3<f32>>,
|
|
||||||
/// Used to offset beam and particles
|
/// Used to offset beam and particles
|
||||||
pub offset: Vec3<f32>,
|
pub offset: Vec3<f32>,
|
||||||
}
|
}
|
||||||
@ -66,6 +66,13 @@ impl CharacterBehavior for Data {
|
|||||||
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
||||||
let mut update = StateUpdate::from(data);
|
let mut update = StateUpdate::from(data);
|
||||||
|
|
||||||
|
match self.static_data.orientation_behavior {
|
||||||
|
MovementBehavior::Normal => {},
|
||||||
|
MovementBehavior::Turret => {
|
||||||
|
update.ori = Ori::from(data.inputs.look_dir);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
handle_move(data, &mut update, 0.4);
|
handle_move(data, &mut update, 0.4);
|
||||||
handle_jump(data, &mut update);
|
handle_jump(data, &mut update);
|
||||||
if !ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
if !ability_key_is_pressed(data, self.static_data.ability_info.key) {
|
||||||
@ -87,7 +94,6 @@ impl CharacterBehavior for Data {
|
|||||||
.timer
|
.timer
|
||||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
particle_ori: Some(*data.inputs.look_dir),
|
|
||||||
..*self
|
..*self
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -107,7 +113,6 @@ impl CharacterBehavior for Data {
|
|||||||
update.character = CharacterState::BasicBeam(Data {
|
update.character = CharacterState::BasicBeam(Data {
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
stage_section: StageSection::Cast,
|
stage_section: StageSection::Cast,
|
||||||
particle_ori: Some(*data.inputs.look_dir),
|
|
||||||
offset: body_offsets,
|
offset: body_offsets,
|
||||||
..*self
|
..*self
|
||||||
});
|
});
|
||||||
@ -185,7 +190,6 @@ impl CharacterBehavior for Data {
|
|||||||
.timer
|
.timer
|
||||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
particle_ori: Some(*data.inputs.look_dir),
|
|
||||||
offset: body_offsets,
|
offset: body_offsets,
|
||||||
..*self
|
..*self
|
||||||
});
|
});
|
||||||
@ -199,7 +203,6 @@ impl CharacterBehavior for Data {
|
|||||||
update.character = CharacterState::BasicBeam(Data {
|
update.character = CharacterState::BasicBeam(Data {
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
stage_section: StageSection::Recover,
|
stage_section: StageSection::Recover,
|
||||||
particle_ori: Some(*data.inputs.look_dir),
|
|
||||||
..*self
|
..*self
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -211,7 +214,6 @@ impl CharacterBehavior for Data {
|
|||||||
.timer
|
.timer
|
||||||
.checked_add(Duration::from_secs_f32(data.dt.0))
|
.checked_add(Duration::from_secs_f32(data.dt.0))
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
particle_ori: Some(*data.inputs.look_dir),
|
|
||||||
..*self
|
..*self
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -232,3 +234,9 @@ impl CharacterBehavior for Data {
|
|||||||
update
|
update
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum MovementBehavior {
|
||||||
|
Normal,
|
||||||
|
Turret,
|
||||||
|
}
|
||||||
|
@ -66,7 +66,7 @@ impl Body {
|
|||||||
Body::BirdSmall(_) => 75.0,
|
Body::BirdSmall(_) => 75.0,
|
||||||
Body::FishSmall(_) => 60.0,
|
Body::FishSmall(_) => 60.0,
|
||||||
Body::BipedLarge(_) => 75.0,
|
Body::BipedLarge(_) => 75.0,
|
||||||
Body::Object(_) => 40.0,
|
Body::Object(_) => 0.0,
|
||||||
Body::Golem(_) => 60.0,
|
Body::Golem(_) => 60.0,
|
||||||
Body::Theropod(_) => 135.0,
|
Body::Theropod(_) => 135.0,
|
||||||
Body::QuadrupedLow(quadruped_low) => match quadruped_low.species {
|
Body::QuadrupedLow(quadruped_low) => match quadruped_low.species {
|
||||||
@ -116,7 +116,7 @@ impl Body {
|
|||||||
Body::BirdSmall(_) => 35.0,
|
Body::BirdSmall(_) => 35.0,
|
||||||
Body::FishSmall(_) => 10.0,
|
Body::FishSmall(_) => 10.0,
|
||||||
Body::BipedLarge(_) => 12.0,
|
Body::BipedLarge(_) => 12.0,
|
||||||
Body::Object(_) => 5.0,
|
Body::Object(_) => 10.0,
|
||||||
Body::Golem(_) => 8.0,
|
Body::Golem(_) => 8.0,
|
||||||
Body::Theropod(theropod) => match theropod.species {
|
Body::Theropod(theropod) => match theropod.species {
|
||||||
theropod::Species::Archaeos => 2.5,
|
theropod::Species::Archaeos => 2.5,
|
||||||
|
@ -533,6 +533,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
Some(ToolKind::Unique(UniqueKind::QuadLowBreathe)) => Tactic::Lavadrake,
|
Some(ToolKind::Unique(UniqueKind::QuadLowBreathe)) => Tactic::Lavadrake,
|
||||||
Some(ToolKind::Unique(UniqueKind::TheropodBasic)) => Tactic::Theropod,
|
Some(ToolKind::Unique(UniqueKind::TheropodBasic)) => Tactic::Theropod,
|
||||||
Some(ToolKind::Unique(UniqueKind::TheropodBird)) => Tactic::Theropod,
|
Some(ToolKind::Unique(UniqueKind::TheropodBird)) => Tactic::Theropod,
|
||||||
|
Some(ToolKind::Unique(UniqueKind::ObjectTurret)) => Tactic::Turret,
|
||||||
_ => Tactic::Melee,
|
_ => Tactic::Melee,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1437,6 +1438,38 @@ impl<'a> System<'a> for Sys {
|
|||||||
do_idle = true;
|
do_idle = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Tactic::Turret => {
|
||||||
|
if can_see_tgt(&*terrain, pos, tgt_pos, dist_sqrd)
|
||||||
|
{
|
||||||
|
inputs.primary.set_state(true);
|
||||||
|
} else {
|
||||||
|
do_idle = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Tactic::FixedTurret => {
|
||||||
|
inputs.look_dir = ori.look_dir();
|
||||||
|
if can_see_tgt(&*terrain, pos, tgt_pos, dist_sqrd)
|
||||||
|
{
|
||||||
|
inputs.primary.set_state(true);
|
||||||
|
} else {
|
||||||
|
do_idle = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Tactic::RotatingTurret => {
|
||||||
|
inputs.look_dir = Dir::new(
|
||||||
|
Quaternion::from_xyzw(ori.look_dir().x, ori.look_dir().y, 0.0, 0.0)
|
||||||
|
.rotated_z(6.0 * dt.0 as f32)
|
||||||
|
.into_vec3()
|
||||||
|
.try_normalized()
|
||||||
|
.unwrap_or_default(),
|
||||||
|
);
|
||||||
|
if can_see_tgt(&*terrain, pos, tgt_pos, dist_sqrd)
|
||||||
|
{
|
||||||
|
inputs.primary.set_state(true);
|
||||||
|
} else {
|
||||||
|
do_idle = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
do_idle = true;
|
do_idle = true;
|
||||||
|
@ -159,11 +159,7 @@ impl Animation for RunAnimation {
|
|||||||
Quaternion::rotation_x(0.6 * speednorm + (footrotr * -1.2) * speednorm)
|
Quaternion::rotation_x(0.6 * speednorm + (footrotr * -1.2) * speednorm)
|
||||||
* Quaternion::rotation_y(footrotr * 0.4 * speednorm);
|
* Quaternion::rotation_y(footrotr * 0.4 * speednorm);
|
||||||
|
|
||||||
next.hand_r.position = Vec3::new(
|
next.hand_r.position = -next.hand_l.position;
|
||||||
s_a.hand.0 + foothoril * 1.3 * speednorm,
|
|
||||||
3.0 * speednorm + s_a.hand.1 + foothoril * -7.0 * speednorm,
|
|
||||||
1.5 * speednorm + s_a.hand.2 - foothoril * 5.5 * speednorm,
|
|
||||||
);
|
|
||||||
next.hand_r.orientation =
|
next.hand_r.orientation =
|
||||||
Quaternion::rotation_x(0.6 * speednorm + (footrotl * -1.2) * speednorm)
|
Quaternion::rotation_x(0.6 * speednorm + (footrotl * -1.2) * speednorm)
|
||||||
* Quaternion::rotation_y(footrotl * -0.4 * speednorm);
|
* Quaternion::rotation_y(footrotl * -0.4 * speednorm);
|
||||||
|
45
voxygen/anim/src/object/beam.rs
Normal file
45
voxygen/anim/src/object/beam.rs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
use super::{
|
||||||
|
super::{vek::*, Animation},
|
||||||
|
ObjectSkeleton, SkeletonAttr,
|
||||||
|
};
|
||||||
|
use common::{
|
||||||
|
comp::{item::ToolKind, object::Body},
|
||||||
|
states::utils::StageSection,
|
||||||
|
};
|
||||||
|
pub struct BeamAnimation;
|
||||||
|
|
||||||
|
type BeamAnimationDependency = (
|
||||||
|
Option<ToolKind>,
|
||||||
|
Option<ToolKind>,
|
||||||
|
Option<StageSection>,
|
||||||
|
Body,
|
||||||
|
);
|
||||||
|
impl Animation for BeamAnimation {
|
||||||
|
type Dependency = BeamAnimationDependency;
|
||||||
|
type Skeleton = ObjectSkeleton;
|
||||||
|
|
||||||
|
#[cfg(feature = "use-dyn-lib")]
|
||||||
|
const UPDATE_FN: &'static [u8] = b"object_beam\0";
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "be-dyn-lib", export_name = "object_beam")]
|
||||||
|
#[allow(clippy::approx_constant)] // TODO: Pending review in #587
|
||||||
|
fn update_skeleton_inner(
|
||||||
|
skeleton: &Self::Skeleton,
|
||||||
|
(_active_tool_kind, _second_tool_kind, _stage_section, _body): Self::Dependency,
|
||||||
|
_anim_time: f64,
|
||||||
|
rate: &mut f32,
|
||||||
|
s_a: &SkeletonAttr,
|
||||||
|
) -> Self::Skeleton {
|
||||||
|
*rate = 1.0;
|
||||||
|
|
||||||
|
let mut next = (*skeleton).clone();
|
||||||
|
|
||||||
|
next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2) / 11.0;
|
||||||
|
next.bone0.orientation = Quaternion::rotation_z(0.0);
|
||||||
|
|
||||||
|
next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2) / 11.0;
|
||||||
|
next.bone1.orientation = Quaternion::rotation_z(0.0);
|
||||||
|
|
||||||
|
next
|
||||||
|
}
|
||||||
|
}
|
33
voxygen/anim/src/object/idle.rs
Normal file
33
voxygen/anim/src/object/idle.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
use super::{
|
||||||
|
super::{vek::*, Animation},
|
||||||
|
ObjectSkeleton, SkeletonAttr,
|
||||||
|
};
|
||||||
|
use common::comp::item::ToolKind;
|
||||||
|
|
||||||
|
pub struct IdleAnimation;
|
||||||
|
|
||||||
|
impl Animation for IdleAnimation {
|
||||||
|
type Dependency = (Option<ToolKind>, Option<ToolKind>, f64);
|
||||||
|
type Skeleton = ObjectSkeleton;
|
||||||
|
|
||||||
|
#[cfg(feature = "use-dyn-lib")]
|
||||||
|
const UPDATE_FN: &'static [u8] = b"object_idle\0";
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "be-dyn-lib", export_name = "object_idle")]
|
||||||
|
#[allow(clippy::approx_constant)] // TODO: Pending review in #587
|
||||||
|
fn update_skeleton_inner(
|
||||||
|
skeleton: &Self::Skeleton,
|
||||||
|
(_active_tool_kind, _second_tool_kind, _global_time): Self::Dependency,
|
||||||
|
_anim_time: f64,
|
||||||
|
_rate: &mut f32,
|
||||||
|
s_a: &SkeletonAttr,
|
||||||
|
) -> Self::Skeleton {
|
||||||
|
let mut next = (*skeleton).clone();
|
||||||
|
|
||||||
|
next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2) / 11.0;
|
||||||
|
|
||||||
|
next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2) / 11.0;
|
||||||
|
|
||||||
|
next
|
||||||
|
}
|
||||||
|
}
|
@ -1,30 +1,26 @@
|
|||||||
|
pub mod beam;
|
||||||
|
pub mod idle;
|
||||||
|
pub mod shoot;
|
||||||
|
|
||||||
|
// Reexports
|
||||||
|
pub use self::{beam::BeamAnimation, idle::IdleAnimation, shoot::ShootAnimation};
|
||||||
|
|
||||||
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
use super::{make_bone, vek::*, FigureBoneData, Skeleton};
|
||||||
use common::comp::{self};
|
use common::comp::{self};
|
||||||
|
use core::convert::TryFrom;
|
||||||
|
|
||||||
pub type Body = comp::object::Body;
|
pub type Body = comp::object::Body;
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
skeleton_impls!(struct ObjectSkeleton {
|
||||||
pub struct ObjectSkeleton;
|
+ bone0,
|
||||||
|
+ bone1,
|
||||||
impl<'a, Factor> Lerp<Factor> for &'a ObjectSkeleton {
|
});
|
||||||
type Output = ObjectSkeleton;
|
|
||||||
|
|
||||||
fn lerp_unclamped_precise(_from: Self, _to: Self, _factor: Factor) -> Self::Output {
|
|
||||||
ObjectSkeleton
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lerp_unclamped(_from: Self, _to: Self, _factor: Factor) -> Self::Output { ObjectSkeleton }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SkeletonAttr;
|
|
||||||
|
|
||||||
const SCALE: f32 = 1.0 / 11.0;
|
|
||||||
|
|
||||||
impl Skeleton for ObjectSkeleton {
|
impl Skeleton for ObjectSkeleton {
|
||||||
type Attr = SkeletonAttr;
|
type Attr = SkeletonAttr;
|
||||||
type Body = Body;
|
type Body = Body;
|
||||||
|
|
||||||
const BONE_COUNT: usize = 1;
|
const BONE_COUNT: usize = 2;
|
||||||
#[cfg(feature = "use-dyn-lib")]
|
#[cfg(feature = "use-dyn-lib")]
|
||||||
const COMPUTE_FN: &'static [u8] = b"object_compute_mats\0";
|
const COMPUTE_FN: &'static [u8] = b"object_compute_mats\0";
|
||||||
|
|
||||||
@ -34,17 +30,53 @@ impl Skeleton for ObjectSkeleton {
|
|||||||
base_mat: Mat4<f32>,
|
base_mat: Mat4<f32>,
|
||||||
buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
|
buf: &mut [FigureBoneData; super::MAX_BONE_COUNT],
|
||||||
) -> Vec3<f32> {
|
) -> Vec3<f32> {
|
||||||
buf[0] = make_bone(base_mat * Mat4::scaling_3d(SCALE));
|
let bone0_mat = base_mat * Mat4::<f32>::from(self.bone0);
|
||||||
// TODO: Make dependent on bone, when we find an easier way to make that
|
|
||||||
// information available.
|
*(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
|
||||||
Vec3::unit_z() * 0.5
|
make_bone(bone0_mat * Mat4::scaling_3d(1.0 / 11.0)),
|
||||||
|
make_bone(Mat4::<f32>::from(self.bone1) * Mat4::scaling_3d(1.0 / 11.0)), /* Decorellated from ori */
|
||||||
|
];
|
||||||
|
Vec3::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct SkeletonAttr {
|
||||||
|
bone0: (f32, f32, f32),
|
||||||
|
bone1: (f32, f32, f32),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
fn try_from(body: &'a comp::Body) -> Result<Self, Self::Error> {
|
||||||
|
match body {
|
||||||
|
comp::Body::Object(body) => Ok(SkeletonAttr::from(body)),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SkeletonAttr {
|
impl Default for SkeletonAttr {
|
||||||
fn default() -> Self { Self }
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
bone0: (0.0, 0.0, 0.0),
|
||||||
|
bone1: (0.0, 0.0, 0.0),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||||
fn from(_body: &'a Body) -> Self { Self }
|
fn from(body: &'a Body) -> Self {
|
||||||
|
use comp::object::Body::*;
|
||||||
|
Self {
|
||||||
|
bone0: match body {
|
||||||
|
Crossbow => (0.0, 0.0, 14.0),
|
||||||
|
_ => (0.0, 0.0, 0.0),
|
||||||
|
},
|
||||||
|
bone1: match body {
|
||||||
|
Crossbow => (0.0, 0.0, 8.0),
|
||||||
|
_ => (0.0, 0.0, 0.0),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
62
voxygen/anim/src/object/shoot.rs
Normal file
62
voxygen/anim/src/object/shoot.rs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
use super::{
|
||||||
|
super::{vek::*, Animation},
|
||||||
|
ObjectSkeleton, SkeletonAttr,
|
||||||
|
};
|
||||||
|
use common::{
|
||||||
|
comp::{item::ToolKind, object::Body},
|
||||||
|
states::utils::StageSection,
|
||||||
|
};
|
||||||
|
pub struct ShootAnimation;
|
||||||
|
|
||||||
|
type ShootAnimationDependency = (
|
||||||
|
Option<ToolKind>,
|
||||||
|
Option<ToolKind>,
|
||||||
|
Option<StageSection>,
|
||||||
|
Body,
|
||||||
|
);
|
||||||
|
impl Animation for ShootAnimation {
|
||||||
|
type Dependency = ShootAnimationDependency;
|
||||||
|
type Skeleton = ObjectSkeleton;
|
||||||
|
|
||||||
|
#[cfg(feature = "use-dyn-lib")]
|
||||||
|
const UPDATE_FN: &'static [u8] = b"object_shoot\0";
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "be-dyn-lib", export_name = "object_shoot")]
|
||||||
|
#[allow(clippy::approx_constant)] // TODO: Pending review in #587
|
||||||
|
fn update_skeleton_inner(
|
||||||
|
skeleton: &Self::Skeleton,
|
||||||
|
(_active_tool_kind, _second_tool_kind, stage_section, body): Self::Dependency,
|
||||||
|
anim_time: f64,
|
||||||
|
rate: &mut f32,
|
||||||
|
s_a: &SkeletonAttr,
|
||||||
|
) -> Self::Skeleton {
|
||||||
|
*rate = 1.0;
|
||||||
|
|
||||||
|
let mut next = (*skeleton).clone();
|
||||||
|
|
||||||
|
let (movement1, movement2, movement3) = match stage_section {
|
||||||
|
Some(StageSection::Buildup) => (anim_time as f32, 0.0, 0.0),
|
||||||
|
Some(StageSection::Swing) => (1.0, (anim_time as f32).powf(0.25), 0.0),
|
||||||
|
Some(StageSection::Recover) => (1.0, 1.0, anim_time as f32),
|
||||||
|
_ => (0.0, 0.0, 0.0),
|
||||||
|
};
|
||||||
|
|
||||||
|
next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2) / 11.0;
|
||||||
|
next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2) / 11.0;
|
||||||
|
|
||||||
|
#[allow(clippy::single_match)]
|
||||||
|
match body {
|
||||||
|
Body::Crossbow => {
|
||||||
|
next.bone0.position = Vec3::new(s_a.bone0.0, s_a.bone0.1, s_a.bone0.2) / 11.0;
|
||||||
|
next.bone0.orientation =
|
||||||
|
Quaternion::rotation_x(movement1 * 0.05 + movement2 * 0.1) * (1.0 - movement3);
|
||||||
|
|
||||||
|
next.bone1.position = Vec3::new(s_a.bone1.0, s_a.bone1.1, s_a.bone1.2) / 11.0;
|
||||||
|
next.bone1.orientation = Quaternion::rotation_z(0.0);
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
next
|
||||||
|
}
|
||||||
|
}
|
@ -317,7 +317,10 @@ impl SfxMgr {
|
|||||||
// TODO: from sfx config?
|
// TODO: from sfx config?
|
||||||
match body {
|
match body {
|
||||||
Body::Object(
|
Body::Object(
|
||||||
object::Body::Arrow | object::Body::MultiArrow | object::Body::ArrowSnake,
|
object::Body::Arrow
|
||||||
|
| object::Body::MultiArrow
|
||||||
|
| object::Body::ArrowSnake
|
||||||
|
| object::Body::ArrowTurret,
|
||||||
) => {
|
) => {
|
||||||
let file_ref = vec![
|
let file_ref = vec![
|
||||||
"voxygen.audio.sfx.abilities.arrow_shot_1",
|
"voxygen.audio.sfx.abilities.arrow_shot_1",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::ecs::comp::Interpolated;
|
use crate::ecs::comp::Interpolated;
|
||||||
use common::{
|
use common::{
|
||||||
comp::{Ori, Pos, Vel},
|
comp::{object, Body, Ori, Pos, Vel},
|
||||||
resources::DeltaTime,
|
resources::DeltaTime,
|
||||||
};
|
};
|
||||||
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
|
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
|
||||||
@ -17,20 +17,28 @@ impl<'a> System<'a> for Sys {
|
|||||||
ReadStorage<'a, Pos>,
|
ReadStorage<'a, Pos>,
|
||||||
ReadStorage<'a, Ori>,
|
ReadStorage<'a, Ori>,
|
||||||
ReadStorage<'a, Vel>,
|
ReadStorage<'a, Vel>,
|
||||||
|
ReadStorage<'a, Body>,
|
||||||
WriteStorage<'a, Interpolated>,
|
WriteStorage<'a, Interpolated>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
&mut self,
|
&mut self,
|
||||||
(entities, dt, positions, orientations, velocities, mut interpolated): Self::SystemData,
|
(entities, dt, positions, orientations, velocities, bodies, mut interpolated): Self::SystemData,
|
||||||
) {
|
) {
|
||||||
// Update interpolated positions and orientations
|
// Update interpolated positions and orientations
|
||||||
for (pos, ori, i, vel) in (&positions, &orientations, &mut interpolated, &velocities).join()
|
for (pos, ori, i, body, vel) in (
|
||||||
|
&positions,
|
||||||
|
&orientations,
|
||||||
|
&mut interpolated,
|
||||||
|
&bodies,
|
||||||
|
&velocities,
|
||||||
|
)
|
||||||
|
.join()
|
||||||
{
|
{
|
||||||
// Update interpolation values
|
// Update interpolation values
|
||||||
if i.pos.distance_squared(pos.0) < 64.0 * 64.0 {
|
if i.pos.distance_squared(pos.0) < 64.0 * 64.0 {
|
||||||
i.pos = Lerp::lerp(i.pos, pos.0 + vel.0 * 0.03, 10.0 * dt.0);
|
i.pos = Lerp::lerp(i.pos, pos.0 + vel.0 * 0.03, 10.0 * dt.0);
|
||||||
i.ori = Ori::slerp(i.ori, *ori, 5.0 * dt.0);
|
i.ori = Ori::slerp(i.ori, *ori, base_ori_interp(body) * dt.0);
|
||||||
} else {
|
} else {
|
||||||
i.pos = pos.0;
|
i.pos = pos.0;
|
||||||
i.ori = *ori;
|
i.ori = *ori;
|
||||||
@ -72,3 +80,14 @@ impl<'a> System<'a> for Sys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::collapsible_match)]
|
||||||
|
fn base_ori_interp(body: &Body) -> f32 {
|
||||||
|
match body {
|
||||||
|
Body::Object(object) => match object {
|
||||||
|
object::Body::Crossbow => 100.0,
|
||||||
|
_ => 10.0,
|
||||||
|
},
|
||||||
|
_ => 10.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3801,6 +3801,7 @@ struct ObjectCentralSpec(HashMap<object::Body, SidedObjectCentralVoxSpec>);
|
|||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct SidedObjectCentralVoxSpec {
|
struct SidedObjectCentralVoxSpec {
|
||||||
bone0: ObjectCentralSubSpec,
|
bone0: ObjectCentralSubSpec,
|
||||||
|
bone1: ObjectCentralSubSpec,
|
||||||
}
|
}
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct ObjectCentralSubSpec {
|
struct ObjectCentralSubSpec {
|
||||||
@ -3818,7 +3819,9 @@ make_vox_spec!(
|
|||||||
Some(spec.central.read().0.mesh_bone0(
|
Some(spec.central.read().0.mesh_bone0(
|
||||||
body,
|
body,
|
||||||
)),
|
)),
|
||||||
None,
|
Some(spec.central.read().0.mesh_bone1(
|
||||||
|
body,
|
||||||
|
)),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@ -3850,4 +3853,17 @@ impl ObjectCentralSpec {
|
|||||||
|
|
||||||
(central, Vec3::from(spec.bone0.offset))
|
(central, Vec3::from(spec.bone0.offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mesh_bone1(&self, obj: &object::Body) -> BoneMeshes {
|
||||||
|
let spec = match self.0.get(&obj) {
|
||||||
|
Some(spec) => spec,
|
||||||
|
None => {
|
||||||
|
error!("No specification exists for {:?}", obj);
|
||||||
|
return load_mesh("not_found", Vec3::new(-5.0, -5.0, -2.5));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let central = graceful_load_segment(&spec.bone1.central.0);
|
||||||
|
|
||||||
|
(central, Vec3::from(spec.bone1.offset))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3480,7 +3480,7 @@ impl FigureMgr {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
Body::Object(body) => {
|
Body::Object(body) => {
|
||||||
let (model, _) = self.object_model_cache.get_or_create_model(
|
let (model, skeleton_attr) = self.object_model_cache.get_or_create_model(
|
||||||
renderer,
|
renderer,
|
||||||
&mut self.col_lights,
|
&mut self.col_lights,
|
||||||
*body,
|
*body,
|
||||||
@ -3496,6 +3496,96 @@ impl FigureMgr {
|
|||||||
FigureState::new(renderer, ObjectSkeleton::default())
|
FigureState::new(renderer, ObjectSkeleton::default())
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let (character, last_character) = match (character, last_character) {
|
||||||
|
(Some(c), Some(l)) => (c, l),
|
||||||
|
_ => (&CharacterState::Idle, &Last {
|
||||||
|
0: CharacterState::Idle,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
if !character.same_variant(&last_character.0) {
|
||||||
|
state.state_time = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let target_base = match (
|
||||||
|
physics.on_ground,
|
||||||
|
vel.0.magnitude_squared() > MOVING_THRESHOLD_SQR, // Moving
|
||||||
|
physics.in_liquid.is_some(), // In water
|
||||||
|
) {
|
||||||
|
// Standing
|
||||||
|
(true, false, false) => anim::object::IdleAnimation::update_skeleton(
|
||||||
|
&ObjectSkeleton::default(),
|
||||||
|
(active_tool_kind, second_tool_kind, time),
|
||||||
|
state.state_time,
|
||||||
|
&mut state_animation_rate,
|
||||||
|
skeleton_attr,
|
||||||
|
),
|
||||||
|
_ => anim::object::IdleAnimation::update_skeleton(
|
||||||
|
&ObjectSkeleton::default(),
|
||||||
|
(active_tool_kind, second_tool_kind, time),
|
||||||
|
state.state_time,
|
||||||
|
&mut state_animation_rate,
|
||||||
|
skeleton_attr,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
let target_bones = match &character {
|
||||||
|
CharacterState::BasicRanged(s) => {
|
||||||
|
let stage_time = s.timer.as_secs_f64();
|
||||||
|
|
||||||
|
let stage_progress = match s.stage_section {
|
||||||
|
StageSection::Buildup => {
|
||||||
|
stage_time / s.static_data.buildup_duration.as_secs_f64()
|
||||||
|
},
|
||||||
|
StageSection::Recover => {
|
||||||
|
stage_time / s.static_data.recover_duration.as_secs_f64()
|
||||||
|
},
|
||||||
|
|
||||||
|
_ => 0.0,
|
||||||
|
};
|
||||||
|
anim::object::ShootAnimation::update_skeleton(
|
||||||
|
&target_base,
|
||||||
|
(
|
||||||
|
active_tool_kind,
|
||||||
|
second_tool_kind,
|
||||||
|
Some(s.stage_section),
|
||||||
|
*body,
|
||||||
|
),
|
||||||
|
stage_progress,
|
||||||
|
&mut state_animation_rate,
|
||||||
|
skeleton_attr,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
CharacterState::BasicBeam(s) => {
|
||||||
|
let stage_time = s.timer.as_secs_f64();
|
||||||
|
let stage_progress = match s.stage_section {
|
||||||
|
StageSection::Buildup => {
|
||||||
|
stage_time / s.static_data.buildup_duration.as_secs_f64()
|
||||||
|
},
|
||||||
|
StageSection::Cast => s.timer.as_secs_f64(),
|
||||||
|
StageSection::Recover => {
|
||||||
|
stage_time / s.static_data.recover_duration.as_secs_f64()
|
||||||
|
},
|
||||||
|
_ => 0.0,
|
||||||
|
};
|
||||||
|
anim::object::BeamAnimation::update_skeleton(
|
||||||
|
&target_base,
|
||||||
|
(
|
||||||
|
active_tool_kind,
|
||||||
|
second_tool_kind,
|
||||||
|
Some(s.stage_section),
|
||||||
|
*body,
|
||||||
|
),
|
||||||
|
stage_progress,
|
||||||
|
&mut state_animation_rate,
|
||||||
|
skeleton_attr,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
// TODO!
|
||||||
|
_ => target_base,
|
||||||
|
};
|
||||||
|
|
||||||
|
state.skeleton = anim::vek::Lerp::lerp(&state.skeleton, &target_bones, dt_lerp);
|
||||||
state.update(
|
state.update(
|
||||||
renderer,
|
renderer,
|
||||||
pos.0,
|
pos.0,
|
||||||
|
@ -8,13 +8,13 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
assets::{AssetExt, DotVoxAsset},
|
assets::{AssetExt, DotVoxAsset},
|
||||||
comp::{item::Reagent, object, Body, CharacterState, Ori, Pos, Shockwave},
|
combat::CombatEffect,
|
||||||
|
comp::{item::Reagent, object, BeamSegment, Body, CharacterState, Ori, Pos, Shockwave},
|
||||||
figure::Segment,
|
figure::Segment,
|
||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
resources::DeltaTime,
|
resources::DeltaTime,
|
||||||
span,
|
span,
|
||||||
spiral::Spiral2d,
|
spiral::Spiral2d,
|
||||||
states::utils::StageSection,
|
|
||||||
terrain::TerrainChunk,
|
terrain::TerrainChunk,
|
||||||
vol::{RectRasterableVol, SizedVol},
|
vol::{RectRasterableVol, SizedVol},
|
||||||
};
|
};
|
||||||
@ -366,65 +366,62 @@ impl ParticleMgr {
|
|||||||
let state = scene_data.state;
|
let state = scene_data.state;
|
||||||
let ecs = state.ecs();
|
let ecs = state.ecs();
|
||||||
let time = state.get_time();
|
let time = state.get_time();
|
||||||
|
let dt = scene_data.state.ecs().fetch::<DeltaTime>().0;
|
||||||
|
|
||||||
for (pos, ori, character_state) in (
|
for (pos, ori, beam) in (
|
||||||
&ecs.read_storage::<Pos>(),
|
&ecs.read_storage::<Pos>(),
|
||||||
&ecs.read_storage::<Ori>(),
|
&ecs.read_storage::<Ori>(),
|
||||||
&ecs.read_storage::<CharacterState>(),
|
&ecs.read_storage::<BeamSegment>(),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
|
.filter(|(_, _, b)| b.creation.map_or(true, |c| (c + dt as f64) >= time))
|
||||||
{
|
{
|
||||||
if let CharacterState::BasicBeam(b) = character_state {
|
let range = beam.properties.speed * beam.properties.duration.as_secs_f32();
|
||||||
let particle_ori = b.particle_ori.unwrap_or_else(|| ori.look_vec());
|
if beam
|
||||||
if b.stage_section == StageSection::Cast {
|
.properties
|
||||||
if b.static_data.base_hps > 0.0 {
|
.attack
|
||||||
// Emit a light when using healing
|
.effects()
|
||||||
lights.push(Light::new(pos.0 + b.offset, Rgb::new(0.1, 1.0, 0.15), 1.0));
|
.any(|e| matches!(e.effect(), CombatEffect::Heal(h) if *h > 0.0))
|
||||||
for i in 0..self.scheduler.heartbeats(Duration::from_millis(1)) {
|
{
|
||||||
self.particles.push(Particle::new_beam(
|
// Emit a light when using healing
|
||||||
b.static_data.beam_duration,
|
lights.push(Light::new(pos.0, Rgb::new(0.1, 1.0, 0.15), 1.0));
|
||||||
time + i as f64 / 1000.0,
|
for i in 0..self.scheduler.heartbeats(Duration::from_millis(1)) {
|
||||||
ParticleMode::HealingBeam,
|
self.particles.push(Particle::new_beam(
|
||||||
pos.0 + particle_ori * 0.5 + b.offset,
|
beam.properties.duration,
|
||||||
pos.0 + particle_ori * b.static_data.range + b.offset,
|
time + i as f64 / 1000.0,
|
||||||
));
|
ParticleMode::HealingBeam,
|
||||||
}
|
pos.0,
|
||||||
} else {
|
pos.0 + *ori.look_dir() * range,
|
||||||
let mut rng = thread_rng();
|
));
|
||||||
let (from, to) = (Vec3::<f32>::unit_z(), particle_ori);
|
|
||||||
let m = Mat3::<f32>::rotation_from_to_3d(from, to);
|
|
||||||
// Emit a light when using flames
|
|
||||||
lights.push(Light::new(
|
|
||||||
pos.0 + b.offset,
|
|
||||||
Rgb::new(1.0, 0.25, 0.05).map(|e| e * rng.gen_range(0.8..1.2)),
|
|
||||||
2.0,
|
|
||||||
));
|
|
||||||
self.particles.resize_with(
|
|
||||||
self.particles.len()
|
|
||||||
+ 2 * usize::from(
|
|
||||||
self.scheduler.heartbeats(Duration::from_millis(1)),
|
|
||||||
),
|
|
||||||
|| {
|
|
||||||
let phi: f32 =
|
|
||||||
rng.gen_range(0.0..b.static_data.max_angle.to_radians());
|
|
||||||
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_beam(
|
|
||||||
b.static_data.beam_duration,
|
|
||||||
time,
|
|
||||||
ParticleMode::FlameThrower,
|
|
||||||
pos.0 + random_ori * 0.5 + b.offset,
|
|
||||||
pos.0 + random_ori * b.static_data.range + b.offset,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
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);
|
||||||
|
// Emit a light when using flames
|
||||||
|
lights.push(Light::new(
|
||||||
|
pos.0,
|
||||||
|
Rgb::new(1.0, 0.25, 0.05).map(|e| e * rng.gen_range(0.8..1.2)),
|
||||||
|
2.0,
|
||||||
|
));
|
||||||
|
self.particles.resize_with(
|
||||||
|
self.particles.len()
|
||||||
|
+ 2 * usize::from(self.scheduler.heartbeats(Duration::from_millis(1))),
|
||||||
|
|| {
|
||||||
|
let phi: f32 = rng.gen_range(0.0..beam.properties.angle.to_radians());
|
||||||
|
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_beam(
|
||||||
|
beam.properties.duration,
|
||||||
|
time,
|
||||||
|
ParticleMode::FlameThrower,
|
||||||
|
pos.0 + random_ori,
|
||||||
|
pos.0 + random_ori * range,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -701,6 +701,12 @@ impl Floor {
|
|||||||
.with_main_tool(comp::Item::new_from_asset_expect(
|
.with_main_tool(comp::Item::new_from_asset_expect(
|
||||||
"common.items.weapons.staff.cultist_staff",
|
"common.items.weapons.staff.cultist_staff",
|
||||||
)),
|
)),
|
||||||
|
1 => entity
|
||||||
|
.with_body(comp::Body::Object(comp::object::Body::Crossbow))
|
||||||
|
.with_name("Possessed Turret".to_string())
|
||||||
|
.with_loot_drop(comp::Item::new_from_asset_expect(
|
||||||
|
"common.items.crafting_ing.twigs",
|
||||||
|
)),
|
||||||
_ => entity
|
_ => entity
|
||||||
.with_name("Cultist Warlord")
|
.with_name("Cultist Warlord")
|
||||||
.with_loadout_config(loadout_builder::LoadoutConfig::Warlord)
|
.with_loadout_config(loadout_builder::LoadoutConfig::Warlord)
|
||||||
|
Loading…
Reference in New Issue
Block a user