From bf81ffc029885b1ea8f6f952b4090153dccf4b87 Mon Sep 17 00:00:00 2001 From: flo Date: Wed, 15 Feb 2023 00:10:37 +0000 Subject: [PATCH] frost_gigas --- .../common/abilities/ability_set_manifest.ron | 25 ++ .../arthropods/blackwidow/ensnaringwebs.ron | 1 + .../arthropods/tarantula/ensnaringwebs.ron | 1 + .../custom/birdlargefire/fireshockwave.ron | 1 + .../custom/boreal_warrior/bow/charged.ron | 24 ++ .../custom/boreal_warrior/bow/repeater.ron | 22 ++ .../custom/boreal_warrior/bow/shotgun.ron | 21 ++ .../custom/boreal_warrior/hammer/dash.ron | 33 +++ .../custom/boreal_warrior/hammer/leap.ron | 26 ++ .../boreal_warrior/hammer/singlestrike.ron | 31 +++ .../abilities/custom/claygolem/shockwave.ron | 1 + .../custom/cloudwyvern/windshockwave.ron | 1 + .../abilities/custom/dagon/seaurchins.ron | 1 + .../abilities/custom/dagon/steamwave.ron | 1 + .../custom/flamewyvern/fireshockwave.ron | 1 + .../custom/frostwyvern/iceshockwave.ron | 1 + .../abilities/custom/gigas_frost/cleave.ron | 24 ++ .../custom/gigas_frost/flashfreeze.ron | 24 ++ .../custom/gigas_frost/frost_summons.ron | 18 ++ .../custom/gigas_frost/ice_volley.ron | 15 ++ .../custom/gigas_frost/icespike_smash.ron | 10 + .../custom/gigas_frost/leapshockwave.ron | 26 ++ .../custom/gigas_frost/wide_cleave.ron | 24 ++ .../custom/harvester/ensnaringvines.ron | 1 + .../custom/roshwalr/freezeshockwave.ron | 1 + .../custom/seawyvern/seashockwave.ron | 1 + .../custom/stonegolemfist/shockwave.ron | 1 + .../custom/tidalwarrior/totem_wave.ron | 1 + .../custom/wealdwyvern/fireshockwave.ron | 1 + .../abilities/custom/woodgolem/shockwave.ron | 1 + .../abilities/custom/yeti/icespikes.ron | 1 + .../gnarling/chieftain/fireshockwave.ron | 1 + .../common/abilities/staff/fireshockwave.ron | 1 + .../entity/world/world_bosses/gigas_frost.ron | 11 + .../world_bosses/summons/boreal_warrior.ron | 19 ++ assets/common/items/armor/boreal/back.ron | 10 + assets/common/items/armor/boreal/belt.ron | 10 + assets/common/items/armor/boreal/chest.ron | 10 + assets/common/items/armor/boreal/foot.ron | 10 + assets/common/items/armor/boreal/hand.ron | 10 + assets/common/items/armor/boreal/pants.ron | 10 + assets/common/items/armor/boreal/shoulder.ron | 10 + .../items/crafting_ing/glacial_crystal.ron | 9 + assets/common/items/crafting_ing/pearl.ron | 9 + assets/common/items/glider/winter_wings.ron | 7 + .../npc_armor/biped_large/gigas_frost.ron | 14 ++ .../biped_small/boreal/chest/warrior.ron | 16 ++ .../biped_small/boreal/foot/warrior.ron | 16 ++ .../biped_small/boreal/hand/warrior.ron | 16 ++ .../biped_small/boreal/head/warrior.ron | 16 ++ .../biped_small/boreal/pants/warrior.ron | 16 ++ .../items/npc_weapons/axe/gigas_frost_axe.ron | 21 ++ .../npc_weapons/biped_small/boreal/bow.ron | 21 ++ .../npc_weapons/biped_small/boreal/hammer.ron | 21 ++ .../items/tool/instruments/glass_flute.ron | 2 +- .../items/tool/instruments/guitar_dark.ron | 2 +- .../items/tool/instruments/icy_talharpa.ron | 2 +- .../loadout/world/boreal/boreal_warrior.ron | 12 + assets/common/loot_tables/armor/boreal.ron | 10 + .../dungeon/sea_chapel/chest_coral.ron | 1 + .../loot_tables/dungeon/sea_chapel/dagon.ron | 1 + .../world/world_bosses/gigas_frost/boss.ron | 4 + .../world/world_bosses/gigas_frost/summon.ron | 8 + assets/common/material_stats_manifest.ron | 7 + assets/common/npc_names.ron | 10 +- assets/common/recipe_book.ron | 33 +++ assets/server/manifests/kits.ron | 10 + assets/voxygen/audio/sfx.ron | 36 +++ .../audio/sfx/abilities/gigas_frost_roar.ogg | 3 + .../voxygen/audio/sfx/abilities/ice_crack.ogg | 3 + assets/voxygen/item_image_manifest.ron | 41 ++++ assets/voxygen/shaders/particle-vert.glsl | 10 + assets/voxygen/voxel/armor/boreal/back.vox | 3 + assets/voxygen/voxel/armor/boreal/belt.vox | 3 + assets/voxygen/voxel/armor/boreal/chest.vox | 3 + assets/voxygen/voxel/armor/boreal/foot.vox | 3 + assets/voxygen/voxel/armor/boreal/hand.vox | 3 + assets/voxygen/voxel/armor/boreal/hat.vox | 3 + assets/voxygen/voxel/armor/boreal/pants.vox | 3 + .../voxygen/voxel/armor/boreal/shoulder.vox | 3 + .../voxel/biped_large_central_manifest.ron | 52 ++++ .../voxel/biped_large_lateral_manifest.ron | 68 ++++++ .../biped_small_armor_chest_manifest.ron | 3 + .../voxel/biped_small_armor_foot_manifest.ron | 8 + .../voxel/biped_small_armor_hand_manifest.ron | 10 +- .../voxel/biped_small_armor_head_manifest.ron | 4 + .../biped_small_armor_pants_manifest.ron | 3 + .../voxygen/voxel/biped_weapon_manifest.ron | 12 + assets/voxygen/voxel/glider/winter_wings.vox | 3 + .../voxel/humanoid_armor_back_manifest.ron | 4 + .../voxel/humanoid_armor_belt_manifest.ron | 4 + .../voxel/humanoid_armor_chest_manifest.ron | 4 + .../voxel/humanoid_armor_foot_manifest.ron | 4 + .../voxel/humanoid_armor_hand_manifest.ron | 10 + .../voxel/humanoid_armor_pants_manifest.ron | 4 + .../humanoid_armor_shoulder_manifest.ron | 10 + .../voxel/humanoid_glider_manifest.ron | 4 + assets/voxygen/voxel/item_drop_manifest.ron | 11 + .../voxel/npc/boreal/warrior/chest.vox | 3 + .../voxel/npc/boreal/warrior/foot_r.vox | 3 + .../voxel/npc/boreal/warrior/hand_r.vox | 3 + .../voxygen/voxel/npc/boreal/warrior/head.vox | 3 + .../voxel/npc/boreal/warrior/pants.vox | 3 + .../voxel/npc/gigas_frost/male/foot_l.vox | 3 + .../voxel/npc/gigas_frost/male/foot_r.vox | 3 + .../voxel/npc/gigas_frost/male/hand_l.vox | 3 + .../voxel/npc/gigas_frost/male/hand_r.vox | 3 + .../voxel/npc/gigas_frost/male/head.vox | 3 + .../voxel/npc/gigas_frost/male/jaw.vox | 3 + .../voxel/npc/gigas_frost/male/leg_l.vox | 3 + .../voxel/npc/gigas_frost/male/leg_r.vox | 3 + .../voxel/npc/gigas_frost/male/shoulder_l.vox | 3 + .../voxel/npc/gigas_frost/male/shoulder_r.vox | 3 + .../npc/gigas_frost/male/torso_lower.vox | 3 + .../npc/gigas_frost/male/torso_upper.vox | 3 + .../voxygen/voxel/object/glacial_crystal.vox | 3 + assets/voxygen/voxel/object_manifest.ron | 10 + .../voxel/sprite/crafting_ing/pearl.vox | 3 + assets/voxygen/voxel/sprite/misc/icespike.vox | 3 + assets/voxygen/voxel/sprite_manifest.ron | 11 + .../voxel/weapon/axe/2haxe_gigas_frost.vox | 3 + .../weapon/biped_small/bow/boreal_bow.vox | 3 + .../biped_small/hammer/boreal_hammer.vox | 3 + .../voxel/weapon/projectile/ice_bomb.vox | 3 + common/src/comp/ability.rs | 163 +++++++++++++ common/src/comp/agent.rs | 2 +- common/src/comp/aura.rs | 15 ++ common/src/comp/body.rs | 25 +- common/src/comp/body/biped_large.rs | 6 +- common/src/comp/body/biped_small.rs | 6 +- common/src/comp/body/object.rs | 7 +- common/src/comp/character_state.rs | 17 ++ common/src/comp/inventory/loadout_builder.rs | 10 + common/src/comp/projectile.rs | 88 ++++++- common/src/explosion.rs | 3 +- common/src/outcome.rs | 12 + common/src/states/basic_ranged.rs | 4 + common/src/states/charged_melee.rs | 3 + common/src/states/charged_ranged.rs | 4 + common/src/states/leap_melee.rs | 3 + common/src/states/leap_shockwave.rs | 226 ++++++++++++++++++ common/src/states/mod.rs | 1 + common/src/states/repeater_ranged.rs | 4 + common/src/states/shockwave.rs | 15 +- common/src/states/sprite_summon.rs | 17 +- common/src/states/utils.rs | 2 + common/src/terrain/block.rs | 2 +- common/src/terrain/sprite.rs | 2 + common/systems/src/buff.rs | 25 ++ common/systems/src/stats.rs | 1 + server/agent/src/action_nodes.rs | 21 +- server/agent/src/attack.rs | 182 ++++++++++++++ server/agent/src/data.rs | 2 + server/src/cmd.rs | 2 +- server/src/events/entity_manipulation.rs | 11 +- server/src/sys/object.rs | 7 +- server/src/wiring.rs | 2 +- voxygen/anim/src/biped_large/alpha.rs | 104 ++++++-- voxygen/anim/src/biped_large/jump.rs | 11 +- voxygen/anim/src/biped_large/leapshockwave.rs | 89 +++++++ voxygen/anim/src/biped_large/mod.rs | 19 +- voxygen/anim/src/biped_large/selfbuff.rs | 28 +++ voxygen/anim/src/biped_large/shockwave.rs | 73 ++++++ voxygen/anim/src/biped_large/shoot.rs | 48 ++++ voxygen/anim/src/biped_large/spinmelee.rs | 56 ++++- voxygen/anim/src/biped_large/spritesummon.rs | 58 +++++ voxygen/anim/src/biped_large/summon.rs | 33 +++ voxygen/anim/src/biped_small/alpha.rs | 2 +- voxygen/anim/src/biped_small/leapmelee.rs | 102 ++++++++ voxygen/anim/src/biped_small/mod.rs | 15 +- voxygen/anim/src/biped_small/wield.rs | 2 +- voxygen/src/audio/sfx/mod.rs | 33 ++- voxygen/src/render/pipelines/particle.rs | 2 + voxygen/src/scene/figure/mod.rs | 65 +++++ voxygen/src/scene/particle.rs | 132 +++++++++- 175 files changed, 2837 insertions(+), 79 deletions(-) create mode 100644 assets/common/abilities/custom/boreal_warrior/bow/charged.ron create mode 100644 assets/common/abilities/custom/boreal_warrior/bow/repeater.ron create mode 100644 assets/common/abilities/custom/boreal_warrior/bow/shotgun.ron create mode 100644 assets/common/abilities/custom/boreal_warrior/hammer/dash.ron create mode 100644 assets/common/abilities/custom/boreal_warrior/hammer/leap.ron create mode 100644 assets/common/abilities/custom/boreal_warrior/hammer/singlestrike.ron create mode 100644 assets/common/abilities/custom/gigas_frost/cleave.ron create mode 100644 assets/common/abilities/custom/gigas_frost/flashfreeze.ron create mode 100644 assets/common/abilities/custom/gigas_frost/frost_summons.ron create mode 100644 assets/common/abilities/custom/gigas_frost/ice_volley.ron create mode 100644 assets/common/abilities/custom/gigas_frost/icespike_smash.ron create mode 100644 assets/common/abilities/custom/gigas_frost/leapshockwave.ron create mode 100644 assets/common/abilities/custom/gigas_frost/wide_cleave.ron create mode 100644 assets/common/entity/world/world_bosses/gigas_frost.ron create mode 100644 assets/common/entity/world/world_bosses/summons/boreal_warrior.ron create mode 100644 assets/common/items/armor/boreal/back.ron create mode 100644 assets/common/items/armor/boreal/belt.ron create mode 100644 assets/common/items/armor/boreal/chest.ron create mode 100644 assets/common/items/armor/boreal/foot.ron create mode 100644 assets/common/items/armor/boreal/hand.ron create mode 100644 assets/common/items/armor/boreal/pants.ron create mode 100644 assets/common/items/armor/boreal/shoulder.ron create mode 100644 assets/common/items/crafting_ing/glacial_crystal.ron create mode 100644 assets/common/items/crafting_ing/pearl.ron create mode 100644 assets/common/items/glider/winter_wings.ron create mode 100644 assets/common/items/npc_armor/biped_large/gigas_frost.ron create mode 100644 assets/common/items/npc_armor/biped_small/boreal/chest/warrior.ron create mode 100644 assets/common/items/npc_armor/biped_small/boreal/foot/warrior.ron create mode 100644 assets/common/items/npc_armor/biped_small/boreal/hand/warrior.ron create mode 100644 assets/common/items/npc_armor/biped_small/boreal/head/warrior.ron create mode 100644 assets/common/items/npc_armor/biped_small/boreal/pants/warrior.ron create mode 100644 assets/common/items/npc_weapons/axe/gigas_frost_axe.ron create mode 100644 assets/common/items/npc_weapons/biped_small/boreal/bow.ron create mode 100644 assets/common/items/npc_weapons/biped_small/boreal/hammer.ron create mode 100644 assets/common/loadout/world/boreal/boreal_warrior.ron create mode 100644 assets/common/loot_tables/armor/boreal.ron create mode 100644 assets/common/loot_tables/world/world_bosses/gigas_frost/boss.ron create mode 100644 assets/common/loot_tables/world/world_bosses/gigas_frost/summon.ron create mode 100644 assets/voxygen/audio/sfx/abilities/gigas_frost_roar.ogg create mode 100644 assets/voxygen/audio/sfx/abilities/ice_crack.ogg create mode 100644 assets/voxygen/voxel/armor/boreal/back.vox create mode 100644 assets/voxygen/voxel/armor/boreal/belt.vox create mode 100644 assets/voxygen/voxel/armor/boreal/chest.vox create mode 100644 assets/voxygen/voxel/armor/boreal/foot.vox create mode 100644 assets/voxygen/voxel/armor/boreal/hand.vox create mode 100644 assets/voxygen/voxel/armor/boreal/hat.vox create mode 100644 assets/voxygen/voxel/armor/boreal/pants.vox create mode 100644 assets/voxygen/voxel/armor/boreal/shoulder.vox create mode 100644 assets/voxygen/voxel/glider/winter_wings.vox create mode 100644 assets/voxygen/voxel/npc/boreal/warrior/chest.vox create mode 100644 assets/voxygen/voxel/npc/boreal/warrior/foot_r.vox create mode 100644 assets/voxygen/voxel/npc/boreal/warrior/hand_r.vox create mode 100644 assets/voxygen/voxel/npc/boreal/warrior/head.vox create mode 100644 assets/voxygen/voxel/npc/boreal/warrior/pants.vox create mode 100644 assets/voxygen/voxel/npc/gigas_frost/male/foot_l.vox create mode 100644 assets/voxygen/voxel/npc/gigas_frost/male/foot_r.vox create mode 100644 assets/voxygen/voxel/npc/gigas_frost/male/hand_l.vox create mode 100644 assets/voxygen/voxel/npc/gigas_frost/male/hand_r.vox create mode 100644 assets/voxygen/voxel/npc/gigas_frost/male/head.vox create mode 100644 assets/voxygen/voxel/npc/gigas_frost/male/jaw.vox create mode 100644 assets/voxygen/voxel/npc/gigas_frost/male/leg_l.vox create mode 100644 assets/voxygen/voxel/npc/gigas_frost/male/leg_r.vox create mode 100644 assets/voxygen/voxel/npc/gigas_frost/male/shoulder_l.vox create mode 100644 assets/voxygen/voxel/npc/gigas_frost/male/shoulder_r.vox create mode 100644 assets/voxygen/voxel/npc/gigas_frost/male/torso_lower.vox create mode 100644 assets/voxygen/voxel/npc/gigas_frost/male/torso_upper.vox create mode 100644 assets/voxygen/voxel/object/glacial_crystal.vox create mode 100644 assets/voxygen/voxel/sprite/crafting_ing/pearl.vox create mode 100644 assets/voxygen/voxel/sprite/misc/icespike.vox create mode 100644 assets/voxygen/voxel/weapon/axe/2haxe_gigas_frost.vox create mode 100644 assets/voxygen/voxel/weapon/biped_small/bow/boreal_bow.vox create mode 100644 assets/voxygen/voxel/weapon/biped_small/hammer/boreal_hammer.vox create mode 100644 assets/voxygen/voxel/weapon/projectile/ice_bomb.vox create mode 100644 common/src/states/leap_shockwave.rs create mode 100644 voxygen/anim/src/biped_large/leapshockwave.rs create mode 100644 voxygen/anim/src/biped_small/leapmelee.rs diff --git a/assets/common/abilities/ability_set_manifest.ron b/assets/common/abilities/ability_set_manifest.ron index 47e6860575..c31791ac1b 100644 --- a/assets/common/abilities/ability_set_manifest.ron +++ b/assets/common/abilities/ability_set_manifest.ron @@ -516,6 +516,31 @@ secondary: "common.abilities.custom.birdmediumbasic.singlestrike", abilities: [], ), + Custom("Frost Gigas"): ( + primary: "common.abilities.custom.gigas_frost.cleave", + secondary: "common.abilities.custom.gigas_frost.wide_cleave", + abilities: [ + Simple(None, "common.abilities.custom.gigas_frost.icespike_smash"), + Simple(None, "common.abilities.custom.gigas_frost.leapshockwave"), + Simple(None, "common.abilities.custom.gigas_frost.ice_volley"), + Simple(None, "common.abilities.custom.gigas_frost.frost_summons"), + Simple(None, "common.abilities.custom.gigas_frost.flashfreeze"), + ], + ), + Custom("Boreal Bow"): ( + primary: "common.abilities.custom.boreal_warrior.bow.charged", + secondary: "common.abilities.custom.boreal_warrior.bow.repeater", + abilities: [ + Simple(None, "common.abilities.custom.boreal_warrior.bow.shotgun") + ], + ), + Custom("Boreal Hammer"): ( + primary: "common.abilities.custom.boreal_warrior.hammer.singlestrike", + secondary: "common.abilities.custom.boreal_warrior.hammer.dash", + abilities: [ + Simple(None, "common.abilities.custom.boreal_warrior.hammer.leap") + ], + ), Custom("Tornado"): ( primary: "common.abilities.custom.tornado.spin", secondary: "common.abilities.empty.basic", diff --git a/assets/common/abilities/custom/arthropods/blackwidow/ensnaringwebs.ron b/assets/common/abilities/custom/arthropods/blackwidow/ensnaringwebs.ron index b5d5b0ff70..da4f882969 100644 --- a/assets/common/abilities/custom/arthropods/blackwidow/ensnaringwebs.ron +++ b/assets/common/abilities/custom/arthropods/blackwidow/ensnaringwebs.ron @@ -6,4 +6,5 @@ SpriteSummon( del_timeout: None, summon_distance: (0, 10), sparseness: 0.76, + angle: 360, ) \ No newline at end of file diff --git a/assets/common/abilities/custom/arthropods/tarantula/ensnaringwebs.ron b/assets/common/abilities/custom/arthropods/tarantula/ensnaringwebs.ron index da0bfab83d..f873461302 100644 --- a/assets/common/abilities/custom/arthropods/tarantula/ensnaringwebs.ron +++ b/assets/common/abilities/custom/arthropods/tarantula/ensnaringwebs.ron @@ -6,4 +6,5 @@ SpriteSummon( del_timeout: None, summon_distance: (0, 9), sparseness: 0.8, + angle: 360, ) \ No newline at end of file diff --git a/assets/common/abilities/custom/birdlargefire/fireshockwave.ron b/assets/common/abilities/custom/birdlargefire/fireshockwave.ron index 9989b39290..841c443ccb 100644 --- a/assets/common/abilities/custom/birdlargefire/fireshockwave.ron +++ b/assets/common/abilities/custom/birdlargefire/fireshockwave.ron @@ -14,4 +14,5 @@ Shockwave( move_efficiency: 0.1, damage_kind: Energy, specifier: Fire, + ori_rate: 1.0, ) diff --git a/assets/common/abilities/custom/boreal_warrior/bow/charged.ron b/assets/common/abilities/custom/boreal_warrior/bow/charged.ron new file mode 100644 index 0000000000..fffe006cdd --- /dev/null +++ b/assets/common/abilities/custom/boreal_warrior/bow/charged.ron @@ -0,0 +1,24 @@ +ChargedRanged( + energy_cost: 0, + energy_drain: 0, + initial_regen: 2, + scaled_regen: 14, + initial_damage: 2, + scaled_damage: 12, + initial_knockback: 0, + scaled_knockback: 12, + buildup_duration: 0.25, + charge_duration: 1.0, + recover_duration: 0.4, + projectile_body: Object(Arrow), + projectile_light: None, + initial_projectile_speed: 50.0, + scaled_projectile_speed: 200.0, + damage_effect: Some(Buff(( + kind: Frozen, + dur_secs: 2.0, + strength: DamageFraction(0.1), + chance: 1.0, + ))), + move_speed: 0.6, +) diff --git a/assets/common/abilities/custom/boreal_warrior/bow/repeater.ron b/assets/common/abilities/custom/boreal_warrior/bow/repeater.ron new file mode 100644 index 0000000000..07cb6d5b8d --- /dev/null +++ b/assets/common/abilities/custom/boreal_warrior/bow/repeater.ron @@ -0,0 +1,22 @@ +RepeaterRanged( + energy_cost: 6.0, + buildup_duration: 0.2, + shoot_duration: 0.3, + recover_duration: 0.5, + max_speed: 4.0, + half_speed_at: 3, + projectile: Arrow( + damage: 5.0, + knockback: 0, + energy_regen: 0, + ), + projectile_body: Object(Arrow), + projectile_light: None, + projectile_speed: 100.0, + damage_effect: Some(Buff(( + kind: Frozen, + dur_secs: 2.0, + strength: DamageFraction(0.1), + chance: 1.0, + ))), +) \ No newline at end of file diff --git a/assets/common/abilities/custom/boreal_warrior/bow/shotgun.ron b/assets/common/abilities/custom/boreal_warrior/bow/shotgun.ron new file mode 100644 index 0000000000..05837b1fa3 --- /dev/null +++ b/assets/common/abilities/custom/boreal_warrior/bow/shotgun.ron @@ -0,0 +1,21 @@ +BasicRanged( + energy_cost: 25.0, + buildup_duration: 0.3, + recover_duration: 0.3, + projectile_spread: 0.05, + projectile: Arrow( + damage: 6, + knockback: 5, + energy_regen: 0, + ), + projectile_body: Object(Arrow), + projectile_light: None, + projectile_speed: 80.0, + num_projectiles: 5, + damage_effect: Some(Buff(( + kind: Frozen, + dur_secs: 2.0, + strength: DamageFraction(0.1), + chance: 1.0, + ))), +) \ No newline at end of file diff --git a/assets/common/abilities/custom/boreal_warrior/hammer/dash.ron b/assets/common/abilities/custom/boreal_warrior/hammer/dash.ron new file mode 100644 index 0000000000..83c72f1ba1 --- /dev/null +++ b/assets/common/abilities/custom/boreal_warrior/hammer/dash.ron @@ -0,0 +1,33 @@ +DashMelee( + energy_cost: 3.0, + melee_constructor: ( + kind: Bash( + damage: 9.0, + poise: 40.0, + knockback: 16.0, + energy_regen: 0.0, + ), + scaled: Some(Bash( + damage: 10.0, + poise: 0.0, + knockback: 20.0, + energy_regen: 0.0, + )), + range: 5.0, + angle: 45.0, + damage_effect: Some(Buff(( + kind: Frozen, + dur_secs: 2.0, + strength: DamageFraction(0.1), + chance: 1.0, + ))), + ), + energy_drain: 0, + forward_speed: 12.0, + buildup_duration: 0.6, + charge_duration: 0.2, + swing_duration: 0.1, + recover_duration: 0.9, + ori_modifier: 0.3, + charge_through: false, +) diff --git a/assets/common/abilities/custom/boreal_warrior/hammer/leap.ron b/assets/common/abilities/custom/boreal_warrior/hammer/leap.ron new file mode 100644 index 0000000000..935ecc5398 --- /dev/null +++ b/assets/common/abilities/custom/boreal_warrior/hammer/leap.ron @@ -0,0 +1,26 @@ +LeapMelee( + energy_cost: 35.0, + buildup_duration: 0.1, + movement_duration: 0.6, + swing_duration: 0.15, + recover_duration: 0.2, + melee_constructor: ( + kind: Bash( + damage: 25.0, + poise: 40.0, + knockback: 25.0, + energy_regen: 0.0, + ), + range: 4.5, + angle: 360.0, + multi_target: Some(Normal), + damage_effect: Some(Buff(( + kind: Frozen, + dur_secs: 2.0, + strength: DamageFraction(0.1), + chance: 1.0, + ))), + ), + forward_leap_strength: 20.0, + vertical_leap_strength: 8.0, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/boreal_warrior/hammer/singlestrike.ron b/assets/common/abilities/custom/boreal_warrior/hammer/singlestrike.ron new file mode 100644 index 0000000000..3cc7a58275 --- /dev/null +++ b/assets/common/abilities/custom/boreal_warrior/hammer/singlestrike.ron @@ -0,0 +1,31 @@ +ComboMelee( + stage_data: [( + stage: 1, + base_damage: 15.0, + damage_increase: 0.75, + base_poise_damage: 0, + poise_damage_increase: 0, + knockback: 3.5, + range: 4.5, + angle: 50.0, + base_buildup_duration: 0.7, + base_swing_duration: 0.1, + hit_timing: 0.5, + base_recover_duration: 0.45, + forward_movement: 0.0, + damage_kind: Crushing, + damage_effect: Some(Buff(( + kind: Frozen, + dur_secs: 2.0, + strength: DamageFraction(0.1), + chance: 1.0, + ))), + )], + initial_energy_gain: 5.0, + max_energy_gain: 12.5, + energy_increase: 2.5, + speed_increase: 0.1, + max_speed_increase: 0.4, + scales_from_combo: 2, + ori_modifier: 1.0, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/claygolem/shockwave.ron b/assets/common/abilities/custom/claygolem/shockwave.ron index ec82804242..63cb59b4dc 100644 --- a/assets/common/abilities/custom/claygolem/shockwave.ron +++ b/assets/common/abilities/custom/claygolem/shockwave.ron @@ -14,4 +14,5 @@ Shockwave( move_efficiency: 0.0, damage_kind: Crushing, specifier: Ground, + ori_rate: 1.0, ) diff --git a/assets/common/abilities/custom/cloudwyvern/windshockwave.ron b/assets/common/abilities/custom/cloudwyvern/windshockwave.ron index 7cbdeff4fc..d99f043161 100644 --- a/assets/common/abilities/custom/cloudwyvern/windshockwave.ron +++ b/assets/common/abilities/custom/cloudwyvern/windshockwave.ron @@ -14,4 +14,5 @@ Shockwave( move_efficiency: 0.1, damage_kind: Energy, specifier: Water, + ori_rate: 1.0, ) diff --git a/assets/common/abilities/custom/dagon/seaurchins.ron b/assets/common/abilities/custom/dagon/seaurchins.ron index f07f55f428..e5300db69d 100644 --- a/assets/common/abilities/custom/dagon/seaurchins.ron +++ b/assets/common/abilities/custom/dagon/seaurchins.ron @@ -6,4 +6,5 @@ SpriteSummon( del_timeout: Some((4, 5)), summon_distance: (5, 3.1), sparseness: 0.2, + angle: 360, ) \ No newline at end of file diff --git a/assets/common/abilities/custom/dagon/steamwave.ron b/assets/common/abilities/custom/dagon/steamwave.ron index fbccb65a38..b4160242be 100644 --- a/assets/common/abilities/custom/dagon/steamwave.ron +++ b/assets/common/abilities/custom/dagon/steamwave.ron @@ -14,4 +14,5 @@ Shockwave( move_efficiency: 0.0, damage_kind: Crushing, specifier: Steam, + ori_rate: 1.0, ) diff --git a/assets/common/abilities/custom/flamewyvern/fireshockwave.ron b/assets/common/abilities/custom/flamewyvern/fireshockwave.ron index 9989b39290..841c443ccb 100644 --- a/assets/common/abilities/custom/flamewyvern/fireshockwave.ron +++ b/assets/common/abilities/custom/flamewyvern/fireshockwave.ron @@ -14,4 +14,5 @@ Shockwave( move_efficiency: 0.1, damage_kind: Energy, specifier: Fire, + ori_rate: 1.0, ) diff --git a/assets/common/abilities/custom/frostwyvern/iceshockwave.ron b/assets/common/abilities/custom/frostwyvern/iceshockwave.ron index 9cb22f0af9..3b5a5f8433 100644 --- a/assets/common/abilities/custom/frostwyvern/iceshockwave.ron +++ b/assets/common/abilities/custom/frostwyvern/iceshockwave.ron @@ -14,4 +14,5 @@ Shockwave( move_efficiency: 0.1, damage_kind: Energy, specifier: IceSpikes, + ori_rate: 1.0, ) diff --git a/assets/common/abilities/custom/gigas_frost/cleave.ron b/assets/common/abilities/custom/gigas_frost/cleave.ron new file mode 100644 index 0000000000..95b284c8b9 --- /dev/null +++ b/assets/common/abilities/custom/gigas_frost/cleave.ron @@ -0,0 +1,24 @@ +BasicMelee( + energy_cost: 0, + buildup_duration: 0.9, + swing_duration: 0.1, + recover_duration: 0.7, + melee_constructor: ( + kind: Slash( + damage: 85.0, + poise: 5.0, + knockback: 5.0, + energy_regen: 10.0, + ), + range: 5.0, + angle: 75.0, + damage_effect: Some(Buff(( + kind: Frozen, + dur_secs: 1.0, + strength: DamageFraction(0.1), + chance: 0.3, + ))), + multi_target: Some(Normal), + ), + ori_modifier: 0.2, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/gigas_frost/flashfreeze.ron b/assets/common/abilities/custom/gigas_frost/flashfreeze.ron new file mode 100644 index 0000000000..b383ebb674 --- /dev/null +++ b/assets/common/abilities/custom/gigas_frost/flashfreeze.ron @@ -0,0 +1,24 @@ +Shockwave( + energy_cost: 0, + buildup_duration: 2.0, + swing_duration: 0.12, + recover_duration: 1.5, + damage: 45.0, + poise_damage: 30, + knockback: (strength: 0.0, direction: TowardsUp), + shockwave_angle: 240.0, + shockwave_vertical_angle: 360.0, + shockwave_speed: 200.0, + shockwave_duration: 0.15, + requires_ground: false, + move_efficiency: 0.0, + damage_kind: Piercing, + specifier: IceSpikes, + ori_rate: 0.0, + damage_effect: Some(Buff(( + kind: Frozen, + dur_secs: 2.0, + strength: DamageFraction(0.3), + chance: 1.0, + ))), +) \ No newline at end of file diff --git a/assets/common/abilities/custom/gigas_frost/frost_summons.ron b/assets/common/abilities/custom/gigas_frost/frost_summons.ron new file mode 100644 index 0000000000..c2ff3cf16d --- /dev/null +++ b/assets/common/abilities/custom/gigas_frost/frost_summons.ron @@ -0,0 +1,18 @@ +BasicSummon( + buildup_duration: 1.75, + cast_duration: 1.5, + recover_duration: 0.75, + summon_amount: 12, + summon_distance: (10, 15), + summon_info: ( + body: BipedSmall(( + species: Boreal, + body_type: Male, + )), + scale: None, + has_health: true, + loadout_config: Some(BorealSummon), + skillset_config: None, + ), + duration: None, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/gigas_frost/ice_volley.ron b/assets/common/abilities/custom/gigas_frost/ice_volley.ron new file mode 100644 index 0000000000..a453ba6a5a --- /dev/null +++ b/assets/common/abilities/custom/gigas_frost/ice_volley.ron @@ -0,0 +1,15 @@ +BasicRanged( + energy_cost: 0, + buildup_duration: 0.5, + recover_duration: 0.9, + projectile: IceBomb( + damage: 30.0, + radius: 3.0, + knockback: 12.0, + min_falloff: 0.1, + ), + projectile_body: Object(IceBomb), + projectile_speed: 25.0, + num_projectiles: 5, + projectile_spread: 0.07, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/gigas_frost/icespike_smash.ron b/assets/common/abilities/custom/gigas_frost/icespike_smash.ron new file mode 100644 index 0000000000..69047e8275 --- /dev/null +++ b/assets/common/abilities/custom/gigas_frost/icespike_smash.ron @@ -0,0 +1,10 @@ +SpriteSummon( + buildup_duration: 1.3, + cast_duration: 0.1, + recover_duration: 1.1, + sprite: IceSpike, + del_timeout: Some((2, 5)), + summon_distance: (2, 12), + sparseness: 0.95, + angle: 360, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/gigas_frost/leapshockwave.ron b/assets/common/abilities/custom/gigas_frost/leapshockwave.ron new file mode 100644 index 0000000000..40ea424050 --- /dev/null +++ b/assets/common/abilities/custom/gigas_frost/leapshockwave.ron @@ -0,0 +1,26 @@ +LeapShockwave( + energy_cost: 0, + buildup_duration: 1.4, + movement_duration: 0.8, + swing_duration: 0.15, + recover_duration: 0.9, + damage: 45.0, + poise_damage: 10, + knockback: (strength: 3.0, direction: Up), + shockwave_angle: 360.0, + shockwave_vertical_angle: 15.0, + shockwave_speed: 20.0, + shockwave_duration: 0.8, + requires_ground: true, + move_efficiency: 0.2, + damage_kind: Piercing, + specifier: IceSpikes, + damage_effect: Some(Buff(( + kind: Frozen, + dur_secs: 1.0, + strength: DamageFraction(0.1), + chance: 1.0, + ))), + forward_leap_strength: 45.0, + vertical_leap_strength: 10.0, +) diff --git a/assets/common/abilities/custom/gigas_frost/wide_cleave.ron b/assets/common/abilities/custom/gigas_frost/wide_cleave.ron new file mode 100644 index 0000000000..50f1da813c --- /dev/null +++ b/assets/common/abilities/custom/gigas_frost/wide_cleave.ron @@ -0,0 +1,24 @@ +BasicMelee( + energy_cost: 0, + buildup_duration: 0.4, + swing_duration: 0.1, + recover_duration: 0.8, + melee_constructor: ( + kind: Slash( + damage: 90.0, + poise: 20.0, + knockback: 5.0, + energy_regen: 5.0, + ), + range: 5.0, + angle: 120.0, + damage_effect: Some(Buff(( + kind: Frozen, + dur_secs: 1.0, + strength: DamageFraction(0.1), + chance: 0.5, + ))), + multi_target: Some(Normal), + ), + ori_modifier: 1.0, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/harvester/ensnaringvines.ron b/assets/common/abilities/custom/harvester/ensnaringvines.ron index 2a5c82f908..e5d460b2f5 100644 --- a/assets/common/abilities/custom/harvester/ensnaringvines.ron +++ b/assets/common/abilities/custom/harvester/ensnaringvines.ron @@ -6,4 +6,5 @@ SpriteSummon( del_timeout: None, summon_distance: (0, 25), sparseness: 0.67, + angle: 360, ) \ No newline at end of file diff --git a/assets/common/abilities/custom/roshwalr/freezeshockwave.ron b/assets/common/abilities/custom/roshwalr/freezeshockwave.ron index 9e2ea1fbdf..cd70c59205 100644 --- a/assets/common/abilities/custom/roshwalr/freezeshockwave.ron +++ b/assets/common/abilities/custom/roshwalr/freezeshockwave.ron @@ -14,6 +14,7 @@ Shockwave( move_efficiency: 0.2, damage_kind: Piercing, specifier: IceSpikes, + ori_rate: 1.0, damage_effect: Some(Buff(( kind: Frozen, dur_secs: 4.0, diff --git a/assets/common/abilities/custom/seawyvern/seashockwave.ron b/assets/common/abilities/custom/seawyvern/seashockwave.ron index 7cbdeff4fc..d99f043161 100644 --- a/assets/common/abilities/custom/seawyvern/seashockwave.ron +++ b/assets/common/abilities/custom/seawyvern/seashockwave.ron @@ -14,4 +14,5 @@ Shockwave( move_efficiency: 0.1, damage_kind: Energy, specifier: Water, + ori_rate: 1.0, ) diff --git a/assets/common/abilities/custom/stonegolemfist/shockwave.ron b/assets/common/abilities/custom/stonegolemfist/shockwave.ron index 03b105a6c5..8c5ce39340 100644 --- a/assets/common/abilities/custom/stonegolemfist/shockwave.ron +++ b/assets/common/abilities/custom/stonegolemfist/shockwave.ron @@ -14,4 +14,5 @@ Shockwave( move_efficiency: 0.05, damage_kind: Crushing, specifier: Ground, + ori_rate: 1.0, ) diff --git a/assets/common/abilities/custom/tidalwarrior/totem_wave.ron b/assets/common/abilities/custom/tidalwarrior/totem_wave.ron index e384f2f05c..edc56d4ead 100644 --- a/assets/common/abilities/custom/tidalwarrior/totem_wave.ron +++ b/assets/common/abilities/custom/tidalwarrior/totem_wave.ron @@ -14,4 +14,5 @@ Shockwave( move_efficiency: 0.0, damage_kind: Crushing, specifier: Water, + ori_rate: 0.0, ) diff --git a/assets/common/abilities/custom/wealdwyvern/fireshockwave.ron b/assets/common/abilities/custom/wealdwyvern/fireshockwave.ron index 9989b39290..841c443ccb 100644 --- a/assets/common/abilities/custom/wealdwyvern/fireshockwave.ron +++ b/assets/common/abilities/custom/wealdwyvern/fireshockwave.ron @@ -14,4 +14,5 @@ Shockwave( move_efficiency: 0.1, damage_kind: Energy, specifier: Fire, + ori_rate: 1.0, ) diff --git a/assets/common/abilities/custom/woodgolem/shockwave.ron b/assets/common/abilities/custom/woodgolem/shockwave.ron index ae016860cb..fc695477da 100644 --- a/assets/common/abilities/custom/woodgolem/shockwave.ron +++ b/assets/common/abilities/custom/woodgolem/shockwave.ron @@ -14,4 +14,5 @@ Shockwave( move_efficiency: 0.0, damage_kind: Crushing, specifier: Ground, + ori_rate: 1.0, ) diff --git a/assets/common/abilities/custom/yeti/icespikes.ron b/assets/common/abilities/custom/yeti/icespikes.ron index 51b0469973..a1452397b4 100644 --- a/assets/common/abilities/custom/yeti/icespikes.ron +++ b/assets/common/abilities/custom/yeti/icespikes.ron @@ -14,6 +14,7 @@ Shockwave( move_efficiency: 0.2, damage_kind: Piercing, specifier: IceSpikes, + ori_rate: 1.0, damage_effect: Some(Buff(( kind: Bleeding, dur_secs: 10.0, diff --git a/assets/common/abilities/gnarling/chieftain/fireshockwave.ron b/assets/common/abilities/gnarling/chieftain/fireshockwave.ron index b1d28fb0dc..aa7f8be86e 100644 --- a/assets/common/abilities/gnarling/chieftain/fireshockwave.ron +++ b/assets/common/abilities/gnarling/chieftain/fireshockwave.ron @@ -14,4 +14,5 @@ Shockwave( move_efficiency: 0, damage_kind: Energy, specifier: Fire, + ori_rate: 1.0, ) diff --git a/assets/common/abilities/staff/fireshockwave.ron b/assets/common/abilities/staff/fireshockwave.ron index eac4f3f5d2..64dcbf9506 100644 --- a/assets/common/abilities/staff/fireshockwave.ron +++ b/assets/common/abilities/staff/fireshockwave.ron @@ -14,4 +14,5 @@ Shockwave( move_efficiency: 0.1, damage_kind: Energy, specifier: Fire, + ori_rate: 1.0, ) diff --git a/assets/common/entity/world/world_bosses/gigas_frost.ron b/assets/common/entity/world/world_bosses/gigas_frost.ron new file mode 100644 index 0000000000..a6b728cc73 --- /dev/null +++ b/assets/common/entity/world/world_bosses/gigas_frost.ron @@ -0,0 +1,11 @@ +#![enable(implicit_some)] +( + name: Name("Frost Gigas"), + body: RandomWith("gigas_frost"), + alignment: Alignment(Enemy), + loot: LootTable("common.loot_tables.world.world_bosses.gigas_frost.boss"), + inventory: ( + loadout: FromBody, + ), + meta: [], +) \ No newline at end of file diff --git a/assets/common/entity/world/world_bosses/summons/boreal_warrior.ron b/assets/common/entity/world/world_bosses/summons/boreal_warrior.ron new file mode 100644 index 0000000000..be9843911e --- /dev/null +++ b/assets/common/entity/world/world_bosses/summons/boreal_warrior.ron @@ -0,0 +1,19 @@ +#![enable(implicit_some)] +( + name: Name("Boreal Warrior"), + body: RandomWith("boreal"), + alignment: Alignment(Enemy), + loot: LootTable("common.loot_tables.world.world_bosses.gigas_frost.summon"), + inventory: ( + loadout: Inline(( + inherit: Asset("common.loadout.world.boreal.boreal_warrior"), + active_hands: InHands((Choice([ + (1, Item("common.items.npc_weapons.biped_small.boreal.bow")), + (1, Item("common.items.npc_weapons.biped_small.boreal.hammer")), + ]), None)), + )), + ), + meta: [ + SkillSetAsset("common.skillset.preset.rank5.fullskill"), + ], +) \ No newline at end of file diff --git a/assets/common/items/armor/boreal/back.ron b/assets/common/items/armor/boreal/back.ron new file mode 100644 index 0000000000..803db9e94a --- /dev/null +++ b/assets/common/items/armor/boreal/back.ron @@ -0,0 +1,10 @@ +ItemDef( + name: "Boreal's Cloak", + description: "Thick yet surprisingly cold.", + kind: Armor(( + kind: Back, + stats: FromSet("Boreal"), + )), + quality: Legendary, + tags: [], +) \ No newline at end of file diff --git a/assets/common/items/armor/boreal/belt.ron b/assets/common/items/armor/boreal/belt.ron new file mode 100644 index 0000000000..e4b8f4e2da --- /dev/null +++ b/assets/common/items/armor/boreal/belt.ron @@ -0,0 +1,10 @@ +ItemDef( + name: "Boreal Belt", + description: "It's cold.", + kind: Armor(( + kind: Belt, + stats: FromSet("Boreal"), + )), + quality: Legendary, + tags: [], +) diff --git a/assets/common/items/armor/boreal/chest.ron b/assets/common/items/armor/boreal/chest.ron new file mode 100644 index 0000000000..3b57834eb3 --- /dev/null +++ b/assets/common/items/armor/boreal/chest.ron @@ -0,0 +1,10 @@ +ItemDef( + name: "Boreal's Chestplate", + description: "So frigid that you can feel it in your heart.", + kind: Armor(( + kind: Chest, + stats: FromSet("Boreal"), + )), + quality: Legendary, + tags: [], +) \ No newline at end of file diff --git a/assets/common/items/armor/boreal/foot.ron b/assets/common/items/armor/boreal/foot.ron new file mode 100644 index 0000000000..10886d34d5 --- /dev/null +++ b/assets/common/items/armor/boreal/foot.ron @@ -0,0 +1,10 @@ +ItemDef( + name: "Boreal's Wrappings", + description: "The blistering cold makes it hard to move.", + kind: Armor(( + kind: Foot, + stats: FromSet("Boreal"), + )), + quality: Legendary, + tags: [], +) \ No newline at end of file diff --git a/assets/common/items/armor/boreal/hand.ron b/assets/common/items/armor/boreal/hand.ron new file mode 100644 index 0000000000..ee347dc4cd --- /dev/null +++ b/assets/common/items/armor/boreal/hand.ron @@ -0,0 +1,10 @@ +ItemDef( + name: "Boreal's Guantlets", + description: "Colder than the touch of death.", + kind: Armor(( + kind: Hand, + stats: FromSet("Boreal"), + )), + quality: Legendary, + tags: [], +) \ No newline at end of file diff --git a/assets/common/items/armor/boreal/pants.ron b/assets/common/items/armor/boreal/pants.ron new file mode 100644 index 0000000000..f43ef0aed3 --- /dev/null +++ b/assets/common/items/armor/boreal/pants.ron @@ -0,0 +1,10 @@ +ItemDef( + name: "Boreal's Tunic", + description: "Colder than the climate it protects you from.", + kind: Armor(( + kind: Pants, + stats: FromSet("Boreal"), + )), + quality: Legendary, + tags: [], +) \ No newline at end of file diff --git a/assets/common/items/armor/boreal/shoulder.ron b/assets/common/items/armor/boreal/shoulder.ron new file mode 100644 index 0000000000..07f8e449cc --- /dev/null +++ b/assets/common/items/armor/boreal/shoulder.ron @@ -0,0 +1,10 @@ +ItemDef( + name: "Boreal's Spaulders", + description: "I should probbaly think of something before merging", + kind: Armor(( + kind: Shoulder, + stats: FromSet("Boreal"), + )), + quality: Legendary, + tags: [], +) \ No newline at end of file diff --git a/assets/common/items/crafting_ing/glacial_crystal.ron b/assets/common/items/crafting_ing/glacial_crystal.ron new file mode 100644 index 0000000000..b77ce270b9 --- /dev/null +++ b/assets/common/items/crafting_ing/glacial_crystal.ron @@ -0,0 +1,9 @@ +ItemDef( + name: "Glacial Crystal", + description: "The purest form of ice, cold enough to cool lava.", + kind: Ingredient( + // Descriptor not needed + descriptor: "", ), + quality: Legendary, + tags: [], +) \ No newline at end of file diff --git a/assets/common/items/crafting_ing/pearl.ron b/assets/common/items/crafting_ing/pearl.ron new file mode 100644 index 0000000000..8d331c4ff4 --- /dev/null +++ b/assets/common/items/crafting_ing/pearl.ron @@ -0,0 +1,9 @@ +ItemDef( + name: "Pearl", + description: "Would make a nice lamp.", + kind: Ingredient( + // Descriptor not needed + descriptor: "", ), + quality: Epic, + tags: [], +) \ No newline at end of file diff --git a/assets/common/items/glider/winter_wings.ron b/assets/common/items/glider/winter_wings.ron new file mode 100644 index 0000000000..ae49f84954 --- /dev/null +++ b/assets/common/items/glider/winter_wings.ron @@ -0,0 +1,7 @@ +ItemDef( + name: "Wings of Winter", + description: "Sparkles brilliantly and cooly even under the warm sun.", + kind: Glider, + quality: Legendary, + tags: [], +) diff --git a/assets/common/items/npc_armor/biped_large/gigas_frost.ron b/assets/common/items/npc_armor/biped_large/gigas_frost.ron new file mode 100644 index 0000000000..15fe2b7a46 --- /dev/null +++ b/assets/common/items/npc_armor/biped_large/gigas_frost.ron @@ -0,0 +1,14 @@ +ItemDef( + name: "Frost Gigas Armor", + description: "The best defense is a good offense.", + kind: Armor(( + kind: Chest, + stats: Direct(( + protection: Some(Normal(140.0)), + poise_resilience: Some(Normal(25.0)), + energy_max: Some(150.0), + )), + )), + quality: Legendary, + tags: [], +) diff --git a/assets/common/items/npc_armor/biped_small/boreal/chest/warrior.ron b/assets/common/items/npc_armor/biped_small/boreal/chest/warrior.ron new file mode 100644 index 0000000000..cd9e2b56a3 --- /dev/null +++ b/assets/common/items/npc_armor/biped_small/boreal/chest/warrior.ron @@ -0,0 +1,16 @@ +ItemDef( + name: "Boreal's Chestplate", + description: "So frigid that you can feel it in your heart.", + kind: Armor(( + kind: Chest, + stats: Direct(( + protection: Some(Normal(80.0)), + poise_resilience: Some(Normal(60.0)), + energy_max: Some(120.0), + energy_reward: Some(0.027), + crit_power: Some(0.025), + )), + )), + quality: Legendary, + tags: [], +) \ No newline at end of file diff --git a/assets/common/items/npc_armor/biped_small/boreal/foot/warrior.ron b/assets/common/items/npc_armor/biped_small/boreal/foot/warrior.ron new file mode 100644 index 0000000000..6c9738902e --- /dev/null +++ b/assets/common/items/npc_armor/biped_small/boreal/foot/warrior.ron @@ -0,0 +1,16 @@ +ItemDef( + name: "Boreal's Wrappings", + description: "The blistering cold makes it hard to move.", + kind: Armor(( + kind: Foot, + stats: Direct(( + protection: Some(Normal(1.0)), + poise_resilience: Some(Normal(1.0)), + energy_max: Some(0.9), + energy_reward: Some(0.009), + crit_power: Some(0.008), + )), + )), + quality: Legendary, + tags: [], +) \ No newline at end of file diff --git a/assets/common/items/npc_armor/biped_small/boreal/hand/warrior.ron b/assets/common/items/npc_armor/biped_small/boreal/hand/warrior.ron new file mode 100644 index 0000000000..03103e5bb5 --- /dev/null +++ b/assets/common/items/npc_armor/biped_small/boreal/hand/warrior.ron @@ -0,0 +1,16 @@ +ItemDef( + name: "Boreal's Guantlets", + description: "Colder than the touch of death.", + kind: Armor(( + kind: Hand, + stats: Direct(( + protection: Some(Normal(1.0)), + poise_resilience: Some(Normal(1.0)), + energy_max: Some(0.9), + energy_reward: Some(0.009), + crit_power: Some(0.008), + )), + )), + quality: Legendary, + tags: [], +) \ No newline at end of file diff --git a/assets/common/items/npc_armor/biped_small/boreal/head/warrior.ron b/assets/common/items/npc_armor/biped_small/boreal/head/warrior.ron new file mode 100644 index 0000000000..5ae2e6b6a8 --- /dev/null +++ b/assets/common/items/npc_armor/biped_small/boreal/head/warrior.ron @@ -0,0 +1,16 @@ +ItemDef( + name: "Boreal Helmet", + description: "Did somebody say...BRAINFREEZE?!", + kind: Armor(( + kind: Head, + stats: Direct(( + protection: Some(Normal(1.0)), + poise_resilience: Some(Normal(1.0)), + energy_max: Some(0.9), + energy_reward: Some(0.009), + crit_power: Some(0.008), + )), + )), + quality: Legendary, + tags: [], +) \ No newline at end of file diff --git a/assets/common/items/npc_armor/biped_small/boreal/pants/warrior.ron b/assets/common/items/npc_armor/biped_small/boreal/pants/warrior.ron new file mode 100644 index 0000000000..ef046d808f --- /dev/null +++ b/assets/common/items/npc_armor/biped_small/boreal/pants/warrior.ron @@ -0,0 +1,16 @@ +ItemDef( + name: "Boreal's Tunic", + description: "Colder than the climate it protects you from.", + kind: Armor(( + kind: Pants, + stats: Direct(( + protection: Some(Normal(1.0)), + poise_resilience: Some(Normal(1.0)), + energy_max: Some(0.9), + energy_reward: Some(0.009), + crit_power: Some(0.008), + )), + )), + quality: Legendary, + tags: [], +) \ No newline at end of file diff --git a/assets/common/items/npc_weapons/axe/gigas_frost_axe.ron b/assets/common/items/npc_weapons/axe/gigas_frost_axe.ron new file mode 100644 index 0000000000..c49e0d7cea --- /dev/null +++ b/assets/common/items/npc_weapons/axe/gigas_frost_axe.ron @@ -0,0 +1,21 @@ +ItemDef( + name: "Frost Gigas Axe", + description: "Placeholder", + kind: Tool(( + kind: Axe, + hands: Two, + stats: ( + equip_time_secs: 0.5, + power: 1.0, + effect_power: 1.0, + speed: 1.0, + crit_chance: 0.1, + range: 1.0, + energy_efficiency: 1.0, + buff_strength: 1.0, + ), + )), + quality: Legendary, + tags: [], + ability_spec: Some(Custom("Frost Gigas")), +) \ No newline at end of file diff --git a/assets/common/items/npc_weapons/biped_small/boreal/bow.ron b/assets/common/items/npc_weapons/biped_small/boreal/bow.ron new file mode 100644 index 0000000000..d7181fff8b --- /dev/null +++ b/assets/common/items/npc_weapons/biped_small/boreal/bow.ron @@ -0,0 +1,21 @@ +ItemDef( + name: "Boreal Bow", + description: "", + kind: Tool(( + kind: Bow, + hands: Two, + stats: ( + equip_time_secs: 0.0, + power: 1.0, + effect_power: 1.0, + speed: 1.0, + crit_chance: 0.12, + range: 1.0, + energy_efficiency: 1.0, + buff_strength: 1.0, + ), + )), + quality: Epic, + tags: [], + ability_spec: Some(Custom("Boreal Bow")), +) \ No newline at end of file diff --git a/assets/common/items/npc_weapons/biped_small/boreal/hammer.ron b/assets/common/items/npc_weapons/biped_small/boreal/hammer.ron new file mode 100644 index 0000000000..4ccc0bac79 --- /dev/null +++ b/assets/common/items/npc_weapons/biped_small/boreal/hammer.ron @@ -0,0 +1,21 @@ +ItemDef( + name: "Boreal Hammer", + description: "", + kind: Tool(( + kind: Hammer, + hands: Two, + stats: ( + equip_time_secs: 0.0, + power: 1.0, + effect_power: 1.0, + speed: 1.0, + crit_chance: 0.12, + range: 1.0, + energy_efficiency: 1.0, + buff_strength: 1.0, + ), + )), + quality: Epic, + tags: [], + ability_spec: Some(Custom("Boreal Hammer")), +) \ No newline at end of file diff --git a/assets/common/items/tool/instruments/glass_flute.ron b/assets/common/items/tool/instruments/glass_flute.ron index a06524cc71..6744861925 100644 --- a/assets/common/items/tool/instruments/glass_flute.ron +++ b/assets/common/items/tool/instruments/glass_flute.ron @@ -15,7 +15,7 @@ ItemDef( buff_strength: 1.0, ), )), - quality: Common, + quality: Legendary, tags: [Utility], ability_spec: Some(Custom("GlassFlute")), ) diff --git a/assets/common/items/tool/instruments/guitar_dark.ron b/assets/common/items/tool/instruments/guitar_dark.ron index efa9f76031..d76811a867 100644 --- a/assets/common/items/tool/instruments/guitar_dark.ron +++ b/assets/common/items/tool/instruments/guitar_dark.ron @@ -15,7 +15,7 @@ ItemDef( buff_strength: 1.0, ), )), - quality: Common, + quality: Legendary, tags: [Utility], ability_spec: Some(Custom("DarkGuitar")), ) \ No newline at end of file diff --git a/assets/common/items/tool/instruments/icy_talharpa.ron b/assets/common/items/tool/instruments/icy_talharpa.ron index 9e7588ebc0..c25d658270 100644 --- a/assets/common/items/tool/instruments/icy_talharpa.ron +++ b/assets/common/items/tool/instruments/icy_talharpa.ron @@ -15,7 +15,7 @@ ItemDef( buff_strength: 1.0, ), )), - quality: Common, + quality: Legendary, tags: [Utility], ability_spec: Some(Custom("IcyTalharpa")), ) \ No newline at end of file diff --git a/assets/common/loadout/world/boreal/boreal_warrior.ron b/assets/common/loadout/world/boreal/boreal_warrior.ron new file mode 100644 index 0000000000..4af0851be0 --- /dev/null +++ b/assets/common/loadout/world/boreal/boreal_warrior.ron @@ -0,0 +1,12 @@ +#![enable(implicit_some)] +( + head: Item("common.items.npc_armor.biped_small.boreal.head.warrior"), + chest: Item("common.items.npc_armor.biped_small.boreal.chest.warrior"), + gloves: Item("common.items.npc_armor.biped_small.boreal.hand.warrior"), + legs: Item("common.items.npc_armor.biped_small.boreal.pants.warrior"), + feet: Item("common.items.npc_armor.biped_small.boreal.foot.warrior"), + active_hands: InHands((Choice([ + (1, Item("common.items.npc_weapons.biped_small.boreal.bow")), + (1, Item("common.items.npc_weapons.biped_small.boreal.hammer")), + ]), None)), +) \ No newline at end of file diff --git a/assets/common/loot_tables/armor/boreal.ron b/assets/common/loot_tables/armor/boreal.ron new file mode 100644 index 0000000000..30fb5bda30 --- /dev/null +++ b/assets/common/loot_tables/armor/boreal.ron @@ -0,0 +1,10 @@ +[ + (1.0, Item("common.items.armor.boreal.belt")), + (1.0, Item("common.items.armor.boreal.chest")), + (1.0, Item("common.items.armor.boreal.foot")), + (1.0, Item("common.items.armor.boreal.hand")), + (1.0, Item("common.items.armor.boreal.pants")), + (1.0, Item("common.items.armor.boreal.shoulder")), + (1.0, Item("common.items.armor.boreal.back")), + (1.0, Item("common.items.armor.misc.head.boreal_warhelm")), +] \ No newline at end of file diff --git a/assets/common/loot_tables/dungeon/sea_chapel/chest_coral.ron b/assets/common/loot_tables/dungeon/sea_chapel/chest_coral.ron index e537aa6fbd..533cbb4dc8 100644 --- a/assets/common/loot_tables/dungeon/sea_chapel/chest_coral.ron +++ b/assets/common/loot_tables/dungeon/sea_chapel/chest_coral.ron @@ -1,5 +1,6 @@ [ // Ingredients (0.5, Item("common.items.crafting_ing.coral_branch")), + (0.3, Item("common.items.crafting_ing.pearl")), (5.0, Item("common.items.crafting_ing.seashells")), ] \ No newline at end of file diff --git a/assets/common/loot_tables/dungeon/sea_chapel/dagon.ron b/assets/common/loot_tables/dungeon/sea_chapel/dagon.ron index 8901187705..7e10c98663 100644 --- a/assets/common/loot_tables/dungeon/sea_chapel/dagon.ron +++ b/assets/common/loot_tables/dungeon/sea_chapel/dagon.ron @@ -1,5 +1,6 @@ [ (0.5, Item("common.items.crafting_ing.abyssal_heart")), + (0.5, Item("common.items.crafting_ing.pearl")), (5.0, LootTable("common.loot_tables.creature.quad_low.fanged")), (5.0, Item("common.items.food.meat.tough_raw")), ] \ No newline at end of file diff --git a/assets/common/loot_tables/world/world_bosses/gigas_frost/boss.ron b/assets/common/loot_tables/world/world_bosses/gigas_frost/boss.ron new file mode 100644 index 0000000000..0e599748f5 --- /dev/null +++ b/assets/common/loot_tables/world/world_bosses/gigas_frost/boss.ron @@ -0,0 +1,4 @@ +[ + (1.0, LootTable("common.loot_tables.armor.boreal")), + (1.0, ItemQuantity("common.items.crafting_ing.glacial_crystal", 5, 15)), +] \ No newline at end of file diff --git a/assets/common/loot_tables/world/world_bosses/gigas_frost/summon.ron b/assets/common/loot_tables/world/world_bosses/gigas_frost/summon.ron new file mode 100644 index 0000000000..c1626bb6f6 --- /dev/null +++ b/assets/common/loot_tables/world/world_bosses/gigas_frost/summon.ron @@ -0,0 +1,8 @@ +[ + // Currency + (1.0, ItemQuantity("common.items.utility.coins", 40, 100)), + // Food + (1.0, LootTable("common.loot_tables.food.prepared")), + // Nothing + (2.0, Nothing), +] \ No newline at end of file diff --git a/assets/common/material_stats_manifest.ron b/assets/common/material_stats_manifest.ron index 135f1c0671..16ad69e44b 100644 --- a/assets/common/material_stats_manifest.ron +++ b/assets/common/material_stats_manifest.ron @@ -317,5 +317,12 @@ energy_reward: Some(0.5), crit_power: Some(0.8), ), + "Boreal": ( + protection: Some(Normal(98.0)), + poise_resilence: Some(Normal(34.0)), + energy_reward: Some(-0.35), + crit_power: Some(0.35), + stealth: Some(0.5), + ) }, ) diff --git a/assets/common/npc_names.ron b/assets/common/npc_names.ron index 138805ae7f..793c879fa7 100644 --- a/assets/common/npc_names.ron +++ b/assets/common/npc_names.ron @@ -961,6 +961,10 @@ tursus: ( keyword: "tursus", generic: "Tursus" + ), + gigas_frost: ( + keyword: "gigas_frost", + generic: "Frost Gigas" ) ) ), @@ -1128,7 +1132,11 @@ husk: ( keyword: "husk", generic: "Husk" - ) + ), + boreal: ( + keyword: "boreal", + generic: "Boreal", + ), ) ), fish_small: ( diff --git a/assets/common/recipe_book.ron b/assets/common/recipe_book.ron index 1bc723599f..f775e50f90 100644 --- a/assets/common/recipe_book.ron +++ b/assets/common/recipe_book.ron @@ -489,6 +489,17 @@ craft_sprite: Some(CraftingBench), is_recycling: false, ), + "winter_wings": ( + output: ("common.items.glider.winter_wings", 1), + inputs: [ + (Item("common.items.crafting_ing.glacial_crystal"), 2, false), + (Item("common.items.crafting_ing.animal_misc.icy_fang"), 32, false), + (Item("common.items.mineral.gem.sapphire"), 18, false), + (Item("common.items.tool.craftsman_hammer"), 0, false), + ], + craft_sprite: Some(CraftingBench), + is_recycling: false, + ), "healing_sceptre": ( output: ("common.items.weapons.sceptre.starter_sceptre", 1), inputs: [ @@ -1899,6 +1910,17 @@ ], craft_sprite: Some(Anvil), ), + "polaris": ( + output: ("common.items.lantern.polaris", 1), + inputs: [ + (Item("common.items.crafting_ing.glacial_crystal"), 1, false), + (Item("common.items.crafting_ing.animal_misc.icy_fang"), 16, false), + (Item("common.items.crafting_ing.pearl"), 1, false), + (Item("common.items.tool.craftsman_hammer"), 0, false), + ], + craft_sprite: Some(CraftingBench), + is_recycling: false, + ), /// MODULAR WEAPONS/SWORDS/SECONDARY COMPONENTS "short_hilt": ( output: ("common.items.modular.weapon.secondary.sword.short", 1), @@ -2164,4 +2186,15 @@ craft_sprite: Some(CraftingBench), is_recycling: false, ), + "icy_talharpa": ( + output: ("common.items.tool.instruments.icy_talharpa", 1), + inputs: [ + (Item("common.items.crafting_ing.glacial_crystal"), 4, false), + (Item("common.items.crafting_ing.animal_misc.icy_fang"), 8, false), + (Item("common.items.crafting_ing.cloth.silk"), 3, false), + (Item("common.items.tool.craftsman_hammer"), 0, false), + ], + craft_sprite: Some(CraftingBench), + is_recycling: false, + ), } diff --git a/assets/server/manifests/kits.ron b/assets/server/manifests/kits.ron index ac32ff1522..e1719de679 100644 --- a/assets/server/manifests/kits.ron +++ b/assets/server/manifests/kits.ron @@ -378,6 +378,16 @@ (Item("common.items.armor.merchant.pants"),1), (Item("common.items.armor.merchant.shoulder"),1), ], + "boreal": [ + (Item("common.items.armor.boreal.chest"),1), + (Item("common.items.armor.boreal.pants"),1), + (Item("common.items.armor.boreal.hand"),1), + (Item("common.items.armor.boreal.foot"),1), + (Item("common.items.armor.boreal.shoulder"),1), + (Item("common.items.armor.boreal.belt"),1), + (Item("common.items.armor.boreal.back"),1), + (Item("common.items.armor.misc.head.boreal_warhelm"),1), + ], "instruments": [ (Item("common.items.tool.instruments.double_bass"),1), (Item("common.items.tool.instruments.flute"),1), diff --git a/assets/voxygen/audio/sfx.ron b/assets/voxygen/audio/sfx.ron index b48df9bebc..c938ae4389 100644 --- a/assets/voxygen/audio/sfx.ron +++ b/assets/voxygen/audio/sfx.ron @@ -348,6 +348,12 @@ ], threshold: 0.8, ), + Attack(DashMelee(Action), Hammer): ( + files: [ + "voxygen.audio.sfx.abilities.swing", + ], + threshold: 0.7, + ), Attack(SpinMelee(Action), Sword): ( files: [ "voxygen.audio.sfx.abilities.swing_sword", @@ -458,6 +464,12 @@ ], threshold: 0.8, ), + Attack(BasicMelee(Action), Axe): ( + files: [ + "voxygen.audio.sfx.abilities.swing", + ], + threshold: 0.8, + ), Inventory(CollectedTool(Axe)): ( files: [ "voxygen.audio.sfx.inventory.pickup_sword", @@ -1232,6 +1244,30 @@ ], threshold: 0.2, ), + GigaRoar: ( + files: [ + "voxygen.audio.sfx.abilities.gigas_frost_roar", + ], + threshold: 1.3, + ), + FlashFreeze: ( + files: [ + "voxygen.audio.sfx.abilities.minotaur_smash_2", + ], + threshold: 0.2, + ), + IceSpikes: ( + files: [ + "voxygen.audio.sfx.abilities.minotaur_smash_2", + ], + threshold: 0.2, + ), + IceCrack: ( + files: [ + "voxygen.audio.sfx.abilities.ice_crack", + ], + threshold: 0.9, + ), Utterance(Angry, Alligator): ( files: [ "voxygen.audio.sfx.utterance.alligator_angry1", diff --git a/assets/voxygen/audio/sfx/abilities/gigas_frost_roar.ogg b/assets/voxygen/audio/sfx/abilities/gigas_frost_roar.ogg new file mode 100644 index 0000000000..bb109f4e8a --- /dev/null +++ b/assets/voxygen/audio/sfx/abilities/gigas_frost_roar.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f7157a95488e29a9954273fdd6447dd75b44745e6f8a7d9e787c1c947af0650 +size 38571 diff --git a/assets/voxygen/audio/sfx/abilities/ice_crack.ogg b/assets/voxygen/audio/sfx/abilities/ice_crack.ogg new file mode 100644 index 0000000000..894f782c21 --- /dev/null +++ b/assets/voxygen/audio/sfx/abilities/ice_crack.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:826c13df931896c93e320cdf7e347e9e83ea46565a2dcfc3e9d6af36b8bc35fd +size 50327 diff --git a/assets/voxygen/item_image_manifest.ron b/assets/voxygen/item_image_manifest.ron index 4e19648ce3..59d61f494d 100644 --- a/assets/voxygen/item_image_manifest.ron +++ b/assets/voxygen/item_image_manifest.ron @@ -1950,6 +1950,35 @@ "voxel.armor.ferocious.back", (0.0, 0.0, 0.0), (-120.0, 210.0,15.0), 0.9, ), + //Boreal Armor + Simple("common.items.armor.boreal.chest"): VoxTrans( + "voxel.armor.boreal.chest", + (0.0, 1.0, 0.0), (-120.0, 210.0,15.0), 1.1, + ), + Simple("common.items.armor.boreal.pants"): VoxTrans( + "voxel.armor.boreal.pants", + (0.0, 1.0, 0.0), (-120.0, 210.0,15.0), 0.9, + ), + Simple("common.items.armor.boreal.belt"): VoxTrans( + "voxel.armor.boreal.belt", + (0.0, 0.0, 0.0), (-120.0, 210.0,15.0), 0.9, + ), + Simple("common.items.armor.boreal.foot"): VoxTrans( + "voxel.armor.boreal.foot", + (0.0, 0.0, 0.0), (-120.0, 210.0,15.0), 0.9, + ), + Simple("common.items.armor.boreal.hand"): VoxTrans( + "voxel.armor.boreal.hand", + (0.0, 0.0, 0.0), (-90.0, 135.0, 0.0), 1.0, + ), + Simple("common.items.armor.boreal.shoulder"): VoxTrans( + "voxel.armor.boreal.shoulder", + (0.0, 0.0, 0.0), (-120.0, 210.0,15.0), 1.0, + ), + Simple("common.items.armor.boreal.back"): VoxTrans( + "voxel.armor.boreal.back", + (0.0, 0.0, 0.0), (-120.0, 210.0,15.0), 0.9, + ), //Blue Leather Armor Simple("common.items.npc_armor.chest.leather_blue"): VoxTrans( "voxel.armor.leather_blue.chest", @@ -3592,10 +3621,18 @@ "voxel.sprite.crafting_ing.abyssal_heart", (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8, ), + Simple("common.items.crafting_ing.pearl"): VoxTrans( + "voxel.sprite.crafting_ing.pearl", + (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.5, + ), Simple("common.items.crafting_ing.coral_branch"): VoxTrans( "voxel.sprite.crafting_ing.coral_branch", (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8, ), + Simple("common.items.crafting_ing.glacial_crystal"): VoxTrans( + "voxel.object.glacial_crystal", + (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 0.8, + ), // Gliders Simple("common.items.glider.cloverleaf"): VoxTrans( "voxel.glider.starter", @@ -3657,6 +3694,10 @@ "voxel.glider.leaves", (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 1.1, ), + Simple("common.items.glider.winter_wings"): VoxTrans( + "voxel.glider.winter_wings", + (0.0, 0.0, 0.0), (-50.0, 30.0, 20.0), 1.1, + ), // Debug Items Simple("common.items.debug.admin_stick"): VoxTrans( "voxel.weapon.tool.broom_belzeshrub_purple", diff --git a/assets/voxygen/shaders/particle-vert.glsl b/assets/voxygen/shaders/particle-vert.glsl index 438648c113..1dd6faacb8 100644 --- a/assets/voxygen/shaders/particle-vert.glsl +++ b/assets/voxygen/shaders/particle-vert.glsl @@ -79,6 +79,7 @@ const int LIGHTNING = 38; const int STEAM = 39; const int BARRELORGAN = 40; const int POTION_SICKNESS = 41; +const int GIGA_SNOW = 42; // meters per second squared (acceleration) const float earth_gravity = 9.807; @@ -656,6 +657,15 @@ void main() { spin_in_axis(vec3(1,0,0),0) ); break; + case GIGA_SNOW: + f_reflect = 0.0; + attr = Attr( + (inst_dir * slow_end(1.5)) + vec3(rand0, rand1, rand2) * (percent() + 2) * 0.1, + vec3((3.5 * (1 - slow_start(0.2)))), + vec4(vec3(2, 2, 2), 1), + spin_in_axis(vec3(rand6, rand7, rand8), percent() * 10 + 3 * rand9) + ); + break; default: attr = Attr( linear_motion( diff --git a/assets/voxygen/voxel/armor/boreal/back.vox b/assets/voxygen/voxel/armor/boreal/back.vox new file mode 100644 index 0000000000..f5425e859f --- /dev/null +++ b/assets/voxygen/voxel/armor/boreal/back.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6124f8d77fcab8837d636763351cfdae3d0d3727ebc2afa8c3bc90015a8e8a6 +size 2128 diff --git a/assets/voxygen/voxel/armor/boreal/belt.vox b/assets/voxygen/voxel/armor/boreal/belt.vox new file mode 100644 index 0000000000..706838b46c --- /dev/null +++ b/assets/voxygen/voxel/armor/boreal/belt.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9971b93eccef01e440154a51b3e37ac7702694868d69052eb2af9ee2b99dc953 +size 1480 diff --git a/assets/voxygen/voxel/armor/boreal/chest.vox b/assets/voxygen/voxel/armor/boreal/chest.vox new file mode 100644 index 0000000000..14a34f487d --- /dev/null +++ b/assets/voxygen/voxel/armor/boreal/chest.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0767c30830ba39a195ef711fa3362d1e89d59e4883aceab98daf8ebfcbcb9a9f +size 2856 diff --git a/assets/voxygen/voxel/armor/boreal/foot.vox b/assets/voxygen/voxel/armor/boreal/foot.vox new file mode 100644 index 0000000000..992ca80476 --- /dev/null +++ b/assets/voxygen/voxel/armor/boreal/foot.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:addac9ad52077c966d01bbd782c09b20e636b172421ab7cb68819fd7f23db036 +size 1492 diff --git a/assets/voxygen/voxel/armor/boreal/hand.vox b/assets/voxygen/voxel/armor/boreal/hand.vox new file mode 100644 index 0000000000..34aef25488 --- /dev/null +++ b/assets/voxygen/voxel/armor/boreal/hand.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d1d99058b243642f02c3de08910fdafa8115cd39e6f24af93430d1d29c493e8 +size 1288 diff --git a/assets/voxygen/voxel/armor/boreal/hat.vox b/assets/voxygen/voxel/armor/boreal/hat.vox new file mode 100644 index 0000000000..d99bae06b4 --- /dev/null +++ b/assets/voxygen/voxel/armor/boreal/hat.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f62786e35236600ade760cdf8cce748ea806177eed7a0d0f6d260e8542f1f90d +size 36456 diff --git a/assets/voxygen/voxel/armor/boreal/pants.vox b/assets/voxygen/voxel/armor/boreal/pants.vox new file mode 100644 index 0000000000..95e8bfe5c3 --- /dev/null +++ b/assets/voxygen/voxel/armor/boreal/pants.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f53540d2941083ae90d69b577aef762182cb6e91d03ca5eae2337c4d27ae9ee +size 2064 diff --git a/assets/voxygen/voxel/armor/boreal/shoulder.vox b/assets/voxygen/voxel/armor/boreal/shoulder.vox new file mode 100644 index 0000000000..8351314644 --- /dev/null +++ b/assets/voxygen/voxel/armor/boreal/shoulder.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0c6ac8cd596135721391379f875be3484366b1f0ee5acfbce8805f545c3f7e0 +size 1392 diff --git a/assets/voxygen/voxel/biped_large_central_manifest.ron b/assets/voxygen/voxel/biped_large_central_manifest.ron index d34fdc6e9b..a1a32c1529 100644 --- a/assets/voxygen/voxel/biped_large_central_manifest.ron +++ b/assets/voxygen/voxel/biped_large_central_manifest.ron @@ -1144,4 +1144,56 @@ central: ("armor.empty"), ) ), + (Gigasfrost, Male): ( + head: ( + offset: (-13.0, -7.0, 0.0), + central: ("npc.gigas_frost.male.head"), + ), + torso_upper: ( + offset: (-11.0, -15.5, -10.0), + central: ("npc.gigas_frost.male.torso_upper"), + ), + torso_lower: ( + offset: (-15.0, -12.5, -17.0), + central: ("npc.gigas_frost.male.torso_lower"), + ), + jaw: ( + offset: (-3.0, 0.0, -3.5), + central: ("npc.gigas_frost.male.jaw"), + ), + tail: ( + offset: (-1.5, -17.0, -8.0), + central: ("armor.empty"), + ), + second: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ) + ), + (Gigasfrost, Female): ( + head: ( + offset: (-13.0, -7.0, 0.0), + central: ("npc.gigas_frost.male.head"), + ), + torso_upper: ( + offset: (-11.0, -15.5, -10.0), + central: ("npc.gigas_frost.male.torso_upper"), + ), + torso_lower: ( + offset: (-15.0, -12.5, -17.0), + central: ("npc.gigas_frost.male.torso_lower"), + ), + jaw: ( + offset: (-3.0, 0.0, -3.5), + central: ("npc.gigas_frost.male.jaw"), + ), + tail: ( + offset: (-1.5, -17.0, -8.0), + central: ("armor.empty"), + ), + second: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ) + ), }) diff --git a/assets/voxygen/voxel/biped_large_lateral_manifest.ron b/assets/voxygen/voxel/biped_large_lateral_manifest.ron index 83d947ea56..f1cd82e135 100644 --- a/assets/voxygen/voxel/biped_large_lateral_manifest.ron +++ b/assets/voxygen/voxel/biped_large_lateral_manifest.ron @@ -1495,4 +1495,72 @@ lateral: ("npc.tursus.male.foot_r"), ), ), + (Gigasfrost, Male): ( + shoulder_l: ( + offset: (-5.5, -4.5, -5.5), + lateral: ("npc.gigas_frost.male.shoulder_l"), + ), + shoulder_r: ( + offset: (-5.5, -4.5, -5.5), + lateral: ("npc.gigas_frost.male.shoulder_r"), + ), + hand_l: ( + offset: (-7.5, -5.5, -16.0), + lateral: ("npc.gigas_frost.male.hand_l"), + ), + hand_r: ( + offset: (-7.5, -5.5, -16.0), + lateral: ("npc.gigas_frost.male.hand_r"), + ), + leg_l: ( + offset: (-4.0, -4.0, -6.0), + lateral: ("npc.gigas_frost.male.leg_l"), + ), + leg_r: ( + offset: (-4.0, -4.0, -6.0), + lateral: ("npc.gigas_frost.male.leg_r"), + ), + foot_l: ( + offset: (-4.5, -6.5, -4.5), + lateral: ("npc.gigas_frost.male.foot_l"), + ), + foot_r: ( + offset: (-4.5, -6.5, -4.5), + lateral: ("npc.gigas_frost.male.foot_r"), + ) + ), + (Gigasfrost, Female): ( + shoulder_l: ( + offset: (-5.5, -4.5, -5.5), + lateral: ("npc.gigas_frost.male.shoulder_l"), + ), + shoulder_r: ( + offset: (-5.5, -4.5, -5.5), + lateral: ("npc.gigas_frost.male.shoulder_r"), + ), + hand_l: ( + offset: (-7.5, -5.5, -16.0), + lateral: ("npc.gigas_frost.male.hand_l"), + ), + hand_r: ( + offset: (-7.5, -5.5, -16.0), + lateral: ("npc.gigas_frost.male.hand_r"), + ), + leg_l: ( + offset: (-4.0, -4.0, -6.0), + lateral: ("npc.gigas_frost.male.leg_l"), + ), + leg_r: ( + offset: (-4.0, -4.0, -6.0), + lateral: ("npc.gigas_frost.male.leg_r"), + ), + foot_l: ( + offset: (-4.5, -6.5, -4.5), + lateral: ("npc.gigas_frost.male.foot_l"), + ), + foot_r: ( + offset: (-4.5, -6.5, -4.5), + lateral: ("npc.gigas_frost.male.foot_r"), + ) + ), }) \ No newline at end of file diff --git a/assets/voxygen/voxel/biped_small_armor_chest_manifest.ron b/assets/voxygen/voxel/biped_small_armor_chest_manifest.ron index 890b349daf..56d809c5c2 100644 --- a/assets/voxygen/voxel/biped_small_armor_chest_manifest.ron +++ b/assets/voxygen/voxel/biped_small_armor_chest_manifest.ron @@ -75,5 +75,8 @@ "common.items.npc_armor.biped_small.husk.chest.husk": ( vox_spec: ("npc.husk.male.chest", (-6.0, -4.5, -4.0)), ), + "common.items.npc_armor.biped_small.boreal.chest.warrior": ( + vox_spec: ("npc.boreal.warrior.chest", (-9.0, -6.0, -8.5)), + ), }, )) diff --git a/assets/voxygen/voxel/biped_small_armor_foot_manifest.ron b/assets/voxygen/voxel/biped_small_armor_foot_manifest.ron index 756663b8c2..6ea80fa2c7 100644 --- a/assets/voxygen/voxel/biped_small_armor_foot_manifest.ron +++ b/assets/voxygen/voxel/biped_small_armor_foot_manifest.ron @@ -200,5 +200,13 @@ vox_spec: ("npc.husk.male.foot_r", (-2.0, -3.5, -7.0)), ) ), + "common.items.npc_armor.biped_small.boreal.foot.warrior": ( + left: ( + vox_spec: ("npc.boreal.warrior.foot_r", (-2.5, -3.5, -9.0)), + ), + right: ( + vox_spec: ("npc.boreal.warrior.foot_r", (-2.5, -3.5, -9.0)), + ) + ), }, )) diff --git a/assets/voxygen/voxel/biped_small_armor_hand_manifest.ron b/assets/voxygen/voxel/biped_small_armor_hand_manifest.ron index 4eaf9a28bf..2573b15526 100644 --- a/assets/voxygen/voxel/biped_small_armor_hand_manifest.ron +++ b/assets/voxygen/voxel/biped_small_armor_hand_manifest.ron @@ -200,5 +200,13 @@ vox_spec: ("npc.husk.male.hand_r", (0.0, -2.5, -10.0)), ) ), - }, + "common.items.npc_armor.biped_small.boreal.hand.warrior": ( + left: ( + vox_spec: ("npc.boreal.warrior.hand_r", (-6.0, -2.5, -10.0)), + ), + right: ( + vox_spec: ("npc.boreal.warrior.hand_r", (0.0, -2.5, -10.0)), + ) + ), + } )) diff --git a/assets/voxygen/voxel/biped_small_armor_head_manifest.ron b/assets/voxygen/voxel/biped_small_armor_head_manifest.ron index ed3104e699..ab1bd89a76 100644 --- a/assets/voxygen/voxel/biped_small_armor_head_manifest.ron +++ b/assets/voxygen/voxel/biped_small_armor_head_manifest.ron @@ -1,4 +1,5 @@ (( + // (, , ) default: ( vox_spec: ("armor.empty", (0.0, 0.0, 0.0)), ), @@ -75,5 +76,8 @@ "common.items.npc_armor.biped_small.husk.head.husk": ( vox_spec: ("npc.husk.male.head", (-6.0, -6.0, -5.5)), ), + "common.items.npc_armor.biped_small.boreal.head.warrior": ( + vox_spec: ("npc.boreal.warrior.head", (-8.0, -6.0, -8.0)), + ), }, )) diff --git a/assets/voxygen/voxel/biped_small_armor_pants_manifest.ron b/assets/voxygen/voxel/biped_small_armor_pants_manifest.ron index c4c151c92a..768d7493d5 100644 --- a/assets/voxygen/voxel/biped_small_armor_pants_manifest.ron +++ b/assets/voxygen/voxel/biped_small_armor_pants_manifest.ron @@ -75,5 +75,8 @@ "common.items.npc_armor.biped_small.husk.pants.husk": ( vox_spec: ("npc.husk.male.pants", (-5.0, -4.5, -6.0)), ), + "common.items.npc_armor.biped_small.boreal.pants.warrior": ( + vox_spec: ("npc.boreal.warrior.pants", (-7.0, -5.0, -3.5)), + ), }, )) diff --git a/assets/voxygen/voxel/biped_weapon_manifest.ron b/assets/voxygen/voxel/biped_weapon_manifest.ron index a4aa3ca883..3193ad31e4 100644 --- a/assets/voxygen/voxel/biped_weapon_manifest.ron +++ b/assets/voxygen/voxel/biped_weapon_manifest.ron @@ -1751,4 +1751,16 @@ vox_spec: ("armor.empty", (0.0, 0.0, 0.0)), color: None ), + Tool("common.items.npc_weapons.axe.gigas_frost_axe"): ( + vox_spec: ("weapon.axe.2haxe_gigas_frost", (-3.0, -15.5, -14.0)), + color: None + ), + Tool("common.items.npc_weapons.biped_small.boreal.bow"): ( + vox_spec: ("weapon.biped_small.bow.boreal_bow", (-2.5, -6.0, -12.0)), + color: None + ), + Tool("common.items.npc_weapons.biped_small.boreal.hammer"): ( + vox_spec: ("weapon.biped_small.hammer.boreal_hammer", (-2.5, -6.0, -4.0)), + color: None + ), }) diff --git a/assets/voxygen/voxel/glider/winter_wings.vox b/assets/voxygen/voxel/glider/winter_wings.vox new file mode 100644 index 0000000000..0b89d0096f --- /dev/null +++ b/assets/voxygen/voxel/glider/winter_wings.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7acb698748b77b2340ea56a2dc94905b40330417b76cacc8e6b0925a669e44e7 +size 9240 diff --git a/assets/voxygen/voxel/humanoid_armor_back_manifest.ron b/assets/voxygen/voxel/humanoid_armor_back_manifest.ron index e9463e8238..8e5128abdc 100644 --- a/assets/voxygen/voxel/humanoid_armor_back_manifest.ron +++ b/assets/voxygen/voxel/humanoid_armor_back_manifest.ron @@ -28,6 +28,10 @@ vox_spec: ("armor.ferocious.back", (-5.0, -1.5, -14.0)), color: None ), + "common.items.armor.boreal.back": ( + vox_spec: ("armor.boreal.back", (-5.0, -2.0, -14.0)), + color: None + ), "common.items.armor.misc.back.backpack": ( vox_spec: ("armor.misc.back.backpack", (-7.0, -5.0, -10.0)), color: None diff --git a/assets/voxygen/voxel/humanoid_armor_belt_manifest.ron b/assets/voxygen/voxel/humanoid_armor_belt_manifest.ron index 768255cc0a..87653926f7 100644 --- a/assets/voxygen/voxel/humanoid_armor_belt_manifest.ron +++ b/assets/voxygen/voxel/humanoid_armor_belt_manifest.ron @@ -28,6 +28,10 @@ vox_spec: ("armor.ferocious.belt", (-4.0, -3.5, -1.0)), color: None ), + "common.items.armor.boreal.belt": ( + vox_spec: ("armor.boreal.belt", (-4.0, -3.0, 2.0)), + color: None + ), "common.items.armor.cloth_purple.belt": ( vox_spec: ("armor.cloth_purple.belt", (-5.0, -3.5, 2.0)), color: None diff --git a/assets/voxygen/voxel/humanoid_armor_chest_manifest.ron b/assets/voxygen/voxel/humanoid_armor_chest_manifest.ron index 6f058cf5b6..0a2e60f19d 100644 --- a/assets/voxygen/voxel/humanoid_armor_chest_manifest.ron +++ b/assets/voxygen/voxel/humanoid_armor_chest_manifest.ron @@ -32,6 +32,10 @@ vox_spec: ("armor.ferocious.chest", (-7.0, -3.5, 2.0)), color: None ), + "common.items.armor.boreal.chest": ( + vox_spec: ("armor.boreal.chest", (-7.0, -3.5, 2.0)), + color: None + ), "common.items.armor.assassin.chest": ( vox_spec: ("armor.assassin.chest", (-7.0, -3.5, 2.0)), color: None diff --git a/assets/voxygen/voxel/humanoid_armor_foot_manifest.ron b/assets/voxygen/voxel/humanoid_armor_foot_manifest.ron index 646bc47c2e..67686101a0 100644 --- a/assets/voxygen/voxel/humanoid_armor_foot_manifest.ron +++ b/assets/voxygen/voxel/humanoid_armor_foot_manifest.ron @@ -24,6 +24,10 @@ vox_spec: ("armor.ferocious.foot", (-2.5, -3.5, -2.0)), color: None ), + "common.items.armor.boreal.foot": ( + vox_spec: ("armor.boreal.foot", (-2.5, -3.5, -2.0)), + color: None + ), "common.items.armor.cloth_blue.foot": ( vox_spec: ("armor.cloth_blue.foot", (-2.5, -3.5, -2.0)), color: None diff --git a/assets/voxygen/voxel/humanoid_armor_hand_manifest.ron b/assets/voxygen/voxel/humanoid_armor_hand_manifest.ron index 3a961a1f7d..298a6d24db 100644 --- a/assets/voxygen/voxel/humanoid_armor_hand_manifest.ron +++ b/assets/voxygen/voxel/humanoid_armor_hand_manifest.ron @@ -40,6 +40,16 @@ color: None ) ), + "common.items.armor.boreal.hand": ( + left: ( + vox_spec: ("armor.boreal.hand", (-2.0, -1.5, -3.0)), + color: None + ), + right: ( + vox_spec: ("armor.boreal.hand", (-2.0, -1.5, -3.0)), + color: None + ) + ), "common.items.armor.cloth_purple.hand": ( left: ( vox_spec: ("armor.cloth_purple.hand", (-1.5, -1.5, -2.5)), diff --git a/assets/voxygen/voxel/humanoid_armor_pants_manifest.ron b/assets/voxygen/voxel/humanoid_armor_pants_manifest.ron index 09b36eb831..50dd8b1d30 100644 --- a/assets/voxygen/voxel/humanoid_armor_pants_manifest.ron +++ b/assets/voxygen/voxel/humanoid_armor_pants_manifest.ron @@ -35,6 +35,10 @@ "common.items.armor.ferocious.pants": ( vox_spec: ("armor.ferocious.pants", (-5.0, -3.5, 1.0)), color: None + ), + "common.items.armor.boreal.pants": ( + vox_spec: ("armor.boreal.pants", (-5.0, -3.5, 0.0)), + color: None ), "common.items.npc_armor.pants.plate_red": ( vox_spec: ("armor.misc.pants.plate_grey", (-5.0, -3.5, 1.0)), diff --git a/assets/voxygen/voxel/humanoid_armor_shoulder_manifest.ron b/assets/voxygen/voxel/humanoid_armor_shoulder_manifest.ron index c305c92f29..501bab7447 100644 --- a/assets/voxygen/voxel/humanoid_armor_shoulder_manifest.ron +++ b/assets/voxygen/voxel/humanoid_armor_shoulder_manifest.ron @@ -51,6 +51,16 @@ color: None ) ), + "common.items.armor.boreal.shoulder": ( + left: ( + vox_spec: ("armor.boreal.shoulder", (-3.5, -3.5, -3.0)), + color: None + ), + right: ( + vox_spec: ("armor.boreal.shoulder", (-1.5, -3.5, -3.0)), + color: None + ) + ), "common.items.armor.cloth_purple.shoulder": ( left: ( vox_spec: ("armor.cloth_purple.shoulder", (-3.2, -3.5, 0.0)), diff --git a/assets/voxygen/voxel/humanoid_glider_manifest.ron b/assets/voxygen/voxel/humanoid_glider_manifest.ron index 4b287c6ebe..ca1bffa593 100644 --- a/assets/voxygen/voxel/humanoid_glider_manifest.ron +++ b/assets/voxygen/voxel/humanoid_glider_manifest.ron @@ -64,5 +64,9 @@ vox_spec: ("glider.leaves", (-26.0, -26.0, 0.0)), color: None ), + "common.items.glider.winter_wings": ( + vox_spec: ("glider.winter_wings", (-26.0, -26.0, 0.0)), + color: None + ), }, )) diff --git a/assets/voxygen/voxel/item_drop_manifest.ron b/assets/voxygen/voxel/item_drop_manifest.ron index 86993b9d50..9e9e24d786 100644 --- a/assets/voxygen/voxel/item_drop_manifest.ron +++ b/assets/voxygen/voxel/item_drop_manifest.ron @@ -479,6 +479,14 @@ Simple("common.items.armor.ferocious.hand"): "voxel.armor.ferocious.hand", Simple("common.items.armor.ferocious.shoulder"): "voxel.armor.ferocious.shoulder", Simple("common.items.armor.ferocious.back"): "voxel.armor.ferocious.back", + //Boreal Armor + Simple("common.items.armor.boreal.chest"): "voxel.armor.boreal.chest", + Simple("common.items.armor.boreal.pants"): "voxel.armor.boreal.pants", + Simple("common.items.armor.boreal.belt"): "voxel.armor.boreal.belt", + Simple("common.items.armor.boreal.foot"): "voxel.armor.boreal.foot", + Simple("common.items.armor.boreal.hand"): "voxel.armor.boreal.hand", + Simple("common.items.armor.boreal.shoulder"): "voxel.armor.boreal.shoulder", + Simple("common.items.armor.boreal.back"): "voxel.armor.boreal.back", //Blue Leather Armor Simple("common.items.npc_armor.chest.leather_blue"): "voxel.armor.leather_blue.chest", Simple("common.items.npc_armor.pants.leather_blue"): "voxel.armor.leather_blue.pants", @@ -863,6 +871,7 @@ Simple("common.items.flowers.plant_fiber"): "voxel.sprite.crafting_ing.plant_fiber", Simple("common.items.flowers.moonbell"): "voxel.sprite.flowers.moonbell", Simple("common.items.crafting_ing.abyssal_heart"): "voxel.sprite.crafting_ing.abyssal_heart", + Simple("common.items.crafting_ing.pearl"): "voxel.sprite.crafting_ing.pearl", Simple("common.items.crafting_ing.coral_branch"): "voxel.sprite.crafting_ing.coral_branch", Simple("common.items.flowers.pyrebloom"): "voxel.sprite.flowers.pyrebloom", Simple("common.items.flowers.wild_flax"): "voxel.sprite.flowers.flax", @@ -877,6 +886,7 @@ Simple("common.items.crafting_ing.cloth.linen_red"): "voxel.sprite.crafting_ing.cloth.linen_red", Simple("common.items.crafting_ing.sticky_thread"): "voxel.sprite.crafting_ing.sticky_thread", Simple("common.items.crafting_ing.resin"): "voxel.sprite.crafting_ing.resin", + Simple("common.items.crafting_ing.glacial_crystal"): "voxel.object.glacial_crystal", Simple("common.items.mineral.ingot.silver"): "voxel.sprite.mineral.ingot.silver", Simple("common.items.mineral.ingot.gold"): "voxel.sprite.mineral.ingot.gold", Simple("common.items.mineral.ingot.orichalcum"): "voxel.sprite.mineral.ingot.orichalcum", @@ -925,6 +935,7 @@ Simple("common.items.glider.moonrise"): "voxel.glider.moonrise", Simple("common.items.glider.skullgrin"): "voxel.glider.cultists", Simple("common.items.glider.leaves"): "voxel.glider.leaves", + Simple("common.items.glider.winter_wings"): "voxel.glider.winter_wings", // Debug Items Simple("common.items.debug.admin_stick"): "voxel.weapon.tool.broom_belzeshrub_purple", // Misc diff --git a/assets/voxygen/voxel/npc/boreal/warrior/chest.vox b/assets/voxygen/voxel/npc/boreal/warrior/chest.vox new file mode 100644 index 0000000000..7f0fb7185e --- /dev/null +++ b/assets/voxygen/voxel/npc/boreal/warrior/chest.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b86de34a291089ba4b551748185ae14f7826376086b855e90b279610a43654ba +size 31248 diff --git a/assets/voxygen/voxel/npc/boreal/warrior/foot_r.vox b/assets/voxygen/voxel/npc/boreal/warrior/foot_r.vox new file mode 100644 index 0000000000..fe23e9f4ca --- /dev/null +++ b/assets/voxygen/voxel/npc/boreal/warrior/foot_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e4f542aa4a4fc4f4503f61098f3e7a2bead6761c4a128a9e3a03aafc499ed937 +size 27357 diff --git a/assets/voxygen/voxel/npc/boreal/warrior/hand_r.vox b/assets/voxygen/voxel/npc/boreal/warrior/hand_r.vox new file mode 100644 index 0000000000..4675eac20e --- /dev/null +++ b/assets/voxygen/voxel/npc/boreal/warrior/hand_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7485db9bfec10d67eb0db0aba3d677015712532249c64d684f0ad13cd92bc348 +size 27274 diff --git a/assets/voxygen/voxel/npc/boreal/warrior/head.vox b/assets/voxygen/voxel/npc/boreal/warrior/head.vox new file mode 100644 index 0000000000..4b11bbb89e --- /dev/null +++ b/assets/voxygen/voxel/npc/boreal/warrior/head.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f1a653a219d6ab1b9f16475b3742af985601414ee04b0f1156c08f24ec2f5cf0 +size 31138 diff --git a/assets/voxygen/voxel/npc/boreal/warrior/pants.vox b/assets/voxygen/voxel/npc/boreal/warrior/pants.vox new file mode 100644 index 0000000000..52e8f8b2cf --- /dev/null +++ b/assets/voxygen/voxel/npc/boreal/warrior/pants.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19aec8d2f20369dd7df4a5616cb259a9023b66c58c6a460d16aa1e485527e5f4 +size 28034 diff --git a/assets/voxygen/voxel/npc/gigas_frost/male/foot_l.vox b/assets/voxygen/voxel/npc/gigas_frost/male/foot_l.vox new file mode 100644 index 0000000000..e5d1a77a28 --- /dev/null +++ b/assets/voxygen/voxel/npc/gigas_frost/male/foot_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:185b6bf0abb0bdb581fd3a7c39596796293f036654def8f150e3c16f7a0e5057 +size 3716 diff --git a/assets/voxygen/voxel/npc/gigas_frost/male/foot_r.vox b/assets/voxygen/voxel/npc/gigas_frost/male/foot_r.vox new file mode 100644 index 0000000000..e5d1a77a28 --- /dev/null +++ b/assets/voxygen/voxel/npc/gigas_frost/male/foot_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:185b6bf0abb0bdb581fd3a7c39596796293f036654def8f150e3c16f7a0e5057 +size 3716 diff --git a/assets/voxygen/voxel/npc/gigas_frost/male/hand_l.vox b/assets/voxygen/voxel/npc/gigas_frost/male/hand_l.vox new file mode 100644 index 0000000000..e1349016a8 --- /dev/null +++ b/assets/voxygen/voxel/npc/gigas_frost/male/hand_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae3f2fcfb7da43ce953cfbea1a7f6ea6e4112e8b2a9a48376967619ac0c111a1 +size 8520 diff --git a/assets/voxygen/voxel/npc/gigas_frost/male/hand_r.vox b/assets/voxygen/voxel/npc/gigas_frost/male/hand_r.vox new file mode 100644 index 0000000000..9836886f35 --- /dev/null +++ b/assets/voxygen/voxel/npc/gigas_frost/male/hand_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:35e78b7187126cf889f493636b956eac74cf838bfcd93a72cc6f8f79e74cf97e +size 8520 diff --git a/assets/voxygen/voxel/npc/gigas_frost/male/head.vox b/assets/voxygen/voxel/npc/gigas_frost/male/head.vox new file mode 100644 index 0000000000..a7210377a7 --- /dev/null +++ b/assets/voxygen/voxel/npc/gigas_frost/male/head.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c30e5ba9d69f549c95d2bc735caa4506ff6c695b80707f17ad292786ce050ed +size 9716 diff --git a/assets/voxygen/voxel/npc/gigas_frost/male/jaw.vox b/assets/voxygen/voxel/npc/gigas_frost/male/jaw.vox new file mode 100644 index 0000000000..6f82948135 --- /dev/null +++ b/assets/voxygen/voxel/npc/gigas_frost/male/jaw.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:20f9ca92adb377167114edbe8b730e94cabf6335d17ec166bceece88421419f4 +size 1920 diff --git a/assets/voxygen/voxel/npc/gigas_frost/male/leg_l.vox b/assets/voxygen/voxel/npc/gigas_frost/male/leg_l.vox new file mode 100644 index 0000000000..9c341102a9 --- /dev/null +++ b/assets/voxygen/voxel/npc/gigas_frost/male/leg_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08df5639b3ea9fe5e0507c3e918ec11f16e1d8a82a0416c7bc95c4c305db02f3 +size 3400 diff --git a/assets/voxygen/voxel/npc/gigas_frost/male/leg_r.vox b/assets/voxygen/voxel/npc/gigas_frost/male/leg_r.vox new file mode 100644 index 0000000000..79faa6845a --- /dev/null +++ b/assets/voxygen/voxel/npc/gigas_frost/male/leg_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62f5ff8cc3a8082a91f1a835d4f7fde10f07d6ee4372e231793b739721ce6aaf +size 3400 diff --git a/assets/voxygen/voxel/npc/gigas_frost/male/shoulder_l.vox b/assets/voxygen/voxel/npc/gigas_frost/male/shoulder_l.vox new file mode 100644 index 0000000000..5db2c722cf --- /dev/null +++ b/assets/voxygen/voxel/npc/gigas_frost/male/shoulder_l.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ffd365d673e8a9143ffa2e8f84302f1a101eda0b34e1df3465c78fe1f007c36a +size 3872 diff --git a/assets/voxygen/voxel/npc/gigas_frost/male/shoulder_r.vox b/assets/voxygen/voxel/npc/gigas_frost/male/shoulder_r.vox new file mode 100644 index 0000000000..8e1869a1d2 --- /dev/null +++ b/assets/voxygen/voxel/npc/gigas_frost/male/shoulder_r.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e8030429694e234d18bdaff50467ef7e1fcb07aac9de3010bba0cae4a191defe +size 3872 diff --git a/assets/voxygen/voxel/npc/gigas_frost/male/torso_lower.vox b/assets/voxygen/voxel/npc/gigas_frost/male/torso_lower.vox new file mode 100644 index 0000000000..a17729d951 --- /dev/null +++ b/assets/voxygen/voxel/npc/gigas_frost/male/torso_lower.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5412432d3c222783183df1f5c9aa28d63c3f4c5250728f2ad9307c2cf5340e10 +size 12352 diff --git a/assets/voxygen/voxel/npc/gigas_frost/male/torso_upper.vox b/assets/voxygen/voxel/npc/gigas_frost/male/torso_upper.vox new file mode 100644 index 0000000000..54da7c2503 --- /dev/null +++ b/assets/voxygen/voxel/npc/gigas_frost/male/torso_upper.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11d03a619412cfce793b9ba9598f860d0add2b7f7035e1c0f04db276f5b849bf +size 25052 diff --git a/assets/voxygen/voxel/object/glacial_crystal.vox b/assets/voxygen/voxel/object/glacial_crystal.vox new file mode 100644 index 0000000000..dbe123c9df --- /dev/null +++ b/assets/voxygen/voxel/object/glacial_crystal.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b6fc7530d3f047b36b83d60b139339ae8f0934bd4f9dfe91c88dc3505d43870 +size 1524 diff --git a/assets/voxygen/voxel/object_manifest.ron b/assets/voxygen/voxel/object_manifest.ron index 548d5a8bd9..cb722811f4 100644 --- a/assets/voxygen/voxel/object_manifest.ron +++ b/assets/voxygen/voxel/object_manifest.ron @@ -879,4 +879,14 @@ central: ("armor.empty"), ) ), + IceBomb: ( + bone0: ( + offset: (-12.5, -12.5, 0.0), + central: ("weapon.projectile.ice_bomb"), + ), + bone1: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ) + ), }) diff --git a/assets/voxygen/voxel/sprite/crafting_ing/pearl.vox b/assets/voxygen/voxel/sprite/crafting_ing/pearl.vox new file mode 100644 index 0000000000..21b9329af8 --- /dev/null +++ b/assets/voxygen/voxel/sprite/crafting_ing/pearl.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:69ba9c80f0a8ed4950b9c23a7edb691902f430bfe31465358814a7964403dc65 +size 1324 diff --git a/assets/voxygen/voxel/sprite/misc/icespike.vox b/assets/voxygen/voxel/sprite/misc/icespike.vox new file mode 100644 index 0000000000..98c83b83b3 --- /dev/null +++ b/assets/voxygen/voxel/sprite/misc/icespike.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2381dc52b8baef56e6be2d53f7e63127217312c3241a022a5c4abcec1eb0158e +size 4324 diff --git a/assets/voxygen/voxel/sprite_manifest.ron b/assets/voxygen/voxel/sprite_manifest.ron index c51d53affb..5a053e426e 100644 --- a/assets/voxygen/voxel/sprite_manifest.ron +++ b/assets/voxygen/voxel/sprite_manifest.ron @@ -4046,6 +4046,17 @@ EnsnaringWeb: Some(( ], wind_sway: 0.0, )), +// Ice spike +IceSpike: Some(( + variations: [ + ( + model: "voxygen.voxel.sprite.misc.icespike", + offset: (-5.0, -6.5, 0.0), + lod_axes: (0.0, 0.0, 0.0), + ), + ], + wind_sway: 0.0, +)), // WOOOOOOD Wood: Some(( variations: [ diff --git a/assets/voxygen/voxel/weapon/axe/2haxe_gigas_frost.vox b/assets/voxygen/voxel/weapon/axe/2haxe_gigas_frost.vox new file mode 100644 index 0000000000..a608d619ed --- /dev/null +++ b/assets/voxygen/voxel/weapon/axe/2haxe_gigas_frost.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ba4cbe20ba7cf24622b08c28275ea8a28e9f1af401d2d721fb9fa24caa356ee +size 4364 diff --git a/assets/voxygen/voxel/weapon/biped_small/bow/boreal_bow.vox b/assets/voxygen/voxel/weapon/biped_small/bow/boreal_bow.vox new file mode 100644 index 0000000000..f6442a022e --- /dev/null +++ b/assets/voxygen/voxel/weapon/biped_small/bow/boreal_bow.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ade1be763ad477493c585930eb038b14ce098bb6c1c137a1911067a459797cdb +size 27129 diff --git a/assets/voxygen/voxel/weapon/biped_small/hammer/boreal_hammer.vox b/assets/voxygen/voxel/weapon/biped_small/hammer/boreal_hammer.vox new file mode 100644 index 0000000000..ea03f4a257 --- /dev/null +++ b/assets/voxygen/voxel/weapon/biped_small/hammer/boreal_hammer.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3fedfba38b1478ae788888eba1eb6c0425a41089021c4adf989dfb40fa86535c +size 28320 diff --git a/assets/voxygen/voxel/weapon/projectile/ice_bomb.vox b/assets/voxygen/voxel/weapon/projectile/ice_bomb.vox new file mode 100644 index 0000000000..9916e8bbe7 --- /dev/null +++ b/assets/voxygen/voxel/weapon/projectile/ice_bomb.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:376aab8b44a6c045d4ccc64aaae000261f50c6361f10e8b3a006586744fa89b3 +size 4068 diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 17ec38a8d0..67479f0a59 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -405,6 +405,7 @@ pub enum CharacterAbilityType { RiposteMelee(StageSection), RapidMelee(StageSection), LeapMelee(StageSection), + LeapShockwave(StageSection), SpinMelee(StageSection), Music(StageSection), Shockwave, @@ -424,6 +425,7 @@ impl From<&CharacterState> for CharacterAbilityType { CharacterState::DashMelee(data) => Self::DashMelee(data.stage_section), CharacterState::BasicBlock(_) => Self::BasicBlock, CharacterState::LeapMelee(data) => Self::LeapMelee(data.stage_section), + CharacterState::LeapShockwave(data) => Self::LeapShockwave(data.stage_section), CharacterState::ComboMelee(data) => Self::ComboMelee(data.stage_section, data.stage), CharacterState::ComboMelee2(data) => { data.stage_section.map_or(Self::Other, Self::ComboMelee2) @@ -486,6 +488,7 @@ pub enum CharacterAbility { projectile_speed: f32, num_projectiles: u32, projectile_spread: f32, + damage_effect: Option, #[serde(default)] meta: AbilityMeta, }, @@ -500,6 +503,7 @@ pub enum CharacterAbility { projectile_body: Body, projectile_light: Option, projectile_speed: f32, + damage_effect: Option, #[serde(default)] meta: AbilityMeta, }, @@ -574,6 +578,30 @@ pub enum CharacterAbility { melee_constructor: MeleeConstructor, forward_leap_strength: f32, vertical_leap_strength: f32, + damage_effect: Option, + #[serde(default)] + meta: AbilityMeta, + }, + LeapShockwave { + energy_cost: f32, + buildup_duration: f32, + movement_duration: f32, + swing_duration: f32, + recover_duration: f32, + damage: f32, + poise_damage: f32, + knockback: Knockback, + shockwave_angle: f32, + shockwave_vertical_angle: f32, + shockwave_speed: f32, + shockwave_duration: f32, + requires_ground: bool, + move_efficiency: f32, + damage_kind: DamageKind, + specifier: comp::shockwave::FrontendSpecifier, + damage_effect: Option, + forward_leap_strength: f32, + vertical_leap_strength: f32, #[serde(default)] meta: AbilityMeta, }, @@ -600,6 +628,7 @@ pub enum CharacterAbility { recover_duration: f32, melee_constructor: MeleeConstructor, specifier: Option, + damage_effect: Option, #[serde(default)] meta: AbilityMeta, }, @@ -619,6 +648,7 @@ pub enum CharacterAbility { projectile_light: Option, initial_projectile_speed: f32, scaled_projectile_speed: f32, + damage_effect: Option, move_speed: f32, #[serde(default)] meta: AbilityMeta, @@ -639,6 +669,7 @@ pub enum CharacterAbility { move_efficiency: f32, damage_kind: DamageKind, specifier: comp::shockwave::FrontendSpecifier, + ori_rate: f32, damage_effect: Option, #[serde(default)] meta: AbilityMeta, @@ -710,6 +741,7 @@ pub enum CharacterAbility { del_timeout: Option<(f32, f32)>, summon_distance: (f32, f32), sparseness: f64, + angle: f32, #[serde(default)] meta: AbilityMeta, }, @@ -823,6 +855,9 @@ impl CharacterAbility { CharacterAbility::LeapMelee { energy_cost, .. } => { update.vel.0.z >= 0.0 && update.energy.try_change_by(-*energy_cost).is_ok() }, + CharacterAbility::LeapShockwave { energy_cost, .. } => { + update.vel.0.z >= 0.0 && update.energy.try_change_by(-*energy_cost).is_ok() + }, CharacterAbility::BasicAura { energy_cost, scales_with_combo, @@ -938,6 +973,7 @@ impl CharacterAbility { ref mut projectile_speed, num_projectiles: _, projectile_spread: _, + damage_effect: _, meta: _, } => { *buildup_duration /= stats.speed; @@ -957,6 +993,7 @@ impl CharacterAbility { projectile_body: _, projectile_light: _, ref mut projectile_speed, + damage_effect: _, meta: _, } => { *buildup_duration /= stats.speed; @@ -1063,6 +1100,7 @@ impl CharacterAbility { ref mut melee_constructor, forward_leap_strength: _, vertical_leap_strength: _, + ref mut damage_effect, meta: _, } => { *buildup_duration /= stats.speed; @@ -1070,6 +1108,54 @@ impl CharacterAbility { *recover_duration /= stats.speed; *energy_cost /= stats.energy_efficiency; *melee_constructor = melee_constructor.adjusted_by_stats(stats); + if let Some(CombatEffect::Buff(combat::CombatBuff { + kind: _, + dur_secs: _, + strength, + chance: _, + })) = damage_effect + { + *strength *= stats.buff_strength; + } + }, + LeapShockwave { + ref mut energy_cost, + ref mut buildup_duration, + movement_duration: _, + ref mut swing_duration, + ref mut recover_duration, + ref mut damage, + ref mut poise_damage, + knockback: _, + shockwave_angle: _, + shockwave_vertical_angle: _, + shockwave_speed: _, + ref mut shockwave_duration, + requires_ground: _, + move_efficiency: _, + damage_kind: _, + specifier: _, + ref mut damage_effect, + forward_leap_strength: _, + vertical_leap_strength: _, + meta: _, + } => { + *buildup_duration /= stats.speed; + *swing_duration /= stats.speed; + *recover_duration /= stats.speed; + *damage *= stats.power; + *poise_damage *= stats.effect_power; + *shockwave_duration *= stats.range; + *energy_cost /= stats.energy_efficiency; + if let Some(CombatEffect::Buff(combat::CombatBuff { + kind: _, + dur_secs: _, + strength, + chance: _, + })) = damage_effect + { + *strength *= stats.buff_strength; + } }, SpinMelee { ref mut buildup_duration, @@ -1099,6 +1185,7 @@ impl CharacterAbility { ref mut recover_duration, ref mut melee_constructor, specifier: _, + ref mut damage_effect, meta: _, } => { *swing_duration /= stats.speed; @@ -1107,6 +1194,15 @@ impl CharacterAbility { *energy_cost /= stats.energy_efficiency; *energy_drain *= stats.speed / stats.energy_efficiency; *melee_constructor = melee_constructor.adjusted_by_stats(stats); + if let Some(CombatEffect::Buff(combat::CombatBuff { + kind: _, + dur_secs: _, + strength, + chance: _, + })) = damage_effect + { + *strength *= stats.buff_strength; + } }, ChargedRanged { ref mut energy_cost, @@ -1124,6 +1220,7 @@ impl CharacterAbility { projectile_light: _, ref mut initial_projectile_speed, ref mut scaled_projectile_speed, + damage_effect: _, move_speed: _, meta: _, } => { @@ -1153,6 +1250,7 @@ impl CharacterAbility { move_efficiency: _, damage_kind: _, specifier: _, + ori_rate: _, ref mut damage_effect, meta: _, } => { @@ -1286,6 +1384,7 @@ impl CharacterAbility { del_timeout: _, summon_distance: (ref mut inner_dist, ref mut outer_dist), sparseness: _, + angle: _, meta: _, } => { // TODO: Figure out how/if power should affect this @@ -1374,6 +1473,7 @@ impl CharacterAbility { | DashMelee { energy_cost, .. } | Roll { energy_cost, .. } | LeapMelee { energy_cost, .. } + | LeapShockwave { energy_cost, .. } | SpinMelee { energy_cost, .. } | ChargedMelee { energy_cost, .. } | ChargedRanged { energy_cost, .. } @@ -1425,6 +1525,7 @@ impl CharacterAbility { | DashMelee { .. } | Roll { .. } | LeapMelee { .. } + | LeapShockwave { .. } | SpinMelee { .. } | ChargedMelee { .. } | ChargedRanged { .. } @@ -1455,6 +1556,7 @@ impl CharacterAbility { | DashMelee { meta, .. } | Roll { meta, .. } | LeapMelee { meta, .. } + | LeapShockwave { meta, .. } | SpinMelee { meta, .. } | ChargedMelee { meta, .. } | ChargedRanged { meta, .. } @@ -2026,6 +2128,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { energy_cost: _, num_projectiles, projectile_spread, + damage_effect, meta: _, } => CharacterState::BasicRanged(basic_ranged::Data { static_data: basic_ranged::StaticData { @@ -2038,6 +2141,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { num_projectiles: *num_projectiles, projectile_spread: *projectile_spread, ability_info, + damage_effect: *damage_effect, }, timer: Duration::default(), stage_section: StageSection::Buildup, @@ -2202,6 +2306,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { melee_constructor, forward_leap_strength, vertical_leap_strength, + damage_effect, meta: _, } => CharacterState::LeapMelee(leap_melee::Data { static_data: leap_melee::StaticData { @@ -2213,6 +2318,54 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { forward_leap_strength: *forward_leap_strength, vertical_leap_strength: *vertical_leap_strength, ability_info, + damage_effect: *damage_effect, + }, + timer: Duration::default(), + stage_section: StageSection::Buildup, + exhausted: false, + }), + CharacterAbility::LeapShockwave { + energy_cost: _, + buildup_duration, + movement_duration, + swing_duration, + recover_duration, + damage, + poise_damage, + knockback, + shockwave_angle, + shockwave_vertical_angle, + shockwave_speed, + shockwave_duration, + requires_ground, + move_efficiency, + damage_kind, + specifier, + damage_effect, + forward_leap_strength, + vertical_leap_strength, + meta: _, + } => CharacterState::LeapShockwave(leap_shockwave::Data { + static_data: leap_shockwave::StaticData { + buildup_duration: Duration::from_secs_f32(*buildup_duration), + movement_duration: Duration::from_secs_f32(*movement_duration), + swing_duration: Duration::from_secs_f32(*swing_duration), + recover_duration: Duration::from_secs_f32(*recover_duration), + damage: *damage, + poise_damage: *poise_damage, + knockback: *knockback, + shockwave_angle: *shockwave_angle, + shockwave_vertical_angle: *shockwave_vertical_angle, + shockwave_speed: *shockwave_speed, + shockwave_duration: Duration::from_secs_f32(*shockwave_duration), + requires_ground: *requires_ground, + move_efficiency: *move_efficiency, + damage_kind: *damage_kind, + specifier: *specifier, + damage_effect: *damage_effect, + forward_leap_strength: *forward_leap_strength, + vertical_leap_strength: *vertical_leap_strength, + ability_info, }, timer: Duration::default(), stage_section: StageSection::Buildup, @@ -2258,6 +2411,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { recover_duration, melee_constructor, specifier, + damage_effect, meta: _, } => CharacterState::ChargedMelee(charged_melee::Data { static_data: charged_melee::StaticData { @@ -2270,6 +2424,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { melee_constructor: *melee_constructor, ability_info, specifier: *specifier, + damage_effect: *damage_effect, }, stage_section: StageSection::Charge, timer: Duration::default(), @@ -2292,6 +2447,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { projectile_light, initial_projectile_speed, scaled_projectile_speed, + damage_effect, move_speed, meta: _, } => CharacterState::ChargedRanged(charged_ranged::Data { @@ -2312,6 +2468,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { scaled_projectile_speed: *scaled_projectile_speed, move_speed: *move_speed, ability_info, + damage_effect: *damage_effect, }, timer: Duration::default(), stage_section: StageSection::Buildup, @@ -2328,6 +2485,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { projectile_body, projectile_light, projectile_speed, + damage_effect, meta: _, } => CharacterState::RepeaterRanged(repeater_ranged::Data { static_data: repeater_ranged::StaticData { @@ -2343,6 +2501,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { projectile_light: *projectile_light, projectile_speed: *projectile_speed, ability_info, + damage_effect: *damage_effect, }, timer: Duration::default(), stage_section: StageSection::Buildup, @@ -2365,6 +2524,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { move_efficiency, damage_kind, specifier, + ori_rate, damage_effect, meta: _, } => CharacterState::Shockwave(shockwave::Data { @@ -2385,6 +2545,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { ability_info, damage_kind: *damage_kind, specifier: *specifier, + ori_rate: *ori_rate, }, timer: Duration::default(), stage_section: StageSection::Buildup, @@ -2520,6 +2681,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { del_timeout, summon_distance, sparseness, + angle, meta: _, } => CharacterState::SpriteSummon(sprite_summon::Data { static_data: sprite_summon::StaticData { @@ -2530,6 +2692,7 @@ impl From<(&CharacterAbility, AbilityInfo, &JoinData<'_>)> for CharacterState { del_timeout: *del_timeout, summon_distance: *summon_distance, sparseness: *sparseness, + angle: *angle, ability_info, }, timer: Duration::default(), diff --git a/common/src/comp/agent.rs b/common/src/comp/agent.rs index ddf59ce457..491b273f5a 100644 --- a/common/src/comp/agent.rs +++ b/common/src/comp/agent.rs @@ -302,7 +302,7 @@ impl<'a> From<&'a Body> for Psyche { biped_small::Species::Haniwa => 0.1, biped_small::Species::Sahagin => 0.1, biped_small::Species::Myrmidon => 0.0, - biped_small::Species::Husk => 0.0, + biped_small::Species::Husk | biped_small::Species::Boreal => 0.0, _ => 0.5, }, Body::BirdMedium(bird_medium) => match bird_medium.species { diff --git a/common/src/comp/aura.rs b/common/src/comp/aura.rs index 8f98b07cdd..aa627f8ef4 100644 --- a/common/src/comp/aura.rs +++ b/common/src/comp/aura.rs @@ -44,6 +44,9 @@ pub struct Aura { /// `AuraTarget::All`. Whereas auras which only affect a player's party /// members will have the type `AuraTarget::GroupOf`. pub target: AuraTarget, + /// Contains data about the original state of the aura that does not change + /// over time + pub data: AuraData, } /// Information about whether aura addition or removal was requested. @@ -74,6 +77,7 @@ pub enum AuraTarget { pub enum Specifier { WardingAura, HealingAura, + Frozen, } impl From<(Option, Option<&Uid>)> for AuraTarget { @@ -86,6 +90,16 @@ impl From<(Option, Option<&Uid>)> for AuraTarget { } } +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct AuraData { + pub duration: Option, +} + +impl AuraData { + #[must_use] + fn new(duration: Option) -> Self { Self { duration } } +} + impl Aura { /// Creates a new Aura to be assigned to an entity pub fn new( @@ -99,6 +113,7 @@ impl Aura { radius, duration, target, + data: AuraData::new(duration), } } } diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index dc2dd4d00d..5da518fbc0 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -277,6 +277,7 @@ impl Body { biped_large::Species::Cavetroll => 600.0, biped_large::Species::Mountaintroll => 600.0, biped_large::Species::Swamptroll => 600.0, + biped_large::Species::Gigasfrost => 400.0, _ => 400.0, }, Body::BipedSmall(_) => 50.0, @@ -416,6 +417,7 @@ impl Body { biped_large::Species::Cultistwarlock => Vec3::new(3.0, 3.0, 3.5), biped_large::Species::Huskbrute => Vec3::new(4.6, 3.0, 5.0), biped_large::Species::Tursus => Vec3::new(4.0, 3.0, 4.0), + biped_large::Species::Gigasfrost => Vec3::new(6.0, 3.0, 8.0), _ => Vec3::new(4.6, 3.0, 6.0), }, Body::BipedSmall(body) => match body.species { @@ -425,6 +427,7 @@ impl Body { biped_small::Species::Sahagin => Vec3::new(1.3, 2.0, 1.7), biped_small::Species::Myrmidon => Vec3::new(1.3, 1.0, 2.2), biped_small::Species::Husk => Vec3::new(1.7, 0.7, 2.7), + biped_small::Species::Boreal => Vec3::new(1.3, 2.0, 2.5), _ => Vec3::new(1.0, 0.75, 1.4), }, @@ -786,6 +789,7 @@ impl Body { biped_large::Species::Huskbrute => 800, biped_large::Species::Cultistwarlord => 250, biped_large::Species::Cultistwarlock => 250, + biped_large::Species::Gigasfrost => 20000, _ => 120, }, Body::BipedSmall(biped_small) => match biped_small.species { @@ -795,6 +799,7 @@ impl Body { biped_small::Species::Haniwa => 100, biped_small::Species::Myrmidon => 100, biped_small::Species::Husk => 50, + biped_small::Species::Boreal => 100, _ => 60, }, Body::Object(object) => match object { @@ -874,8 +879,14 @@ impl Body { match buff { BuffKind::Bleeding => match self { Body::Object(_) | Body::Golem(_) | Body::Ship(_) => true, - Body::BipedSmall(b) => matches!(b.species, biped_small::Species::Husk), - Body::BipedLarge(b) => matches!(b.species, biped_large::Species::Huskbrute), + Body::BipedSmall(b) => matches!( + b.species, + biped_small::Species::Husk | biped_small::Species::Boreal + ), + Body::BipedLarge(b) => matches!( + b.species, + biped_large::Species::Huskbrute | biped_large::Species::Gigasfrost + ), _ => false, }, BuffKind::Burning => match self { @@ -911,6 +922,16 @@ impl Body { ) ) }, + BuffKind::Frozen => match self { + Body::BipedLarge(b) => matches!( + b.species, + biped_large::Species::Yeti | biped_large::Species::Gigasfrost + ), + Body::QuadrupedLow(q) => matches!(q.species, quadruped_low::Species::Icedrake), + Body::BirdLarge(b) => matches!(b.species, bird_large::Species::FrostWyvern), + Body::BipedSmall(b) => matches!(b.species, biped_small::Species::Boreal), + _ => false, + }, BuffKind::ProtectingWard => matches!(self, Body::Object(object::Body::BarrelOrgan)), _ => false, } diff --git a/common/src/comp/body/biped_large.rs b/common/src/comp/body/biped_large.rs index 5bbe9e53e0..00590dcd97 100644 --- a/common/src/comp/body/biped_large.rs +++ b/common/src/comp/body/biped_large.rs @@ -56,6 +56,7 @@ make_case_elim!( Cultistwarlock = 19, Huskbrute = 20, Tursus = 21, + Gigasfrost = 22, } ); @@ -86,6 +87,7 @@ pub struct AllSpecies { pub cultist_warlock: SpeciesMeta, pub husk_brute: SpeciesMeta, pub tursus: SpeciesMeta, + pub gigas_frost: SpeciesMeta, } impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies { @@ -116,11 +118,12 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies Species::Cultistwarlock => &self.cultist_warlock, Species::Huskbrute => &self.husk_brute, Species::Tursus => &self.tursus, + Species::Gigasfrost => &self.gigas_frost, } } } -pub const ALL_SPECIES: [Species; 22] = [ +pub const ALL_SPECIES: [Species; 23] = [ Species::Ogre, Species::Cyclops, Species::Wendigo, @@ -143,6 +146,7 @@ pub const ALL_SPECIES: [Species; 22] = [ Species::Cultistwarlock, Species::Huskbrute, Species::Tursus, + Species::Gigasfrost, ]; impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies { diff --git a/common/src/comp/body/biped_small.rs b/common/src/comp/body/biped_small.rs index 7bfa285af9..02a5078f3e 100644 --- a/common/src/comp/body/biped_small.rs +++ b/common/src/comp/body/biped_small.rs @@ -45,6 +45,7 @@ make_case_elim!( Haniwa = 8, Myrmidon = 9, Husk = 10, + Boreal = 11, } ); @@ -64,6 +65,7 @@ pub struct AllSpecies { pub haniwa: SpeciesMeta, pub myrmidon: SpeciesMeta, pub husk: SpeciesMeta, + pub boreal: SpeciesMeta, } impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies { @@ -83,11 +85,12 @@ impl<'a, SpeciesMeta> core::ops::Index<&'a Species> for AllSpecies Species::Haniwa => &self.haniwa, Species::Myrmidon => &self.myrmidon, Species::Husk => &self.husk, + Species::Boreal => &self.boreal, } } } -pub const ALL_SPECIES: [Species; 11] = [ +pub const ALL_SPECIES: [Species; 12] = [ Species::Gnome, Species::Sahagin, Species::Adlet, @@ -99,6 +102,7 @@ pub const ALL_SPECIES: [Species; 11] = [ Species::Haniwa, Species::Myrmidon, Species::Husk, + Species::Boreal, ]; impl<'a, SpeciesMeta: 'a> IntoIterator for &'a AllSpecies { diff --git a/common/src/comp/body/object.rs b/common/src/comp/body/object.rs index bb274d1248..05a28908e0 100644 --- a/common/src/comp/body/object.rs +++ b/common/src/comp/body/object.rs @@ -100,6 +100,7 @@ make_case_elim!( GnarlingTotemWhite = 85, DagonBomb = 86, BarrelOrgan = 87, + IceBomb = 88, } ); @@ -110,7 +111,7 @@ impl Body { } } -pub const ALL_OBJECTS: [Body; 88] = [ +pub const ALL_OBJECTS: [Body; 89] = [ Body::Arrow, Body::Bomb, Body::Scarecrow, @@ -199,6 +200,7 @@ pub const ALL_OBJECTS: [Body; 88] = [ Body::GnarlingTotemGreen, Body::DagonBomb, Body::BarrelOrgan, + Body::IceBomb, ]; impl From for super::Body { @@ -296,6 +298,7 @@ impl Body { Body::GnarlingTotemWhite => "gnarling_totem_white", Body::DagonBomb => "dagon_bomb", Body::BarrelOrgan => "barrel_organ", + Body::IceBomb => "ice_bomb", } } @@ -409,6 +412,7 @@ impl Body { Body::Hive => 2.0, Body::Coconut => 2.0, Body::GnarlingTotemRed | Body::GnarlingTotemGreen | Body::GnarlingTotemWhite => 100.0, + Body::IceBomb => 12298.0, // 2.5 m diamter but ice }; Mass(m) @@ -430,6 +434,7 @@ impl Body { Vec3::new(0.8, 0.8, 1.4) }, Body::BarrelOrgan => Vec3::new(4.0, 2.0, 3.0), + Body::IceBomb => Vec3::broadcast(2.5), // FIXME: this *must* be exhaustive match _ => Vec3::broadcast(0.5), } diff --git a/common/src/comp/character_state.rs b/common/src/comp/character_state.rs index 9493939f90..16a9c4735e 100644 --- a/common/src/comp/character_state.rs +++ b/common/src/comp/character_state.rs @@ -95,6 +95,8 @@ pub enum CharacterState { ComboMelee2(combo_melee2::Data), /// A leap followed by a small aoe ground attack LeapMelee(leap_melee::Data), + /// A leap followed by a shockwave + LeapShockwave(leap_shockwave::Data), /// Spin around, dealing damage to enemies surrounding you SpinMelee(spin_melee::Data), /// A charged ranged attack (e.g. bow) @@ -153,6 +155,7 @@ impl CharacterState { | CharacterState::ComboMelee2(_) | CharacterState::BasicBlock(_) | CharacterState::LeapMelee(_) + | CharacterState::LeapShockwave(_) | CharacterState::SpinMelee(_) | CharacterState::ChargedMelee(_) | CharacterState::ChargedRanged(_) @@ -215,6 +218,7 @@ impl CharacterState { | CharacterState::ComboMelee(_) | CharacterState::ComboMelee2(_) | CharacterState::LeapMelee(_) + | CharacterState::LeapShockwave(_) | CharacterState::SpinMelee(_) | CharacterState::ChargedMelee(_) | CharacterState::ChargedRanged(_) @@ -243,6 +247,7 @@ impl CharacterState { | CharacterState::ComboMelee2(_) | CharacterState::BasicBlock(_) | CharacterState::LeapMelee(_) + | CharacterState::LeapShockwave(_) | CharacterState::ChargedMelee(_) | CharacterState::ChargedRanged(_) | CharacterState::RepeaterRanged(_) @@ -435,6 +440,7 @@ impl CharacterState { CharacterState::Boost(data) => data.behavior(j, output_events), CharacterState::DashMelee(data) => data.behavior(j, output_events), CharacterState::LeapMelee(data) => data.behavior(j, output_events), + CharacterState::LeapShockwave(data) => data.behavior(j, output_events), CharacterState::SpinMelee(data) => data.behavior(j, output_events), CharacterState::ChargedMelee(data) => data.behavior(j, output_events), CharacterState::ChargedRanged(data) => data.behavior(j, output_events), @@ -488,6 +494,7 @@ impl CharacterState { CharacterState::Boost(data) => data.handle_event(j, output_events, action), CharacterState::DashMelee(data) => data.handle_event(j, output_events, action), CharacterState::LeapMelee(data) => data.handle_event(j, output_events, action), + CharacterState::LeapShockwave(data) => data.handle_event(j, output_events, action), CharacterState::SpinMelee(data) => data.handle_event(j, output_events, action), CharacterState::ChargedMelee(data) => data.handle_event(j, output_events, action), CharacterState::ChargedRanged(data) => data.handle_event(j, output_events, action), @@ -541,6 +548,7 @@ impl CharacterState { CharacterState::Boost(data) => Some(data.static_data.ability_info), CharacterState::DashMelee(data) => Some(data.static_data.ability_info), CharacterState::LeapMelee(data) => Some(data.static_data.ability_info), + CharacterState::LeapShockwave(data) => Some(data.static_data.ability_info), CharacterState::SpinMelee(data) => Some(data.static_data.ability_info), CharacterState::ChargedMelee(data) => Some(data.static_data.ability_info), CharacterState::ChargedRanged(data) => Some(data.static_data.ability_info), @@ -585,6 +593,7 @@ impl CharacterState { CharacterState::Boost(_) => None, CharacterState::DashMelee(data) => Some(data.stage_section), CharacterState::LeapMelee(data) => Some(data.stage_section), + CharacterState::LeapShockwave(data) => Some(data.stage_section), CharacterState::SpinMelee(data) => Some(data.stage_section), CharacterState::ChargedMelee(data) => Some(data.stage_section), CharacterState::ChargedRanged(data) => Some(data.stage_section), @@ -687,6 +696,13 @@ impl CharacterState { movement: Some(data.static_data.movement_duration), ..Default::default() }), + CharacterState::LeapShockwave(data) => Some(DurationsInfo { + buildup: Some(data.static_data.buildup_duration), + action: Some(data.static_data.swing_duration), + recover: Some(data.static_data.recover_duration), + movement: Some(data.static_data.movement_duration), + ..Default::default() + }), CharacterState::SpinMelee(data) => Some(DurationsInfo { buildup: Some(data.static_data.buildup_duration), action: Some(data.static_data.swing_duration), @@ -817,6 +833,7 @@ impl CharacterState { CharacterState::Boost(data) => Some(data.timer), CharacterState::DashMelee(data) => Some(data.timer), CharacterState::LeapMelee(data) => Some(data.timer), + CharacterState::LeapShockwave(data) => Some(data.timer), CharacterState::SpinMelee(data) => Some(data.timer), CharacterState::ChargedMelee(data) => Some(data.timer), CharacterState::ChargedRanged(data) => Some(data.timer), diff --git a/common/src/comp/inventory/loadout_builder.rs b/common/src/comp/inventory/loadout_builder.rs index c8f7bf8ffe..f539fcd72a 100644 --- a/common/src/comp/inventory/loadout_builder.rs +++ b/common/src/comp/inventory/loadout_builder.rs @@ -726,6 +726,9 @@ fn default_main_tool(body: &Body) -> Item { (biped_large::Species::Huskbrute, _) => Some(Item::new_from_asset_expect( "common.items.npc_weapons.unique.husk_brute", )), + (biped_large::Species::Gigasfrost, _) => Some(Item::new_from_asset_expect( + "common.items.npc_weapons.axe.gigas_frost_axe", + )), }, Body::Object(body) => match body { object::Body::Crossbow => Some(Item::new_from_asset_expect( @@ -830,6 +833,7 @@ pub struct LoadoutBuilder(Loadout); #[derive(Copy, Clone, PartialEq, Eq, Deserialize, Serialize, Debug, EnumIter)] pub enum Preset { HuskSummon, + BorealSummon, } impl LoadoutBuilder { @@ -916,6 +920,9 @@ impl LoadoutBuilder { biped_large::Species::Cultistwarlock => { Some("common.items.npc_armor.biped_large.warlock") }, + biped_large::Species::Gigasfrost => { + Some("common.items.npc_armor.biped_large.gigas_frost") + }, _ => None, }, Body::BirdLarge(body) => match body.species { @@ -981,6 +988,9 @@ impl LoadoutBuilder { Preset::HuskSummon => { self = self.with_asset_expect("common.loadout.dungeon.tier-5.husk", rng); }, + Preset::BorealSummon => { + self = self.with_asset_expect("common.loadout.world.boreal.boreal_warrior", rng); + }, } self diff --git a/common/src/comp/projectile.rs b/common/src/comp/projectile.rs index c79ee14ec9..7ff5c21a30 100644 --- a/common/src/comp/projectile.rs +++ b/common/src/comp/projectile.rs @@ -10,6 +10,7 @@ use crate::{ use serde::{Deserialize, Serialize}; use specs::Component; use std::time::Duration; +use vek::Rgb; #[derive(Clone, Debug, Serialize, Deserialize)] pub enum Effect { @@ -104,6 +105,12 @@ pub enum ProjectileConstructor { knockback: f32, min_falloff: f32, }, + IceBomb { + damage: f32, + radius: f32, + knockback: f32, + min_falloff: f32, + }, } impl ProjectileConstructor { @@ -113,6 +120,7 @@ impl ProjectileConstructor { crit_chance: f32, crit_mult: f32, buff_strength: f32, + damage_effect: Option, ) -> Projectile { let instance = rand::random(); use ProjectileConstructor::*; @@ -138,7 +146,7 @@ impl ProjectileConstructor { strength: CombatBuffStrength::DamageFraction(0.1 * buff_strength), chance: 0.1, }); - let damage = AttackDamage::new( + let mut damage = AttackDamage::new( Damage { source: DamageSource::Projectile, kind: DamageKind::Piercing, @@ -148,6 +156,9 @@ impl ProjectileConstructor { instance, ) .with_effect(buff); + if let Some(damage_effect) = damage_effect { + damage = damage.with_effect(damage_effect); + } let attack = Attack::default() .with_damage(damage) .with_crit(crit_chance, crit_mult) @@ -197,7 +208,7 @@ impl ProjectileConstructor { let explosion = Explosion { effects: vec![ RadiusEffect::Attack(attack), - RadiusEffect::TerrainDestruction(2.0), + RadiusEffect::TerrainDestruction(2.0, Rgb::black()), ], radius, reagent: Some(Reagent::Red), @@ -278,7 +289,7 @@ impl ProjectileConstructor { let explosion = Explosion { effects: vec![ RadiusEffect::Attack(attack), - RadiusEffect::TerrainDestruction(5.0), + RadiusEffect::TerrainDestruction(5.0, Rgb::black()), ], radius, reagent: Some(Reagent::Purple), @@ -367,7 +378,7 @@ impl ProjectileConstructor { let explosion = Explosion { effects: vec![ RadiusEffect::Attack(attack), - RadiusEffect::TerrainDestruction(5.0), + RadiusEffect::TerrainDestruction(5.0, Rgb::black()), ], radius, reagent: Some(Reagent::Red), @@ -525,7 +536,7 @@ impl ProjectileConstructor { let explosion = Explosion { effects: vec![ RadiusEffect::Attack(attack), - RadiusEffect::TerrainDestruction(5.0), + RadiusEffect::TerrainDestruction(5.0, Rgb::black()), ], radius, reagent: Some(Reagent::Red), @@ -582,7 +593,7 @@ impl ProjectileConstructor { let explosion = Explosion { effects: vec![ RadiusEffect::Attack(attack), - RadiusEffect::TerrainDestruction(75.0), + RadiusEffect::TerrainDestruction(25.0, Rgb::black()), ], radius, reagent: Some(Reagent::Blue), @@ -598,6 +609,63 @@ impl ProjectileConstructor { is_point: true, } }, + IceBomb { + damage, + radius, + knockback, + min_falloff, + } => { + let knockback = AttackEffect::new( + Some(GroupTarget::OutOfGroup), + CombatEffect::Knockback(Knockback { + strength: knockback, + direction: KnockbackDir::Away, + }), + ) + .with_requirement(CombatRequirement::AnyDamage); + let buff = AttackEffect::new( + Some(GroupTarget::OutOfGroup), + CombatEffect::Buff(CombatBuff { + kind: BuffKind::Frozen, + dur_secs: 5.0, + strength: CombatBuffStrength::DamageFraction(0.05 * buff_strength), + chance: 1.0, + }), + ) + .with_requirement(CombatRequirement::AnyDamage); + 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_effect(knockback) + .with_effect(buff); + let explosion = Explosion { + effects: vec![ + RadiusEffect::Attack(attack), + RadiusEffect::TerrainDestruction(30.0, Rgb::new(255.0, 255.0, 255.0)), + ], + 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, + } + }, } } @@ -697,6 +765,14 @@ impl ProjectileConstructor { *damage *= power; *radius *= range; }, + IceBomb { + ref mut damage, + ref mut radius, + .. + } => { + *damage *= power; + *radius *= range; + }, } self } diff --git a/common/src/explosion.rs b/common/src/explosion.rs index ff02365cf5..bb48cd0f5e 100644 --- a/common/src/explosion.rs +++ b/common/src/explosion.rs @@ -1,5 +1,6 @@ use crate::{combat::Attack, comp::item::Reagent, effect::Effect}; use serde::{Deserialize, Serialize}; +use vek::Rgb; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Explosion { @@ -11,7 +12,7 @@ pub struct Explosion { #[derive(Clone, Debug, Serialize, Deserialize)] pub enum RadiusEffect { - TerrainDestruction(f32), + TerrainDestruction(f32, Rgb), Entity(Effect), Attack(Attack), } diff --git a/common/src/outcome.rs b/common/src/outcome.rs index 6eb9dcfc3d..effdc16810 100644 --- a/common/src/outcome.rs +++ b/common/src/outcome.rs @@ -88,6 +88,15 @@ pub enum Outcome { GroundSlam { pos: Vec3, }, + IceSpikes { + pos: Vec3, + }, + IceCrack { + pos: Vec3, + }, + FlashFreeze { + pos: Vec3, + }, Utterance { pos: Vec3, body: comp::Body, @@ -118,6 +127,9 @@ impl Outcome { | Outcome::Block { pos, .. } | Outcome::PoiseChange { pos, .. } | Outcome::GroundSlam { pos } + | Outcome::FlashFreeze { pos } + | Outcome::IceSpikes { pos } + | Outcome::IceCrack { pos } | Outcome::Utterance { pos, .. } | Outcome::SpriteDelete { pos, .. } | Outcome::Glider { pos, .. } => Some(*pos), diff --git a/common/src/states/basic_ranged.rs b/common/src/states/basic_ranged.rs index d691d28f08..d7b952848e 100644 --- a/common/src/states/basic_ranged.rs +++ b/common/src/states/basic_ranged.rs @@ -3,6 +3,7 @@ use crate::{ character_state::OutputEvents, Body, CharacterState, LightEmitter, Pos, ProjectileConstructor, StateUpdate, }, + combat::CombatEffect, event::ServerEvent, states::{ behavior::{CharacterBehavior, JoinData}, @@ -32,6 +33,8 @@ pub struct StaticData { pub num_projectiles: u32, /// What key is used to press ability pub ability_info: AbilityInfo, + /// + pub damage_effect: Option, } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -83,6 +86,7 @@ impl CharacterBehavior for Data { crit_chance, crit_mult, buff_strength, + self.static_data.damage_effect, ); // Shoots all projectiles simultaneously for i in 0..self.static_data.num_projectiles { diff --git a/common/src/states/charged_melee.rs b/common/src/states/charged_melee.rs index 15ec8d4b7e..7ea20aab3c 100644 --- a/common/src/states/charged_melee.rs +++ b/common/src/states/charged_melee.rs @@ -1,5 +1,6 @@ use crate::{ comp::{character_state::OutputEvents, CharacterState, MeleeConstructor, StateUpdate}, + combat::CombatEffect, event::LocalEvent, outcome::Outcome, states::{ @@ -31,6 +32,8 @@ pub struct StaticData { pub ability_info: AbilityInfo, /// Used to specify the melee attack to the frontend pub specifier: Option, + /// Adds an effect onto the main damage of the attack + pub damage_effect: Option, } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] diff --git a/common/src/states/charged_ranged.rs b/common/src/states/charged_ranged.rs index 3d282c5bf8..6d9c09e036 100644 --- a/common/src/states/charged_ranged.rs +++ b/common/src/states/charged_ranged.rs @@ -3,6 +3,7 @@ use crate::{ character_state::OutputEvents, projectile::ProjectileConstructor, Body, CharacterState, LightEmitter, Pos, StateUpdate, }, + combat::CombatEffect, event::ServerEvent, states::{ behavior::{CharacterBehavior, JoinData}, @@ -44,6 +45,8 @@ pub struct StaticData { pub move_speed: f32, /// What key is used to press ability pub ability_info: AbilityInfo, + /// Adds an effect onto the main damage of the attack + pub damage_effect: Option, } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -118,6 +121,7 @@ impl CharacterBehavior for Data { crit_chance, crit_mult, buff_strength, + self.static_data.damage_effect, ); output_events.emit_server(ServerEvent::Shoot { entity: data.entity, diff --git a/common/src/states/leap_melee.rs b/common/src/states/leap_melee.rs index 99e0765080..ddc778ca9d 100644 --- a/common/src/states/leap_melee.rs +++ b/common/src/states/leap_melee.rs @@ -1,5 +1,6 @@ use crate::{ comp::{character_state::OutputEvents, CharacterState, MeleeConstructor, StateUpdate}, + combat::CombatEffect, states::{ behavior::{CharacterBehavior, JoinData}, utils::{StageSection, *}, @@ -27,6 +28,8 @@ pub struct StaticData { pub vertical_leap_strength: f32, /// What key is used to press ability pub ability_info: AbilityInfo, + /// + pub damage_effect: Option, } #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] diff --git a/common/src/states/leap_shockwave.rs b/common/src/states/leap_shockwave.rs new file mode 100644 index 0000000000..338f05f359 --- /dev/null +++ b/common/src/states/leap_shockwave.rs @@ -0,0 +1,226 @@ +use crate::{ + combat::{ + Attack, AttackDamage, AttackEffect, CombatEffect, CombatRequirement, Damage, DamageKind, + DamageSource, GroupTarget, Knockback, + }, + comp::{character_state::OutputEvents, CharacterState, shockwave, StateUpdate}, + event::{LocalEvent, ServerEvent}, + outcome::Outcome, + states::{ + behavior::{CharacterBehavior, JoinData}, + utils::{StageSection, *}, + }, +}; +use serde::{Deserialize, Serialize}; +use std::time::Duration; + +/// Separated out to condense update portions of character state +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct StaticData { + /// How long the state is moving + pub movement_duration: Duration, + /// How long until state should deal damage + pub buildup_duration: Duration, + /// How long the state is swinging for + pub swing_duration: Duration, + /// How long the state has until exiting + pub recover_duration: Duration, + /// Base damage + pub damage: f32, + /// Base poise damage + pub poise_damage: f32, + /// Knockback + pub knockback: Knockback, + /// Angle of the shockwave + pub shockwave_angle: f32, + /// Vertical angle of the shockwave + pub shockwave_vertical_angle: f32, + /// Speed of the shockwave + pub shockwave_speed: f32, + /// How long the shockwave travels for + pub shockwave_duration: Duration, + /// Whether the shockwave requires the target to be on the ground + pub requires_ground: bool, + /// Movement speed efficiency + pub move_efficiency: f32, + /// Adds an effect onto the main damage of the attack + pub damage_effect: Option, + /// What kind of damage the attack does + pub damage_kind: DamageKind, + /// Used to specify the shockwave to the frontend + pub specifier: shockwave::FrontendSpecifier, + /// Affects how far forward the player leaps + pub forward_leap_strength: f32, + /// Affects how high the player leaps + pub vertical_leap_strength: f32, + /// What key is used to press ability + pub ability_info: AbilityInfo, +} + +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Data { + /// Struct containing data that does not change over the course of the + /// character state + pub static_data: StaticData, + /// Timer for each stage + pub timer: Duration, + /// What section the character stage is in + pub stage_section: StageSection, + /// Whether the attack can deal more damage + pub exhausted: bool, +} + +impl CharacterBehavior for Data { + fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate { + let mut update = StateUpdate::from(data); + + handle_orientation(data, &mut update, 1.0, None); + + match self.stage_section { + // Delay before leaping into the air + StageSection::Buildup => { + handle_move(data, &mut update, 0.3); + handle_jump(data, output_events, &mut update, 1.0); + // Wait for `buildup_duration` to expire + if self.timer < self.static_data.buildup_duration { + update.character = CharacterState::LeapShockwave(Data { + timer: tick_attack_or_default(data, self.timer, None), + ..*self + }); + } else { + + // Transitions to leap portion of state after buildup delay + update.character = CharacterState::LeapShockwave(Data { + timer: Duration::default(), + stage_section: StageSection::Movement, + ..*self + }); + } + }, + StageSection::Movement => { + if self.timer < self.static_data.movement_duration { + // Apply jumping force + let progress = 1.0 + - self.timer.as_secs_f32() + / self.static_data.movement_duration.as_secs_f32(); + handle_forced_movement(data, &mut update, ForcedMovement::Leap { + vertical: self.static_data.vertical_leap_strength, + forward: self.static_data.forward_leap_strength, + progress, + direction: MovementDirection::Look, + }); + + // Increment duration + // If we were to set a timeout for state, this would be + // outside if block and have else check for > movement + // duration * some multiplier + update.character = CharacterState::LeapShockwave(Data { + timer: tick_attack_or_default(data, self.timer, None), + ..*self + }); + } else if data.physics.on_ground.is_some() | data.physics.in_liquid().is_some() { + // Transitions to swing portion of state upon hitting ground + update.character = CharacterState::LeapShockwave(Data { + timer: Duration::default(), + stage_section: StageSection::Action, + ..*self + }); + } + }, + StageSection::Action => { + handle_move(data, &mut update, 0.3); + handle_jump(data, output_events, &mut update, 1.0); + if self.timer < self.static_data.swing_duration { + // Swings + update.character = CharacterState::LeapShockwave(Data { + timer: tick_attack_or_default(data, self.timer, None), + ..*self + }); + + // Attack + let poise = AttackEffect::new( + Some(GroupTarget::OutOfGroup), + CombatEffect::Poise(self.static_data.poise_damage), + ) + .with_requirement(CombatRequirement::AnyDamage); + let knockback = AttackEffect::new( + Some(GroupTarget::OutOfGroup), + CombatEffect::Knockback(self.static_data.knockback), + ) + .with_requirement(CombatRequirement::AnyDamage); + let mut damage = AttackDamage::new( + Damage { + source: DamageSource::Shockwave, + kind: self.static_data.damage_kind, + value: self.static_data.damage, + }, + Some(GroupTarget::OutOfGroup), + rand::random(), + ); + if let Some(effect) = self.static_data.damage_effect { + damage = damage.with_effect(effect); + } + let (crit_chance, crit_mult) = + get_crit_data(data, self.static_data.ability_info); + let attack = Attack::default() + .with_damage(damage) + .with_crit(crit_chance, crit_mult) + .with_effect(poise) + .with_effect(knockback) + .with_combo_increment(); + let properties = shockwave::Properties { + angle: self.static_data.shockwave_angle, + vertical_angle: self.static_data.shockwave_vertical_angle, + speed: self.static_data.shockwave_speed, + duration: self.static_data.shockwave_duration, + attack, + requires_ground: self.static_data.requires_ground, + owner: Some(*data.uid), + specifier: self.static_data.specifier, + }; + output_events.emit_server(ServerEvent::Shockwave { + properties, + pos: *data.pos, + ori: *data.ori, + }); + // Send local event used for frontend shenanigans + output_events.emit_local(LocalEvent::CreateOutcome(Outcome::IceSpikes { + pos: data.pos.0 + + *data.ori.look_dir() + * (data.body.max_radius()), + })); + } else { + // Transitions to recover + update.character = CharacterState::LeapShockwave(Data { + timer: Duration::default(), + stage_section: StageSection::Recover, + ..*self + }); + } + }, + StageSection::Recover => { + handle_move(data, &mut update, 0.3); + handle_jump(data, output_events, &mut update, 1.0); + if self.timer < self.static_data.recover_duration { + // Recovers + update.character = CharacterState::LeapShockwave(Data { + timer: tick_attack_or_default(data, self.timer, None), + ..*self + }); + } else { + // Done + end_ability(data, &mut update); + } + }, + _ => { + // If it somehow ends up in an incorrect stage section + end_ability(data, &mut update); + }, + } + + // At end of state logic so an interrupt isn't overwritten + handle_interrupts(data, &mut update); + + update + } +} diff --git a/common/src/states/mod.rs b/common/src/states/mod.rs index 13a81f5bb4..4a49159f19 100644 --- a/common/src/states/mod.rs +++ b/common/src/states/mod.rs @@ -21,6 +21,7 @@ pub mod glide; pub mod glide_wield; pub mod idle; pub mod leap_melee; +pub mod leap_shockwave; pub mod music; pub mod rapid_melee; pub mod repeater_ranged; diff --git a/common/src/states/repeater_ranged.rs b/common/src/states/repeater_ranged.rs index 853f51e9ab..8993713008 100644 --- a/common/src/states/repeater_ranged.rs +++ b/common/src/states/repeater_ranged.rs @@ -3,6 +3,7 @@ use crate::{ character_state::OutputEvents, Body, CharacterState, LightEmitter, Pos, ProjectileConstructor, StateUpdate, }, + combat::CombatEffect, event::ServerEvent, states::{ behavior::{CharacterBehavior, JoinData}, @@ -34,6 +35,8 @@ pub struct StaticData { pub projectile_speed: f32, /// What key is used to press ability pub ability_info: AbilityInfo, + /// Adds an effect onto the main damage of the attack + pub damage_effect: Option, } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -99,6 +102,7 @@ impl CharacterBehavior for Data { crit_chance, crit_mult, buff_strength, + self.static_data.damage_effect, ); output_events.emit_server(ServerEvent::Shoot { entity: data.entity, diff --git a/common/src/states/shockwave.rs b/common/src/states/shockwave.rs index ed43d2782b..cdcd302115 100644 --- a/common/src/states/shockwave.rs +++ b/common/src/states/shockwave.rs @@ -4,7 +4,8 @@ use crate::{ DamageSource, GroupTarget, Knockback, }, comp::{character_state::OutputEvents, shockwave, CharacterState, StateUpdate}, - event::ServerEvent, + event::{LocalEvent, ServerEvent}, + outcome::Outcome, states::{ behavior::{CharacterBehavior, JoinData}, utils::*, @@ -48,6 +49,8 @@ pub struct StaticData { pub damage_kind: DamageKind, /// Used to specify the shockwave to the frontend pub specifier: shockwave::FrontendSpecifier, + /// How fast enemy can rotate + pub ori_rate: f32, } #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -65,7 +68,7 @@ impl CharacterBehavior for Data { fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate { let mut update = StateUpdate::from(data); - handle_orientation(data, &mut update, 1.0, None); + handle_orientation(data, &mut update, self.static_data.ori_rate, None); handle_move(data, &mut update, self.static_data.move_efficiency); match self.stage_section { @@ -139,6 +142,14 @@ impl CharacterBehavior for Data { timer: tick_attack_or_default(data, self.timer, None), ..*self }); + // Send local event used for frontend shenanigans + if self.static_data.specifier == shockwave::FrontendSpecifier::IceSpikes { + output_events.emit_local(LocalEvent::CreateOutcome(Outcome::FlashFreeze { + pos: data.pos.0 + + *data.ori.look_dir() + * (data.body.max_radius()), + })); + } } else { // Transitions to recover update.character = CharacterState::Shockwave(Data { diff --git a/common/src/states/sprite_summon.rs b/common/src/states/sprite_summon.rs index fbcbb0ea90..2bb53385b4 100644 --- a/common/src/states/sprite_summon.rs +++ b/common/src/states/sprite_summon.rs @@ -1,6 +1,7 @@ use crate::{ comp::{character_state::OutputEvents, CharacterState, StateUpdate}, - event::ServerEvent, + event::{LocalEvent, ServerEvent}, + outcome::Outcome, spiral::Spiral2d, states::{ behavior::{CharacterBehavior, JoinData}, @@ -31,6 +32,8 @@ pub struct StaticData { pub summon_distance: (f32, f32), /// Chance that sprite is not created on a particular square pub sparseness: f64, + /// Angle of total coverage, centered on the forward-facing orientation + pub angle: f32, /// Miscellaneous information about the ability pub ability_info: AbilityInfo, } @@ -88,8 +91,8 @@ impl CharacterBehavior for Data { // Creates a spiral iterator for the newly achieved radius let spiral = Spiral2d::with_edge_radius(radius); for point in spiral { - // If square is not sparse, generate sprite - if !thread_rng().gen_bool(self.static_data.sparseness) { + // If square is in the angle and is not sparse, generate sprite + if data.ori.look_vec().xy().angle_between(point.as_()).to_degrees() <= (self.static_data.angle / 2.0) && !thread_rng().gen_bool(self.static_data.sparseness) { // The coordinates of where the sprite is created let sprite_pos = Vec3::new( data.pos.0.x.floor() as i32 + point.x, @@ -141,6 +144,14 @@ impl CharacterBehavior for Data { achieved_radius: summon_distance, ..*self }); + // Send local event used for frontend shenanigans + if self.static_data.sprite == SpriteKind::IceSpike { + output_events.emit_local(LocalEvent::CreateOutcome(Outcome::IceCrack { + pos: data.pos.0 + + *data.ori.look_dir() + * (data.body.max_radius()), + })); + } } else { // Transitions to recover section of stage update.character = CharacterState::SpriteSummon(Data { diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 72b78f63d0..14a4d7006f 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -100,6 +100,7 @@ impl Body { biped_large::Species::Huskbrute => 130.0, biped_large::Species::Cultistwarlord => 110.0, biped_large::Species::Cultistwarlock => 90.0, + biped_large::Species::Gigasfrost => 45.0, _ => 80.0, }, Body::BirdMedium(_) => 80.0, @@ -109,6 +110,7 @@ impl Body { Body::FishSmall(_) => 60.0, Body::BipedSmall(biped_small) => match biped_small.species { biped_small::Species::Haniwa => 65.0, + biped_small::Species::Boreal => 100.0, _ => 80.0, }, Body::Object(_) => 0.0, diff --git a/common/src/terrain/block.rs b/common/src/terrain/block.rs index 74abc44363..de79ba1833 100644 --- a/common/src/terrain/block.rs +++ b/common/src/terrain/block.rs @@ -304,7 +304,7 @@ impl Block { | SpriteKind::SeaDecorWindowVer | SpriteKind::Rope | SpriteKind::GlassBarrier => None, - SpriteKind::EnsnaringVines | SpriteKind::EnsnaringWeb | SpriteKind::SeaUrchin => { + SpriteKind::EnsnaringVines | SpriteKind::EnsnaringWeb | SpriteKind::SeaUrchin | SpriteKind::IceSpike => { Some(0.1) }, _ => Some(0.25), diff --git a/common/src/terrain/sprite.rs b/common/src/terrain/sprite.rs index 46e79868a2..53612421e8 100644 --- a/common/src/terrain/sprite.rs +++ b/common/src/terrain/sprite.rs @@ -226,6 +226,7 @@ make_case_elim!( SeaDecorPillar = 0xC7, SeashellLantern = 0xC8, Rope = 0xC9, + IceSpike = 0xDA, } ); @@ -291,6 +292,7 @@ impl SpriteKind { SpriteKind::Anvil => 1.1, SpriteKind::CookingPot => 1.36, SpriteKind::DismantlingBench => 1.18, + SpriteKind::IceSpike => 1.0, // TODO: Find suitable heights. SpriteKind::BarrelCactus | SpriteKind::RoundCactus diff --git a/common/systems/src/buff.rs b/common/systems/src/buff.rs index 0a6900a7c7..45c4522f46 100644 --- a/common/systems/src/buff.rs +++ b/common/systems/src/buff.rs @@ -167,6 +167,31 @@ impl<'a> System<'a> for Sys { )), }); } + if matches!( + physics_state.on_ground.and_then(|b| b.get_sprite()), + Some(SpriteKind::IceSpike) + ) { + // When standing on IceSpike, apply bleeding + server_emitter.emit(ServerEvent::Buff { + entity, + buff_change: BuffChange::Add(Buff::new( + BuffKind::Bleeding, + BuffData::new(15.0, Some(Duration::from_secs_f32(0.1)), None), + Vec::new(), + BuffSource::World, + )), + }); + // When standing on IceSpike also apply Frozen + server_emitter.emit(ServerEvent::Buff { + entity, + buff_change: BuffChange::Add(Buff::new( + BuffKind::Frozen, + BuffData::new(0.2, Some(Duration::from_secs_f32(1.0)), None), + Vec::new(), + BuffSource::World, + )), + }); + } if matches!( physics_state.in_fluid, Some(Fluid::Liquid { diff --git a/common/systems/src/stats.rs b/common/systems/src/stats.rs index 139c0aabc5..ae123ba5aa 100644 --- a/common/systems/src/stats.rs +++ b/common/systems/src/stats.rs @@ -179,6 +179,7 @@ impl<'a> System<'a> for Sys { CharacterState::BasicMelee(_) | CharacterState::DashMelee(_) | CharacterState::LeapMelee(_) + | CharacterState::LeapShockwave(_) | CharacterState::SpinMelee(_) | CharacterState::ComboMelee(_) | CharacterState::ComboMelee2(_) diff --git a/server/agent/src/action_nodes.rs b/server/agent/src/action_nodes.rs index 9e35a4f778..257e8f947b 100644 --- a/server/agent/src/action_nodes.rs +++ b/server/agent/src/action_nodes.rs @@ -834,7 +834,7 @@ impl<'a> AgentData<'a> { "Oni" | "Sword Simple" => Tactic::Sword, "Staff Simple" => Tactic::Staff, "Simple Flying Melee" => Tactic::SimpleFlyingMelee, - "Bow Simple" => Tactic::Bow, + "Bow Simple" | "Boreal Bow" => Tactic::Bow, "Stone Golem" => Tactic::StoneGolem, "Quad Med Quick" => Tactic::CircleCharge { radius: 3, @@ -894,6 +894,8 @@ impl<'a> AgentData<'a> { "Mandragora" => Tactic::Mandragora, "Wood Golem" => Tactic::WoodGolem, "Gnarling Chieftain" => Tactic::GnarlingChieftain, + "Frost Gigas" => Tactic::FrostGigas, + "Boreal Hammer" => Tactic::BorealHammer, _ => Tactic::SimpleMelee, }, AbilitySpec::Tool(tool_kind) => tool_tactic(*tool_kind), @@ -1014,9 +1016,11 @@ impl<'a> AgentData<'a> { ), ) }, - CharacterState::LeapMelee(_) if matches!(tactic, Tactic::Hammer | Tactic::Axe) => { + CharacterState::LeapMelee(_) + if matches!(tactic, Tactic::Hammer | Tactic::BorealHammer | Tactic::Axe) => + { let direction_weight = match tactic { - Tactic::Hammer => 0.1, + Tactic::Hammer | Tactic::BorealHammer => 0.1, Tactic::Axe => 0.3, _ => unreachable!("Direction weight called on incorrect tactic."), }; @@ -1309,6 +1313,17 @@ impl<'a> AgentData<'a> { read_data, rng, ), + Tactic::FrostGigas => { + self.handle_frostgigas_attack(agent, controller, &attack_data, tgt_data, read_data) + }, + Tactic::BorealHammer => self.handle_boreal_hammer_attack( + agent, + controller, + &attack_data, + tgt_data, + read_data, + rng, + ), } } diff --git a/server/agent/src/attack.rs b/server/agent/src/attack.rs index 060ccecead..0f392025f3 100644 --- a/server/agent/src/attack.rs +++ b/server/agent/src/attack.rs @@ -3708,6 +3708,188 @@ impl<'a> AgentData<'a> { ); } + pub fn handle_frostgigas_attack( + &self, + agent: &mut Agent, + controller: &mut Controller, + attack_data: &AttackData, + tgt_data: &TargetData, + read_data: &ReadData, + ) { + const GIGAS_MELEE_RANGE: f32 = 6.0; + const GIGAS_SPIKE_RANGE: f32 = 12.0; + const GIGAS_FREEZE_RANGE: f32 = 20.0; + const GIGAS_LEAP_RANGE: f32 = 30.0; + const MINION_SUMMON_THRESHOLD: f32 = 0.2; + + enum ActionStateFCounters { + MinionSummonThreshold = 0, + } + enum ActionStateTimers { + AttackChange = 0, + } + if agent.action_state.timers[ActionStateTimers::AttackChange as usize] > 2.5 { + agent.action_state.timers[ActionStateTimers::AttackChange as usize] = 0.0; + } + + let line_of_sight_with_target = || { + entities_have_line_of_sight(self.pos, self.body, tgt_data.pos, tgt_data.body, read_data) + }; + let health_fraction = self.health.map_or(0.5, |h| h.fraction()); + // Sets counter at start of combat, using `condition` to keep track of whether + // it was already initialized + if !agent.action_state.initialized { + agent.action_state.counters[ActionStateFCounters::MinionSummonThreshold as usize] = + 1.0 - MINION_SUMMON_THRESHOLD; + agent.action_state.initialized = true; + } else if health_fraction + < agent.action_state.counters[ActionStateFCounters::MinionSummonThreshold as usize] + { + // Summon minions at particular thresholds of health + controller.push_basic_input(InputKind::Ability(3)); + + if matches!(self.char_state, CharacterState::BasicSummon(c) if matches!(c.stage_section, StageSection::Recover)) + { + agent.action_state.counters + [ActionStateFCounters::MinionSummonThreshold as usize] -= + MINION_SUMMON_THRESHOLD; + } + } else { + // If the target is in melee range of frost use primary and secondary + // attacks accordingly + if attack_data.dist_sqrd < GIGAS_MELEE_RANGE.powi(2) { + if agent.action_state.timers[ActionStateTimers::AttackChange as usize] > 1.0 { + // Backhand anyone trying to circle strafe frost + if attack_data.angle > 160.0 { + // Use reorientate strike + controller.push_basic_input(InputKind::Secondary); + // If in front of frost use primary + } else { + // Hit them regularly + controller.push_basic_input(InputKind::Primary); + } + } else { + controller.push_basic_input(InputKind::Ability(4)); + } + } else if attack_data.dist_sqrd < GIGAS_SPIKE_RANGE.powi(2) + && line_of_sight_with_target() + { + if agent.action_state.timers[ActionStateTimers::AttackChange as usize] > 1.0 { + // Use icespike attack + controller.push_basic_input(InputKind::Ability(0)); + } else { + // or Flashfreeze + controller.push_basic_input(InputKind::Ability(4)); + } + } else if attack_data.dist_sqrd < GIGAS_FREEZE_RANGE.powi(2) + && line_of_sight_with_target() + { + // Use Flashfreeze + controller.push_basic_input(InputKind::Ability(4)); + } else if attack_data.dist_sqrd > GIGAS_LEAP_RANGE.powi(2) { + // Use ranged attack (icebombs) when past a certain distance + controller.push_basic_input(InputKind::Ability(2)); + } else if attack_data.dist_sqrd < GIGAS_LEAP_RANGE.powi(2) { + // Use a leap attack (custom comp made by ythern) that goes + // after the furthest entity in range, Angle + // doesn't matter, should be spurratic + if agent.action_state.timers[ActionStateTimers::AttackChange as usize] > 1.0 { + controller.push_basic_input(InputKind::Ability(1)); + } else { + // or icebombs + controller.push_basic_input(InputKind::Ability(2)); + } + } + agent.action_state.timers[ActionStateTimers::AttackChange as usize] += read_data.dt.0; + } + // Always attempt to path towards target + self.path_toward_target( + agent, + controller, + tgt_data.pos.0, + read_data, + Path::Partial, + None, + ); + } + + pub fn handle_boreal_hammer_attack( + &self, + agent: &mut Agent, + controller: &mut Controller, + attack_data: &AttackData, + tgt_data: &TargetData, + read_data: &ReadData, + rng: &mut impl Rng, + ) { + enum ActionStateTimers { + TimerHandleHammerAttack = 0, + } + let has_leap = || { + self.skill_set + .has_skill(Skill::Hammer(HammerSkill::UnlockLeap)) + }; + + let has_energy = |need| self.energy.current() > need; + + let use_leap = |controller: &mut Controller| { + controller.push_basic_input(InputKind::Ability(0)); + }; + + if attack_data.in_min_range() && attack_data.angle < 45.0 { + controller.inputs.move_dir = Vec2::zero(); + if agent.action_state.timers[ActionStateTimers::TimerHandleHammerAttack as usize] > 4.0 + { + controller.push_cancel_input(InputKind::Secondary); + agent.action_state.timers[ActionStateTimers::TimerHandleHammerAttack as usize] = + 0.0; + } else if agent.action_state.timers[ActionStateTimers::TimerHandleHammerAttack as usize] + > 3.0 + { + controller.push_basic_input(InputKind::Secondary); + agent.action_state.timers[ActionStateTimers::TimerHandleHammerAttack as usize] += + read_data.dt.0; + } else if has_leap() && has_energy(50.0) && rng.gen_bool(0.9) { + use_leap(controller); + agent.action_state.timers[ActionStateTimers::TimerHandleHammerAttack as usize] += + read_data.dt.0; + } else { + controller.push_basic_input(InputKind::Primary); + agent.action_state.timers[ActionStateTimers::TimerHandleHammerAttack as usize] += + read_data.dt.0; + } + } else { + self.path_toward_target( + agent, + controller, + tgt_data.pos.0, + read_data, + Path::Separate, + None, + ); + + if attack_data.dist_sqrd < 32.0f32.powi(2) + && has_leap() + && has_energy(50.0) + && entities_have_line_of_sight( + self.pos, + self.body, + tgt_data.pos, + tgt_data.body, + read_data, + ) + { + use_leap(controller); + } + if self.body.map(|b| b.is_humanoid()).unwrap_or(false) + && attack_data.dist_sqrd < 16.0f32.powi(2) + && rng.gen::() < 0.02 + { + controller.push_basic_input(InputKind::Roll); + } + } + } + pub fn handle_cardinal_attack( &self, agent: &mut Agent, diff --git a/server/agent/src/data.rs b/server/agent/src/data.rs index 8eb792e323..d6f27e7a9e 100644 --- a/server/agent/src/data.rs +++ b/server/agent/src/data.rs @@ -142,6 +142,8 @@ pub enum Tactic { Dagon, Cardinal, Roshwalr, + FrostGigas, + BorealHammer, } #[derive(SystemData)] diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 337cd40a51..16e8efa3ea 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -2222,7 +2222,7 @@ fn handle_explosion( kind: DamageKind::Energy, value: 100.0 * power, })), - RadiusEffect::TerrainDestruction(power), + RadiusEffect::TerrainDestruction(power, Rgb::black()), ], radius: 3.0 * power, reagent: None, diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index eb13f2c4ec..74354f083c 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -725,7 +725,7 @@ pub fn handle_explosion(server: &Server, pos: Vec3, explosion: Explosion, o let mut rng = rand::thread_rng(); 'effects: for effect in explosion.effects { match effect { - RadiusEffect::TerrainDestruction(power) => { + RadiusEffect::TerrainDestruction(power, new_color) => { const RAYS: usize = 500; let spatial_grid = ecs.read_resource::(); @@ -793,11 +793,14 @@ pub fn handle_explosion(server: &Server, pos: Vec3, explosion: Explosion, o let fade = (1.0 - diff2 / color_range.powi(2)).max(0.0); if let Some(mut color) = block.get_color() { let r = color[0] as f32 - + (fade * (color[0] as f32 * 0.5 - color[0] as f32)); + + (fade + * (color[0] as f32 * 0.5 - color[0] as f32 + new_color[0])); let g = color[1] as f32 - + (fade * (color[1] as f32 * 0.3 - color[1] as f32)); + + (fade + * (color[1] as f32 * 0.3 - color[1] as f32 + new_color[1])); let b = color[2] as f32 - + (fade * (color[2] as f32 * 0.3 - color[2] as f32)); + + (fade + * (color[2] as f32 * 0.3 - color[2] as f32 + new_color[2])); // Darken blocks, but not too much color[0] = (r as u8).max(30); color[1] = (g as u8).max(30); diff --git a/server/src/sys/object.rs b/server/src/sys/object.rs index 7e3754e20d..51392b5ad1 100644 --- a/server/src/sys/object.rs +++ b/server/src/sys/object.rs @@ -7,6 +7,7 @@ use common::{ }; use common_ecs::{Job, Origin, Phase, System}; use specs::{Entities, Join, Read, ReadStorage, WriteStorage}; +use vek::Rgb; /// This system is responsible for handling misc object behaviours #[derive(Default)] @@ -56,7 +57,7 @@ impl<'a> System<'a> for Sys { value: 40.0, })), RadiusEffect::Entity(Effect::Poise(-100.0)), - RadiusEffect::TerrainDestruction(4.0), + RadiusEffect::TerrainDestruction(4.0, Rgb::black()), ], radius: 12.0, reagent: None, @@ -76,7 +77,7 @@ impl<'a> System<'a> for Sys { }; use rand::Rng; use std::{f32::consts::PI, time::Duration}; - use vek::{Rgb, Vec3}; + use vek::Vec3; let mut rng = rand::thread_rng(); // Note that if the expected fireworks per firework is > 1, this will // eventually cause enough server lag that more players can't log in. @@ -149,7 +150,7 @@ impl<'a> System<'a> for Sys { value: 5.0, })), RadiusEffect::Entity(Effect::Poise(-40.0)), - RadiusEffect::TerrainDestruction(4.0), + RadiusEffect::TerrainDestruction(4.0, Rgb::black()), ], radius: 12.0, reagent: Some(*reagent), diff --git a/server/src/wiring.rs b/server/src/wiring.rs index bfe901be75..9fc259f4ef 100644 --- a/server/src/wiring.rs +++ b/server/src/wiring.rs @@ -188,7 +188,7 @@ impl WiringAction { pos, dir: Dir::forward(), body: Body::Object(object::Body::Arrow), - projectile: constr.create_projectile(None, 0.0, 1.0, 1.0), + projectile: constr.create_projectile(None, 0.0, 1.0, 1.0, None), light: None, speed: 5.0, object: None, diff --git a/voxygen/anim/src/biped_large/alpha.rs b/voxygen/anim/src/biped_large/alpha.rs index 82d86c76df..f989d34992 100644 --- a/voxygen/anim/src/biped_large/alpha.rs +++ b/voxygen/anim/src/biped_large/alpha.rs @@ -19,6 +19,7 @@ impl Animation for AlphaAnimation { Option, f32, f32, + Option<&'a str>, ); type Skeleton = BipedLargeSkeleton; @@ -36,6 +37,7 @@ impl Animation for AlphaAnimation { stage_section, acc_vel, timer, + ability_id, ): Self::Dependency<'_>, anim_time: f32, rate: &mut f32, @@ -143,30 +145,90 @@ impl Animation for AlphaAnimation { * Quaternion::rotation_y(-1.8 + move1 * -0.8 + move2 * 3.0) * Quaternion::rotation_z(move1 * -0.8 + move2 * -0.8); }, - Some(ToolKind::Axe) => { - next.control_l.position = Vec3::new(-1.0, 2.0, 12.0 + move2 * -10.0); - next.control_r.position = Vec3::new(1.0, 2.0, -2.0); + Some(ToolKind::Axe) => match ability_id { + Some("common.abilities.custom.gigas_frost.combomelee") => { + next.control_l.position = Vec3::new(-1.0, 2.0, 12.0 + move2 * -10.0); + next.control_r.position = Vec3::new(1.0, 2.0, -2.0); - next.control.position = Vec3::new( - 4.0 + move1 * -12.0 + move2 * 28.0, - (s_a.grip.0 / 1.0) + move1 * -3.0 + move2 * -5.0, - (-s_a.grip.0 / 0.8) + move1 * 2.0 + move2 * 8.0, - ); - next.head.orientation = Quaternion::rotation_x(move1 * -0.25) - * Quaternion::rotation_z(move1 * -0.2 + move2 * 0.6); - next.upper_torso.orientation = Quaternion::rotation_z(move1 * 0.6 + move2 * -0.9); - next.lower_torso.orientation = Quaternion::rotation_z(move1 * -0.6 + move2 * 0.9); + next.control.position = Vec3::new( + 4.0 + move1 * -12.0 + move2 * 28.0, + (s_a.grip.0 / 1.0) + move1 * -3.0 + move2 * -5.0, + (-s_a.grip.0 / 0.8) + move1 * 2.0 + move2 * -6.0, + ); + next.head.orientation = Quaternion::rotation_x(move1 * -0.25) + * Quaternion::rotation_z(move1 * -0.2 + move2 * 0.6); + next.upper_torso.orientation = + Quaternion::rotation_z(move1 * 0.6 + move2 * -0.9); + next.lower_torso.orientation = + Quaternion::rotation_z(move1 * -0.6 + move2 * 0.9); - next.control_l.orientation = - Quaternion::rotation_x(PI / 2.0 + move2 * 0.8) * Quaternion::rotation_y(-0.0); - next.control_r.orientation = Quaternion::rotation_x(PI / 2.0 + 0.2 + move2 * 0.8) - * Quaternion::rotation_y(0.0) - * Quaternion::rotation_z(0.0); + next.control_l.orientation = Quaternion::rotation_x(PI / 2.0 + move2 * 0.8) + * Quaternion::rotation_y(-0.0); + next.control_r.orientation = + Quaternion::rotation_x(PI / 2.0 + 0.2 + move2 * 0.8) + * Quaternion::rotation_y(0.0) + * Quaternion::rotation_z(0.0); - next.control.orientation = - Quaternion::rotation_x(-1.0 + move1 * -0.5 + move2 * -0.3) - * Quaternion::rotation_y(-1.8 + move1 * -0.4 + move2 * 3.5) - * Quaternion::rotation_z(move1 * -1.0 + move2 * -1.5); + next.control.orientation = Quaternion::rotation_x(-0.3 + move2 * -1.5) + * Quaternion::rotation_y(move1 * -0.9 + move2 * 2.0) + * Quaternion::rotation_z(-0.3); + }, + Some("common.abilities.custom.gigas_frost.wide_cleave") => { + next.control_l.position = Vec3::new(-1.0, 2.0, 12.0 + move2 * -10.0); + next.control_r.position = Vec3::new(1.0, 2.0, -2.0); + + next.control.position = Vec3::new( + 4.0 + move1 * -12.0 + move2 * 28.0, + (s_a.grip.0 / 1.0) + move1 * -3.0 + move2 * -5.0, + (-s_a.grip.0 / 0.8) + move1 * 2.0 + move2 * 8.0, + ); + next.head.orientation = Quaternion::rotation_x(move1 * -0.25) + * Quaternion::rotation_z(move1 * -0.2 + move2 * 0.6); + next.upper_torso.orientation = + Quaternion::rotation_z(move1 * 0.6 + move2 * -0.9); + next.lower_torso.orientation = + Quaternion::rotation_z(move1 * -0.6 + move2 * 0.9); + + next.control_l.orientation = Quaternion::rotation_x(PI / 2.0 + move2 * 0.8) + * Quaternion::rotation_y(-0.0); + next.control_r.orientation = + Quaternion::rotation_x(PI / 2.0 + 0.2 + move2 * 0.8) + * Quaternion::rotation_y(0.0) + * Quaternion::rotation_z(0.0); + + next.control.orientation = + Quaternion::rotation_x(-1.0 + move1 * -0.5 + move2 * -0.3) + * Quaternion::rotation_y(-1.8 + move1 * -0.4 + move2 * 3.5) + * Quaternion::rotation_z(move1 * -1.0 + move2 * -1.5); + }, + _ => { + next.control_l.position = Vec3::new(-1.0, 2.0, 12.0 + move2 * -10.0); + next.control_r.position = Vec3::new(1.0, 2.0, -2.0); + + next.control.position = Vec3::new( + 4.0 + move1 * -12.0 + move2 * 28.0, + (s_a.grip.0 / 1.0) + move1 * -3.0 + move2 * -5.0, + (-s_a.grip.0 / 0.8) + move1 * 2.0 + move2 * 8.0, + ); + next.head.orientation = Quaternion::rotation_x(move1 * -0.25) + * Quaternion::rotation_z(move1 * -0.2 + move2 * 0.6); + next.upper_torso.orientation = + Quaternion::rotation_z(move1 * 0.6 + move2 * -0.9); + next.lower_torso.orientation = + Quaternion::rotation_z(move1 * -0.6 + move2 * 0.9); + + next.control_l.orientation = Quaternion::rotation_x(PI / 2.0 + move2 * 0.8) + * Quaternion::rotation_y(-0.0); + next.control_r.orientation = + Quaternion::rotation_x(PI / 2.0 + 0.2 + move2 * 0.8) + * Quaternion::rotation_y(0.0) + * Quaternion::rotation_z(0.0); + + next.control.orientation = + Quaternion::rotation_x(-1.0 + move1 * -0.5 + move2 * -0.3) + * Quaternion::rotation_y(-1.8 + move1 * -0.4 + move2 * 3.5) + * Quaternion::rotation_z(move1 * -1.0 + move2 * -1.5); + }, }, Some(ToolKind::Natural) => { if let Some(AbilitySpec::Custom(spec)) = active_tool_spec { diff --git a/voxygen/anim/src/biped_large/jump.rs b/voxygen/anim/src/biped_large/jump.rs index afd64d2197..59f9e3d8ec 100644 --- a/voxygen/anim/src/biped_large/jump.rs +++ b/voxygen/anim/src/biped_large/jump.rs @@ -56,10 +56,13 @@ impl Animation for JumpAnimation { next.control.position = Vec3::new(0.0, 0.0, 0.0); next.control.orientation = Quaternion::rotation_z(0.0); - next.second.position = Vec3::new(0.0, 0.0, 0.0); - next.second.orientation = - Quaternion::rotation_x(PI) * Quaternion::rotation_y(0.0) * Quaternion::rotation_z(0.0); - next.second.scale = Vec3::one() * 1.0; + if active_tool_kind != Some(ToolKind::Axe) { + next.second.position = Vec3::new(0.0, 0.0, 0.0); + next.second.orientation = Quaternion::rotation_x(PI) + * Quaternion::rotation_y(0.0) + * Quaternion::rotation_z(0.0); + next.second.scale = Vec3::one() * 1.0; + }; match active_tool_kind { Some(ToolKind::Bow) => { diff --git a/voxygen/anim/src/biped_large/leapshockwave.rs b/voxygen/anim/src/biped_large/leapshockwave.rs new file mode 100644 index 0000000000..0b9280e020 --- /dev/null +++ b/voxygen/anim/src/biped_large/leapshockwave.rs @@ -0,0 +1,89 @@ +use super::{ + super::{vek::*, Animation}, + BipedLargeSkeleton, SkeletonAttr, +}; +use common::{comp::item::ToolKind, states::utils::StageSection}; +use core::f32::consts::PI; + +pub struct LeapShockAnimation; + +impl Animation for LeapShockAnimation { + type Dependency<'a> = ( + Option, + Option, + Vec3, + f32, + Option, + ); + type Skeleton = BipedLargeSkeleton; + + #[cfg(feature = "use-dyn-lib")] + const UPDATE_FN: &'static [u8] = b"biped_large_leapshockwave\0"; + + #[cfg_attr(feature = "be-dyn-lib", export_name = "biped_large_leapshockwave")] + fn update_skeleton_inner( + skeleton: &Self::Skeleton, + (_active_tool_kind, _second_tool_kind, _velocity, _global_time, stage_section): Self::Dependency<'_>, + anim_time: f32, + rate: &mut f32, + s_a: &SkeletonAttr, + ) -> Self::Skeleton { + *rate = 1.0; + let mut next = (*skeleton).clone(); + + let (movement1, movement2, movement3, movement4) = match stage_section { + Some(StageSection::Buildup) => (anim_time, 0.0, 0.0, 0.0), + Some(StageSection::Movement) => (1.0, anim_time.powf(0.25), 0.0, 0.0), + Some(StageSection::Action) => (1.0, 1.0, anim_time.powf(0.25), 0.0), + Some(StageSection::Recover) => (1.0, 1.0, 1.0, anim_time), + _ => (0.0, 0.0, 0.0, 0.0), + }; + + if true { + next.hand_l.position = Vec3::new(s_a.hhl.0, s_a.hhl.1, s_a.hhl.2); + next.hand_l.orientation = Quaternion::rotation_x(s_a.hhl.3); + next.hand_r.position = Vec3::new(s_a.hhr.0, s_a.hhr.1, s_a.hhr.2); + next.hand_r.orientation = Quaternion::rotation_x(s_a.hhr.3); + next.main.position = Vec3::new(0.0, 0.0, 0.0); + next.main.orientation = Quaternion::rotation_y(0.0) * Quaternion::rotation_z(0.0); + + next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); + + next.control.position = Vec3::new( + s_a.hc.0 + movement2 * -10.0 + movement3 * 6.0, + s_a.hc.1 + movement2 * 5.0 + movement3 * 7.0, + s_a.hc.2 + movement2 * 5.0 + movement3 * -10.0, + ); + next.control.orientation = + Quaternion::rotation_x(s_a.hc.3 + movement2 * PI / 2.0 + movement3 * -2.3) + * Quaternion::rotation_y(s_a.hc.4 + movement2 * 1.3) + * Quaternion::rotation_z(s_a.hc.5 + movement2 * -1.0 + movement3 * 0.5); + next.upper_torso.orientation = + Quaternion::rotation_x( + movement1 * 0.3 + movement2 * 0.3 + movement3 * -0.9 + movement4 * 0.3, + ) * Quaternion::rotation_z(movement1 * 0.5 + movement2 * 0.2 + movement3 * -0.7); + + next.head.orientation = Quaternion::rotation_x(movement3 * 0.2) + * Quaternion::rotation_y(0.0 + movement2 * -0.1) + * Quaternion::rotation_z(movement1 * -0.4 + movement2 * -0.2 + movement3 * 0.6); + + //next.hand_l.position = Vec3::new(-12.0 + movement3 * 10.0, 0.0, 0.0); + + next.foot_l.position = Vec3::new( + -s_a.foot.0, + s_a.foot.1 + movement3 * 13.0, + s_a.foot.2 + movement3 * -2.0, + ); + next.foot_l.orientation = Quaternion::rotation_x(-0.8 + movement3 * 1.7); + + next.foot_r.position = Vec3::new( + s_a.foot.0, + s_a.foot.1 + 8.0 + movement3 * -13.0, + s_a.foot.2 + 5.0 + movement3 * -5.0, + ); + next.foot_r.orientation = Quaternion::rotation_x(0.9 + movement3 * -1.7); + } + + next + } +} diff --git a/voxygen/anim/src/biped_large/mod.rs b/voxygen/anim/src/biped_large/mod.rs index 6c22aa2920..e4ed21a7d9 100644 --- a/voxygen/anim/src/biped_large/mod.rs +++ b/voxygen/anim/src/biped_large/mod.rs @@ -9,6 +9,7 @@ pub mod equip; pub mod idle; pub mod jump; pub mod leapmelee; +pub mod leapshockwave; pub mod run; pub mod selfbuff; pub mod shockwave; @@ -25,10 +26,10 @@ pub use self::{ alpha::AlphaAnimation, beam::BeamAnimation, beta::BetaAnimation, blink::BlinkAnimation, charge::ChargeAnimation, chargemelee::ChargeMeleeAnimation, dash::DashAnimation, equip::EquipAnimation, idle::IdleAnimation, jump::JumpAnimation, leapmelee::LeapAnimation, - run::RunAnimation, selfbuff::SelfBuffAnimation, shockwave::ShockwaveAnimation, - shoot::ShootAnimation, spin::SpinAnimation, spinmelee::SpinMeleeAnimation, - spritesummon::SpriteSummonAnimation, stunned::StunnedAnimation, summon::SummonAnimation, - wield::WieldAnimation, + leapshockwave::LeapShockAnimation, run::RunAnimation, selfbuff::SelfBuffAnimation, + shockwave::ShockwaveAnimation, shoot::ShootAnimation, spin::SpinAnimation, + spinmelee::SpinMeleeAnimation, spritesummon::SpriteSummonAnimation, stunned::StunnedAnimation, + summon::SummonAnimation, wield::WieldAnimation, }; use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; @@ -249,6 +250,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Cultistwarlock, _) => (0.5, 11.0), (Huskbrute, _) => (8.5, 4.0), (Tursus, _) => (-4.5, -14.0), + (Gigasfrost, _) => (-1.5, 5.0), }, jaw: match (body.species, body.body_type) { (Ogre, _) => (0.0, 0.0), @@ -273,6 +275,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Cultistwarlock, _) => (0.0, 3.5), (Huskbrute, _) => (-5.0, -5.0), (Tursus, _) => (4.0, 10.5), + (Gigasfrost, _) => (-1.0, 5.5), }, upper_torso: match (body.species, body.body_type) { (Ogre, Male) => (0.0, 27.5), @@ -298,6 +301,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Cultistwarlock, _) => (-1.0, 17.5), (Huskbrute, _) => (-1.0, 23.5), (Tursus, _) => (3.0, 26.0), + (Gigasfrost, _) => (-1.0, 30.0), }, lower_torso: match (body.species, body.body_type) { (Ogre, Male) => (1.0, -7.0), @@ -323,6 +327,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Cultistwarlock, _) => (1.0, -2.5), (Huskbrute, _) => (-0.5, -7.0), (Tursus, _) => (-5.0, -9.0), + (Gigasfrost, _) => (0.0, -5.5), }, tail: match (body.species, body.body_type) { (Werewolf, _) => (-5.5, -2.0), @@ -356,6 +361,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Cultistwarlock, _) => (8.0, 0.0, 3.5), (Huskbrute, _) => (10.5, 0.0, -1.5), (Tursus, _) => (12.5, -2.5, 1.0), + (Gigasfrost, _) => (10.5, 0.5, 0.0), }, hand: match (body.species, body.body_type) { (Ogre, Male) => (14.5, 0.0, -4.0), @@ -381,6 +387,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Cultistwarlock, _) => (9.5, -1.0, 1.0), (Huskbrute, _) => (13.0, 0.5, -4.0), (Tursus, _) => (15.5, -2.5, -8.0), + (Gigasfrost, _) => (17.0, 0.5, -6.0), }, leg: match (body.species, body.body_type) { (Ogre, Male) => (0.0, 0.0, -4.0), @@ -406,6 +413,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Cultistwarlock, _) => (3.5, -1.0, -8.5), (Huskbrute, _) => (4.0, 0.0, -7.5), (Tursus, _) => (4.5, 1.0, -9.0), + (Gigasfrost, _) => (6.0, 0.0, -10.0), }, foot: match (body.species, body.body_type) { (Ogre, Male) => (4.0, 1.0, -12.0), @@ -431,6 +439,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Cultistwarlock, _) => (3.5, 0.0, -10.5), (Huskbrute, _) => (4.5, 0.5, -12.5), (Tursus, _) => (5.5, 3.0, -14.5), + (Gigasfrost, _) => (6.5, 2.0, -19.5), }, scaler: match (body.species, body.body_type) { (Ogre, Male) => 1.12, @@ -456,6 +465,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Cultistwarlock, _) => 1.0, (Huskbrute, _) => 1.2, (Tursus, _) => 1.0, + (Gigasfrost, _) => 1.7, }, tempo: match (body.species, body.body_type) { (Ogre, Male) => 0.9, @@ -492,6 +502,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Cultistwarlock, _) => (8.0, 0.0), (Huskbrute, _) => (12.5, 0.0), (Tursus, _) => (13.0, 0.0), + (Gigasfrost, _) => (16.0, 0.0), }, shl: match (body.species, body.body_type) { (Dullahan, _) => (-4.75, -11.0, 8.5, 1.47, -0.2, 0.0), diff --git a/voxygen/anim/src/biped_large/selfbuff.rs b/voxygen/anim/src/biped_large/selfbuff.rs index 58669b784e..67fb8f3b5b 100644 --- a/voxygen/anim/src/biped_large/selfbuff.rs +++ b/voxygen/anim/src/biped_large/selfbuff.rs @@ -102,6 +102,34 @@ impl Animation for SelfBuffAnimation { // TODO: Remove clippy allow when second species is added #[allow(clippy::single_match)] match active_tool_kind { + Some(ToolKind::Axe) => { + next.control_l.position = Vec3::new(-1.0, 2.0, 12.0); + next.control_r.position = Vec3::new(1.0, 2.0, -2.0); + + next.control.position = Vec3::new( + 4.0 + move1 * -20.0 + tension2 * 5.0, + 0.0 + s_a.grip.0 / 1.0 + move1 * -5.0, + -s_a.grip.0 / 0.8 + move1 * 5.0, + ); + next.jaw.orientation = Quaternion::rotation_x(move1 * -0.3 + tension2 * -0.15); + next.head.orientation = + Quaternion::rotation_x(move1 * 0.3) * Quaternion::rotation_z(tension2 * 0.5); + next.control_l.orientation = Quaternion::rotation_x(PI / 2.0 + move1 * 0.2) + * Quaternion::rotation_y(move1 * -1.0); + next.control_r.orientation = Quaternion::rotation_x(PI / 2.0 + 0.2 + move1 * -0.2) + * Quaternion::rotation_y(0.0) + * Quaternion::rotation_z(0.0); + + next.control.orientation = Quaternion::rotation_x(-1.0 + move1 * 1.0) + * Quaternion::rotation_y(-1.8 + move1 * 1.2 + tension * 0.09) + * Quaternion::rotation_z(move1 * 1.5); + next.shoulder_l.orientation = + Quaternion::rotation_x(move1 * -0.5) * Quaternion::rotation_y(move1 * 0.5); + next.shoulder_r.orientation = + Quaternion::rotation_x(move1 * 0.6) * Quaternion::rotation_y(move1 * 0.4); + next.upper_torso.orientation = Quaternion::rotation_z(tension2 * -0.08); + next.lower_torso.orientation = Quaternion::rotation_z(tension2 * 0.08); + }, Some(ToolKind::Natural) => { if let Some(AbilitySpec::Custom(spec)) = active_tool_spec { match spec.as_str() { diff --git a/voxygen/anim/src/biped_large/shockwave.rs b/voxygen/anim/src/biped_large/shockwave.rs index 5e42d11d15..deba0bc640 100644 --- a/voxygen/anim/src/biped_large/shockwave.rs +++ b/voxygen/anim/src/biped_large/shockwave.rs @@ -197,6 +197,79 @@ impl Animation for ShockwaveAnimation { } } }, + Some(ToolKind::Axe) => { + if let Some(AbilitySpec::Custom(spec)) = active_tool_spec { + match spec.as_str() { + "Frost Gigas" => { + next.second.scale = Vec3::one() * 0.0; + + next.head.orientation = + Quaternion::rotation_x(move1pow * 0.8 + move2 * -1.2); + next.jaw.position = Vec3::new(0.0, s_a.jaw.0, s_a.jaw.1); + next.jaw.orientation = Quaternion::rotation_x(move2 * -0.3); + next.control_l.position = Vec3::new(-0.5, 4.0, 1.0); + next.control_r.position = Vec3::new(-0.5, 4.0, 1.0); + next.control_l.orientation = Quaternion::rotation_x(PI / 2.0); + next.control_r.orientation = Quaternion::rotation_x(PI / 2.0); + next.weapon_l.position = + Vec3::new(-12.0 + (move1pow * 20.0).min(10.0), -1.0, -15.0); + next.weapon_r.position = + Vec3::new(12.0 + (move1pow * -20.0).max(-10.0), -1.0, -15.0); + + next.weapon_l.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1) + * Quaternion::rotation_z(move1pow * -1.0); + next.weapon_r.orientation = Quaternion::rotation_x(-PI / 2.0 - 0.1) + * Quaternion::rotation_z(move1pow * 1.0); + + next.shoulder_l.orientation = + Quaternion::rotation_x(-0.3 + move1pow * 2.8 + move2 * -2.8); + + next.shoulder_r.orientation = + Quaternion::rotation_x(-0.3 + move1pow * 2.8 + move2 * -2.8); + + next.control.orientation = + Quaternion::rotation_x(move1pow * 1.5 + move2 * 0.6); + + let twist = move1 * 0.6 + move3 * -0.6; + next.upper_torso.position = + Vec3::new(0.0, s_a.upper_torso.0, s_a.upper_torso.1); + next.upper_torso.orientation = + Quaternion::rotation_x(move1pow * 0.4 + move2 * -1.1) + * Quaternion::rotation_z( + twist * -0.2 + move1 * -0.1 + move2 * 0.3, + ); + + next.lower_torso.orientation = + Quaternion::rotation_x(move1pow * -0.4 + move2 * 1.1) + * Quaternion::rotation_z(twist); + + next.foot_l.position = Vec3::new( + -s_a.foot.0, + s_a.foot.1 + move1pow * -7.0 + move2 * 7.0, + s_a.foot.2, + ); + next.foot_l.orientation = + Quaternion::rotation_x(move1pow * -0.8 + move2 * 0.8) + * Quaternion::rotation_z(move1pow * 0.3 + move2 * -0.3); + + next.foot_r.position = Vec3::new( + s_a.foot.0, + s_a.foot.1 + move1pow * 5.0 + move2 * -5.0, + s_a.foot.2, + ); + next.foot_r.orientation = + Quaternion::rotation_y(move1pow * -0.3 + move2 * 0.3) + * Quaternion::rotation_z(move1pow * 0.4 + move2 * -0.4); + next.main.position = + Vec3::new(-5.0 + (move1pow * 20.0).min(10.0), 4.0, 12.0); + next.main.orientation = + Quaternion::rotation_y(move1 * 0.4 + move2 * -0.1) + * Quaternion::rotation_x(PI); + }, + _ => {}, + } + } + }, _ => {}, } next diff --git a/voxygen/anim/src/biped_large/shoot.rs b/voxygen/anim/src/biped_large/shoot.rs index 904117ac80..313f6890df 100644 --- a/voxygen/anim/src/biped_large/shoot.rs +++ b/voxygen/anim/src/biped_large/shoot.rs @@ -186,6 +186,54 @@ impl Animation for ShootAnimation { next.shoulder_r.orientation = Quaternion::rotation_x(move1 * 0.8 + 1.2 * speednorm + (footrotl * -0.2)); }, + Some(ToolKind::Axe) => { + let (move1base, move2, 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), + _ => (0.0, 0.0, 0.0), + }; + let pullback = 1.0 - move3; + let move1 = move1base * pullback; + let move2 = move2 * pullback; + + next.shoulder_r.orientation = + Quaternion::rotation_y(move1 * -0.5) * Quaternion::rotation_x(move1 * -0.5); + next.head.orientation = Quaternion::rotation_x(0.0) + * Quaternion::rotation_y(move1 * 0.3) + * Quaternion::rotation_z(move1 * -0.2 + move2 * 0.5); + + next.main.position = Vec3::new(0.0, 0.0, 0.0); + next.main.orientation = Quaternion::rotation_z(move1 * 5.0); + + next.hand_l.position = Vec3::new(s_a.grip.1, 0.0, s_a.grip.0); + next.hand_r.position = Vec3::new(-s_a.grip.1, 0.0, s_a.grip.0); + + next.hand_l.orientation = Quaternion::rotation_x(0.0); + next.hand_r.orientation = Quaternion::rotation_x(0.0); + + next.control_l.position = Vec3::new(-1.0, 2.0, 12.0); + next.control_r.position = Vec3::new(1.0 + move1 * 40.0, 2.0, -2.0 + move1 * 10.0); + + next.control.position = Vec3::new( + 4.0 + move1 * -25.0, + 0.0 + s_a.grip.0 / 1.0 + move1 * -6.0, + -s_a.grip.0 / 0.8 + move1 * 10.0, + ); + + next.control_l.orientation = + Quaternion::rotation_x(PI / 2.0 + move1 * 0.3) * Quaternion::rotation_y(-0.0); + next.control_r.orientation = Quaternion::rotation_x(PI / 2.0 + 0.2 + move1 * 1.0) + * Quaternion::rotation_y(0.0) + * Quaternion::rotation_z(0.0); + next.control.orientation = Quaternion::rotation_x(-1.0 + move1 * 0.0) + * Quaternion::rotation_y(-1.8 + move1 * 2.0) + * Quaternion::rotation_z(0.0 + move1 * -0.0); + next.upper_torso.orientation = Quaternion::rotation_y(move1 * 0.3); + + next.lower_torso.orientation = Quaternion::rotation_y(move1 * -0.3); + next.torso.position = Vec3::new(move1, 0.0, 0.0); + }, Some(ToolKind::Natural) => { if let Some(AbilitySpec::Custom(spec)) = active_tool_spec { match spec.as_str() { diff --git a/voxygen/anim/src/biped_large/spinmelee.rs b/voxygen/anim/src/biped_large/spinmelee.rs index d86d9ce931..080154d95e 100644 --- a/voxygen/anim/src/biped_large/spinmelee.rs +++ b/voxygen/anim/src/biped_large/spinmelee.rs @@ -3,7 +3,7 @@ use super::{ BipedLargeSkeleton, SkeletonAttr, }; use common::{comp::item::ToolKind, states::utils::StageSection}; -use core::f32::consts::PI; +use core::f32::consts::{PI, TAU}; pub struct SpinMeleeAnimation; @@ -115,7 +115,61 @@ impl Animation for SpinMeleeAnimation { next.lower_torso.orientation = Quaternion::rotation_x(move1 * 0.8); next.torso.position = Vec3::new(0.0, 0.0, move1 * 6.4); }, + Some(ToolKind::Axe) => { + let (move1base, move2, 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), + _ => (0.0, 0.0, 0.0), + }; + let pullback = 1.0 - move3; + let move1 = move1base * pullback; + let move2ret = move2 * pullback; + next.shoulder_r.orientation = + Quaternion::rotation_y(move1 * 0.5) * Quaternion::rotation_x(move1 * 0.5); + next.head.orientation = Quaternion::rotation_x(move2ret * 0.7) + * Quaternion::rotation_y(move1 * 0.3) + * Quaternion::rotation_z(move1 * -0.2 - move2ret * 0.5); + + next.main.position = Vec3::new(0.0, 0.0, 0.0); + next.main.orientation = Quaternion::rotation_x(0.0); + + next.hand_l.position = Vec3::new(s_a.grip.1, 0.0, s_a.grip.0); + next.hand_r.position = Vec3::new(-s_a.grip.1, 0.0, s_a.grip.0); + + next.hand_l.orientation = Quaternion::rotation_x(0.0); + next.hand_r.orientation = Quaternion::rotation_x(0.0); + + next.control_l.position = Vec3::new(-1.0, 2.0, 12.0); + next.control_r.position = Vec3::new(1.0, 2.0, -2.0); + + next.control.position = Vec3::new( + 4.0 + move1 * -25.0, + 0.0 + s_a.grip.0 / 1.0 + move1 * -TAU, + -s_a.grip.0 / 0.8 + move1 * 10.0, + ); + + next.control_l.orientation = + Quaternion::rotation_x(PI / 2.0 + move1 * 0.3) * Quaternion::rotation_y(-0.0); + next.control_r.orientation = Quaternion::rotation_x(PI / 2.0 + 0.2) + * Quaternion::rotation_y(0.0) + * Quaternion::rotation_z(0.0); + next.control.orientation = Quaternion::rotation_x(-1.0 + move1 * -1.2) + * Quaternion::rotation_y(-1.8 + move1 * -1.0) + * Quaternion::rotation_z(0.0 + move1 * -1.5); + next.upper_torso.orientation = Quaternion::rotation_y(move1 * -0.4); + + next.lower_torso.orientation = Quaternion::rotation_y(move1 * 0.5); + next.torso.position = Vec3::new(move1 * -2.0, 0.0, 0.0); + + next.leg_l.orientation = Quaternion::rotation_x(0.0); + next.leg_r.orientation = Quaternion::rotation_x(move1 * -0.5); + next.foot_r.orientation = + Quaternion::rotation_x(move1 * -0.5) * Quaternion::rotation_y(move1 * -0.2); + next.foot_r.position = Vec3::new(s_a.foot.0, s_a.foot.1 + move1 * -3.0, s_a.foot.2); + next.torso.orientation = Quaternion::rotation_z(move2 * -TAU); + }, _ => {}, } diff --git a/voxygen/anim/src/biped_large/spritesummon.rs b/voxygen/anim/src/biped_large/spritesummon.rs index 44e3643245..6a66b7a99f 100644 --- a/voxygen/anim/src/biped_large/spritesummon.rs +++ b/voxygen/anim/src/biped_large/spritesummon.rs @@ -52,6 +52,64 @@ impl Animation for SpriteSummonAnimation { next.hand_r.orientation = Quaternion::rotation_x(0.0); match active_tool_kind { + Some(ToolKind::Axe) => { + let (move1base, move2, 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), + _ => (0.0, 0.0, 0.0), + }; + let pullback = 1.0 - move3; + let move1 = move1base * pullback; + let move2 = move2 * pullback; + let move2cyc = (move2 * 10.0).sin() * pullback; + + next.shoulder_r.orientation = + Quaternion::rotation_y(move1 * 0.5) * Quaternion::rotation_x(move1 * 0.5); + next.shoulder_l.orientation = + Quaternion::rotation_y(move1 * 0.5) * Quaternion::rotation_x(move1 * 0.5); + next.head.orientation = Quaternion::rotation_x(move1 * -0.2) + * Quaternion::rotation_z(move1 * -0.6 + move2 * 1.2); + + next.main.position = Vec3::new(0.0, 0.0, 0.0); + next.main.orientation = Quaternion::rotation_x(0.0); + + next.hand_l.position = Vec3::new(s_a.grip.1, 0.0, s_a.grip.0); + next.hand_r.position = Vec3::new(-s_a.grip.1, 0.0, s_a.grip.0); + + next.hand_l.orientation = Quaternion::rotation_x(0.0); + next.hand_r.orientation = Quaternion::rotation_x(0.0); + + next.main.orientation = Quaternion::rotation_x(move2 * -0.5); + + next.control_l.position = + Vec3::new(-1.0 + move1 * 16.0, 2.0, 12.0 + move1 * 20.0 + move2 * 20.0); + next.control_r.position = Vec3::new(1.0, 2.0 + move1 * 3.0, -2.0); + + next.control.position = Vec3::new( + 4.0 + move1 * 5.0 + move2 * 10.0, + 0.0 + s_a.grip.0 / 1.0 + move1 * 5.0 + move2 * -5.0, + -s_a.grip.0 / 0.8 + move1 * -2.0, + ); + + next.control_l.orientation = + Quaternion::rotation_x(PI / 2.0 + move1 * -0.2 + move2 * 0.9) + * Quaternion::rotation_z(move1 * -3.0 + move2cyc * 0.15); + next.control_r.orientation = + Quaternion::rotation_x(PI / 2.0 + 0.2 + move1 * -0.35 + move2 * -0.5) + * Quaternion::rotation_y(move1 * 0.5) + * Quaternion::rotation_z(0.0); + next.control.orientation = Quaternion::rotation_x(-1.0 + move1 * -1.8) + * Quaternion::rotation_y(-1.8 + move1 * -0.0) + * Quaternion::rotation_z(0.0 + move1 * -2.5); + + next.torso.position = Vec3::new(0.0, 0.0, 0.0); + next.upper_torso.orientation = Quaternion::rotation_z(move1 * -0.5 + move2 * 0.5) + * Quaternion::rotation_y(move2 * 0.1); + + next.lower_torso.orientation = Quaternion::rotation_z(move1 * 0.5 + move2 * -0.5) + * Quaternion::rotation_y(move2 * -0.1); + }, Some(ToolKind::Natural) => { if let Some(AbilitySpec::Custom(spec)) = active_tool_spec { match spec.as_str() { diff --git a/voxygen/anim/src/biped_large/summon.rs b/voxygen/anim/src/biped_large/summon.rs index 685c2b3c9e..ce4c0484c7 100644 --- a/voxygen/anim/src/biped_large/summon.rs +++ b/voxygen/anim/src/biped_large/summon.rs @@ -190,6 +190,39 @@ impl Animation for SummonAnimation { } } }, + Some(ToolKind::Axe) => { + if let Some(AbilitySpec::Custom(spec)) = active_tool_spec { + match spec.as_str() { + "Frost Gigas" => { + next.shoulder_l.position = Vec3::new( + -s_a.shoulder.0, + s_a.shoulder.1, + s_a.shoulder.2 - foothorir * 1.0, + ); + next.shoulder_l.orientation = + Quaternion::rotation_x(move1 * 2.7 + 0.1 * speednorm) + * Quaternion::rotation_y(move1 * 0.7 + 0.1 * speednorm); + next.head.orientation = Quaternion::rotation_x(0.0); + next.hand_l.position = Vec3::new( + -14.0 + move1 * -5.0, + 2.0 + move1 * -2.0, + -2.0 + move1 * 6.0 + move2 * 4.0, + ); + next.hand_r.position = Vec3::new(14.0, 2.0, -4.0); + next.hand_l.orientation = + Quaternion::rotation_x(PI / 3.0 + move1 * 2.2) + * Quaternion::rotation_y(move1 * 0.1) + * Quaternion::rotation_z(-0.35); + next.hand_r.orientation = + Quaternion::rotation_x(PI / 3.0) * Quaternion::rotation_z(0.35); + next.main.position = Vec3::new(14.0, 2.0, -4.0); + next.main.orientation = + Quaternion::rotation_x(PI / 3.0) * Quaternion::rotation_z(0.35); + }, + _ => {}, + } + } + }, _ => {}, } diff --git a/voxygen/anim/src/biped_small/alpha.rs b/voxygen/anim/src/biped_small/alpha.rs index 42a7efc20e..38bf624c00 100644 --- a/voxygen/anim/src/biped_small/alpha.rs +++ b/voxygen/anim/src/biped_small/alpha.rs @@ -113,7 +113,7 @@ impl Animation for AlphaAnimation { next.tail.orientation = Quaternion::rotation_x(0.05 * fastalt * speednormcancel) * Quaternion::rotation_z(fast * 0.15 * speednormcancel); }, - Some(ToolKind::Axe) => { + Some(ToolKind::Axe) | Some(ToolKind::Hammer) => { next.head.orientation = Quaternion::rotation_z(move1abs * 0.3 + move2abs * -0.6); next.control_l.position = Vec3::new(2.0 - s_a.grip.0 * 2.0, 1.0, 3.0); next.control_r.position = Vec3::new( diff --git a/voxygen/anim/src/biped_small/leapmelee.rs b/voxygen/anim/src/biped_small/leapmelee.rs new file mode 100644 index 0000000000..809c5e2b47 --- /dev/null +++ b/voxygen/anim/src/biped_small/leapmelee.rs @@ -0,0 +1,102 @@ +use super::{ + super::{vek::*, Animation}, + BipedSmallSkeleton, SkeletonAttr, +}; +use common::{comp::item::ToolKind, states::utils::StageSection}; +use core::f32::consts::PI; + +pub struct LeapAnimation; + +impl Animation for LeapAnimation { + type Dependency<'a> = ( + Option, + Option, + Vec3, + f32, + Option, + ); + type Skeleton = BipedSmallSkeleton; + + #[cfg(feature = "use-dyn-lib")] + const UPDATE_FN: &'static [u8] = b"biped_small_leapmelee\0"; + + #[cfg_attr(feature = "be-dyn-lib", export_name = "biped_small_leapmelee")] + fn update_skeleton_inner( + skeleton: &Self::Skeleton, + (active_tool_kind, _second_tool_kind, _velocity, _global_time, stage_section): Self::Dependency<'_>, + anim_time: f32, + rate: &mut f32, + s_a: &SkeletonAttr, + ) -> Self::Skeleton { + *rate = 1.0; + let mut next = (*skeleton).clone(); + + let (movement1, movement2, movement3, movement4) = match stage_section { + Some(StageSection::Buildup) => (anim_time, 0.0, 0.0, 0.0), + Some(StageSection::Movement) => (1.0, anim_time.powf(0.25), 0.0, 0.0), + Some(StageSection::Action) => (1.0, 1.0, anim_time.powf(0.25), 0.0), + Some(StageSection::Recover) => (1.0, 1.0, 1.0, anim_time), + _ => (0.0, 0.0, 0.0, 0.0), + }; + + if let Some(ToolKind::Hammer) = active_tool_kind { + next.hand_l.position = Vec3::new(s_a.grip.0 * 2.0, 0.0, s_a.grip.2); + next.hand_r.position = Vec3::new(-s_a.grip.0 * 2.0, 0.0, s_a.grip.2); + next.hand_l.orientation = Quaternion::rotation_x(0.0); + next.hand_r.orientation = Quaternion::rotation_x(0.0); + next.main.position = Vec3::new(0.0, 0.0, 0.0); + next.main.orientation = Quaternion::rotation_y(0.0) * Quaternion::rotation_z(0.0); + + next.head.position = Vec3::new(0.0, s_a.head.0, s_a.head.1); + next.control_l.position = Vec3::new(2.0 - s_a.grip.0 * 2.0, 1.0, 3.0); + next.control_r.position = Vec3::new( + 9.0 + movement2 * -10.0 + s_a.grip.0 * 2.0, + -1.0 + movement2 * 2.0, + movement2 * 3.0 - 2.0, + ); + + next.control.position = Vec3::new( + -5.0 + movement2 * 5.0, + -1.0 + s_a.grip.2, + -1.0 + movement2 * 3.0 + -s_a.grip.2 / 2.5 + s_a.grip.0 * -2.0, + ); + + next.control_l.orientation = Quaternion::rotation_x(PI / 2.0 + movement3 * 1.0) + * Quaternion::rotation_y(-0.0) + * Quaternion::rotation_z(-0.0); + next.control_r.orientation = + Quaternion::rotation_x(0.5 + movement3 * 1.5 + s_a.grip.0 * 0.2) + * Quaternion::rotation_y(0.2 + s_a.grip.0 * 0.2) + * Quaternion::rotation_z(-0.0); + + next.control.orientation = Quaternion::rotation_x(-0.3 + movement3 * -1.0) + * Quaternion::rotation_y(movement3 * -0.9 + movement3 * 2.0) + * Quaternion::rotation_z(-0.3); + + next.chest.orientation = + Quaternion::rotation_x( + movement1 * 0.3 + movement2 * 0.3 + movement3 * -0.9 + movement4 * 0.3, + ) * Quaternion::rotation_z(movement1 * 0.5 + movement2 * 0.2 + movement3 * -0.7); + + next.head.orientation = Quaternion::rotation_x(movement3 * 0.2) + * Quaternion::rotation_y(0.0 + movement2 * -0.1) + * Quaternion::rotation_z(movement1 * -0.4 + movement2 * -0.2 + movement3 * 0.6); + + next.foot_l.position = Vec3::new( + -s_a.foot.0, + s_a.foot.1 + movement3 * 6.5, + s_a.foot.2 + movement3 * -1.0, + ); + next.foot_l.orientation = Quaternion::rotation_x(-0.8 + movement3 * 1.7); + + next.foot_r.position = Vec3::new( + s_a.foot.0, + s_a.foot.1 + 4.0 + movement3 * -6.5, + s_a.foot.2 + 2.5 + movement3 * -2.5, + ); + next.foot_r.orientation = Quaternion::rotation_x(0.9 + movement3 * -1.7); + } + + next + } +} diff --git a/voxygen/anim/src/biped_small/mod.rs b/voxygen/anim/src/biped_small/mod.rs index 9348e597b1..e4909417d4 100644 --- a/voxygen/anim/src/biped_small/mod.rs +++ b/voxygen/anim/src/biped_small/mod.rs @@ -2,6 +2,7 @@ pub mod alpha; pub mod beam; pub mod dash; pub mod idle; +pub mod leapmelee; pub mod run; pub mod shockwave; pub mod shoot; @@ -13,9 +14,9 @@ pub mod wield; // Reexports pub use self::{ alpha::AlphaAnimation, beam::BeamAnimation, dash::DashAnimation, idle::IdleAnimation, - run::RunAnimation, shockwave::ShockwaveAnimation, shoot::ShootAnimation, - spinmelee::SpinMeleeAnimation, stunned::StunnedAnimation, summon::SummonAnimation, - wield::WieldAnimation, + leapmelee::LeapAnimation, run::RunAnimation, shockwave::ShockwaveAnimation, + shoot::ShootAnimation, spinmelee::SpinMeleeAnimation, stunned::StunnedAnimation, + summon::SummonAnimation, wield::WieldAnimation, }; use super::{make_bone, vek::*, FigureBoneData, Offsets, Skeleton}; @@ -144,6 +145,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Haniwa, _) => (0.0, 7.0), (Myrmidon, _) => (0.0, 8.0), (Husk, _) => (0.5, 8.5), + (Boreal, _) => (-0.5, 13.0), }, chest: match (body.species, body.body_type) { (Gnome, _) => (0.0, 9.0), @@ -157,6 +159,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Haniwa, _) => (0.0, 11.0), (Myrmidon, _) => (0.0, 11.0), (Husk, _) => (0.0, 13.0), + (Boreal, _) => (0.0, 12.0), }, pants: match (body.species, body.body_type) { (Gnome, _) => (0.0, -3.0), @@ -170,6 +173,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Haniwa, _) => (0.0, -3.5), (Myrmidon, _) => (0.0, -3.0), (Husk, _) => (-1.0, -3.0), + (Boreal, _) => (1.5, -5.0), }, tail: match (body.species, body.body_type) { (Gnome, _) => (0.0, 0.0), @@ -183,6 +187,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Haniwa, _) => (-4.5, -2.0), (Myrmidon, _) => (-2.5, -1.0), (Husk, _) => (0.0, 0.0), + (Boreal, _) => (0.0, 0.0), }, hand: match (body.species, body.body_type) { (Gnome, _) => (4.0, 0.5, -1.0), @@ -196,6 +201,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Haniwa, _) => (4.25, -1.0, 1.5), (Myrmidon, _) => (3.5, 1.5, 2.0), (Husk, _) => (4.0, 0.0, 1.0), + (Boreal, _) => (5.0, 0.5, 5.0), }, foot: match (body.species, body.body_type) { (Gnome, _) => (3.0, 0.0, 4.0), @@ -209,6 +215,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Haniwa, _) => (3.0, 0.5, 8.0), (Myrmidon, _) => (3.0, 0.5, 7.0), (Husk, _) => (4.0, 0.5, 7.0), + (Boreal, _) => (3.0, 0.0, 9.0), }, grip: match (body.species, body.body_type) { (Gnome, _) => (0.0, 0.0, 5.0), @@ -222,6 +229,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Haniwa, _) => (0.0, 0.5, 8.0), (Myrmidon, _) => (0.0, 0.0, 8.0), (Husk, _) => (0.0, 0.0, 8.0), + (Boreal, _) => (1.0, 0.0, 5.0), }, scaler: match (body.species, body.body_type) { (Gnome, _) => 0.8, @@ -235,6 +243,7 @@ impl<'a> From<&'a Body> for SkeletonAttr { (Haniwa, _) => 1.12, (Myrmidon, _) => 1.24, (Husk, _) => 1.12, + (Boreal, _) => 1.0, }, } } diff --git a/voxygen/anim/src/biped_small/wield.rs b/voxygen/anim/src/biped_small/wield.rs index 75ffe9e640..04f717834a 100644 --- a/voxygen/anim/src/biped_small/wield.rs +++ b/voxygen/anim/src/biped_small/wield.rs @@ -167,7 +167,7 @@ impl Animation for WieldAnimation { * Quaternion::rotation_y(-0.2 * speednorm) * Quaternion::rotation_z(0.5); }, - Some(ToolKind::Axe) => { + Some(ToolKind::Axe) | Some(ToolKind::Hammer) => { next.control_l.position = Vec3::new(2.0 - s_a.grip.0 * 2.0, 1.0, 3.0); next.control_r.position = Vec3::new(9.0 + s_a.grip.0 * 2.0, -1.0, -2.0 + speednorm * -3.0); diff --git a/voxygen/src/audio/sfx/mod.rs b/voxygen/src/audio/sfx/mod.rs index 47a8a8f6c1..f3877b7cf9 100644 --- a/voxygen/src/audio/sfx/mod.rs +++ b/voxygen/src/audio/sfx/mod.rs @@ -165,6 +165,10 @@ pub enum SfxEvent { FlameThrower, PoiseChange(PoiseState), GroundSlam, + FlashFreeze, + GigaRoar, + IceSpikes, + IceCrack, Utterance(UtteranceKind, VoiceKind), Lightning, Music(ToolKind, AbilitySpec), @@ -426,6 +430,31 @@ impl SfxMgr { let sfx_trigger_item = triggers.get_key_value(&SfxEvent::GroundSlam); audio.emit_sfx(sfx_trigger_item, *pos, Some(2.0), underwater); }, + Outcome::FlashFreeze { pos, .. } => { + let sfx_trigger_item = triggers.get_key_value(&SfxEvent::FlashFreeze); + audio.emit_sfx(sfx_trigger_item, *pos, Some(2.0), underwater); + }, + Outcome::SummonedCreature { pos, body, .. } => { + match body { + Body::BipedSmall(body) => match body.species { + biped_small::Species::Boreal => { + let sfx_trigger_item = triggers.get_key_value(&SfxEvent::GigaRoar); + audio.emit_sfx(sfx_trigger_item, *pos, Some(2.0), underwater); + }, + _ => {}, + }, + _ => { // not mapped to sfx file + }, + } + }, + Outcome::IceSpikes { pos, .. } => { + let sfx_trigger_item = triggers.get_key_value(&SfxEvent::IceSpikes); + audio.emit_sfx(sfx_trigger_item, *pos, Some(2.0), underwater); + }, + Outcome::IceCrack { pos, .. } => { + let sfx_trigger_item = triggers.get_key_value(&SfxEvent::IceCrack); + audio.emit_sfx(sfx_trigger_item, *pos, Some(2.0), underwater); + }, Outcome::ProjectileShot { pos, body, .. } => { match body { Body::Object( @@ -602,9 +631,7 @@ impl SfxMgr { _ => {}, }; }, - Outcome::ExpChange { .. } - | Outcome::ComboChange { .. } - | Outcome::SummonedCreature { .. } => {}, + Outcome::ExpChange { .. } | Outcome::ComboChange { .. } => {}, } } diff --git a/voxygen/src/render/pipelines/particle.rs b/voxygen/src/render/pipelines/particle.rs index 71194ac5eb..c0134532df 100644 --- a/voxygen/src/render/pipelines/particle.rs +++ b/voxygen/src/render/pipelines/particle.rs @@ -93,6 +93,8 @@ pub enum ParticleMode { Steam = 39, BarrelOrgan = 40, PotionSickness = 41, + GigaSnow = 42, + SnowStorm = 43, } impl ParticleMode { diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index 33e641257f..eb42e8483c 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -3868,6 +3868,37 @@ impl FigureMgr { skeleton_attr, ) }, + CharacterState::LeapMelee(s) => { + let stage_time = s.timer.as_secs_f32(); + let stage_progress = match s.stage_section { + StageSection::Buildup => { + stage_time / s.static_data.buildup_duration.as_secs_f32() + }, + StageSection::Movement => { + stage_time / s.static_data.movement_duration.as_secs_f32() + }, + StageSection::Action => { + stage_time / s.static_data.swing_duration.as_secs_f32() + }, + StageSection::Recover => { + stage_time / s.static_data.recover_duration.as_secs_f32() + }, + _ => 0.0, + }; + anim::biped_small::LeapAnimation::update_skeleton( + &target_base, + ( + active_tool_kind, + second_tool_kind, + rel_vel, + time, + Some(s.stage_section), + ), + stage_progress, + &mut state_animation_rate, + skeleton_attr, + ) + }, CharacterState::Shockwave(s) => { let stage_time = s.timer.as_secs_f32(); let stage_progress = match s.stage_section { @@ -5102,6 +5133,7 @@ impl FigureMgr { Some(s.stage_section), state.acc_vel, state.state_time, + ability_id, ), stage_progress, &mut state_animation_rate, @@ -5297,6 +5329,7 @@ impl FigureMgr { Some(s.stage_section), state.acc_vel, state.state_time, + ability_id, ), stage_progress, &mut state_animation_rate, @@ -5434,6 +5467,38 @@ impl FigureMgr { skeleton_attr, ) }, + CharacterState::LeapShockwave(s) => { + let stage_time = s.timer.as_secs_f32(); + let stage_progress = match s.stage_section { + StageSection::Buildup => { + stage_time / s.static_data.buildup_duration.as_secs_f32() + }, + StageSection::Movement => { + stage_time / s.static_data.buildup_duration.as_secs_f32() + }, + StageSection::Action => { + stage_time / s.static_data.swing_duration.as_secs_f32() + }, + StageSection::Recover => { + stage_time / s.static_data.recover_duration.as_secs_f32() + }, + _ => 0.0, + }; + + anim::biped_large::LeapShockAnimation::update_skeleton( + &target_base, + ( + active_tool_kind, + second_tool_kind, + rel_vel, + time, + Some(s.stage_section), + ), + stage_progress, + &mut state_animation_rate, + skeleton_attr, + ) + }, CharacterState::Shockwave(s) => { let stage_time = s.timer.as_secs_f32(); let stage_progress = match s.stage_section { diff --git a/voxygen/src/scene/particle.rs b/voxygen/src/scene/particle.rs index 1a4e2276f4..0c2d847bba 100644 --- a/voxygen/src/scene/particle.rs +++ b/voxygen/src/scene/particle.rs @@ -243,6 +243,32 @@ impl ParticleMgr { }, ); }, + Body::BipedSmall(b) if matches!(b.species, body::biped_small::Species::Boreal) => { + self.particles.resize_with( + self.particles.len() + + 2 * usize::from(self.scheduler.heartbeats(Duration::from_millis(1))), + || { + let start_pos = pos + Vec3::unit_z() * body.height() / 2.0; + let end_pos = pos + + Vec3::new( + 2.0 * rng.gen::() - 1.0, + 2.0 * rng.gen::() - 1.0, + 0.0, + ) + .normalized() + * (body.max_radius() + 4.0) + + Vec3::unit_z() * (body.height() + 20.0) * rng.gen::(); + + Particle::new_directed( + Duration::from_secs_f32(0.5), + time, + ParticleMode::GigaSnow, + start_pos, + end_pos, + ) + }, + ); + }, _ => {}, }, Outcome::ProjectileHit { pos, target, .. } => { @@ -293,6 +319,33 @@ impl ParticleMgr { ) }); }, + Outcome::FlashFreeze { pos, .. } => { + self.particles.resize_with( + self.particles.len() + + 2 * usize::from(self.scheduler.heartbeats(Duration::from_millis(1))), + || { + let start_pos = pos + Vec3::unit_z() - 1.0; + let end_pos = pos + + Vec3::new( + 4.0 * rng.gen::() - 1.0, + 4.0 * rng.gen::() - 1.0, + 0.0, + ) + .normalized() + * 1.5 + + Vec3::unit_z() + + 5.0 * rng.gen::(); + + Particle::new_directed( + Duration::from_secs_f32(0.5), + time, + ParticleMode::GigaSnow, + start_pos, + end_pos, + ) + }, + ); + }, Outcome::Death { pos, .. } => { self.particles.resize_with(self.particles.len() + 40, || { Particle::new( @@ -314,6 +367,8 @@ impl ParticleMgr { | Outcome::HealthChange { .. } | Outcome::PoiseChange { .. } | Outcome::Utterance { .. } + | Outcome::IceSpikes { .. } + | Outcome::IceCrack { .. } | Outcome::Glider { .. } => {}, } } @@ -1023,10 +1078,11 @@ impl ParticleMgr { let mut rng = thread_rng(); let dt = scene_data.state.get_delta_time(); - for (interp, pos, auras) in ( + for (interp, pos, auras, body_maybe) in ( ecs.read_storage::().maybe(), &ecs.read_storage::(), &ecs.read_storage::(), + ecs.read_storage::().maybe(), ) .join() { @@ -1136,6 +1192,39 @@ impl ParticleMgr { }, ); }, + aura::AuraKind::Buff { + kind: buff::BuffKind::Frozen, + .. + } => { + let is_new_aura = aura.data.duration.map_or(true, |max_dur| { + aura.duration.map_or(true, |rem_dur| { + rem_dur.as_secs_f32() > max_dur.as_secs_f32() * 0.9 + }) + }); + if is_new_aura { + let heartbeats = self.scheduler.heartbeats(Duration::from_millis(5)); + self.particles.resize_with( + self.particles.len() + + aura.radius.powi(2) as usize * usize::from(heartbeats) / 300, + || { + let rand_angle = rng.gen_range(0.0..TAU); + let offset = + Vec2::new(rand_angle.cos(), rand_angle.sin()) * aura.radius; + let z_start = body_maybe + .map_or(0.0, |b| rng.gen_range(0.5..0.75) * b.height()); + let z_end = body_maybe + .map_or(0.0, |b| rng.gen_range(0.0..3.0) * b.height()); + Particle::new_directed( + Duration::from_secs(3), + time, + ParticleMode::Ice, + pos.x + Vec3::unit_z() * z_start, + pos.x + offset.with_z(z_end), + ) + }, + ); + } + }, _ => {}, } } @@ -1691,10 +1780,14 @@ impl ParticleMgr { // Reserves capacity for new particles let new_particle_count = particles_per_length * heartbeats as usize; self.particles.reserve(new_particle_count); - + // higher wave when wave doesn't require ground + let wave = if shockwave.properties.requires_ground { + 0.5 + } else { + 8.0 + }; // Used to make taller the further out spikes are - let height_scale = 0.5 + 1.5 * percent; - + let height_scale = wave + 1.5 * percent; for i in 0..particles_per_length { let angle = theta + dtheta * i as f32; let direction = Vec3::new(angle.cos(), angle.sin(), 0.0); @@ -1702,9 +1795,38 @@ impl ParticleMgr { // Sub tick dt let dt = (j as f32 / heartbeats as f32) * dt; let scaled_distance = scaled_distance + scaled_speed * dt; - let pos1 = pos + (scaled_distance * direction).floor() * scale; + let mut pos1 = pos + (scaled_distance * direction).floor() * scale; let time = time + dt as f64; + // Arbitrary number chosen that is large enough to be able to accurately + // place particles most of the time, but also not too big as to make ray + // be too large (for performance reasons) + let half_ray_length = 10.0; + let mut last_air = false; + // TODO: Optimize ray to only be cast at most once per block per tick if + // it becomes an issue. + // From imbris: + // each ray is ~2 us + // at 30 FPS, it peaked at 113 rays in a tick + // total time was 240 us (although potentially half that is + // overhead from the profiling of each ray) + let _ = terrain + .ray( + pos1 + Vec3::unit_z() * half_ray_length, + pos1 - Vec3::unit_z() * half_ray_length, + ) + .for_each(|block: &Block, pos: Vec3| { + if block.is_solid() && block.get_sprite().is_none() { + if last_air { + pos1 = pos1.xy().with_z(pos.z as f32 + 1.0); + last_air = false; + } + } else { + last_air = true; + } + }) + .cast(); + let get_positions = |a| { let pos1 = match a { 2 => pos1 + Vec3::unit_x() * scale,