From aad97340556088b2f5b01cb38df8a23f62d48103 Mon Sep 17 00:00:00 2001 From: jiminycrick Date: Mon, 23 Nov 2020 11:27:18 -0800 Subject: [PATCH] Agent tactic refactoring Lower theropods spawns clippy, changelog review response --- CHANGELOG.md | 1 + .../unique/quadlowbasic/singlestrike.ron | 10 +- .../unique/quadlowbasic/triplestrike.ron | 22 +- .../abilities/unique/quadlowbreathe/dash.ron | 2 +- .../unique/quadlowbreathe/triplestrike.ron | 22 +- .../abilities/unique/quadlowquick/dash.ron | 2 +- .../unique/quadlowquick/quadstrike.ron | 26 +- .../unique/quadlowranged/firebomb.ron | 4 +- .../unique/quadlowranged/singlestrike.ron | 12 +- .../unique/quadlowtail/triplestrike.ron | 22 +- .../unique/quadmedbasic/singlestrike.ron | 12 +- .../unique/quadmedbasic/triplestrike.ron | 22 +- .../abilities/unique/quadmedcharge/dash.ron | 4 +- .../unique/quadmedcharge/doublestrike.ron | 18 +- .../unique/quadmedjump/doublestrike.ron | 18 +- .../abilities/unique/quadmedquick/dash.ron | 4 +- .../unique/quadmedquick/triplestrike.ron | 20 +- .../unique/quadsmallbasic/singlestrike.ron | 12 +- .../unique/theropodbasic/singlestrike.ron | 12 +- .../unique/theropodbasic/triplestrike.ron | 22 +- .../unique/theropodbird/singlestrike.ron | 12 +- .../unique/theropodbird/triplestrike.ron | 22 +- common/src/comp/body.rs | 2 +- common/src/loadout_builder.rs | 10 +- common/src/states/utils.rs | 2 +- common/src/sys/agent.rs | 1177 ++++++++++++----- voxygen/src/anim/src/quadruped_medium/dash.rs | 67 +- voxygen/src/scene/figure/mod.rs | 6 +- world/src/layer/wildlife.rs | 250 ++-- 29 files changed, 1205 insertions(+), 610 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2382628d2..25c900f298 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Variable dungeon difficulty - Aurora Borealis (localised entirely within the kitchen) - Block-based voxel lighting +- Animals now have customized attacks and AI ### Changed diff --git a/assets/common/abilities/unique/quadlowbasic/singlestrike.ron b/assets/common/abilities/unique/quadlowbasic/singlestrike.ron index 95e8f88cb2..cbef5c4335 100644 --- a/assets/common/abilities/unique/quadlowbasic/singlestrike.ron +++ b/assets/common/abilities/unique/quadlowbasic/singlestrike.ron @@ -4,7 +4,7 @@ ComboMelee( stage: 1, base_damage: 100, max_damage: 100, - damage_increase: 10, + damage_increase: 0, knockback: 5.0, range: 3.5, angle: 60.0, @@ -15,9 +15,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, + max_energy_gain: 0, energy_increase: 0, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) \ No newline at end of file diff --git a/assets/common/abilities/unique/quadlowbasic/triplestrike.ron b/assets/common/abilities/unique/quadlowbasic/triplestrike.ron index 36a67aed2c..4cf7afcd01 100644 --- a/assets/common/abilities/unique/quadlowbasic/triplestrike.ron +++ b/assets/common/abilities/unique/quadlowbasic/triplestrike.ron @@ -3,8 +3,8 @@ ComboMelee( ( stage: 1, base_damage: 120, - max_damage: 140, - damage_increase: 10, + max_damage: 120, + damage_increase: 0, knockback: 10.0, range: 3.5, angle: 30.0, @@ -16,8 +16,8 @@ ComboMelee( ( stage: 2, base_damage: 80, - max_damage: 110, - damage_increase: 15, + max_damage: 80, + damage_increase: 0, knockback: 10.0, range: 3.5, angle: 30.0, @@ -29,8 +29,8 @@ ComboMelee( ( stage: 3, base_damage: 130, - max_damage: 170, - damage_increase: 20, + max_damage: 130, + damage_increase: 0, knockback: 10.0, range: 3.5, angle: 30.0, @@ -41,9 +41,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, - energy_increase: 20, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) \ No newline at end of file diff --git a/assets/common/abilities/unique/quadlowbreathe/dash.ron b/assets/common/abilities/unique/quadlowbreathe/dash.ron index 96647c3eb0..ea49ea8921 100644 --- a/assets/common/abilities/unique/quadlowbreathe/dash.ron +++ b/assets/common/abilities/unique/quadlowbreathe/dash.ron @@ -13,5 +13,5 @@ DashMelee( swing_duration: 100, recover_duration: 800, infinite_charge: true, - is_interruptible: true, + is_interruptible: false, ) diff --git a/assets/common/abilities/unique/quadlowbreathe/triplestrike.ron b/assets/common/abilities/unique/quadlowbreathe/triplestrike.ron index 38908118bb..89c653db45 100644 --- a/assets/common/abilities/unique/quadlowbreathe/triplestrike.ron +++ b/assets/common/abilities/unique/quadlowbreathe/triplestrike.ron @@ -3,8 +3,8 @@ ComboMelee( ( stage: 1, base_damage: 100, - max_damage: 120, - damage_increase: 10, + max_damage: 100, + damage_increase: 0, knockback: 10.0, range: 4.5, angle: 30.0, @@ -16,8 +16,8 @@ ComboMelee( ( stage: 2, base_damage: 80, - max_damage: 110, - damage_increase: 15, + max_damage: 80, + damage_increase: 0, knockback: 10.0, range: 3.5, angle: 30.0, @@ -29,8 +29,8 @@ ComboMelee( ( stage: 3, base_damage: 130, - max_damage: 170, - damage_increase: 20, + max_damage: 130, + damage_increase: 0, knockback: 10.0, range: 3.5, angle: 30.0, @@ -41,9 +41,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, - energy_increase: 20, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) diff --git a/assets/common/abilities/unique/quadlowquick/dash.ron b/assets/common/abilities/unique/quadlowquick/dash.ron index 292cfb22b7..2b051e0455 100644 --- a/assets/common/abilities/unique/quadlowquick/dash.ron +++ b/assets/common/abilities/unique/quadlowquick/dash.ron @@ -13,5 +13,5 @@ DashMelee( swing_duration: 100, recover_duration: 500, infinite_charge: true, - is_interruptible: true, + is_interruptible: false, ) diff --git a/assets/common/abilities/unique/quadlowquick/quadstrike.ron b/assets/common/abilities/unique/quadlowquick/quadstrike.ron index 58ce193a22..1a35c2e7a6 100644 --- a/assets/common/abilities/unique/quadlowquick/quadstrike.ron +++ b/assets/common/abilities/unique/quadlowquick/quadstrike.ron @@ -3,8 +3,8 @@ ComboMelee( ( stage: 1, base_damage: 100, - max_damage: 120, - damage_increase: 10, + max_damage: 100, + damage_increase: 0, knockback: 2.0, range: 3.5, angle: 30.0, @@ -16,8 +16,8 @@ ComboMelee( ( stage: 2, base_damage: 130, - max_damage: 170, - damage_increase: 15, + max_damage: 130, + damage_increase: 0, knockback: 2.0, range: 3.5, angle: 30.0, @@ -29,8 +29,8 @@ ComboMelee( ( stage: 3, base_damage: 130, - max_damage: 170, - damage_increase: 20, + max_damage: 130, + damage_increase: 0, knockback: 2.0, range: 3.5, angle: 30.0, @@ -42,8 +42,8 @@ ComboMelee( ( stage: 4, base_damage: 130, - max_damage: 170, - damage_increase: 20, + max_damage: 130, + damage_increase: 0, knockback: 8.0, range: 3.5, angle: 30.0, @@ -54,9 +54,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, - energy_increase: 20, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) \ No newline at end of file diff --git a/assets/common/abilities/unique/quadlowranged/firebomb.ron b/assets/common/abilities/unique/quadlowranged/firebomb.ron index 77011621e8..eb0d41a830 100644 --- a/assets/common/abilities/unique/quadlowranged/firebomb.ron +++ b/assets/common/abilities/unique/quadlowranged/firebomb.ron @@ -13,6 +13,6 @@ BasicRanged( ..Default::default() }),*/ projectile_gravity: Some(Gravity(5.0)), - projectile_speed: 60.0, + projectile_speed: 70.0, can_continue: true, -) \ No newline at end of file +) diff --git a/assets/common/abilities/unique/quadlowranged/singlestrike.ron b/assets/common/abilities/unique/quadlowranged/singlestrike.ron index 80f45a4b4e..237deb4a92 100644 --- a/assets/common/abilities/unique/quadlowranged/singlestrike.ron +++ b/assets/common/abilities/unique/quadlowranged/singlestrike.ron @@ -4,7 +4,7 @@ ComboMelee( stage: 1, base_damage: 60, max_damage: 60, - damage_increase: 10, + damage_increase: 0, knockback: 5.0, range: 3.5, angle: 60.0, @@ -15,9 +15,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, - energy_increase: 20, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) \ No newline at end of file diff --git a/assets/common/abilities/unique/quadlowtail/triplestrike.ron b/assets/common/abilities/unique/quadlowtail/triplestrike.ron index 5d6f742535..2022e1a22b 100644 --- a/assets/common/abilities/unique/quadlowtail/triplestrike.ron +++ b/assets/common/abilities/unique/quadlowtail/triplestrike.ron @@ -3,8 +3,8 @@ ComboMelee( ( stage: 1, base_damage: 100, - max_damage: 120, - damage_increase: 10, + max_damage: 100, + damage_increase: 0, knockback: 10.0, range: 3.5, angle: 30.0, @@ -16,8 +16,8 @@ ComboMelee( ( stage: 2, base_damage: 120, - max_damage: 140, - damage_increase: 15, + max_damage: 120, + damage_increase: 0, knockback: 10.0, range: 3.5, angle: 30.0, @@ -29,8 +29,8 @@ ComboMelee( ( stage: 3, base_damage: 130, - max_damage: 170, - damage_increase: 20, + max_damage: 130, + damage_increase: 0, knockback: 10.0, range: 3.5, angle: 30.0, @@ -41,9 +41,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, - energy_increase: 20, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) \ No newline at end of file diff --git a/assets/common/abilities/unique/quadmedbasic/singlestrike.ron b/assets/common/abilities/unique/quadmedbasic/singlestrike.ron index 508a99a809..00c1a0306d 100644 --- a/assets/common/abilities/unique/quadmedbasic/singlestrike.ron +++ b/assets/common/abilities/unique/quadmedbasic/singlestrike.ron @@ -4,7 +4,7 @@ ComboMelee( stage: 1, base_damage: 120, max_damage: 120, - damage_increase: 10, + damage_increase: 0, knockback: 5.0, range: 3.5, angle: 60.0, @@ -15,9 +15,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, - energy_increase: 20, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) diff --git a/assets/common/abilities/unique/quadmedbasic/triplestrike.ron b/assets/common/abilities/unique/quadmedbasic/triplestrike.ron index 66a639028d..cc2091727b 100644 --- a/assets/common/abilities/unique/quadmedbasic/triplestrike.ron +++ b/assets/common/abilities/unique/quadmedbasic/triplestrike.ron @@ -3,8 +3,8 @@ ComboMelee( ( stage: 1, base_damage: 120, - max_damage: 140, - damage_increase: 10, + max_damage: 120, + damage_increase: 0, knockback: 10.0, range: 3.5, angle: 30.0, @@ -16,8 +16,8 @@ ComboMelee( ( stage: 2, base_damage: 120, - max_damage: 140, - damage_increase: 15, + max_damage: 120, + damage_increase: 0, knockback: 10.0, range: 3.5, angle: 30.0, @@ -29,8 +29,8 @@ ComboMelee( ( stage: 3, base_damage: 120, - max_damage: 140, - damage_increase: 20, + max_damage: 120, + damage_increase: 0, knockback: 10.0, range: 3.5, angle: 30.0, @@ -41,9 +41,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, - energy_increase: 20, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) diff --git a/assets/common/abilities/unique/quadmedcharge/dash.ron b/assets/common/abilities/unique/quadmedcharge/dash.ron index 56c63f5e03..6e21bcaca6 100644 --- a/assets/common/abilities/unique/quadmedcharge/dash.ron +++ b/assets/common/abilities/unique/quadmedcharge/dash.ron @@ -1,7 +1,7 @@ DashMelee( energy_cost: 0, base_damage: 150, - max_damage: 150, + max_damage: 190, base_knockback: 8.0, max_knockback: 25.0, range: 4.0, @@ -13,5 +13,5 @@ DashMelee( swing_duration: 100, recover_duration: 1100, infinite_charge: true, - is_interruptible: true, + is_interruptible: false, ) diff --git a/assets/common/abilities/unique/quadmedcharge/doublestrike.ron b/assets/common/abilities/unique/quadmedcharge/doublestrike.ron index 11371dbfa0..0b4797e6c8 100644 --- a/assets/common/abilities/unique/quadmedcharge/doublestrike.ron +++ b/assets/common/abilities/unique/quadmedcharge/doublestrike.ron @@ -3,8 +3,8 @@ ComboMelee( ( stage: 1, base_damage: 100, - max_damage: 120, - damage_increase: 10, + max_damage: 100, + damage_increase: 0, knockback: 10.0, range: 3.5, angle: 30.0, @@ -16,8 +16,8 @@ ComboMelee( ( stage: 2, base_damage: 80, - max_damage: 110, - damage_increase: 15, + max_damage: 80, + damage_increase: 0, knockback: 10.0, range: 3.5, angle: 30.0, @@ -28,9 +28,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, - energy_increase: 20, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) diff --git a/assets/common/abilities/unique/quadmedjump/doublestrike.ron b/assets/common/abilities/unique/quadmedjump/doublestrike.ron index ea4edb35d2..80828b5f9c 100644 --- a/assets/common/abilities/unique/quadmedjump/doublestrike.ron +++ b/assets/common/abilities/unique/quadmedjump/doublestrike.ron @@ -3,8 +3,8 @@ ComboMelee( ( stage: 1, base_damage: 100, - max_damage: 120, - damage_increase: 10, + max_damage: 100, + damage_increase: 0, knockback: 8.0, range: 3.5, angle: 30.0, @@ -16,8 +16,8 @@ ComboMelee( ( stage: 2, base_damage: 80, - max_damage: 110, - damage_increase: 15, + max_damage: 80, + damage_increase: 0, knockback: 8.0, range: 3.5, angle: 30.0, @@ -28,9 +28,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, - energy_increase: 20, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) diff --git a/assets/common/abilities/unique/quadmedquick/dash.ron b/assets/common/abilities/unique/quadmedquick/dash.ron index 4e1331026c..f59f12f563 100644 --- a/assets/common/abilities/unique/quadmedquick/dash.ron +++ b/assets/common/abilities/unique/quadmedquick/dash.ron @@ -1,7 +1,7 @@ DashMelee( energy_cost: 0, base_damage: 130, - max_damage: 130, + max_damage: 150, base_knockback: 8.0, max_knockback: 15.0, range: 2.0, @@ -13,5 +13,5 @@ DashMelee( swing_duration: 100, recover_duration: 500, infinite_charge: true, - is_interruptible: true, + is_interruptible: false, ) diff --git a/assets/common/abilities/unique/quadmedquick/triplestrike.ron b/assets/common/abilities/unique/quadmedquick/triplestrike.ron index 9f9fbffda9..bf7b8aed7e 100644 --- a/assets/common/abilities/unique/quadmedquick/triplestrike.ron +++ b/assets/common/abilities/unique/quadmedquick/triplestrike.ron @@ -3,8 +3,8 @@ ComboMelee( ( stage: 1, base_damage: 150, - max_damage: 170, - damage_increase: 10, + max_damage: 150, + damage_increase: 0, knockback: 5.0, range: 3.5, angle: 60.0, @@ -16,8 +16,8 @@ ComboMelee( ( stage: 2, base_damage: 150, - max_damage: 170, - damage_increase: 15, + max_damage: 150, + damage_increase: 0, knockback: 5.0, range: 3.5, angle: 60.0, @@ -29,8 +29,8 @@ ComboMelee( ( stage: 3, base_damage: 150, - max_damage: 170, - damage_increase: 20, + max_damage: 150, + damage_increase: 0, knockback: 5.0, range: 3.5, angle: 60.0, @@ -41,9 +41,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, + max_energy_gain: 0, energy_increase: 0, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) diff --git a/assets/common/abilities/unique/quadsmallbasic/singlestrike.ron b/assets/common/abilities/unique/quadsmallbasic/singlestrike.ron index 2ef7ce9ee5..9f0b0f4c9c 100644 --- a/assets/common/abilities/unique/quadsmallbasic/singlestrike.ron +++ b/assets/common/abilities/unique/quadsmallbasic/singlestrike.ron @@ -4,7 +4,7 @@ ComboMelee( stage: 1, base_damage: 30, max_damage: 30, - damage_increase: 10, + damage_increase: 0, knockback: 5.0, range: 3.5, angle: 60.0, @@ -15,9 +15,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, - energy_increase: 20, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) \ No newline at end of file diff --git a/assets/common/abilities/unique/theropodbasic/singlestrike.ron b/assets/common/abilities/unique/theropodbasic/singlestrike.ron index 51d6f415dd..1418f2ac85 100644 --- a/assets/common/abilities/unique/theropodbasic/singlestrike.ron +++ b/assets/common/abilities/unique/theropodbasic/singlestrike.ron @@ -4,7 +4,7 @@ ComboMelee( stage: 1, base_damage: 150, max_damage: 150, - damage_increase: 10, + damage_increase: 0, knockback: 5.0, range: 7.5, angle: 60.0, @@ -15,9 +15,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, - energy_increase: 20, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) \ No newline at end of file diff --git a/assets/common/abilities/unique/theropodbasic/triplestrike.ron b/assets/common/abilities/unique/theropodbasic/triplestrike.ron index 2fe20697d2..a6d0f4f076 100644 --- a/assets/common/abilities/unique/theropodbasic/triplestrike.ron +++ b/assets/common/abilities/unique/theropodbasic/triplestrike.ron @@ -3,8 +3,8 @@ ComboMelee( ( stage: 1, base_damage: 170, - max_damage: 190, - damage_increase: 10, + max_damage: 170, + damage_increase: 0, knockback: 10.0, range: 7.5, angle: 30.0, @@ -16,8 +16,8 @@ ComboMelee( ( stage: 2, base_damage: 190, - max_damage: 210, - damage_increase: 15, + max_damage: 190, + damage_increase: 0, knockback: 10.0, range: 5.5, angle: 30.0, @@ -29,8 +29,8 @@ ComboMelee( ( stage: 3, base_damage: 230, - max_damage: 250, - damage_increase: 20, + max_damage: 230, + damage_increase: 0, knockback: 10.0, range: 5.5, angle: 30.0, @@ -41,9 +41,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, - energy_increase: 20, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) diff --git a/assets/common/abilities/unique/theropodbird/singlestrike.ron b/assets/common/abilities/unique/theropodbird/singlestrike.ron index 9b9c5a8931..6a80240dfd 100644 --- a/assets/common/abilities/unique/theropodbird/singlestrike.ron +++ b/assets/common/abilities/unique/theropodbird/singlestrike.ron @@ -4,7 +4,7 @@ ComboMelee( stage: 1, base_damage: 150, max_damage: 150, - damage_increase: 10, + damage_increase: 0, knockback: 5.0, range: 5.5, angle: 5.0, @@ -15,9 +15,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, - energy_increase: 20, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) \ No newline at end of file diff --git a/assets/common/abilities/unique/theropodbird/triplestrike.ron b/assets/common/abilities/unique/theropodbird/triplestrike.ron index 9936cdf0f1..dc19a3128c 100644 --- a/assets/common/abilities/unique/theropodbird/triplestrike.ron +++ b/assets/common/abilities/unique/theropodbird/triplestrike.ron @@ -3,8 +3,8 @@ ComboMelee( ( stage: 1, base_damage: 170, - max_damage: 190, - damage_increase: 10, + max_damage: 170, + damage_increase: 0, knockback: 10.0, range: 4.5, angle: 5.0, @@ -16,8 +16,8 @@ ComboMelee( ( stage: 2, base_damage: 190, - max_damage: 210, - damage_increase: 15, + max_damage: 190, + damage_increase: 0, knockback: 10.0, range: 4.0, angle: 10.0, @@ -29,8 +29,8 @@ ComboMelee( ( stage: 3, base_damage: 230, - max_damage: 250, - damage_increase: 20, + max_damage: 230, + damage_increase: 0, knockback: 10.0, range: 4.0, angle: 10.0, @@ -41,9 +41,9 @@ ComboMelee( ), ], initial_energy_gain: 0, - max_energy_gain: 100, - energy_increase: 20, - speed_increase: 0.05, - max_speed_increase: 1.8, - is_interruptible: true, + max_energy_gain: 0, + energy_increase: 0, + speed_increase: 0.0, + max_speed_increase: 1.0, + is_interruptible: false, ) diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index 3655f115ca..eadfc3b370 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -176,7 +176,7 @@ impl Body { Body::Theropod(body) => match body.species { theropod::Species::Snowraptor => 0.5, theropod::Species::Sandraptor => 0.5, - theropod::Species::Woodraptor => 0.5, + theropod::Species::Woodraptor => 0.5, _ => 0.9, }, Body::BirdMedium(_) => 0.35, diff --git a/common/src/loadout_builder.rs b/common/src/loadout_builder.rs index e68824a800..5a89ec7231 100644 --- a/common/src/loadout_builder.rs +++ b/common/src/loadout_builder.rs @@ -168,12 +168,10 @@ impl LoadoutBuilder { )); }, }, - Body::QuadrupedSmall(quadruped_small) => match quadruped_small.species { - _ => { - main_tool = Some(Item::new_from_asset_expect( - "common.items.npc_weapons.unique.quadsmallbasic", - )); - }, + Body::QuadrupedSmall(_) => { + main_tool = Some(Item::new_from_asset_expect( + "common.items.npc_weapons.unique.quadsmallbasic", + )); }, Body::Theropod(theropod) => match theropod.species { theropod::Species::Sandraptor diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 0e479dff2b..db3d53a73f 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -212,7 +212,7 @@ pub fn handle_forced_movement( // Multiply decreasing amount linearly over time (with average of 1) * 2.0 * progress // Apply inputted movement directions with some efficiency - + (data.inputs.look_dir.try_normalized().unwrap_or_default()/* + update.vel.0.xy()*/) + + (data.inputs.look_dir.try_normalized().unwrap_or_default()) .try_normalized() .unwrap_or_default() // Multiply by forward leap strength diff --git a/common/src/sys/agent.rs b/common/src/sys/agent.rs index ad3b4fb92f..87947b9cc1 100644 --- a/common/src/sys/agent.rs +++ b/common/src/sys/agent.rs @@ -207,7 +207,6 @@ impl<'a> System<'a> for Sys { // obstacles that smaller entities would not). let node_tolerance = scale * 1.5; let slow_factor = body.map(|b| b.base_accel() / 250.0).unwrap_or(0.0).min(1.0); - let traversal_config = TraversalConfig { node_tolerance, slow_factor, @@ -274,6 +273,11 @@ impl<'a> System<'a> for Sys { inputs.move_dir = *bearing * 0.65; } + // Put away weapon + if thread_rng().gen::() < 0.005 { + controller.actions.push(ControlAction::Unwield); + } + // Sit if thread_rng().gen::() < 0.0035 { controller.actions.push(ControlAction::Sit); @@ -333,13 +337,13 @@ impl<'a> System<'a> for Sys { Bow, Staff, StoneGolemBoss, - Wolf, - Ram, + CircleCharge { radius: u8, circle_time: u8 }, QuadLowRanged, TailSlap, QuadLowQuick, QuadLowBasic, QuadMedJump, + QuadMedBasic, Lavadrake, Theropod, } @@ -359,12 +363,22 @@ impl<'a> System<'a> for Sys { Some(ToolKind::Unique(UniqueKind::StoneGolemFist)) => { Tactic::StoneGolemBoss }, - Some(ToolKind::Unique(UniqueKind::QuadMedQuick)) => Tactic::Wolf, - Some(ToolKind::Unique(UniqueKind::QuadMedCharge)) => Tactic::Ram, + Some(ToolKind::Unique(UniqueKind::QuadMedQuick)) => { + Tactic::CircleCharge { + radius: 3, + circle_time: 2, + } + }, + Some(ToolKind::Unique(UniqueKind::QuadMedCharge)) => { + Tactic::CircleCharge { + radius: 15, + circle_time: 1, + } + }, Some(ToolKind::Unique(UniqueKind::QuadMedJump)) => Tactic::QuadMedJump, Some(ToolKind::Unique(UniqueKind::QuadMedBasic)) => { - Tactic::QuadLowBasic + Tactic::QuadMedBasic }, Some(ToolKind::Unique(UniqueKind::QuadLowRanged)) => { Tactic::QuadLowRanged @@ -400,14 +414,21 @@ impl<'a> System<'a> for Sys { let mut tgt_eye_offset = bodies.get(*target).map_or(0.0, |b| b.eye_height()); + // Special case for jumping attacks to jump at the body + // of the target and not the ground around the target + // For the ranged it is to shoot at the feet and not + // the head to get splash damage if tactic == Tactic::QuadMedJump { tgt_eye_offset += 1.0; + } else if matches!(tactic, Tactic::QuadLowRanged) { + tgt_eye_offset -= 1.0; } + // Hacky distance offset for ranged weapons let distance_offset = match tactic { Tactic::Bow => 0.0004 * pos.0.distance_squared(tgt_pos.0), Tactic::Staff => 0.0015 * pos.0.distance_squared(tgt_pos.0), - Tactic::QuadLowRanged => 0.02 * pos.0.distance_squared(tgt_pos.0), + Tactic::QuadLowRanged => 0.03 * pos.0.distance_squared(tgt_pos.0), _ => 0.0, }; @@ -468,388 +489,846 @@ impl<'a> System<'a> for Sys { ) { inputs.move_dir = bearing.xy().try_normalized().unwrap_or(Vec2::zero()) - * speed - * 1.0; + * speed; inputs.jump.set_state(bearing.z > 1.5); inputs.move_z = bearing.z; } } else { do_idle = true; } - } else if (tactic == Tactic::Theropod - && dist_sqrd < (2.0 * MIN_ATTACK_DIST * scale).powf(2.0)) - || (tactic == Tactic::Lavadrake - && dist_sqrd < (2.5 * MIN_ATTACK_DIST * scale).powf(2.0)) - || (tactic == Tactic::QuadLowRanged - && dist_sqrd < (4.0 * MIN_ATTACK_DIST * scale).powf(2.0)) - || (tactic == Tactic::Wolf - && dist_sqrd < (3.0 * MIN_ATTACK_DIST * scale).powf(2.0)) - || (tactic == Tactic::Ram - && dist_sqrd < (15.0 * MIN_ATTACK_DIST * scale).powf(2.0)) - || ((tactic == Tactic::TailSlap || tactic == Tactic::QuadLowBasic) - && dist_sqrd < (1.5 * MIN_ATTACK_DIST * scale).powf(2.0)) - || (tactic == Tactic::QuadMedJump - && dist_sqrd < (1.5 * MIN_ATTACK_DIST * scale).powf(2.0)) - || dist_sqrd < (MIN_ATTACK_DIST * scale).powf(2.0) - { - // Movement + } else { + // Match on tactic. Each tactic has different controls + // depending on the distance from the agent to the target match tactic { - Tactic::Wolf | Tactic::Ram => { - // Run away from target to get clear + Tactic::Melee => { + if dist_sqrd < (MIN_ATTACK_DIST * scale).powf(2.0) { + inputs.primary.set_state(true); + inputs.move_dir = Vec2::zero(); + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; + } + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; + } + + if dist_sqrd < 16.0f32.powf(2.0) + && thread_rng().gen::() < 0.02 + { + inputs.roll.set_state(true); + } + } else { + do_idle = true; + } + }, + Tactic::Axe => { + if dist_sqrd < (MIN_ATTACK_DIST * scale).powf(2.0) { + inputs.move_dir = Vec2::zero(); + if *powerup > 6.0 { + inputs.secondary.set_state(false); + *powerup = 0.0; + } else if *powerup > 4.0 && energy.current() > 10 { + inputs.secondary.set_state(true); + *powerup += dt.0; + } else if energy.current() > 800 + && thread_rng().gen_bool(0.5) + { + inputs.ability3.set_state(true); + *powerup += dt.0; + } else { + inputs.primary.set_state(true); + *powerup += dt.0; + } + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; + } + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; + } + if dist_sqrd < 16.0f32.powf(2.0) + && thread_rng().gen::() < 0.02 + { + inputs.roll.set_state(true); + } + } else { + do_idle = true; + } + }, + Tactic::Hammer => { + if dist_sqrd < (MIN_ATTACK_DIST * scale).powf(2.0) { + inputs.move_dir = Vec2::zero(); + if *powerup > 4.0 { + inputs.secondary.set_state(false); + *powerup = 0.0; + } else if *powerup > 2.0 { + inputs.secondary.set_state(true); + *powerup += dt.0; + } else if energy.current() > 700 { + inputs.ability3.set_state(true); + *powerup += dt.0; + } else { + inputs.primary.set_state(true); + *powerup += dt.0; + } + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; + } + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { + if can_see_tgt(&*terrain, pos, tgt_pos, dist_sqrd) { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + if *powerup > 5.0 { + inputs.ability3.set_state(true); + *powerup = 0.0; + } else { + *powerup += dt.0; + } + } else { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; + } + } + if dist_sqrd < 16.0f32.powf(2.0) + && thread_rng().gen::() < 0.02 + { + inputs.roll.set_state(true); + } + } else { + do_idle = true; + } + }, + Tactic::Sword => { + if dist_sqrd < (MIN_ATTACK_DIST * scale).powf(2.0) { + inputs.move_dir = Vec2::zero(); + if *powerup < 2.0 && energy.current() > 600 { + inputs.ability3.set_state(true); + *powerup += dt.0; + } else if *powerup > 2.0 { + *powerup = 0.0; + } else { + inputs.primary.set_state(true); + *powerup += dt.0; + } + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; + } + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { + if can_see_tgt(&*terrain, pos, tgt_pos, dist_sqrd) { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + if *powerup > 4.0 { + inputs.secondary.set_state(true); + *powerup = 0.0; + } else { + *powerup += dt.0; + } + } else { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; + } + } + if dist_sqrd < 16.0f32.powf(2.0) + && thread_rng().gen::() < 0.02 + { + inputs.roll.set_state(true); + } + } else { + do_idle = true; + } + }, + Tactic::Bow => { + if dist_sqrd < (2.0 * MIN_ATTACK_DIST * scale).powf(2.0) { + inputs.roll.set_state(true); + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; + } + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { + if can_see_tgt(&*terrain, pos, tgt_pos, dist_sqrd) { + inputs.move_dir = bearing + .xy() + .rotated_z( + thread_rng().gen_range(0.5, 1.57), + ) + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + if *powerup > 4.0 { + inputs.secondary.set_state(false); + *powerup = 0.0; + } else if *powerup > 2.0 + && energy.current() > 300 + { + inputs.secondary.set_state(true); + *powerup += dt.0; + } else if energy.current() > 400 + && thread_rng().gen_bool(0.8) + { + inputs.secondary.set_state(false); + inputs.ability3.set_state(true); + *powerup += dt.0; + } else { + inputs.secondary.set_state(false); + inputs.primary.set_state(true); + *powerup += dt.0; + } + } else { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; + } + } + if dist_sqrd < 16.0f32.powf(2.0) + && thread_rng().gen::() < 0.02 + { + inputs.roll.set_state(true); + } + } else { + do_idle = true; + } + }, + Tactic::Staff => { + if dist_sqrd < (MIN_ATTACK_DIST * scale).powf(2.0) { + inputs.roll.set_state(true); + } else if dist_sqrd + < (5.0 * MIN_ATTACK_DIST * scale).powf(2.0) + { + if *powerup < 1.5 { + inputs.move_dir = (tgt_pos.0 - pos.0) + .xy() + .rotated_z(0.47 * PI) + .try_normalized() + .unwrap_or(Vec2::unit_y()); + *powerup += dt.0; + } else if *powerup < 3.0 { + inputs.move_dir = (tgt_pos.0 - pos.0) + .xy() + .rotated_z(-0.47 * PI) + .try_normalized() + .unwrap_or(Vec2::unit_y()); + *powerup += dt.0; + } else { + *powerup = 0.0; + } + if energy.current() > 800 + && thread_rng().gen::() > 0.8 + { + inputs.ability3.set_state(true); + } else if energy.current() > 10 { + inputs.secondary.set_state(true); + } else { + inputs.primary.set_state(true); + } + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; + } + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { + if can_see_tgt(&*terrain, pos, tgt_pos, dist_sqrd) { + inputs.move_dir = bearing + .xy() + .rotated_z( + thread_rng().gen_range(-1.57, -0.5), + ) + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + inputs.primary.set_state(true); + } else { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; + } + } + if dist_sqrd < 16.0f32.powf(2.0) + && thread_rng().gen::() < 0.02 + { + inputs.roll.set_state(true); + } + } else { + do_idle = true; + } + }, + Tactic::StoneGolemBoss => { + if dist_sqrd < (MIN_ATTACK_DIST * scale).powf(2.0) { + inputs.move_dir = Vec2::zero(); + inputs.primary.set_state(true); + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; + } + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { + if can_see_tgt(&*terrain, pos, tgt_pos, dist_sqrd) { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + if *powerup > 5.0 { + inputs.secondary.set_state(true); + *powerup = 0.0; + } else { + *powerup += dt.0; + } + } else { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; + } + } + } else { + do_idle = true; + } + }, + Tactic::CircleCharge { + radius, + circle_time, + } => { if dist_sqrd < (MIN_ATTACK_DIST * scale).powf(2.0) && thread_rng().gen_bool(0.5) { inputs.move_dir = Vec2::zero(); inputs.primary.set_state(true); - } else { + } else if dist_sqrd + < (radius as f32 * MIN_ATTACK_DIST * scale).powf(2.0) + { inputs.move_dir = (pos.0 - tgt_pos.0) .xy() .try_normalized() .unwrap_or(Vec2::unit_y()); - } - }, - Tactic::QuadLowRanged => { - inputs.move_dir = (tgt_pos.0 - pos.0) - .xy() - .try_normalized() - .unwrap_or(Vec2::unit_y()); - }, - Tactic::TailSlap => { - inputs.move_dir = (tgt_pos.0 - pos.0) - .xy() - .try_normalized() - .unwrap_or(Vec2::unit_y()) - * 0.1; - }, - _ => { - inputs.move_dir = Vec2::zero(); - }, - } - - match tactic { - Tactic::Hammer => { - if *powerup > 4.0 { - inputs.secondary.set_state(false); - *powerup = 0.0; - } else if *powerup > 2.0 { - inputs.secondary.set_state(true); - *powerup += dt.0; - } else if energy.current() > 700 { - inputs.ability3.set_state(true); - *powerup += dt.0; - } else { - inputs.primary.set_state(true); - *powerup += dt.0; - } - }, - Tactic::Sword => { - if *powerup < 2.0 && energy.current() > 500 { - inputs.ability3.set_state(true); - *powerup += dt.0; - } else if *powerup > 2.0 { - *powerup = 0.0; - } else { - inputs.primary.set_state(true); - *powerup += dt.0; - } - }, - Tactic::Axe => { - if *powerup > 6.0 { - inputs.secondary.set_state(false); - *powerup = 0.0; - } else if *powerup > 4.0 && energy.current() > 10 { - inputs.secondary.set_state(true); - *powerup += dt.0; - } else { - inputs.primary.set_state(true); - *powerup += dt.0; - } - }, - Tactic::Bow => inputs.roll.set_state(true), - Tactic::Staff => inputs.roll.set_state(true), - Tactic::Melee => inputs.primary.set_state(true), - // Animal attacks - Tactic::TailSlap => { - if *powerup > 4.0 { - inputs.primary.set_state(false); - *powerup = 0.0; - } else if *powerup > 1.0 { - inputs.primary.set_state(true); - *powerup += dt.0; - } else { - inputs.secondary.set_state(true); - *powerup += dt.0; - } - }, - Tactic::QuadLowRanged => inputs.primary.set_state(true), - Tactic::QuadLowBasic => { - if *powerup > 5.0 { - *powerup = 0.0; - } else if *powerup > 2.0 { - inputs.secondary.set_state(true); - *powerup += dt.0; - } else { - inputs.primary.set_state(true); - *powerup += dt.0; - } - }, - Tactic::QuadLowQuick => inputs.secondary.set_state(true), - Tactic::QuadMedJump => inputs.secondary.set_state(true), - Tactic::Lavadrake => inputs.secondary.set_state(true), - Tactic::Theropod => inputs.primary.set_state(true), - _ => {}, - } - } else if tactic == Tactic::Wolf - && dist_sqrd < (4.0 * MIN_ATTACK_DIST * scale).powf(2.0) - && dist_sqrd > (3.0 * MIN_ATTACK_DIST * scale).powf(2.0) - || tactic == Tactic::Ram - && dist_sqrd < (16.0 * MIN_ATTACK_DIST * scale).powf(2.0) - && dist_sqrd > (15.0 * MIN_ATTACK_DIST * scale).powf(2.0) - { - let movement_interval = match tactic { - Tactic::Wolf => 2.0, - Tactic::Ram => 1.0, - _ => 4.0, - }; - if *powerup < movement_interval { - inputs.move_dir = (tgt_pos.0 - pos.0) - .xy() - .rotated_z(0.47 * PI) - .try_normalized() - .unwrap_or(Vec2::unit_y()); - *powerup += dt.0; - } else if *powerup < movement_interval + 0.5 { - inputs.secondary.set_state(true); - *powerup += dt.0; - } else if *powerup < 2.0 * movement_interval + 0.5 { - inputs.move_dir = (tgt_pos.0 - pos.0) - .xy() - .rotated_z(-0.47 * PI) - .try_normalized() - .unwrap_or(Vec2::unit_y()); - *powerup += dt.0; - } else if *powerup < 2.0 * movement_interval + 1.0 { - inputs.secondary.set_state(true); - *powerup += dt.0; - } else { - *powerup = 0.0; - } - } else if tactic == Tactic::QuadLowQuick - && dist_sqrd < (3.0 * MIN_ATTACK_DIST * scale).powf(2.0) - && dist_sqrd > (2.0 * MIN_ATTACK_DIST * scale).powf(2.0) - { - inputs.primary.set_state(true); - } else if tactic == Tactic::QuadMedJump - && dist_sqrd < (5.0 * MIN_ATTACK_DIST * scale).powf(2.0) - { - inputs.ability3.set_state(true); - } else if tactic == Tactic::Staff - && dist_sqrd < (5.0 * MIN_ATTACK_DIST * scale).powf(2.0) - { - inputs.move_dir = Vec2::zero(); - if energy.current() > 800 && thread_rng().gen::() > 0.8 { - inputs.ability3.set_state(true); - } else if energy.current() > 10 { - inputs.secondary.set_state(true); - } else { - inputs.primary.set_state(true); - } - } else if tactic == Tactic::Lavadrake - && dist_sqrd < (7.0 * MIN_ATTACK_DIST * scale).powf(2.0) - { - if *powerup < 2.0 { - inputs.move_dir = (tgt_pos.0 - pos.0) - .xy() - .rotated_z(0.47 * PI) - .try_normalized() - .unwrap_or(Vec2::unit_y()); - inputs.primary.set_state(true); - *powerup += dt.0; - } else if *powerup < 4.0 { - inputs.move_dir = (tgt_pos.0 - pos.0) - .xy() - .rotated_z(-0.47 * PI) - .try_normalized() - .unwrap_or(Vec2::unit_y()); - inputs.primary.set_state(true); - *powerup += dt.0; - } else if *powerup < 6.0 { - inputs.ability3.set_state(true); - *powerup += dt.0; - } else { - *powerup = 0.0; - } - } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) - || (dist_sqrd < SIGHT_DIST.powf(2.0) - && (!*been_close || !matches!(tactic, Tactic::Melee))) - { - let can_see_tgt = match tactic { - Tactic::QuadLowRanged => { - terrain - .ray(pos.0 + Vec3::unit_z(), tgt_pos.0 + Vec3::unit_z()) - .until(Block::is_opaque) - .cast() - .0 - .powf(2.0) - >= dist_sqrd - && dist_sqrd < (1.2 * MAX_CHASE_DIST).powf(2.0) - }, - _ => { - terrain - .ray(pos.0 + Vec3::unit_z(), tgt_pos.0 + Vec3::unit_z()) - .until(Block::is_opaque) - .cast() - .0 - .powf(2.0) - >= dist_sqrd - }, - }; - - if can_see_tgt { - match tactic { - Tactic::Bow => { - if *powerup > 4.0 { - inputs.secondary.set_state(false); - *powerup = 0.0; - } else if *powerup > 2.0 && energy.current() > 300 { + } else if dist_sqrd + < ((radius as f32 + 1.0) * MIN_ATTACK_DIST * scale) + .powf(2.0) + && dist_sqrd + > (radius as f32 * MIN_ATTACK_DIST * scale) + .powf(2.0) + { + if *powerup < circle_time as f32 { + inputs.move_dir = (tgt_pos.0 - pos.0) + .xy() + .rotated_z(0.47 * PI) + .try_normalized() + .unwrap_or(Vec2::unit_y()); + *powerup += dt.0; + } else if *powerup < circle_time as f32 + 0.5 { inputs.secondary.set_state(true); *powerup += dt.0; - } else if energy.current() > 400 - && thread_rng().gen_bool(0.8) - { - inputs.secondary.set_state(false); - inputs.ability3.set_state(true); + } else if *powerup < 2.0 * circle_time as f32 + 0.5 { + inputs.move_dir = (tgt_pos.0 - pos.0) + .xy() + .rotated_z(-0.47 * PI) + .try_normalized() + .unwrap_or(Vec2::unit_y()); + *powerup += dt.0; + } else if *powerup < 2.0 * circle_time as f32 + 1.0 { + inputs.secondary.set_state(true); + *powerup += dt.0; + } else { + *powerup = 0.0; + } + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; + } + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; + } + } else { + do_idle = true; + } + }, + Tactic::QuadLowRanged => { + if dist_sqrd < (5.0 * MIN_ATTACK_DIST * scale).powf(2.0) { + inputs.move_dir = (tgt_pos.0 - pos.0) + .xy() + .try_normalized() + .unwrap_or(Vec2::unit_y()); + inputs.primary.set_state(true); + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; + } + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { + if can_see_tgt(&*terrain, pos, tgt_pos, dist_sqrd) { + if *powerup > 5.0 { + *powerup = 0.0; + } else if *powerup > 2.5 { + inputs.move_dir = (tgt_pos.0 - pos.0) + .xy() + .rotated_z(1.75 * PI) + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + *powerup += dt.0; + } else { + inputs.move_dir = (tgt_pos.0 - pos.0) + .xy() + .rotated_z(0.25 * PI) + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + *powerup += dt.0; + } + inputs.secondary.set_state(true); + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; + } + } else { + } + } else { + do_idle = true; + } + }, + Tactic::TailSlap => { + if dist_sqrd < (1.5 * MIN_ATTACK_DIST * scale).powf(2.0) { + if *powerup > 4.0 { + inputs.primary.set_state(false); + *powerup = 0.0; + } else if *powerup > 1.0 { + inputs.primary.set_state(true); + *powerup += dt.0; + } else { + inputs.secondary.set_state(true); + *powerup += dt.0; + } + inputs.move_dir = (tgt_pos.0 - pos.0) + .xy() + .try_normalized() + .unwrap_or(Vec2::unit_y()) + * 0.1; + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; + } + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; + } + } else { + do_idle = true; + } + }, + Tactic::QuadLowQuick => { + if dist_sqrd < (1.5 * MIN_ATTACK_DIST * scale).powf(2.0) { + inputs.move_dir = Vec2::zero(); + inputs.secondary.set_state(true); + } else if dist_sqrd + < (3.0 * MIN_ATTACK_DIST * scale).powf(2.0) + && dist_sqrd > (2.0 * MIN_ATTACK_DIST * scale).powf(2.0) + { + inputs.primary.set_state(true); + inputs.move_dir = (tgt_pos.0 - pos.0) + .xy() + .rotated_z(-0.47 * PI) + .try_normalized() + .unwrap_or(Vec2::unit_y()); + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; + } + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; + } + } else { + do_idle = true; + } + }, + Tactic::QuadLowBasic => { + if dist_sqrd < (1.5 * MIN_ATTACK_DIST * scale).powf(2.0) { + inputs.move_dir = Vec2::zero(); + if *powerup > 5.0 { + *powerup = 0.0; + } else if *powerup > 2.0 { + inputs.secondary.set_state(true); *powerup += dt.0; } else { - inputs.secondary.set_state(false); inputs.primary.set_state(true); *powerup += dt.0; } - }, - Tactic::Sword => { - if *powerup > 4.0 { - inputs.secondary.set_state(true); - *powerup = 0.0; - } else { - *powerup += dt.0; + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; } - }, - Tactic::Staff => { - inputs.primary.set_state(true); - }, - Tactic::Hammer => { - if *powerup > 5.0 { - inputs.ability3.set_state(true); - *powerup = 0.0; - } else { - *powerup += dt.0; + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; } - }, - Tactic::StoneGolemBoss => { - if *powerup > 5.0 { - inputs.secondary.set_state(true); - *powerup = 0.0; - } else { - *powerup += dt.0; - } - }, - Tactic::QuadLowRanged => { - inputs.secondary.set_state(true); - }, - Tactic::QuadMedJump => { - inputs.primary.set_state(true); - }, - Tactic::Lavadrake => { - if *powerup > 4.0 { - inputs.ability3.set_state(true); - *powerup = 0.0; - } else { - *powerup += dt.0; - } - }, - _ => {}, - } - } - - if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { - *been_close = true; - } - - // Long-range chase - if let Some((bearing, speed)) = chaser.chase( - &*terrain, - pos.0, - vel.0, - tgt_pos.0, - TraversalConfig { - min_tgt_dist: 1.25, - ..traversal_config + } else { + do_idle = true; + } }, - ) { - if can_see_tgt { - match tactic { - Tactic::Bow => { - inputs.move_dir = bearing - .xy() - .rotated_z(thread_rng().gen_range(0.5, 1.57)) - .try_normalized() - .unwrap_or(Vec2::zero()) - * speed; - }, - Tactic::Staff => { - inputs.move_dir = bearing - .xy() - .rotated_z(thread_rng().gen_range(-1.57, -0.5)) - .try_normalized() - .unwrap_or(Vec2::zero()) - * speed; - }, - Tactic::QuadLowRanged => { - if *powerup > 5.0 { - *powerup = 0.0; - } else if *powerup > 2.5 { + Tactic::QuadMedJump => { + if dist_sqrd < (1.5 * MIN_ATTACK_DIST * scale).powf(2.0) { + inputs.move_dir = Vec2::zero(); + inputs.secondary.set_state(true); + } else if dist_sqrd + < (5.0 * MIN_ATTACK_DIST * scale).powf(2.0) + { + inputs.ability3.set_state(true); + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; + } + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { + if can_see_tgt(&*terrain, pos, tgt_pos, dist_sqrd) { + inputs.primary.set_state(true); inputs.move_dir = bearing .xy() - .rotated_z(1.75 * PI) .try_normalized() .unwrap_or(Vec2::zero()) * speed; - *powerup += dt.0; } else { inputs.move_dir = bearing .xy() - .rotated_z(0.25 * PI) .try_normalized() .unwrap_or(Vec2::zero()) * speed; - *powerup += dt.0; + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; } - }, - _ => { + } + } else { + do_idle = true; + } + }, + Tactic::QuadMedBasic => { + if dist_sqrd < (MIN_ATTACK_DIST * scale).powf(2.0) { + inputs.move_dir = Vec2::zero(); + if *powerup < 2.0 { + inputs.secondary.set_state(true); + *powerup += dt.0; + } else if *powerup < 3.0 { + inputs.primary.set_state(true); + *powerup += dt.0; + } else { + *powerup = 0.0; + } + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; + } + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { inputs.move_dir = bearing .xy() .try_normalized() .unwrap_or(Vec2::zero()) * speed; - }, + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; + } + } else { + do_idle = true; } - } else { - inputs.move_dir = - bearing.xy().try_normalized().unwrap_or(Vec2::zero()) - * speed; - inputs.jump.set_state(bearing.z > 1.5); - inputs.move_z = bearing.z; - } + }, + Tactic::Lavadrake => { + if dist_sqrd < (2.5 * MIN_ATTACK_DIST * scale).powf(2.0) { + inputs.move_dir = Vec2::zero(); + inputs.secondary.set_state(true); + } else if dist_sqrd + < (7.0 * MIN_ATTACK_DIST * scale).powf(2.0) + { + if *powerup < 2.0 { + inputs.move_dir = (tgt_pos.0 - pos.0) + .xy() + .rotated_z(0.47 * PI) + .try_normalized() + .unwrap_or(Vec2::unit_y()); + inputs.primary.set_state(true); + *powerup += dt.0; + } else if *powerup < 4.0 { + inputs.move_dir = (tgt_pos.0 - pos.0) + .xy() + .rotated_z(-0.47 * PI) + .try_normalized() + .unwrap_or(Vec2::unit_y()); + inputs.primary.set_state(true); + *powerup += dt.0; + } else if *powerup < 6.0 { + inputs.ability3.set_state(true); + *powerup += dt.0; + } else { + *powerup = 0.0; + } + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; + } + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; + } + } else { + do_idle = true; + } + }, + Tactic::Theropod => { + if dist_sqrd < (2.0 * MIN_ATTACK_DIST * scale).powf(2.0) { + inputs.move_dir = Vec2::zero(); + inputs.primary.set_state(true); + } else if dist_sqrd < MAX_CHASE_DIST.powf(2.0) + || (dist_sqrd < SIGHT_DIST.powf(2.0) && !*been_close) + { + if dist_sqrd < MAX_CHASE_DIST.powf(2.0) { + *been_close = true; + } + if let Some((bearing, speed)) = chaser.chase( + &*terrain, + pos.0, + vel.0, + tgt_pos.0, + TraversalConfig { + min_tgt_dist: 1.25, + ..traversal_config + }, + ) { + inputs.move_dir = bearing + .xy() + .try_normalized() + .unwrap_or(Vec2::zero()) + * speed; + inputs.jump.set_state(bearing.z > 1.5); + inputs.move_z = bearing.z; + } + } else { + do_idle = true; + } + }, } - - if dist_sqrd < 16.0f32.powf(2.0) - && matches!(tactic, Tactic::Melee) - && thread_rng().gen::() < 0.02 - { - inputs.roll.set_state(true); - } - } else { - do_idle = true; } } else { do_idle = true; @@ -1017,3 +1496,13 @@ impl<'a> System<'a> for Sys { ); } } + +fn can_see_tgt(terrain: &TerrainGrid, pos: &Pos, tgt_pos: &Pos, dist_sqrd: f32) -> bool { + terrain + .ray(pos.0 + Vec3::unit_z(), tgt_pos.0 + Vec3::unit_z()) + .until(Block::is_opaque) + .cast() + .0 + .powf(2.0) + >= dist_sqrd +} diff --git a/voxygen/src/anim/src/quadruped_medium/dash.rs b/voxygen/src/anim/src/quadruped_medium/dash.rs index ca9cae6c02..888ca96fb6 100644 --- a/voxygen/src/anim/src/quadruped_medium/dash.rs +++ b/voxygen/src/anim/src/quadruped_medium/dash.rs @@ -25,13 +25,20 @@ impl Animation for DashAnimation { ) -> Self::Skeleton { let mut next = (*skeleton).clone(); - let (movement1base, chargemovementbase, movement2base, movement3) = match stage_section { - Some(StageSection::Buildup) => ((anim_time as f32).powf(0.5), 0.0, 0.0, 0.0), - Some(StageSection::Charge) => (1.0, 1.0, 0.0, 0.0), - Some(StageSection::Swing) => (1.0, 1.0, (anim_time as f32).powf(4.0), 0.0), - Some(StageSection::Recover) => (1.0, 1.0, 1.0, anim_time as f32), - _ => (0.0, 0.0, 0.0, 0.0), - }; + let (movement1base, chargemovementbase, movement2base, movement3, legtell) = + match stage_section { + Some(StageSection::Buildup) => ( + (anim_time as f32).powf(0.5), + 0.0, + 0.0, + 0.0, + (anim_time as f32), + ), + Some(StageSection::Charge) => (1.0, 1.0, 0.0, 0.0, 0.0), + Some(StageSection::Swing) => (1.0, 1.0, (anim_time as f32).powf(4.0), 0.0, 1.0), + Some(StageSection::Recover) => (1.0, 1.0, 1.0, anim_time as f32, 1.0), + _ => (0.0, 0.0, 0.0, 0.0, 0.0), + }; let pullback = 1.0 - movement3; let subtract = global_time - timer; let check = subtract - subtract.trunc(); @@ -43,6 +50,8 @@ impl Animation for DashAnimation { //let movement2 = mirror * movement2base * pullback; let movement1abs = movement1base * pullback; let movement2abs = movement2base * pullback; + let legtwitch = (legtell * 6.0).sin() * pullback; + let legswing = legtell * pullback; let short = (((1.0) / (0.72 + 0.28 * ((anim_time as f32 * 16.0 as f32 + PI * 0.25).sin()).powf(2.0 as f32))) @@ -71,35 +80,43 @@ impl Animation for DashAnimation { next.tail.orientation = Quaternion::rotation_x( 0.15 + movement1abs * -0.4 + movement2abs * 0.2 + chargemovementbase * 0.2, ) * Quaternion::rotation_z(shortalt * 0.15); - if let Some(stage_section) = stage_section { - match stage_section { - StageSection::Buildup => { - if mirror == 1.0 { - next.leg_fl.orientation = Quaternion::rotation_x(movement1abs * 0.8); + if legtell > 0.0 { + if mirror.is_sign_positive() { + next.leg_fl.orientation = Quaternion::rotation_x(legswing * 1.1); next.foot_fl.orientation = - Quaternion::rotation_x(movement1abs * -0.8 + twitch1 * 0.5); - next.leg_bl.orientation = Quaternion::rotation_x(movement1abs * 0.8); + Quaternion::rotation_x(legswing * -1.1 + legtwitch * 0.5); + next.leg_bl.orientation = Quaternion::rotation_x(legswing * 1.1); next.foot_bl.orientation = - Quaternion::rotation_x(movement1abs * -0.8 + twitch1 * 0.5); + Quaternion::rotation_x(legswing * -1.1 + legtwitch * 0.5); + + next.leg_fr.orientation = Quaternion::rotation_x(0.0); + + next.foot_fr.orientation = Quaternion::rotation_x(0.0); + + next.leg_br.orientation = Quaternion::rotation_x(0.0); + + next.foot_br.orientation = Quaternion::rotation_x(0.0); } else { - next.leg_fr.orientation = Quaternion::rotation_x(movement1abs * 0.8); + next.leg_fl.orientation = Quaternion::rotation_x(0.0); + + next.foot_fl.orientation = Quaternion::rotation_x(0.0); + next.leg_bl.orientation = Quaternion::rotation_x(0.0); + + next.foot_bl.orientation = Quaternion::rotation_x(0.0); + + next.leg_fr.orientation = Quaternion::rotation_x(legswing * 1.1); next.foot_fr.orientation = - Quaternion::rotation_x(movement1abs * -0.8 + twitch1 * 0.5); + Quaternion::rotation_x(legswing * -1.1 + legtwitch * 0.5); - next.leg_br.orientation = Quaternion::rotation_x(movement1abs * 0.8); + next.leg_br.orientation = Quaternion::rotation_x(legswing * 1.1); next.foot_br.orientation = - Quaternion::rotation_x(movement1abs * -0.8 + twitch1 * 0.5); + Quaternion::rotation_x(legswing * -1.1 + legtwitch * 0.5); } - }, - _ => {}, - - } - } - + }; next } } diff --git a/voxygen/src/scene/figure/mod.rs b/voxygen/src/scene/figure/mod.rs index cffc2a2215..866e82a97f 100644 --- a/voxygen/src/scene/figure/mod.rs +++ b/voxygen/src/scene/figure/mod.rs @@ -1439,8 +1439,8 @@ impl FigureMgr { }, _ => 0.0, }; - match s.stage { - _ => anim::quadruped_small::AlphaAnimation::update_skeleton( + { + anim::quadruped_small::AlphaAnimation::update_skeleton( &target_base, ( vel.0.magnitude(), @@ -1451,7 +1451,7 @@ impl FigureMgr { stage_progress, &mut state_animation_rate, skeleton_attr, - ), + ) } }, CharacterState::Sit { .. } => { diff --git a/world/src/layer/wildlife.rs b/world/src/layer/wildlife.rs index 67355a7f79..fac6efe6b0 100644 --- a/world/src/layer/wildlife.rs +++ b/world/src/layer/wildlife.rs @@ -37,11 +37,11 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( } let scatter: &[Entry] = &[ - // Tundra pack ennemies + // Tundra snow pack ennemies Entry { make_entity: |pos, rng| { EntityInfo::at(pos) - .with_body(match rng.gen_range(0, 4) { + .with_body(match rng.gen_range(0, 3) { 0 => quadruped_medium::Body::random_with( rng, &quadruped_medium::Species::Frostfang, @@ -50,11 +50,31 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( 1 => { theropod::Body::random_with(rng, &theropod::Species::Snowraptor).into() }, - 2 => quadruped_medium::Body::random_with( + _ => quadruped_medium::Body::random_with( rng, &quadruped_medium::Species::Roshwalr, ) .into(), + }) + .with_alignment(Alignment::Enemy) + }, + group_size: 1..4, + is_underwater: false, + get_density: |c, col| { + close(c.temp, CONFIG.snow_temp, 0.3) + * BASE_DENSITY + * col.snow_cover as i32 as f32 + * 1.0 + }, + }, + // Tundra solitary ennemies + Entry { + make_entity: |pos, rng| { + EntityInfo::at(pos) + .with_body(match rng.gen_range(0, 2) { + 0 => { + theropod::Body::random_with(rng, &theropod::Species::Snowraptor).into() + }, _ => quadruped_medium::Body::random_with( rng, &quadruped_medium::Species::Grolgar, @@ -63,11 +83,24 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }) .with_alignment(Alignment::Enemy) }, - group_size: 1..4, + group_size: 1..2, is_underwater: false, get_density: |c, _col| close(c.temp, CONFIG.snow_temp, 0.3) * BASE_DENSITY * 1.0, }, // Tundra rare solitary ennemies + Entry { + make_entity: |pos, rng| { + EntityInfo::at(pos) + .with_body( + theropod::Body::random_with(rng, &theropod::Species::Snowraptor).into(), + ) + .with_alignment(Alignment::Enemy) + }, + group_size: 1..2, + is_underwater: false, + get_density: |c, _col| close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * 0.5, + }, + // Tundra rare solitary ennemies Entry { make_entity: |pos, rng| { EntityInfo::at(pos) @@ -142,7 +175,23 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( is_underwater: false, get_density: |c, _col| close(c.temp, CONFIG.snow_temp + 0.2, 0.6) * BASE_DENSITY * 5.0, }, - // Temperate pack ennemies + // Tundra rock solitary ennemies + Entry { + make_entity: |pos, rng| { + EntityInfo::at(pos) + .with_body( + quadruped_low::Body::random_with(rng, &quadruped_low::Species::Rocksnapper) + .into(), + ) + .with_alignment(Alignment::Enemy) + }, + group_size: 1..2, + is_underwater: false, + get_density: |c, col| { + close(c.temp, CONFIG.snow_temp, 0.15) * BASE_DENSITY * col.rock * 1.0 + }, + }, + // Temperate solitary ennemies Entry { make_entity: |pos, rng| { EntityInfo::at(pos) @@ -165,7 +214,9 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }, group_size: 1..2, is_underwater: false, - get_density: |c, _col| close(c.temp, CONFIG.temperate_temp, 0.35) * BASE_DENSITY * 1.0, + get_density: |c, col| { + close(c.temp, CONFIG.temperate_temp, 0.35) * col.tree_density * BASE_DENSITY * 1.0 + }, }, // Temperate pack wild Entry { @@ -237,7 +288,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( Entry { make_entity: |pos, rng| { EntityInfo::at(pos) - .with_body(match rng.gen_range(0, 15) { + .with_body(match rng.gen_range(0, 13) { 0 => quadruped_small::Body { species: quadruped_small::Species::Fox, body_type: quadruped_small::BodyType::Male, @@ -255,47 +306,40 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( .into(), 4 => quadruped_small::Body::random_with( rng, - &quadruped_small::Species::Porcupine, + &quadruped_small::Species::Skunk, ) .into(), 5 => quadruped_small::Body::random_with( - rng, - &quadruped_small::Species::Skunk, - ) - .into(), - 6 => quadruped_small::Body::random_with( rng, &quadruped_small::Species::Raccoon, ) .into(), - 7 => bird_medium::Body::random_with(rng, &bird_medium::Species::Cockatrice) - .into(), - 8 => quadruped_medium::Body::random_with( + 6 => quadruped_medium::Body::random_with( rng, &quadruped_medium::Species::Catoblepas, ) .into(), - 9 => quadruped_small::Body::random_with( + 7 => quadruped_small::Body::random_with( rng, &quadruped_small::Species::Turtle, ) .into(), - 10 => quadruped_medium::Body::random_with( + 8 => quadruped_medium::Body::random_with( rng, &quadruped_medium::Species::Hirdrasil, ) .into(), - 11 => quadruped_medium::Body::random_with( + 9 => quadruped_medium::Body::random_with( rng, &quadruped_medium::Species::Kelpie, ) .into(), - 12 => quadruped_small::Body::random_with( + 10 => quadruped_small::Body::random_with( rng, &quadruped_small::Species::Truffler, ) .into(), - 13 => quadruped_medium::Body::random_with( + 11 => quadruped_medium::Body::random_with( rng, &quadruped_medium::Species::Donkey, ) @@ -321,15 +365,13 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( Entry { make_entity: |pos, rng| { EntityInfo::at(pos) - .with_body(match rng.gen_range(0, 4) { + .with_body(match rng.gen_range(0, 3) { 0 => { biped_large::Body::random_with(rng, &biped_large::Species::Ogre).into() }, 1 => { biped_large::Body::random_with(rng, &biped_large::Species::Troll).into() }, - 2 => biped_large::Body::random_with(rng, &biped_large::Species::Dullahan) - .into(), _ => biped_large::Body::random_with(rng, &biped_large::Species::Cyclops) .into(), }) @@ -337,7 +379,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( }, group_size: 1..2, is_underwater: false, - get_density: |c, _col| close(c.temp, CONFIG.temperate_temp, 0.8) * BASE_DENSITY * 0.1, + get_density: |c, _col| close(c.temp, CONFIG.temperate_temp, 0.8) * BASE_DENSITY * 0.08, }, // Temperate river wildlife Entry { @@ -365,7 +407,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( get_density: |_c, col| { close(col.temp, CONFIG.temperate_temp, 0.6) * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { - 0.003 + 0.001 } else { 0.0 } @@ -415,22 +457,16 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( Entry { make_entity: |pos, rng| { EntityInfo::at(pos) - .with_body(match rng.gen_range(0, 4) { + .with_body(match rng.gen_range(0, 2) { 0 => { quadruped_low::Body::random_with(rng, &quadruped_low::Species::Maneater) .into() }, - 1 => quadruped_medium::Body::random_with( + _ => quadruped_medium::Body::random_with( rng, &quadruped_medium::Species::Tiger, ) .into(), - 2 => theropod::Body::random_with(rng, &theropod::Species::Odonto).into(), - _ => quadruped_low::Body::random_with( - rng, - &quadruped_low::Species::Rocksnapper, - ) - .into(), }) .with_alignment(Alignment::Enemy) }, @@ -440,20 +476,50 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( close(c.temp, CONFIG.tropical_temp + 0.1, 0.4) * close(c.humidity, CONFIG.jungle_hum, 0.3) * BASE_DENSITY - * 4.0 + * 3.0 + }, + }, + // Jungle rare solitary wild + Entry { + make_entity: |pos, rng| { + EntityInfo::at(pos) + .with_body(match rng.gen_range(0, 4) { + 0 => theropod::Body::random_with(rng, &theropod::Species::Odonto).into(), + 1 => { + biped_large::Body::random_with(rng, &biped_large::Species::Mightysaurok) + .into() + }, + 2 => { + biped_large::Body::random_with(rng, &biped_large::Species::Occultsaurok) + .into() + }, + _ => biped_large::Body::random_with(rng, &biped_large::Species::Slysaurok) + .into(), + }) + .with_alignment(Alignment::Enemy) + }, + group_size: 1..2, + is_underwater: false, + get_density: |c, _col| { + close(c.temp, CONFIG.tropical_temp + 0.1, 0.4) + * close(c.humidity, CONFIG.jungle_hum, 0.3) + * BASE_DENSITY + * 1.0 }, }, // Jungle solitary wild Entry { make_entity: |pos, rng| { EntityInfo::at(pos) - .with_body(match rng.gen_range(0, 3) { + .with_body(match rng.gen_range(0, 4) { 0 => bird_medium::Body::random_with(rng, &bird_medium::Species::Parrot) .into(), 1 => { quadruped_low::Body::random_with(rng, &quadruped_low::Species::Monitor) .into() }, + 2 => bird_medium::Body::random_with(rng, &bird_medium::Species::Cockatrice) + .into(), _ => { quadruped_low::Body::random_with(rng, &quadruped_low::Species::Tortoise) .into() @@ -474,19 +540,10 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( Entry { make_entity: |pos, rng| { EntityInfo::at(pos) - .with_body(match rng.gen_range(0, 2) { - // WE GROW 'EM BIG 'ERE - 0 => quadruped_low::Body::random_with( - rng, - &quadruped_low::Species::Crocodile, - ) - .into(), - _ => quadruped_low::Body::random_with( - rng, - &quadruped_low::Species::Alligator, - ) - .into(), - }) + .with_body( + quadruped_low::Body::random_with(rng, &quadruped_low::Species::Alligator) + .into(), + ) .with_alignment(Alignment::Enemy) }, group_size: 1..3, @@ -494,7 +551,7 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( get_density: |_c, col| { close(col.temp, CONFIG.tropical_temp + 0.2, 0.5) * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { - 0.0002 + 0.0001 } else { 0.0 } @@ -564,58 +621,42 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( Entry { make_entity: |pos, rng| { EntityInfo::at(pos) - .with_body( - quadruped_medium::Body::random_with( + .with_body(match rng.gen_range(0, 2) { + 0 => quadruped_medium::Body::random_with( + rng, + &quadruped_medium::Species::Zebra, + ) + .into(), + _ => quadruped_medium::Body::random_with( rng, &quadruped_medium::Species::Antelope, ) .into(), - ) + }) .with_alignment(Alignment::Wild) }, - group_size: 3..8, + group_size: 3..7, is_underwater: false, get_density: |c, _col| { close(c.temp, CONFIG.tropical_temp + 0.1, 0.4) * close(c.humidity, CONFIG.desert_hum, 0.4) * BASE_DENSITY - * 1.0 - }, - }, - // Desert pack enemy - Entry { - make_entity: |pos, rng| { - EntityInfo::at(pos) - .with_body( - theropod::Body::random_with(rng, &theropod::Species::Sandraptor).into(), - ) - .with_alignment(Alignment::Enemy) - }, - group_size: 3..5, - is_underwater: false, - get_density: |c, _col| { - close(c.temp, CONFIG.tropical_temp + 0.1, 0.4) - * close(c.humidity, CONFIG.desert_hum, 0.4) - * BASE_DENSITY - * 1.0 + * 0.8 }, }, // Desert solitary enemies Entry { make_entity: |pos, rng| { EntityInfo::at(pos) - .with_body(match rng.gen_range(0, 5) { + .with_body(match rng.gen_range(0, 2) { 0 => quadruped_medium::Body::random_with( rng, &quadruped_medium::Species::Bonerattler, ) .into(), - 2 => theropod::Body::random_with(rng, &theropod::Species::Archaeos).into(), - 3 => quadruped_low::Body::random_with( - rng, - &quadruped_low::Species::Lavadrake, - ) - .into(), + 1 => { + theropod::Body::random_with(rng, &theropod::Species::Sandraptor).into() + }, _ => quadruped_low::Body::random_with( rng, &quadruped_low::Species::Sandshark, @@ -633,6 +674,50 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( * 1.5 }, }, + // Desert rare solitary enemies + Entry { + make_entity: |pos, rng| { + EntityInfo::at(pos) + .with_body(match rng.gen_range(0, 2) { + 0 => quadruped_low::Body::random_with( + rng, + &quadruped_low::Species::Lavadrake, + ) + .into(), + _ => theropod::Body::random_with(rng, &theropod::Species::Archaeos).into(), + }) + .with_alignment(Alignment::Enemy) + }, + group_size: 1..2, + is_underwater: false, + get_density: |c, _col| { + close(c.temp, CONFIG.desert_temp + 0.2, 0.3) + * close(c.humidity, CONFIG.desert_hum, 0.5) + * BASE_DENSITY + * 0.2 + }, + }, + // Desert river solitary wild + Entry { + make_entity: |pos, rng| { + EntityInfo::at(pos) + .with_body( + quadruped_low::Body::random_with(rng, &quadruped_low::Species::Crocodile) + .into(), + ) + .with_alignment(Alignment::Enemy) + }, + group_size: 1..3, + is_underwater: false, + get_density: |_c, col| { + close(col.temp, CONFIG.desert_temp + 0.2, 0.3) + * if col.water_dist.map(|d| d < 10.0).unwrap_or(false) { + 0.0001 + } else { + 0.0 + } + }, + }, // Desert solitary wild Entry { make_entity: |pos, rng| { @@ -657,6 +742,11 @@ pub fn apply_wildlife_supplement<'a, R: Rng>( body_type: quadruped_low::BodyType::Male, } .into(), + 4 => quadruped_small::Body::random_with( + rng, + &quadruped_small::Species::Porcupine, + ) + .into(), _ => quadruped_small::Body::random_with( rng, &quadruped_small::Species::Gecko,