diff --git a/assets/common/abilities/ability_set_manifest.ron b/assets/common/abilities/ability_set_manifest.ron index 80a5fb06ed..030c47f3a3 100644 --- a/assets/common/abilities/ability_set_manifest.ron +++ b/assets/common/abilities/ability_set_manifest.ron @@ -476,6 +476,24 @@ Simple(None, "common.abilities.custom.minotaur.frenzy"), ], ), + Custom("Dullahan"): ( + primary: Simple(None, "common.abilities.custom.dullahan.melee"), + secondary: Simple(None, "common.abilities.custom.dullahan.fierce_darts"), + abilities: [ + Simple(None, "common.abilities.custom.dullahan.knife_rain"), + Simple(None, "common.abilities.custom.dullahan.dash"), + ], + ), + Custom("Cyclops"): ( + primary: Simple(None, "common.abilities.custom.cyclops.doublestrike"), + secondary: Simple(None, "common.abilities.custom.cyclops.optic_blast"), + abilities: [ + Simple(None, "common.abilities.custom.cyclops.hammer_shockwave"), + Simple(None, "common.abilities.custom.cyclops.dash"), + Simple(None, "common.abilities.custom.cyclops.reinforce"), + + ], + ), Custom("Clay Golem"): ( primary: Simple(None, "common.abilities.custom.claygolem.strike"), secondary: Simple(None, "common.abilities.custom.claygolem.laser"), diff --git a/assets/common/abilities/custom/cyclops/dash.ron b/assets/common/abilities/custom/cyclops/dash.ron new file mode 100644 index 0000000000..95d3d8f853 --- /dev/null +++ b/assets/common/abilities/custom/cyclops/dash.ron @@ -0,0 +1,28 @@ +DashMelee( + energy_cost: 0, + melee_constructor: ( + kind: Bash( + damage: 28.0, + poise: 20.0, + knockback: 2.0, + energy_regen: 0.0, + ), + scaled: Some(Bash( + damage: 36.0, + poise: 60.0, + knockback: 5.0, + energy_regen: 0.0, + )), + range: 6.0, + angle: 90.0, + multi_target: Some(Normal), + ), + energy_drain: 0, + forward_speed: 9.0, + buildup_duration: 0.8, + charge_duration: 2.0, + swing_duration: 0.1, + recover_duration: 0.8, + ori_modifier: 0.1, + charge_through: false, +) diff --git a/assets/common/abilities/custom/cyclops/doublestrike.ron b/assets/common/abilities/custom/cyclops/doublestrike.ron new file mode 100644 index 0000000000..0fa7b32a60 --- /dev/null +++ b/assets/common/abilities/custom/cyclops/doublestrike.ron @@ -0,0 +1,49 @@ +ComboMelee( + stage_data: [ + ( + stage: 1, + base_damage: 32.0, + damage_increase: 0.0, + base_poise_damage: 20, + poise_damage_increase: 0.0, + knockback: 5.0, + range: 6, + angle: 90.0, + base_buildup_duration: 0.5, + base_swing_duration: 0.4, + hit_timing: 0.4, + base_recover_duration: 0.4, + forward_movement: 0.3, + damage_kind: Crushing, + ), + ( + stage: 2, + base_damage: 36.0, + damage_increase: 0.0, + base_poise_damage: 40.0, + poise_damage_increase: 0.0, + knockback: 10.0, + range: 8, + angle: 45.0, + base_buildup_duration: 0.6, + base_swing_duration: 0.6, + hit_timing: 0.3, + base_recover_duration: 1.2, + forward_movement: 0.2, + damage_kind: Crushing, + damage_effect: Some(Buff(( + kind: Crippled, + dur_secs: 3.0, + strength: DamageFraction(0.1), + chance: 1.0, + ))), + ), + ], + initial_energy_gain: 0, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 0.0, + scales_from_combo: 0, + ori_modifier: 0.65, +) diff --git a/assets/common/abilities/custom/cyclops/hammer_shockwave.ron b/assets/common/abilities/custom/cyclops/hammer_shockwave.ron new file mode 100644 index 0000000000..68492262ac --- /dev/null +++ b/assets/common/abilities/custom/cyclops/hammer_shockwave.ron @@ -0,0 +1,18 @@ +Shockwave( + energy_cost: 0, + buildup_duration: 1.2, + swing_duration: 0.12, + recover_duration: 0.8, + damage: 45.0, + poise_damage: 60, + knockback: (strength: 10.0, direction: TowardsUp), + shockwave_angle: 360.0, + shockwave_vertical_angle: 360.0, + shockwave_speed: 40.0, + shockwave_duration: 0.4, + requires_ground: true, + move_efficiency: 0.0, + damage_kind: Piercing, + specifier: Ground, + ori_rate: 1.0, +) diff --git a/assets/common/abilities/custom/cyclops/optic_blast.ron b/assets/common/abilities/custom/cyclops/optic_blast.ron new file mode 100644 index 0000000000..e49a8b0f8a --- /dev/null +++ b/assets/common/abilities/custom/cyclops/optic_blast.ron @@ -0,0 +1,16 @@ +BasicRanged( + energy_cost: 0.0, + buildup_duration: 1.6, + recover_duration: 1.2, + projectile: LaserBeam( + damage: 48.0, + radius: 8.0, + knockback: 5.0, + energy_regen: 20.0, + min_falloff: 0.0, + ), + projectile_body: Object(LaserBeam), + projectile_speed: 100.0, + num_projectiles: 1, + projectile_spread: 0, +) diff --git a/assets/common/abilities/custom/cyclops/reinforce.ron b/assets/common/abilities/custom/cyclops/reinforce.ron new file mode 100644 index 0000000000..110363697e --- /dev/null +++ b/assets/common/abilities/custom/cyclops/reinforce.ron @@ -0,0 +1,9 @@ +SelfBuff( + buildup_duration: 0.4, + cast_duration: 0.8, + recover_duration: 0.3, + buff_kind: ProtectingWard, + buff_strength: 2.0, + buff_duration: Some(300.0), + energy_cost: 0, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/dullahan/dash.ron b/assets/common/abilities/custom/dullahan/dash.ron new file mode 100644 index 0000000000..fbbc225ef7 --- /dev/null +++ b/assets/common/abilities/custom/dullahan/dash.ron @@ -0,0 +1,28 @@ +DashMelee( + energy_cost: 0, + melee_constructor: ( + kind: Bash( + damage: 28.5, + poise: 30.0, + knockback: 2.0, + energy_regen: 0.0, + ), + scaled: Some(Bash( + damage: 36.0, + poise: 38.6, + knockback: 3.0, + energy_regen: 0.0, + )), + range: 5.0, + angle: 90.0, + multi_target: Some(Normal), + ), + energy_drain: 0, + forward_speed: 8.0, + buildup_duration: 0.6, + charge_duration: 2.0, + swing_duration: 0.1, + recover_duration: 1.2, + ori_modifier: 0.1, + charge_through: false, +) diff --git a/assets/common/abilities/custom/dullahan/fierce_darts.ron b/assets/common/abilities/custom/dullahan/fierce_darts.ron new file mode 100644 index 0000000000..64a9b1f906 --- /dev/null +++ b/assets/common/abilities/custom/dullahan/fierce_darts.ron @@ -0,0 +1,15 @@ +BasicRanged( + energy_cost: 0.0, + buildup_duration: 0.55, + recover_duration: 0.45, + projectile: Knife( + damage: 31.0, + knockback: 5.0, + energy_regen: 20.0, + min_falloff: 0.0, + ), + projectile_body: Object(SpectralSwordLarge), + projectile_speed: 120.0, + num_projectiles: 3, + projectile_spread: 0.075, +) diff --git a/assets/common/abilities/custom/dullahan/knife_rain.ron b/assets/common/abilities/custom/dullahan/knife_rain.ron new file mode 100644 index 0000000000..e1712cb2f3 --- /dev/null +++ b/assets/common/abilities/custom/dullahan/knife_rain.ron @@ -0,0 +1,16 @@ +BasicRanged( + energy_cost: 0.0, + buildup_duration: 1.1, + recover_duration: 0.2, + projectile: Knife( + damage: 34.0, + radius: 3.8, + knockback: 5.0, + energy_regen: 20.0, + min_falloff: 0.3, + ), + projectile_body: Object(SpectralSwordSmall), + projectile_speed: 20.0, + num_projectiles: 36, + projectile_spread: 0.4, +) \ No newline at end of file diff --git a/assets/common/abilities/custom/dullahan/melee.ron b/assets/common/abilities/custom/dullahan/melee.ron new file mode 100644 index 0000000000..c5e30bfc0e --- /dev/null +++ b/assets/common/abilities/custom/dullahan/melee.ron @@ -0,0 +1,55 @@ +ComboMelee( + stage_data: [ + ( + stage: 1, + base_damage: 35.5, + damage_increase: 0.0, + base_poise_damage: 15.0, + poise_damage_increase: 0.0, + knockback: 2.0, + range: 6.0, + angle: 60.0, + base_buildup_duration: 0.8, + base_swing_duration: 0.1, + hit_timing: 0.4, + base_recover_duration: 0.3, + forward_movement: 0.8, + damage_kind: Slashing, + damage_effect: Some(Buff(( + kind: Bleeding, + dur_secs: 3.0, + strength: DamageFraction(0.05), + chance: 0.3, + ))), + ), + ( + stage: 2, + base_damage: 38.5, + damage_increase: 0.0, + base_poise_damage: 20.0, + poise_damage_increase: 0.0, + knockback: 8.0, + range: 6.0, + angle: 60.0, + base_buildup_duration: 0.7, + base_swing_duration: 0.1, + hit_timing: 0.4, + base_recover_duration: 1.3, + forward_movement: 0.2, + damage_kind: Slashing, + damage_effect: Some(Buff(( + kind: Bleeding, + dur_secs: 3.0, + strength: DamageFraction(0.1), + chance: 0.15, + ))), + ), + ], + initial_energy_gain: 0, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 0.0, + scales_from_combo: 0, + ori_modifier: 0.6, +) diff --git a/assets/common/entity/dungeon/tier-4/miniboss.ron b/assets/common/entity/dungeon/tier-4/miniboss.ron index 50a3e08684..b17bb8aef1 100644 --- a/assets/common/entity/dungeon/tier-4/miniboss.ron +++ b/assets/common/entity/dungeon/tier-4/miniboss.ron @@ -1,7 +1,7 @@ #![enable(implicit_some)] ( - name: Name("Dullahan"), - body: RandomWith("dullahan"), + name: Automatic, + body: RandomWith("cyclops"), alignment: Alignment(Enemy), loot: LootTable("common.loot_tables.dungeon.tier-4.miniboss"), inventory: ( diff --git a/assets/common/entity/wild/aggressive/cyclops.ron b/assets/common/entity/wild/aggressive/dullahan.ron similarity index 75% rename from assets/common/entity/wild/aggressive/cyclops.ron rename to assets/common/entity/wild/aggressive/dullahan.ron index b5da54369f..23b6e2380d 100644 --- a/assets/common/entity/wild/aggressive/cyclops.ron +++ b/assets/common/entity/wild/aggressive/dullahan.ron @@ -1,7 +1,7 @@ #![enable(implicit_some)] ( - name: Automatic, - body: RandomWith("cyclops"), + name: Name("Dullahan"), + body: RandomWith("dullahan"), alignment: Alignment(Enemy), loot: LootTable("common.loot_tables.creature.biped_large.default"), inventory: ( diff --git a/assets/common/entity/wild/peaceful/mammoth.ron b/assets/common/entity/wild/peaceful/mammoth.ron index f1242dac20..d168f69c33 100644 --- a/assets/common/entity/wild/peaceful/mammoth.ron +++ b/assets/common/entity/wild/peaceful/mammoth.ron @@ -2,7 +2,7 @@ ( name: Automatic, body: RandomWith("mammoth"), - alignment: Alignment(Enemy), + alignment: Alignment(Wild), loot: LootTable("common.loot_tables.creature.quad_medium.mammoth"), inventory: ( loadout: FromBody, diff --git a/assets/common/items/npc_armor/biped_large/cyclops.ron b/assets/common/items/npc_armor/biped_large/cyclops.ron new file mode 100644 index 0000000000..ac1c0d1ca5 --- /dev/null +++ b/assets/common/items/npc_armor/biped_large/cyclops.ron @@ -0,0 +1,13 @@ +ItemDef( + name: "Cyclops Armor", + description: "Made of mysteries.", + kind: Armor(( + kind: Chest, + stats: Direct(( + protection: Some(Normal(120.0)), + poise_resilience: Some(Normal(60.0)), + )), + )), + quality: Moderate, + tags: [], +) diff --git a/assets/common/items/npc_armor/biped_large/dullahan.ron b/assets/common/items/npc_armor/biped_large/dullahan.ron new file mode 100644 index 0000000000..8cbe6e432b --- /dev/null +++ b/assets/common/items/npc_armor/biped_large/dullahan.ron @@ -0,0 +1,13 @@ +ItemDef( + name: "Dullahan Itself Armor", + description: "Made of It ownself.", + kind: Armor(( + kind: Chest, + stats: Direct(( + protection: Some(Normal(200.0)), + poise_resilience: Some(Normal(10.0)), + )), + )), + quality: Moderate, + tags: [], +) diff --git a/assets/common/items/npc_weapons/hammer/cyclops_hammer.ron b/assets/common/items/npc_weapons/hammer/cyclops_hammer.ron index ce9a3546ec..abf78a8bd9 100644 --- a/assets/common/items/npc_weapons/hammer/cyclops_hammer.ron +++ b/assets/common/items/npc_weapons/hammer/cyclops_hammer.ron @@ -17,5 +17,5 @@ ItemDef( )), quality: Low, tags: [], - ability_spec: Some(Custom("Hammer Simple")), + ability_spec: Some(Custom("Cyclops")), ) \ No newline at end of file diff --git a/assets/common/items/npc_weapons/sword/dullahan_sword.ron b/assets/common/items/npc_weapons/sword/dullahan_sword.ron index ccf989ca91..bd9b05a051 100644 --- a/assets/common/items/npc_weapons/sword/dullahan_sword.ron +++ b/assets/common/items/npc_weapons/sword/dullahan_sword.ron @@ -5,11 +5,11 @@ ItemDef( kind: Sword, hands: Two, stats: ( - equip_time_secs: 0.5, - power: 1.5, + equip_time_secs: 0.01, + power: 1.0, effect_power: 1.0, - speed: 0.75, - crit_chance: 0.0625, + speed: 1.0, + crit_chance: 0.0645, range: 1.0, energy_efficiency: 1.0, buff_strength: 1.0, @@ -17,5 +17,5 @@ ItemDef( )), quality: Low, tags: [], - ability_spec: Some(Custom("Sword Simple")), + ability_spec: Some(Custom("Dullahan")), ) \ No newline at end of file diff --git a/assets/voxygen/audio/sfx.ron b/assets/voxygen/audio/sfx.ron index c938ae4389..53e064e111 100644 --- a/assets/voxygen/audio/sfx.ron +++ b/assets/voxygen/audio/sfx.ron @@ -1244,6 +1244,18 @@ ], threshold: 0.2, ), + LaserBeam: ( + files: [ + "voxygen.audio.sfx.abilities.laser_beam", + ], + threshold: 1.25, + ), + CyclopsCharge: ( + files: [ + "voxygen.audio.sfx.abilities.cyclops_charge", + ], + threshold: 0.3, + ), GigaRoar: ( files: [ "voxygen.audio.sfx.abilities.gigas_frost_roar", diff --git a/assets/voxygen/audio/sfx/abilities/cyclops_charge.ogg b/assets/voxygen/audio/sfx/abilities/cyclops_charge.ogg new file mode 100644 index 0000000000..fd1f9a9e30 --- /dev/null +++ b/assets/voxygen/audio/sfx/abilities/cyclops_charge.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8acebb54a599590e712062ae74ee08ae8d6e3a73e17f9c7f3bb9b1673897810e +size 9987 diff --git a/assets/voxygen/audio/sfx/abilities/laser_beam.ogg b/assets/voxygen/audio/sfx/abilities/laser_beam.ogg new file mode 100644 index 0000000000..4af434f12f --- /dev/null +++ b/assets/voxygen/audio/sfx/abilities/laser_beam.ogg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a4c8b0855c0c54d9a086b368786255bc1e5e519963e3e06c208a8505c63b5af +size 11634 diff --git a/assets/voxygen/shaders/particle-vert.glsl b/assets/voxygen/shaders/particle-vert.glsl index 1dd6faacb8..5bb05aa7b3 100644 --- a/assets/voxygen/shaders/particle-vert.glsl +++ b/assets/voxygen/shaders/particle-vert.glsl @@ -80,6 +80,7 @@ const int STEAM = 39; const int BARRELORGAN = 40; const int POTION_SICKNESS = 41; const int GIGA_SNOW = 42; +const int CYCLOPS_CHARGE = 43; // meters per second squared (acceleration) const float earth_gravity = 9.807; @@ -666,6 +667,16 @@ void main() { spin_in_axis(vec3(rand6, rand7, rand8), percent() * 10 + 3 * rand9) ); break; + case CYCLOPS_CHARGE: + f_reflect = 0.0; + float burn_size = 8.0 * (1 - slow_start(0.1)) * slow_end(0.15); + attr = Attr( + (inst_dir * slow_end(1.5)) + vec3(rand0, rand1, rand2) * (percent() + 2) * 0.1, + vec3(burn_size), + vec4(vec3(6.9, 0.0, 0.0), 1), + spin_in_axis(vec3(rand6, rand7, rand8), percent() * 10 + 3 * rand9) + ); + break; default: attr = Attr( linear_motion( diff --git a/assets/voxygen/voxel/object_manifest.ron b/assets/voxygen/voxel/object_manifest.ron index 0907af4b76..c21739a238 100644 --- a/assets/voxygen/voxel/object_manifest.ron +++ b/assets/voxygen/voxel/object_manifest.ron @@ -889,4 +889,34 @@ central: ("armor.empty"), ) ), + SpectralSwordSmall: ( + bone0: ( + offset: (-0.5, -25.0, -8.5), + central: ("weapon.projectile.spectral_sword_small"), + ), + bone1: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ) + ), + SpectralSwordLarge: ( + bone0: ( + offset: (-0.5, -30.0, -8.5), + central: ("weapon.projectile.spectral_sword_large"), + ), + bone1: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ) + ), + LaserBeam: ( + bone0: ( + offset: (-6.0, -60.0, -17.0), + central: ("weapon.projectile.laser_beam"), + ), + bone1: ( + offset: (0.0, 0.0, 0.0), + central: ("armor.empty"), + ) + ), }) diff --git a/assets/voxygen/voxel/weapon/projectile/laser_beam.vox b/assets/voxygen/voxel/weapon/projectile/laser_beam.vox new file mode 100644 index 0000000000..b750dd43a7 --- /dev/null +++ b/assets/voxygen/voxel/weapon/projectile/laser_beam.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f211e806a5d40db89821b12081c823a5733a56c872a370a933267a7cf1710ed +size 50488 diff --git a/assets/voxygen/voxel/weapon/projectile/spectral_sword_large.vox b/assets/voxygen/voxel/weapon/projectile/spectral_sword_large.vox new file mode 100644 index 0000000000..34597b268c --- /dev/null +++ b/assets/voxygen/voxel/weapon/projectile/spectral_sword_large.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cc38d49dc77afe339caf871fef8780b6638c145a3cc5dee53423ee0b695a2677 +size 2284 diff --git a/assets/voxygen/voxel/weapon/projectile/spectral_sword_small.vox b/assets/voxygen/voxel/weapon/projectile/spectral_sword_small.vox new file mode 100644 index 0000000000..c21f368f41 --- /dev/null +++ b/assets/voxygen/voxel/weapon/projectile/spectral_sword_small.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f29a75ca391fae872a5fad1858a2efba0774c19e6a3c9002715dc7811f735318 +size 1908 diff --git a/assets/world/wildlife/spawn/temperate/rare.ron b/assets/world/wildlife/spawn/temperate/rare.ron index e1bd3da4ed..076e7ea827 100644 --- a/assets/world/wildlife/spawn/temperate/rare.ron +++ b/assets/world/wildlife/spawn/temperate/rare.ron @@ -6,7 +6,7 @@ SpawnEntry ( groups: [ (1, (1, 1, "common.entity.wild.aggressive.ogre")), (1, (1, 1, "common.entity.wild.aggressive.swamp_troll")), - (1, (1, 1, "common.entity.wild.aggressive.cyclops")), + (1, (1, 1, "common.entity.wild.aggressive.dullahan")), ], spawn_mode: Land, day_period: [Night, Morning, Noon, Evening], diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index b259123d0d..9153487a32 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -783,12 +783,12 @@ impl Body { Body::FishSmall(_) => 3, Body::BipedLarge(biped_large) => match biped_large.species { biped_large::Species::Ogre => 320, - biped_large::Species::Cyclops => 320, + biped_large::Species::Cyclops => 1000, biped_large::Species::Wendigo => 280, biped_large::Species::Cavetroll => 240, biped_large::Species::Mountaintroll => 240, biped_large::Species::Swamptroll => 240, - biped_large::Species::Dullahan => 700, + biped_large::Species::Dullahan => 600, biped_large::Species::Mindflayer => 1250, biped_large::Species::Tidalwarrior => 1600, biped_large::Species::Yeti => 1200, @@ -895,10 +895,17 @@ impl Body { ), Body::BipedLarge(b) => matches!( b.species, - biped_large::Species::Huskbrute | biped_large::Species::Gigasfrost + biped_large::Species::Huskbrute + | biped_large::Species::Gigasfrost + | biped_large::Species::Dullahan ), _ => false, }, + BuffKind::Crippled => match self { + Body::Object(_) | Body::Golem(_) | Body::Ship(_) => true, + Body::BipedLarge(b) => matches!(b.species, biped_large::Species::Dullahan), + _ => false, + }, BuffKind::Burning => match self { Body::Golem(g) => matches!(g.species, golem::Species::ClayGolem), Body::BipedSmall(b) => matches!(b.species, biped_small::Species::Haniwa), @@ -915,6 +922,7 @@ impl Body { | bird_large::Species::WealdWyvern ), Body::Arthropod(b) => matches!(b.species, arthropod::Species::Moltencrawler), + Body::BipedLarge(b) => matches!(b.species, biped_large::Species::Cyclops), _ => false, }, BuffKind::Ensnared => match self { diff --git a/common/src/comp/body/object.rs b/common/src/comp/body/object.rs index f34cd39782..f0983ee475 100644 --- a/common/src/comp/body/object.rs +++ b/common/src/comp/body/object.rs @@ -101,6 +101,9 @@ make_case_elim!( DagonBomb = 86, BarrelOrgan = 87, IceBomb = 88, + SpectralSwordSmall = 89, + SpectralSwordLarge = 90, + LaserBeam = 91, } ); @@ -111,7 +114,7 @@ impl Body { } } -pub const ALL_OBJECTS: [Body; 89] = [ +pub const ALL_OBJECTS: [Body; 92] = [ Body::Arrow, Body::Bomb, Body::Scarecrow, @@ -124,6 +127,8 @@ pub const ALL_OBJECTS: [Body; 89] = [ Body::ChestLight, Body::ChestOpen, Body::ChestSkull, + Body::SpectralSwordSmall, + Body::SpectralSwordLarge, Body::Pumpkin, Body::Pumpkin2, Body::Pumpkin3, @@ -201,6 +206,7 @@ pub const ALL_OBJECTS: [Body; 89] = [ Body::DagonBomb, Body::BarrelOrgan, Body::IceBomb, + Body::LaserBeam, ]; impl From
for super::Body { @@ -299,6 +305,9 @@ impl Body { Body::DagonBomb => "dagon_bomb", Body::BarrelOrgan => "barrel_organ", Body::IceBomb => "ice_bomb", + Body::SpectralSwordSmall => "spectral_sword_small", + Body::SpectralSwordLarge => "spectral_sword_large", + Body::LaserBeam => "laser_beam", } } @@ -321,7 +330,9 @@ impl Body { | Body::ArrowTurret | Body::MultiArrow | Body::Dart - | Body::DagonBomb => 500.0, + | Body::DagonBomb + | Body::SpectralSwordSmall + | Body::SpectralSwordLarge => 500.0, Body::Bomb => 2000.0, // I have no idea what it's supposed to be Body::Crate => 300.0, // let's say it's a lot of wood and maybe some contents Body::Scarecrow => 900.0, @@ -341,6 +352,8 @@ impl Body { Body::Arrow | Body::ArrowSnake | Body::ArrowTurret | Body::MultiArrow | Body::Dart => { 0.003 }, + Body::SpectralSwordSmall => 0.5, + Body::SpectralSwordLarge => 50.0, Body::BedBlue => 50.0, Body::Bedroll => 3.0, Body::Bench => 100.0, @@ -413,6 +426,7 @@ impl Body { Body::Coconut => 2.0, Body::GnarlingTotemRed | Body::GnarlingTotemGreen | Body::GnarlingTotemWhite => 100.0, Body::IceBomb => 12298.0, // 2.5 m diamter but ice + Body::LaserBeam => 80000.0, }; Mass(m) @@ -424,6 +438,8 @@ impl Body { Vec3::new(0.01, 0.8, 0.01) }, Body::BoltFire => Vec3::new(0.1, 0.1, 0.1), + Body::SpectralSwordSmall => Vec3::new(0.2, 0.9, 0.1), + Body::SpectralSwordLarge => Vec3::new(0.2, 1.5, 0.1), Body::Crossbow => Vec3::new(3.0, 3.0, 1.5), Body::HaniwaSentry => Vec3::new(0.8, 0.8, 1.4), Body::SeaLantern => Vec3::new(0.8, 0.8, 1.4), @@ -435,6 +451,7 @@ impl Body { }, Body::BarrelOrgan => Vec3::new(4.0, 2.0, 3.0), Body::IceBomb => Vec3::broadcast(2.5), + Body::LaserBeam => Vec3::new(8.0, 8.0, 8.0), // FIXME: this *must* be exhaustive match _ => Vec3::broadcast(0.5), } diff --git a/common/src/comp/inventory/loadout_builder.rs b/common/src/comp/inventory/loadout_builder.rs index 7909afada2..4fce8c76fc 100644 --- a/common/src/comp/inventory/loadout_builder.rs +++ b/common/src/comp/inventory/loadout_builder.rs @@ -910,13 +910,16 @@ impl LoadoutBuilder { Some("common.items.npc_armor.biped_large.harvester") }, biped_large::Species::Ogre - | biped_large::Species::Cyclops | biped_large::Species::Blueoni | biped_large::Species::Redoni | biped_large::Species::Cavetroll | biped_large::Species::Wendigo => { Some("common.items.npc_armor.biped_large.generic") }, + biped_large::Species::Cyclops => Some("common.items.npc_armor.biped_large.cyclops"), + biped_large::Species::Dullahan => { + Some("common.items.npc_armor.biped_large.dullahan") + }, biped_large::Species::Cultistwarlord => { Some("common.items.npc_armor.biped_large.warlord") }, diff --git a/common/src/comp/projectile.rs b/common/src/comp/projectile.rs index 27d8c1aba9..5dd38e7160 100644 --- a/common/src/comp/projectile.rs +++ b/common/src/comp/projectile.rs @@ -53,6 +53,11 @@ pub enum ProjectileConstructor { knockback: f32, energy_regen: f32, }, + Knife { + damage: f32, + knockback: f32, + energy_regen: f32, + }, Fireball { damage: f32, radius: f32, @@ -114,6 +119,12 @@ pub enum ProjectileConstructor { knockback: f32, min_falloff: f32, }, + LaserBeam { + damage: f32, + radius: f32, + knockback: f32, + min_falloff: f32, + }, } impl ProjectileConstructor { @@ -181,6 +192,59 @@ impl ProjectileConstructor { is_point: true, } }, + Knife { + damage, + knockback, + energy_regen, + } => { + let knockback = AttackEffect::new( + Some(GroupTarget::OutOfGroup), + CombatEffect::Knockback(Knockback { + strength: knockback, + direction: KnockbackDir::Away, + }) + .adjusted_by_stats(tool_stats), + ) + .with_requirement(CombatRequirement::AnyDamage); + let energy = AttackEffect::new(None, CombatEffect::EnergyReward(energy_regen)) + .with_requirement(CombatRequirement::AnyDamage); + let buff = CombatEffect::Buff(CombatBuff { + kind: BuffKind::Bleeding, + dur_secs: 10.0, + strength: CombatBuffStrength::DamageFraction(0.1), + chance: 0.1, + }) + .adjusted_by_stats(tool_stats); + let mut damage = AttackDamage::new( + Damage { + source: DamageSource::Projectile, + kind: DamageKind::Piercing, + value: damage, + }, + Some(GroupTarget::OutOfGroup), + 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) + .with_effect(energy) + .with_effect(knockback) + .with_combo_increment(); + + Projectile { + hit_solid: vec![Effect::Stick, Effect::Bonk], + hit_entity: vec![Effect::Attack(attack), Effect::Vanish], + time_left: Duration::from_secs(15), + owner, + ignore_group: true, + is_sticky: true, + is_point: true, + } + }, Fireball { damage, radius, @@ -679,6 +743,53 @@ impl ProjectileConstructor { is_point: true, } }, + LaserBeam { + damage, + radius, + knockback, + min_falloff, + } => { + let knockback = AttackEffect::new( + Some(GroupTarget::OutOfGroup), + CombatEffect::Knockback(Knockback { + strength: knockback, + direction: KnockbackDir::Away, + }) + .adjusted_by_stats(tool_stats), + ) + .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); + let explosion = Explosion { + effects: vec![ + RadiusEffect::Attack(attack), + RadiusEffect::TerrainDestruction(10.0, Rgb::black()), + ], + radius, + reagent: Some(Reagent::Yellow), + 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, + } + }, } } @@ -695,6 +806,14 @@ impl ProjectileConstructor { *damage *= power; *energy_regen *= regen; }, + Knife { + ref mut damage, + ref mut energy_regen, + .. + } => { + *damage *= power; + *energy_regen *= regen; + }, Fireball { ref mut damage, ref mut energy_regen, @@ -786,6 +905,14 @@ impl ProjectileConstructor { *damage *= power; *radius *= range; }, + LaserBeam { + ref mut damage, + ref mut radius, + .. + } => { + *damage *= power; + *radius *= range; + }, } self } @@ -794,6 +921,7 @@ impl ProjectileConstructor { use ProjectileConstructor::*; match self { Arrow { .. } => false, + Knife { .. } => false, Fireball { .. } => true, Frostball { .. } => true, Poisonball { .. } => true, @@ -806,6 +934,7 @@ impl ProjectileConstructor { SeaBomb { .. } => true, WindBomb { .. } => true, IceBomb { .. } => true, + LaserBeam { .. } => true, } } } diff --git a/common/src/outcome.rs b/common/src/outcome.rs index 68dd3e0b66..10a58150de 100644 --- a/common/src/outcome.rs +++ b/common/src/outcome.rs @@ -97,6 +97,12 @@ pub enum Outcome { FlashFreeze { pos: Vec3