diff --git a/assets/data/abilities.ron b/assets/data/abilities.ron index 9de5855f..9b4b6358 100644 --- a/assets/data/abilities.ron +++ b/assets/data/abilities.ron @@ -1,10 +1,10 @@ ( charge_ability: ( slot: Two, - base_cooldown_time: 0.8, + base_cooldown_time: 3.0, ability: ( action_time: 0.5, - incoming_damage_multiplier: 0.75, + incoming_damage_multiplier: 1.0, impulse: 12000.0, ) ), @@ -17,7 +17,7 @@ max_spread: 1.57080, projectile_gap: 3.14159, )), - damage_multiplier: 5.0, + damage_multiplier: 3.0, ammunition: Blast(Ally), speed_multiplier: 2.0, direction: 1.57080, @@ -56,8 +56,8 @@ end: 1.25, ), angle_range: ( - start: 1.37445, - end: 1.76715, + start: 0.94, + end: 1.06, ), )), damage_multiplier: 0.8, diff --git a/assets/data/behavior_sequences.ron b/assets/data/behavior_sequences.ron index fefe642f..3e6753fa 100644 --- a/assets/data/behavior_sequences.ron +++ b/assets/data/behavior_sequences.ron @@ -1,30 +1,86 @@ ( sequences: { - Repeater: ( + Ferritharax: ( behaviors: [ ( time: 10.0, spawnable_behaviors: [MoveToPosition((0,175))], mob_behaviors: [DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth], - control_behaviors: [RepeaterAttack], + control_behaviors: [FerritharaxAttack], ), ( time: 20.0, spawnable_behaviors: [MoveToPosition((175, 150))], mob_behaviors: [DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, SpawnMob("mobs-left")], - control_behaviors: [RepeaterProtectHead], + control_behaviors: [FerritharaxProtectHead], ), ( time: 10.0, spawnable_behaviors: [MoveToPosition((0,175))], mob_behaviors: [DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth], - control_behaviors: [RepeaterAttack], + control_behaviors: [FerritharaxAttack], ), ( time: 20.0, spawnable_behaviors: [MoveToPosition((-175, 150))], mob_behaviors: [DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, SpawnMob("mobs-right")], - control_behaviors: [RepeaterProtectHead], + control_behaviors: [FerritharaxProtectHead], + ), + ] + ), + MechaFerritharax: ( + behaviors: [ + ( + time: 8.0, + spawnable_behaviors: [MoveToPosition((0,175))], + mob_behaviors: [DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth], + control_behaviors: [FerritharaxAttack], + ), + ( + time: 20.0, + spawnable_behaviors: [MoveToPosition((175, 150))], + mob_behaviors: [DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, SpawnMob("mobs-left")], + control_behaviors: [FerritharaxProtectHead], + ), + ( + time: 8.0, + spawnable_behaviors: [MoveToPosition((0,175))], + mob_behaviors: [DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth], + control_behaviors: [FerritharaxAttack], + ), + ( + time: 20.0, + spawnable_behaviors: [MoveToPosition((-175, 150))], + mob_behaviors: [DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, SpawnMob("mobs-right")], + control_behaviors: [FerritharaxProtectHead], + ), + ] + ), + MechaSaucetron: ( + behaviors: [ + ( + time: 7.0, + spawnable_behaviors: [MoveToPosition((0,175))], + mob_behaviors: [DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth], + control_behaviors: [FerritharaxAttack], + ), + ( + time: 20.0, + spawnable_behaviors: [MoveToPosition((175, 150))], + mob_behaviors: [DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, SpawnMob("mobs-left")], + control_behaviors: [FerritharaxProtectHead], + ), + ( + time: 7.0, + spawnable_behaviors: [MoveToPosition((0,175))], + mob_behaviors: [DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth], + control_behaviors: [FerritharaxAttack], + ), + ( + time: 20.0, + spawnable_behaviors: [MoveToPosition((-175, 150))], + mob_behaviors: [DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, SpawnMob("mobs-right")], + control_behaviors: [FerritharaxProtectHead], ), ] ), diff --git a/assets/data/characters.ron b/assets/data/characters.ron index 0c968938..cb5a3f36 100644 --- a/assets/data/characters.ron +++ b/assets/data/characters.ron @@ -15,8 +15,7 @@ attraction_distance: 150.0, attraction_acceleration: 15.0, money: 0, - weapon_damage: 12, - ability_type: MegaBlast(5.0), + weapon_damage: 10, projectile_speed: 800.0, projectile_spawn_position: Local((0.0, 40.0)), projectile_despawn_time: 1.0, @@ -34,7 +33,7 @@ collider_dimensions: (4.0 , 5.5), collider_density: 1.5, character_type: Juggernaut, - health: 150, + health: 140, shields: 10, shields_recharge_rate: 0.75, collision_damage: 15, diff --git a/assets/data/consumables.ron b/assets/data/consumables.ron index 706336c5..8a6e5e3d 100644 --- a/assets/data/consumables.ron +++ b/assets/data/consumables.ron @@ -5,9 +5,9 @@ spawnable_behaviors: [BrakeHorizontal, MoveDown, AttractToPlayer], consumable_effects: [GainHealth(20)], consumable_behaviors: [ApplyEffectsOnImpact], - acceleration: (0.0, 3.0), - deceleration: (0.5, 1.0), - speed: (0.0, 100.0), + acceleration: (8.0, 8.0), + deceleration: (5.0, 5.0), + speed: (0.0, 120.0), z_level: 15.0, initial_motion: ( random_linvel: Some(((-100, 50), (100, 100))), @@ -30,9 +30,9 @@ spawnable_behaviors: [BrakeHorizontal, MoveDown, AttractToPlayer], consumable_effects: [GainMoney(3)], consumable_behaviors: [ApplyEffectsOnImpact], - acceleration: (0.0, 3.0), - deceleration: (0.5, 1.0), - speed: (0.0, 100.0), + acceleration: (8.0, 8.0), + deceleration: (5.0, 5.0), + speed: (0.0, 120.0), z_level: 15.0, initial_motion: ( random_linvel: Some(((-100, 50), (100, 100))), @@ -55,9 +55,9 @@ spawnable_behaviors: [BrakeHorizontal, MoveDown, AttractToPlayer], consumable_effects: [GainMoney(1)], consumable_behaviors: [ApplyEffectsOnImpact], - acceleration: (0.0, 3.0), - deceleration: (0.5, 1.0), - speed: (0.0, 100.0), + acceleration: (8.0, 8.0), + deceleration: (5.0, 5.0), + speed: (0.0, 120.0), z_level: 15.0, initial_motion: ( random_linvel: Some(((-120, 50), (120, 120))), @@ -80,9 +80,9 @@ spawnable_behaviors: [BrakeHorizontal, MoveDown, AttractToPlayer], consumable_effects: [GainArmor(1)], consumable_behaviors: [ApplyEffectsOnImpact], - acceleration: (0.0, 3.0), - deceleration: (0.5, 1.0), - speed: (0.0, 100.0), + acceleration: (8.0, 8.0), + deceleration: (5.0, 5.0), + speed: (0.0, 120.0), z_level: 15.0, initial_motion: ( random_linvel: Some(((-100, 50), (100, 100))), @@ -105,9 +105,9 @@ spawnable_behaviors: [BrakeHorizontal, MoveDown, AttractToPlayer], consumable_effects: [GainProjectiles(1)], consumable_behaviors: [ApplyEffectsOnImpact], - acceleration: (0.0, 3.0), - deceleration: (0.5, 1.0), - speed: (0.0, 100.0), + acceleration: (8.0, 8.0), + deceleration: (5.0, 5.0), + speed: (0.0, 120.0), z_level: 15.0, initial_motion: ( random_linvel: Some(((-100, 50), (100, 100))), diff --git a/assets/data/formation_pools.ron b/assets/data/formation_pools.ron index cb4886a0..66c0e79e 100644 --- a/assets/data/formation_pools.ron +++ b/assets/data/formation_pools.ron @@ -1,5 +1,7 @@ ( formation_pools: { + "test": [ + ], "easy": [ ( formation_spawnables: [ @@ -126,7 +128,7 @@ position: (-150.0, 500.0), ), ( - spawnable_type: Mob(Enemy(Shelly)), + spawnable_type: Mob(Enemy(Pawn)), position: (0.0, 500.0), ), ( @@ -135,7 +137,7 @@ ), ], weight: 1.0, - period: 13.0, + period: 7.0, ), ( formation_spawnables: [ @@ -143,10 +145,18 @@ spawnable_type: Mob(Enemy(CrustlingRight)), position: (-150.0, 900.0), ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (75.0, 800.0), + ), ( spawnable_type: Mob(Enemy(CrustlingRight)), position: (0.0, 700.0), ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (-75.0, 600.0), + ), ( spawnable_type: Mob(Enemy(CrustlingRight)), position: (150.0, 500.0), @@ -359,29 +369,23 @@ weight: 1.0, period: 6.5, ), - ], - "hard": [ ( formation_spawnables: [ ( spawnable_type: Mob(Enemy(Shelly)), - position: (-250.0, 500.0), - ), - ( - spawnable_type: Mob(Enemy(Shelly)), - position: (-150.0, 500.0), + position: (-125.0, 550.0), ), ( spawnable_type: Mob(Enemy(Shelly)), - position: (0.0, 500.0), + position: (-75.0, 500.0), ), ( spawnable_type: Mob(Enemy(Shelly)), - position: (150.0, 500.0), + position: (75.0, 500.0), ), ( spawnable_type: Mob(Enemy(Shelly)), - position: (250.0, 500.0), + position: (125.0, 550.0), ), ], weight: 1.0, @@ -389,6 +393,14 @@ ), ( formation_spawnables: [ + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (-400.0, 1000.0), + ), + ( + spawnable_type: Mob(Enemy(Drone)), + position: (400.0, 1000.0), + ), ( spawnable_type: Mob(Enemy(CrustlingLeft)), position: (0.0, 950.0), @@ -439,27 +451,27 @@ formation_spawnables: [ ( spawnable_type: Mob(Enemy(Pawn)), - position: (400.0, 700.0), + position: (300.0, 700.0), ), ( spawnable_type: Mob(Enemy(Pawn)), - position: (300.0, 650.0), + position: (200.0, 650.0), ), ( spawnable_type: Mob(Enemy(Pawn)), - position: (200.0, 600.0), + position: (100.0, 600.0), ), ( spawnable_type: Mob(Enemy(Pawn)), - position: (-400.0, 700.0), + position: (-300.0, 700.0), ), ( spawnable_type: Mob(Enemy(Pawn)), - position: (-300.0, 650.0), + position: (-200.0, 650.0), ), ( spawnable_type: Mob(Enemy(Pawn)), - position: (-200, 600.0), + position: (-100, 600.0), ), ], weight: 1.0, @@ -646,6 +658,372 @@ period: 5.5, ), ], + "hard": [ + ( + formation_spawnables: [ + ( + spawnable_type: Mob(Ally(Hauler3)), + position: (0.0, 600.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (120.0, 1000.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (-120.0, 1000.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (120.0, 900.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (-120.0, 900.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (120.0, 800.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (-120.0, 800.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (-240.0, 700.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (240.0, 700.0), + ), + ], + weight: 0.7, + period: 10.0, + ), + ( + formation_spawnables: [ + ( + spawnable_type: Mob(Enemy(Drone)), + position: (0.0, 500.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (75.0, 525.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (-75.0, 525.0), + ), + ( + spawnable_type: Mob(Enemy(Drone)), + position: (150.0, 550.0), + ), + ( + spawnable_type: Mob(Enemy(Drone)), + position: (-150.0, 550.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (225.0, 575.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (-225.0, 575.0), + ), + ( + spawnable_type: Mob(Enemy(Drone)), + position: (300.0, 600.0), + ), + ( + spawnable_type: Mob(Enemy(Drone)), + position: (-300.0, 600.0), + ), + ], + weight: 1.0, + period: 10.0, + ), + ( + formation_spawnables: [ + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (0.0, 500.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (75.0, 525.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (-75.0, 525.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (150.0, 550.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (-150.0, 550.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (225.0, 575.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (-225.0, 575.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (300.0, 600.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (-300.0, 600.0), + ), + ], + weight: 1.0, + period: 10.0, + ), + ( + formation_spawnables: [ + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (50.0, 450.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (-50.0, 450.0), + ), + + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (200.0, 500.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (250.0, 450.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (150.0, 450.0), + ), + + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (-200.0, 500.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (-250.0, 450.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (-150.0, 450.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (0, 800.0), + ), + ], + weight: 1.0, + period: 11.0, + ), + ( + formation_spawnables: [ + ( + spawnable_type: Mob(Enemy(Drone)), + position: (0.0, 500.0), + ), + ( + spawnable_type: Mob(Enemy(MissileLauncher)), + position: (120.0, 575.0), + ), + ( + spawnable_type: Mob(Enemy(MissileLauncher)), + position: (-120.0, 575.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (60.0, 700.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (-60.0, 700.0), + ), + ], + weight: 1.0, + period: 11.0, + ), + ( + formation_spawnables: [ + ( + spawnable_type: Mob(Neutral(MoneyAsteroid)), + position: (0.0, 650.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (0.0, 550.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (0.0, 750.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (100.0, 650.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (-100.0, 650.0), + ), + ( + spawnable_type: Mob(Enemy(Drone)), + position: (75.0, 500.0), + ), + ( + spawnable_type: Mob(Enemy(Drone)), + position: (-75.0, 500.0), + ), + ], + weight: 0.5, + period: 10.0, + ), + ( + formation_spawnables: [ + ( + spawnable_type: Mob(Enemy(Missile)), + position: (-400.0, 500.0), + ), + ( + spawnable_type: Mob(Enemy(Missile)), + position: (400, 500.0), + ), + ( + spawnable_type: Mob(Enemy(Missile)), + position: (-200.0, 500.0), + ), + ( + spawnable_type: Mob(Enemy(Missile)), + position: (200, 500.0), + ), + ( + spawnable_type: Mob(Enemy(Missile)), + position: (0.0, 500.0), + ), + ( + spawnable_type: Mob(Enemy(Drone)), + position: (0.0, 570.0), + ), + ( + spawnable_type: Mob(Enemy(Drone)), + position: (-80.0, 580.0), + ), + ( + spawnable_type: Mob(Enemy(Drone)), + position: (80.0, 580.0), + ), + ( + spawnable_type: Mob(Enemy(Drone)), + position: (-160.0, 590.0), + ), + ( + spawnable_type: Mob(Enemy(Drone)), + position: (160.0, 590.0), + ), + ], + weight: 1.0, + period: 10.0, + ), + ( + formation_spawnables: [ + ( + spawnable_type: Mob(Enemy(CrustlingRight)), + position: (100.0, 500.0), + ), + ( + spawnable_type: Mob(Enemy(CrustlingLeft)), + position: (-100.0, 500.0), + ), + ( + spawnable_type: Mob(Enemy(CrustlingRight)), + position: (100.0, 650.0), + ), + ( + spawnable_type: Mob(Enemy(CrustlingLeft)), + position: (-100.0, 650.0), + ), + ( + spawnable_type: Mob(Enemy(CrustlingRight)), + position: (100.0, 800.0), + ), + ( + spawnable_type: Mob(Enemy(CrustlingLeft)), + position: (-100.0, 800.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (0.0, 550.0), + ), + ( + spawnable_type: Mob(Enemy(Shelly)), + position: (0.0, 625.0), + ), + ], + weight: 1.0, + period: 13.0, + ), + ( + formation_spawnables: [ + ( + spawnable_type: Mob(Enemy(StraferRight)), + position: (100.0, 500.0), + ), + ( + spawnable_type: Mob(Enemy(StraferLeft)), + position: (-100.0, 500.0), + ), + ( + spawnable_type: Mob(Enemy(StraferRight)), + position: (100.0, 650.0), + ), + ( + spawnable_type: Mob(Enemy(StraferLeft)), + position: (-100.0, 650.0), + ), + ( + spawnable_type: Mob(Enemy(StraferRight)), + position: (100.0, 800.0), + ), + ( + spawnable_type: Mob(Enemy(StraferLeft)), + position: (-100.0, 800.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (0.0, 550.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (0.0, 700.0), + ), + ( + spawnable_type: Mob(Enemy(Pawn)), + position: (0.0, 850.0), + ), + ( + spawnable_type: Mob(Enemy(Missile)), + position: (450.0, 500.0), + ), + ( + spawnable_type: Mob(Enemy(Missile)), + position: (-450.0, 500.0), + ), + ], + weight: 1.0, + period: 11.0, + ), + ], "asteroids": [ ( formation_spawnables: [ diff --git a/assets/data/items.ron b/assets/data/items.ron index 4b484a0e..a31f56e7 100644 --- a/assets/data/items.ron +++ b/assets/data/items.ron @@ -4,9 +4,9 @@ collider_dimensions: (5.0, 5.0), spawnable_behaviors: [BrakeHorizontal, MoveDown, AttractToPlayer], item_behaviors: [OnCollectIncreaseMaxHealth(100), OnCollectFullHeal], - acceleration: (0.0, 2.0), - deceleration: (0.5, 1.0), - speed: (0.0, 110.0), + acceleration: (8.0, 8.0), + deceleration: (5.0, 5.0), + speed: (0.0, 120.0), z_level: 15.0, initial_motion: ( random_linvel: Some(((-100, 50),(100, 100))), diff --git a/assets/data/loot_drops.ron b/assets/data/loot_drops.ron index 1b0c9524..4f4df533 100644 --- a/assets/data/loot_drops.ron +++ b/assets/data/loot_drops.ron @@ -17,11 +17,6 @@ probability: 0.1, consumable: Money1, )), - Consumable(( - rolls: 1, - probability: 0.01, - consumable: GainProjectiles, - )), ], Boss: [ Item(EnhancedPlating), diff --git a/assets/data/mob_segments.ron b/assets/data/mob_segments.ron index bee3fe0b..6167ff34 100644 --- a/assets/data/mob_segments.ron +++ b/assets/data/mob_segments.ron @@ -164,8 +164,8 @@ )) ], ), - Enemy(RepeaterBody): ( - mob_segment_type: Enemy(RepeaterBody), + Enemy(FerritharaxBody): ( + mob_segment_type: Enemy(FerritharaxBody), animation: ( direction: PingPong(Forward), frame_duration: 0.25, @@ -178,7 +178,8 @@ ) ], collision_damage: 10, - health: 350, + health: 450, + density: 2.3, consumable_drops: Standard, z_level: 4.9, anchor_point: (0.0, -51.0), @@ -189,25 +190,25 @@ ], mob_segment_anchor_points: Some([ ( - mob_segment_type: Enemy(RepeaterRightShoulder), + mob_segment_type: Enemy(FerritharaxRightShoulder), position: (72.0, -5.0), joint: Revolute, target_pos: 0.0, - stiffness: 30.0, - damping: 30.0, + stiffness: 50.0, + damping: 50.0, ), ( - mob_segment_type: Enemy(RepeaterLeftShoulder), + mob_segment_type: Enemy(FerritharaxLeftShoulder), position: (-72.0, -5.0), joint: Revolute, target_pos: 0.0, - stiffness: 30.0, - damping: 30.0, + stiffness: 50.0, + damping: 50.0, ), ]), ), - Enemy(RepeaterRightShoulder): ( - mob_segment_type: Enemy(RepeaterRightShoulder), + Enemy(FerritharaxRightShoulder): ( + mob_segment_type: Enemy(FerritharaxRightShoulder), animation: ( direction: None, frame_duration: 1.0, @@ -225,24 +226,25 @@ ) ], collision_damage: 10, - health: 350, + health: 450, + density: 2.3, consumable_drops: Standard, z_level: 5.1, anchor_point: (-75.0, 48.0), behaviors: [], mob_segment_anchor_points: Some([ ( - mob_segment_type: Enemy(RepeaterRightArm), + mob_segment_type: Enemy(FerritharaxRightArm), position: (65.0, -85.0), joint: Revolute, target_pos: 0.0, - stiffness: 30.0, - damping: 30.0, + stiffness: 50.0, + damping: 50.0, ), ]) ), - Enemy(RepeaterLeftShoulder): ( - mob_segment_type: Enemy(RepeaterLeftShoulder), + Enemy(FerritharaxLeftShoulder): ( + mob_segment_type: Enemy(FerritharaxLeftShoulder), animation: ( direction: None, frame_duration: 1.0, @@ -260,24 +262,25 @@ ) ], collision_damage: 10, - health: 350, + health: 450, + density: 2.3, consumable_drops: Standard, z_level: 5.1, anchor_point: (75.0, 48.0), behaviors: [], mob_segment_anchor_points: Some([ ( - mob_segment_type: Enemy(RepeaterLeftArm), + mob_segment_type: Enemy(FerritharaxLeftArm), position: (-65.0, -85.0), joint: Revolute, target_pos: 0.0, - stiffness: 30.0, - damping: 30.0, + stiffness: 50.0, + damping: 50.0, ), ]) ), - Enemy(RepeaterRightArm): ( - mob_segment_type: Enemy(RepeaterRightArm), + Enemy(FerritharaxRightArm): ( + mob_segment_type: Enemy(FerritharaxRightArm), animation: ( direction: None, frame_duration: 1.0, @@ -300,19 +303,20 @@ ), ], collision_damage: 10, - health: 500, + health: 650, + density: 2.3, consumable_drops: Standard, z_level: 5.2, anchor_point: (-28.0, 80.0), behaviors: [], mob_segment_anchor_points: Some([ ( - mob_segment_type: Enemy(RepeaterRightClaw), + mob_segment_type: Enemy(FerritharaxRightClaw), position: (-30.0, -75.0), joint: Revolute, target_pos: 0.0, - stiffness: 30.0, - damping: 30.0, + stiffness: 50.0, + damping: 50.0, ), ]), disconnected_behaviors: Some([ @@ -325,13 +329,13 @@ ( mob_type: Enemy(Missile), position: Local((30.0, -90.0)), - period: 3.5, + period: 5.0, ), ], }), ), - Enemy(RepeaterLeftArm): ( - mob_segment_type: Enemy(RepeaterLeftArm), + Enemy(FerritharaxLeftArm): ( + mob_segment_type: Enemy(FerritharaxLeftArm), animation: ( direction: None, frame_duration: 1.0, @@ -354,19 +358,20 @@ ), ], collision_damage: 10, - health: 500, + health: 650, + density: 2.3, consumable_drops: Standard, z_level: 5.2, anchor_point: (28.0, 80.0), behaviors: [], mob_segment_anchor_points: Some([ ( - mob_segment_type: Enemy(RepeaterLeftClaw), + mob_segment_type: Enemy(FerritharaxLeftClaw), position: (30.0, -75.0), joint: Revolute, target_pos: 0.0, - stiffness: 30.0, - damping: 30.0, + stiffness: 50.0, + damping: 50.0, ), ]), disconnected_behaviors: Some([ @@ -379,13 +384,13 @@ ( mob_type: Enemy(Missile), position: Local((-30.0, -90.0)), - period: 3.5, + period: 5.0, ), ], }), ), - Enemy(RepeaterRightClaw): ( - mob_segment_type: Enemy(RepeaterRightClaw), + Enemy(FerritharaxRightClaw): ( + mob_segment_type: Enemy(FerritharaxRightClaw), animation: ( direction: None, frame_duration: 1.0, @@ -403,14 +408,15 @@ ), ], collision_damage: 10, - health: 600, + health: 700, + density: 2.3, consumable_drops: Standard, z_level: 5.3, anchor_point: (42.0, -23.0), behaviors: [], ), - Enemy(RepeaterLeftClaw): ( - mob_segment_type: Enemy(RepeaterLeftClaw), + Enemy(FerritharaxLeftClaw): ( + mob_segment_type: Enemy(FerritharaxLeftClaw), animation: ( direction: None, frame_duration: 1.0, @@ -428,11 +434,738 @@ ), ], collision_damage: 10, - health: 600, + health: 700, + density: 2.3, consumable_drops: Standard, z_level: 5.3, anchor_point: (-42.0, -23.0), behaviors: [], ), + Enemy(MechaFerritharaxBody): ( + mob_segment_type: Enemy(MechaFerritharaxBody), + animation: ( + direction: PingPong(Forward), + frame_duration: 0.25, + ), + colliders: [ + ( + dimensions: (22.0, 7.0), + position: (0.0, 5.0), + rotation: 0.0, + ), + ( + dimensions: (12.0, 6.0), + position: (0.0, -7.0), + rotation: 0.0, + ) + ], + collision_damage: 10, + health: 725, + density: 3.3, + consumable_drops: Standard, + z_level: 5.1, + anchor_point: (0.0, -51.0), + behaviors: [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + ], + mob_segment_anchor_points: Some([ + ( + mob_segment_type: Enemy(MechaFerritharaxRightShoulder), + position: (90.0, 10.0), + joint: Revolute, + target_pos: 0.0, + stiffness: 300.0, + damping: 300.0, + ), + ( + mob_segment_type: Enemy(MechaFerritharaxLeftShoulder), + position: (-90.0, 10.0), + joint: Revolute, + target_pos: 0.0, + stiffness: 300.0, + damping: 300.0, + ), + ]), + ), + Enemy(MechaFerritharaxRightShoulder): ( + mob_segment_type: Enemy(MechaFerritharaxRightShoulder), + animation: ( + direction: None, + frame_duration: 1.0, + ), + colliders: [ + ( + dimensions: (25.0, 4.5), + position: (11.0, -4.0), + rotation: -1.05, + ), + ( + dimensions: (11.5, 7.5), + position: (-11.5, 15.0), + rotation: -0.261799, + ) + ], + collision_damage: 10, + health: 725, + density: 3.3, + consumable_drops: Standard, + z_level: 5.0, + anchor_point: (-75.0, 48.0), + behaviors: [], + mob_segment_anchor_points: Some([ + ( + mob_segment_type: Enemy(MechaFerritharaxRightArm), + position: (75.0, -85.0), + joint: Revolute, + target_pos: 0.0, + stiffness: 300.0, + damping: 300.0, + ), + ]) + ), + Enemy(MechaFerritharaxLeftShoulder): ( + mob_segment_type: Enemy(MechaFerritharaxLeftShoulder), + animation: ( + direction: None, + frame_duration: 1.0, + ), + colliders: [ + ( + dimensions: (25.0, 4.5), + position: (-11.0, -4.0), + rotation: 1.05, + ), + ( + dimensions: (11.5, 7.5), + position: (11.5, 15.0), + rotation: 0.261799, + ) + ], + collision_damage: 10, + health: 725, + density: 3.3, + consumable_drops: Standard, + z_level: 5.0, + anchor_point: (75.0, 48.0), + behaviors: [], + mob_segment_anchor_points: Some([ + ( + mob_segment_type: Enemy(MechaFerritharaxLeftArm), + position: (-75.0, -85.0), + joint: Revolute, + target_pos: 0.0, + stiffness: 300.0, + damping: 300.0, + ), + ]) + ), + Enemy(MechaFerritharaxRightArm): ( + mob_segment_type: Enemy(MechaFerritharaxRightArm), + animation: ( + direction: None, + frame_duration: 1.0, + ), + colliders: [ + ( + dimensions: (17.0, 4.0), + position: (-4.0, 9.0), + rotation: -1.25, + ), + ( + dimensions: (10.0, 3.0), + position: (-1.0, -14.5), + rotation: 0.75, + ), + ( + dimensions: (4.0, 12.0), + position: (7.0, -8.0), + rotation: 0.0, + ), + ], + collision_damage: 10, + health: 1050, + density: 3.3, + consumable_drops: Standard, + z_level: 5.1, + anchor_point: (-28.0, 80.0), + behaviors: [], + mob_segment_anchor_points: Some([ + ( + mob_segment_type: Enemy(MechaFerritharaxRightClaw), + position: (-48.0, -62.0), + joint: Revolute, + target_pos: 0.0, + stiffness: 300.0, + damping: 300.0, + ), + ]), + disconnected_behaviors: Some([ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + DisableWeapons, + ]), + mob_spawners: Some({ + "missile": [ + ( + mob_type: Enemy(Missile), + position: Local((30.0, -90.0)), + period: 7.0, + ), + ], + }), + weapons: Some([( + reload_time: 1.0, + initial_time: 3.0, + fire_mode: Automatic, + capacity: 3, + projectile_data: ( + ammunition: Bullet(Enemy), + damage: 5, + position: Local((25.0, -70.0)), + speed: 300.0, + direction: 4.45059, + despawn_time: 0.8, + count: 3, + spread_pattern: Arc(( + spread_weights: (0.5, 1.0), + max_spread: 1.57080, + projectile_gap: 3.14159, + )), + size: 1.0, + sound: EnemyFireBlast, + ), + )]), + ), + Enemy(MechaFerritharaxLeftArm): ( + mob_segment_type: Enemy(MechaFerritharaxLeftArm), + animation: ( + direction: None, + frame_duration: 1.0, + ), + colliders: [ + ( + dimensions: (17.0, 4.0), + position: (4.0, 9.0), + rotation: 1.25, + ), + ( + dimensions: (10.0, 3.0), + position: (1.0, -14.5), + rotation: -0.75, + ), + ( + dimensions: (4.0, 12.0), + position: (-7.0, -8.0), + rotation: 0.0, + ), + ], + collision_damage: 10, + health: 1050, + density: 3.3, + consumable_drops: Standard, + z_level: 5.1, + anchor_point: (28.0, 80.0), + behaviors: [], + mob_segment_anchor_points: Some([ + ( + mob_segment_type: Enemy(MechaFerritharaxLeftClaw), + position: (48.0, -62.0), + joint: Revolute, + target_pos: 0.0, + stiffness: 300.0, + damping: 300.0, + ), + ]), + disconnected_behaviors: Some([ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + DisableWeapons, + ]), + mob_spawners: Some({ + "missile": [ + ( + mob_type: Enemy(Missile), + position: Local((-30.0, -90.0)), + period: 7.0, + ), + ], + }), + weapons: Some([( + reload_time: 1.0, + initial_time: 3.0, + fire_mode: Automatic, + capacity: 3, + projectile_data: ( + ammunition: Bullet(Enemy), + damage: 5, + position: Local((-25.0, -70.0)), + speed: 300.0, + direction: 4.97419, + despawn_time: 0.8, + count: 3, + spread_pattern: Arc(( + spread_weights: (0.5, 1.0), + max_spread: 1.57080, + projectile_gap: 3.14159, + )), + size: 1.0, + sound: EnemyFireBlast, + ), + )]), + ), + Enemy(MechaFerritharaxRightClaw): ( + mob_segment_type: Enemy(MechaFerritharaxRightClaw), + animation: ( + direction: None, + frame_duration: 1.0, + ), + colliders: [ + ( + dimensions: (5.0, 2.0), + position: (15.0, 0.0), + rotation: 0.0, + ), + ( + dimensions: (8.0, 2.5), + position: (4.0, -10.0), + rotation: 0.523599, + ), + ( + dimensions: (8.0, 2.0), + position: (-8.0, -13.0), + rotation: -0.174533, + ), + ( + dimensions: (8.0, 2.5), + position: (4.0, 10.0), + rotation: -0.523599, + ), + ( + dimensions: (8.0, 2.0), + position: (-8.0, 13.0), + rotation: 0.174533, + ), + ], + collision_damage: 10, + health: 1100, + density: 3.3, + consumable_drops: Standard, + z_level: 5.3, + anchor_point: (50.0, 0.0), + behaviors: [], + ), + Enemy(MechaFerritharaxLeftClaw): ( + mob_segment_type: Enemy(MechaFerritharaxLeftClaw), + animation: ( + direction: None, + frame_duration: 1.0, + ), + colliders: [ + ( + dimensions: (5.0, 2.0), + position: (-15.0, 0.0), + rotation: 0.0, + ), + ( + dimensions: (8.0, 2.5), + position: (-4.0, -10.0), + rotation: -0.523599, + ), + ( + dimensions: (8.0, 2.0), + position: (8.0, -13.0), + rotation: 0.174533, + ), + ( + dimensions: (8.0, 2.5), + position: (-4.0, 10.0), + rotation: 0.523599, + ), + ( + dimensions: (8.0, 2.0), + position: (8.0, 13.0), + rotation: -0.174533, + ), + ], + collision_damage: 10, + health: 1100, + density: 3.3, + consumable_drops: Standard, + z_level: 5.3, + anchor_point: (-50.0, 0.0), + behaviors: [], + ), + Enemy(MechaSaucetronBody): ( + mob_segment_type: Enemy(MechaSaucetronBody), + animation: ( + direction: PingPong(Forward), + frame_duration: 0.25, + ), + colliders: [ + ( + dimensions: (22.0, 7.0), + position: (0.0, 5.0), + rotation: 0.0, + ), + ( + dimensions: (12.0, 6.0), + position: (0.0, -7.0), + rotation: 0.0, + ) + ], + collision_damage: 10, + health: 1000, + density: 3.6, + consumable_drops: Standard, + z_level: 5.1, + anchor_point: (0.0, -51.0), + behaviors: [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + ], + mob_segment_anchor_points: Some([ + ( + mob_segment_type: Enemy(MechaSaucetronRightShoulder), + position: (90.0, 10.0), + joint: Revolute, + target_pos: 0.0, + stiffness: 300.0, + damping: 300.0, + ), + ( + mob_segment_type: Enemy(MechaSaucetronLeftShoulder), + position: (-90.0, 10.0), + joint: Revolute, + target_pos: 0.0, + stiffness: 300.0, + damping: 300.0, + ), + ]), + ), + Enemy(MechaSaucetronRightShoulder): ( + mob_segment_type: Enemy(MechaSaucetronRightShoulder), + animation: ( + direction: None, + frame_duration: 1.0, + ), + colliders: [ + ( + dimensions: (25.0, 4.5), + position: (11.0, -4.0), + rotation: -1.05, + ), + ( + dimensions: (11.5, 7.5), + position: (-11.5, 15.0), + rotation: -0.261799, + ) + ], + collision_damage: 10, + health: 1000, + density: 3.6, + consumable_drops: Standard, + z_level: 5.0, + anchor_point: (-75.0, 48.0), + behaviors: [], + mob_segment_anchor_points: Some([ + ( + mob_segment_type: Enemy(MechaSaucetronRightArm), + position: (75.0, -85.0), + joint: Revolute, + target_pos: 0.0, + stiffness: 300.0, + damping: 300.0, + ), + ]) + ), + Enemy(MechaSaucetronLeftShoulder): ( + mob_segment_type: Enemy(MechaSaucetronLeftShoulder), + animation: ( + direction: None, + frame_duration: 1.0, + ), + colliders: [ + ( + dimensions: (25.0, 4.5), + position: (-11.0, -4.0), + rotation: 1.05, + ), + ( + dimensions: (11.5, 7.5), + position: (11.5, 15.0), + rotation: 0.261799, + ) + ], + collision_damage: 10, + health: 1000, + density: 3.6, + consumable_drops: Standard, + z_level: 5.0, + anchor_point: (75.0, 48.0), + behaviors: [], + mob_segment_anchor_points: Some([ + ( + mob_segment_type: Enemy(MechaSaucetronLeftArm), + position: (-75.0, -85.0), + joint: Revolute, + target_pos: 0.0, + stiffness: 300.0, + damping: 300.0, + ), + ]) + ), + Enemy(MechaSaucetronRightArm): ( + mob_segment_type: Enemy(MechaSaucetronRightArm), + animation: ( + direction: None, + frame_duration: 1.0, + ), + colliders: [ + ( + dimensions: (17.0, 4.0), + position: (-4.0, 9.0), + rotation: -1.25, + ), + ( + dimensions: (10.0, 3.0), + position: (-1.0, -14.5), + rotation: 0.75, + ), + ( + dimensions: (4.0, 12.0), + position: (7.0, -8.0), + rotation: 0.0, + ), + ], + collision_damage: 10, + health: 1450, + density: 3.6, + consumable_drops: Standard, + z_level: 5.1, + anchor_point: (-28.0, 80.0), + behaviors: [], + mob_segment_anchor_points: Some([ + ( + mob_segment_type: Enemy(MechaSaucetronRightClaw), + position: (-48.0, -62.0), + joint: Revolute, + target_pos: 0.0, + stiffness: 300.0, + damping: 300.0, + ), + ]), + disconnected_behaviors: Some([ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + DisableWeapons, + ]), + mob_spawners: Some({ + "missile": [ + ( + mob_type: Enemy(Missile), + position: Local((30.0, -90.0)), + period: 5.5, + ), + ], + }), + weapons: Some([( + reload_time: 1.0, + initial_time: 3.0, + fire_mode: Automatic, + capacity: 6, + projectile_data: ( + ammunition: Blast(Enemy), + damage: 5, + position: Local((25.0, -70.0)), + speed: 300.0, + direction: 4.45059, + despawn_time: 0.8, + count: 6, + spread_pattern: Random(( + speed_range: ( + start: 0.75, + end: 1.25, + ), + angle_range: ( + start: 0.9, + end: 1.1, + ), + )), + size: 1.0, + sound: EnemyFireBlast, + ), + )]), + ), + Enemy(MechaSaucetronLeftArm): ( + mob_segment_type: Enemy(MechaSaucetronLeftArm), + animation: ( + direction: None, + frame_duration: 1.0, + ), + colliders: [ + ( + dimensions: (17.0, 4.0), + position: (4.0, 9.0), + rotation: 1.25, + ), + ( + dimensions: (10.0, 3.0), + position: (1.0, -14.5), + rotation: -0.75, + ), + ( + dimensions: (4.0, 12.0), + position: (-7.0, -8.0), + rotation: 0.0, + ), + ], + collision_damage: 10, + health: 1450, + density: 3.6, + consumable_drops: Standard, + z_level: 5.1, + anchor_point: (28.0, 80.0), + behaviors: [], + mob_segment_anchor_points: Some([ + ( + mob_segment_type: Enemy(MechaSaucetronLeftClaw), + position: (48.0, -62.0), + joint: Revolute, + target_pos: 0.0, + stiffness: 300.0, + damping: 300.0, + ), + ]), + disconnected_behaviors: Some([ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + DisableWeapons, + ]), + mob_spawners: Some({ + "missile": [ + ( + mob_type: Enemy(Missile), + position: Local((-30.0, -90.0)), + period: 5.5, + ), + ], + }), + weapons: Some([( + reload_time: 1.0, + initial_time: 3.0, + fire_mode: Automatic, + capacity: 6, + projectile_data: ( + ammunition: Blast(Enemy), + damage: 5, + position: Local((-25.0, -70.0)), + speed: 300.0, + direction: 4.97419, + despawn_time: 0.8, + count: 6, + spread_pattern: Random(( + speed_range: ( + start: 0.75, + end: 1.25, + ), + angle_range: ( + start: 0.9, + end: 1.1, + ), + )), + size: 1.0, + sound: EnemyFireBlast, + ), + )]), + ), + Enemy(MechaSaucetronRightClaw): ( + mob_segment_type: Enemy(MechaSaucetronRightClaw), + animation: ( + direction: None, + frame_duration: 1.0, + ), + colliders: [ + ( + dimensions: (5.0, 2.0), + position: (15.0, 0.0), + rotation: 0.0, + ), + ( + dimensions: (8.0, 2.5), + position: (4.0, -10.0), + rotation: 0.523599, + ), + ( + dimensions: (8.0, 2.0), + position: (-8.0, -13.0), + rotation: -0.174533, + ), + ( + dimensions: (8.0, 2.5), + position: (4.0, 10.0), + rotation: -0.523599, + ), + ( + dimensions: (8.0, 2.0), + position: (-8.0, 13.0), + rotation: 0.174533, + ), + ], + collision_damage: 10, + health: 1500, + density: 3.6, + consumable_drops: Standard, + z_level: 5.3, + anchor_point: (50.0, 0.0), + behaviors: [], + ), + Enemy(MechaSaucetronLeftClaw): ( + mob_segment_type: Enemy(MechaSaucetronLeftClaw), + animation: ( + direction: None, + frame_duration: 1.0, + ), + colliders: [ + ( + dimensions: (5.0, 2.0), + position: (-15.0, 0.0), + rotation: 0.0, + ), + ( + dimensions: (8.0, 2.5), + position: (-4.0, -10.0), + rotation: -0.523599, + ), + ( + dimensions: (8.0, 2.0), + position: (8.0, -13.0), + rotation: 0.174533, + ), + ( + dimensions: (8.0, 2.5), + position: (-4.0, 10.0), + rotation: 0.523599, + ), + ( + dimensions: (8.0, 2.0), + position: (8.0, 13.0), + rotation: -0.174533, + ), + ], + collision_damage: 10, + health: 1500, + density: 3.6, + consumable_drops: Standard, + z_level: 5.3, + anchor_point: (-50.0, 0.0), + behaviors: [], + ), }, ) \ No newline at end of file diff --git a/assets/data/mobs.ron b/assets/data/mobs.ron index 68aa4902..f6333c0b 100644 --- a/assets/data/mobs.ron +++ b/assets/data/mobs.ron @@ -1,172 +1,614 @@ { - Enemy(Repeater): ( - mob_type: Enemy(Repeater), + Enemy(MechaSaucetron): ( + mob_type: Enemy(MechaSaucetron), mob_segment_behaviors: Some({ - RepeaterProtectHead: { - Enemy(RepeaterBody): [ + FerritharaxProtectHead: { + Enemy(MechaSaucetronBody): [ DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, ], - Enemy(RepeaterRightShoulder): [ + Enemy(MechaSaucetronRightShoulder): [ DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, - RepeaterProtectHead( + FerritharaxProtectHead( ( angle: -0.15, - stiffness: 30.0, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + Enemy(MechaSaucetronLeftShoulder): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxProtectHead( + ( + angle: 0.15, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + Enemy(MechaSaucetronRightArm): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxProtectHead( + ( + angle: -0.5, + stiffness: 300.0, + damping: 300.0, + ) + ), + SpawnMob("missile"), + ], + Enemy(MechaSaucetronLeftArm): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxProtectHead( + ( + angle: 0.5, + stiffness: 300.0, + damping: 300.0, + ) + ), + SpawnMob("missile"), + ], + Enemy(MechaSaucetronRightClaw): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxProtectHead( + ( + angle: 1.0, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + Enemy(MechaSaucetronLeftClaw): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxProtectHead( + ( + angle: -1.0, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + }, + FerritharaxAttack: { + Enemy(MechaSaucetronBody): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + ], + Enemy(MechaSaucetronRightShoulder): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxAttack( + ( + angle: 0.0, + stiffness: 300.0, + damping: 300.0, + ) + ) + ], + Enemy(MechaSaucetronLeftShoulder): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxAttack( + ( + angle: 0.0, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + Enemy(MechaSaucetronRightArm): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxAttack( + ( + angle: 0.0, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + Enemy(MechaSaucetronLeftArm): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxAttack( + ( + angle: 0.0, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + Enemy(MechaSaucetronRightClaw): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxAttack( + ( + angle: 0.0, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + Enemy(MechaSaucetronLeftClaw): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxAttack( + ( + angle: 0.0, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + }, + }), + behavior_sequence_type: Some(MechaSaucetron), + acceleration: (4.0, 4.0), + deceleration: (4.0, 4.0), + speed: (80.0, 80.0), + collision_damage: 20, + colliders: [ + ( + dimensions: (12.0, 12.0), + position: (0.0, -5.0), + rotation: 0.0, + ) + ], + z_level: 5.0, + consumable_drops: Boss, + health: 2400, + density: 3.8, + animation: ( + direction: PingPong(Forward), + frame_duration: 0.25, + ), + mob_segment_anchor_points: [ + ( + mob_segment_type: Enemy(MechaSaucetronBody), + position: (0.0, 80.0), + joint: Revolute, + target_pos: 0, + stiffness: 500.0, + damping: 500.0, + ), + ], + mob_spawners: { + "mobs-left": [ + ( + mob_type: Enemy(Pawn), + position: Global((-400.0, 500.0)), + period: 7.0, + ), + ( + mob_type: Enemy(Drone), + position: Global((-200.0, 500.0)), + period: 5.0, + ), + ], + "mobs-right": [ + ( + mob_type: Enemy(Pawn), + position: Global((400.0, 500.0)), + period: 7.0, + ), + ( + mob_type: Enemy(Drone), + position: Global((200.0, 500.0)), + period: 5.0, + ), + ], + }, + ), + Enemy(MechaFerritharax): ( + mob_type: Enemy(MechaFerritharax), + mob_segment_behaviors: Some({ + FerritharaxProtectHead: { + Enemy(MechaFerritharaxBody): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + ], + Enemy(MechaFerritharaxRightShoulder): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxProtectHead( + ( + angle: -0.15, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + Enemy(MechaFerritharaxLeftShoulder): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxProtectHead( + ( + angle: 0.15, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + Enemy(MechaFerritharaxRightArm): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxProtectHead( + ( + angle: -0.5, + stiffness: 300.0, + damping: 300.0, + ) + ), + SpawnMob("missile"), + ], + Enemy(MechaFerritharaxLeftArm): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxProtectHead( + ( + angle: 0.5, + stiffness: 300.0, + damping: 300.0, + ) + ), + SpawnMob("missile"), + ], + Enemy(MechaFerritharaxRightClaw): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxProtectHead( + ( + angle: 1.0, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + Enemy(MechaFerritharaxLeftClaw): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxProtectHead( + ( + angle: -1.0, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + }, + FerritharaxAttack: { + Enemy(MechaFerritharaxBody): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + ], + Enemy(MechaFerritharaxRightShoulder): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxAttack( + ( + angle: 0.0, + stiffness: 300.0, + damping: 300.0, + ) + ) + ], + Enemy(MechaFerritharaxLeftShoulder): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxAttack( + ( + angle: 0.0, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + Enemy(MechaFerritharaxRightArm): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxAttack( + ( + angle: 0.0, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + Enemy(MechaFerritharaxLeftArm): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxAttack( + ( + angle: 0.0, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + Enemy(MechaFerritharaxRightClaw): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxAttack( + ( + angle: 0.0, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + Enemy(MechaFerritharaxLeftClaw): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxAttack( + ( + angle: 0.0, + stiffness: 300.0, + damping: 300.0, + ) + ), + ], + }, + }), + behavior_sequence_type: Some(MechaFerritharax), + acceleration: (4.0, 4.0), + deceleration: (4.0, 4.0), + speed: (80.0, 80.0), + collision_damage: 20, + colliders: [ + ( + dimensions: (12.0, 12.0), + position: (0.0, -5.0), + rotation: 0.0, + ) + ], + z_level: 5.0, + consumable_drops: Boss, + health: 1800, + density: 3.5, + animation: ( + direction: PingPong(Forward), + frame_duration: 0.25, + ), + mob_segment_anchor_points: [ + ( + mob_segment_type: Enemy(MechaFerritharaxBody), + position: (0.0, 80.0), + joint: Revolute, + target_pos: 0, + stiffness: 500.0, + damping: 500.0, + ), + ], + mob_spawners: { + "mobs-left": [ + ( + mob_type: Enemy(Pawn), + position: Global((-400.0, 500.0)), + period: 7.0, + ), + ( + mob_type: Enemy(Drone), + position: Global((-200.0, 500.0)), + period: 5.0, + ), + ], + "mobs-right": [ + ( + mob_type: Enemy(Pawn), + position: Global((400.0, 500.0)), + period: 7.0, + ), + ( + mob_type: Enemy(Drone), + position: Global((200.0, 500.0)), + period: 5.0, + ), + ], + }, + ), + Enemy(Ferritharax): ( + mob_type: Enemy(Ferritharax), + mob_segment_behaviors: Some({ + FerritharaxProtectHead: { + Enemy(FerritharaxBody): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + ], + Enemy(FerritharaxRightShoulder): [ + DealDamageToPlayerOnImpact, + ReceiveDamageOnImpact, + DieAtZeroHealth, + FerritharaxProtectHead( + ( + angle: -0.15, + stiffness: 50.0, damping: 50.0, ) ), ], - Enemy(RepeaterLeftShoulder): [ + Enemy(FerritharaxLeftShoulder): [ DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, - RepeaterProtectHead( + FerritharaxProtectHead( ( angle: 0.15, - stiffness: 30.0, + stiffness: 50.0, damping: 50.0, ) ), ], - Enemy(RepeaterRightArm): [ + Enemy(FerritharaxRightArm): [ DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, - RepeaterProtectHead( + FerritharaxProtectHead( ( angle: -0.5, - stiffness: 30.0, + stiffness: 50.0, damping: 50.0, ) ), SpawnMob("missile"), ], - Enemy(RepeaterLeftArm): [ + Enemy(FerritharaxLeftArm): [ DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, - RepeaterProtectHead( + FerritharaxProtectHead( ( angle: 0.5, - stiffness: 30.0, + stiffness: 50.0, damping: 50.0, ) ), SpawnMob("missile"), ], - Enemy(RepeaterRightClaw): [ + Enemy(FerritharaxRightClaw): [ DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, - RepeaterProtectHead( + FerritharaxProtectHead( ( angle: 1.0, - stiffness: 30.0, + stiffness: 50.0, damping: 50.0, ) ), ], - Enemy(RepeaterLeftClaw): [ + Enemy(FerritharaxLeftClaw): [ DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, - RepeaterProtectHead( + FerritharaxProtectHead( ( angle: -1.0, - stiffness: 30.0, + stiffness: 50.0, damping: 50.0, ) ), ], }, - RepeaterAttack: { - Enemy(RepeaterBody): [ + FerritharaxAttack: { + Enemy(FerritharaxBody): [ DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, ], - Enemy(RepeaterRightShoulder): [ + Enemy(FerritharaxRightShoulder): [ DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, - RepeaterAttack( + FerritharaxAttack( ( angle: 0.0, - stiffness: 30.0, + stiffness: 50.0, damping: 50.0, ) ), ], - Enemy(RepeaterLeftShoulder): [ + Enemy(FerritharaxLeftShoulder): [ DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, - RepeaterAttack( + FerritharaxAttack( ( angle: 0.0, - stiffness: 30.0, + stiffness: 50.0, damping: 50.0, ) ), ], - Enemy(RepeaterRightArm): [ + Enemy(FerritharaxRightArm): [ DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, - RepeaterAttack( + FerritharaxAttack( ( angle: 0.0, - stiffness: 30.0, + stiffness: 50.0, damping: 50.0, ) ), ], - Enemy(RepeaterLeftArm): [ + Enemy(FerritharaxLeftArm): [ DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, - RepeaterAttack( + FerritharaxAttack( ( angle: 0.0, - stiffness: 30.0, + stiffness: 50.0, damping: 50.0, ) ), ], - Enemy(RepeaterRightClaw): [ + Enemy(FerritharaxRightClaw): [ DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, - RepeaterAttack( + FerritharaxAttack( ( angle: 0.0, - stiffness: 30.0, + stiffness: 50.0, damping: 50.0, ) ), ], - Enemy(RepeaterLeftClaw): [ + Enemy(FerritharaxLeftClaw): [ DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth, - RepeaterAttack( + FerritharaxAttack( ( angle: 0.0, - stiffness: 30.0, - damping: 30.0, + stiffness: 50.0, + damping: 50.0, ) ), ], }, }), - behavior_sequence_type: Some(Repeater), - acceleration: (2.0, 2.0), - deceleration: (2.0, 2.0), - speed: (80.0, 30.0), + behavior_sequence_type: Some(Ferritharax), + acceleration: (3.6, 3.6), + deceleration: (3.6, 3.6), + speed: (60.0, 60.0), collision_damage: 20, colliders: [ ( @@ -177,19 +619,20 @@ ], z_level: 5.0, consumable_drops: Boss, - health: 1500, + health: 1200, + density: 2.7, animation: ( direction: PingPong(Forward), frame_duration: 0.25, ), mob_segment_anchor_points: [ ( - mob_segment_type: Enemy(RepeaterBody), + mob_segment_type: Enemy(FerritharaxBody), position: (0.0, 60.0), joint: Revolute, target_pos: 0, - stiffness: 30.0, - damping: 30.0, + stiffness: 50.0, + damping: 50.0, ), ], mob_spawners: { @@ -406,7 +849,7 @@ alpha: 1.0, ), )), - weapon: Some(( + weapons: Some([( reload_time: 3.0, initial_time: 1.0, fire_mode: Automatic, @@ -427,7 +870,7 @@ size: 1.0, sound: EnemyFireBlast, ), - )), + )]), ), Enemy(Shelly): ( mob_type: Enemy(Shelly), @@ -441,6 +884,7 @@ deceleration: (2.0, 1.0), speed: (0.0, 75.0), collision_damage: 8, + can_rotate: true, defense_interaction: Some(Damage(8)), colliders: [ ( @@ -451,33 +895,229 @@ ], z_level: 5.0, consumable_drops: Standard, - health: 25, + health: 50, animation: ( direction: PingPong(Forward), frame_duration: 0.25, ), - weapon: Some(( - reload_time: 3.0, - initial_time: 1.0, - fire_mode: Automatic, - capacity: 1, - projectile_data: ( - ammunition: Bullet(Enemy), - damage: 10, - position: Local((0.0, -40.0)), - speed: 400.0, - direction: 4.71239, - despawn_time: 2.0, - count: 1, - spread_pattern: Arc(( - spread_weights: (0.5, 1.0), - max_spread: 1.57080, - projectile_gap: 3.14159, - )), - size: 1.0, - sound: EnemyFireBlast, + weapons: Some([ + ( + reload_time: 1.6, + initial_time: 1.0, + fire_mode: Automatic, + capacity: 1, + projectile_data: ( + ammunition: Bullet(Enemy), + damage: 10, + position: Local((0.0, -40.0)), + speed: 300.0, + direction: 4.71239, + despawn_time: 0.3, + count: 1, + spread_pattern: Random(( + speed_range: ( + start: 0.75, + end: 1.25, + ), + angle_range: ( + start: 0.9, + end: 1.1, + ), + )), + size: 1.0, + sound: EnemyFireBlast, + ), ), - )), + ( + reload_time: 1.6, + initial_time: 1.2, + fire_mode: Automatic, + capacity: 1, + projectile_data: ( + ammunition: Bullet(Enemy), + damage: 10, + position: Local((-28.28427, -28.28427)), + speed: 300.0, + direction: 3.92699, + despawn_time: 0.3, + count: 1, + spread_pattern: Random(( + speed_range: ( + start: 0.75, + end: 1.25, + ), + angle_range: ( + start: 0.9, + end: 1.1, + ), + )), + size: 1.0, + sound: EnemyFireBlast, + ), + ), + ( + reload_time: 1.6, + initial_time: 1.4, + fire_mode: Automatic, + capacity: 1, + projectile_data: ( + ammunition: Bullet(Enemy), + damage: 10, + position: Local((-40.0, 0.0)), + speed: 300.0, + direction: 3.14159, + despawn_time: 0.3, + count: 1, + spread_pattern: Random(( + speed_range: ( + start: 0.75, + end: 1.25, + ), + angle_range: ( + start: 0.9, + end: 1.1, + ), + )), + size: 1.0, + sound: EnemyFireBlast, + ), + ), + ( + reload_time: 1.6, + initial_time: 1.6, + fire_mode: Automatic, + capacity: 1, + projectile_data: ( + ammunition: Bullet(Enemy), + damage: 10, + position: Local((-28.28427, 28.28427)), + speed: 300.0, + direction: 2.35619, + despawn_time: 0.3, + count: 1, + spread_pattern: Random(( + speed_range: ( + start: 0.75, + end: 1.25, + ), + angle_range: ( + start: 0.9, + end: 1.1, + ), + )), + size: 1.0, + sound: EnemyFireBlast, + ), + ), + ( + reload_time: 1.6, + initial_time: 1.8, + fire_mode: Automatic, + capacity: 1, + projectile_data: ( + ammunition: Bullet(Enemy), + damage: 10, + position: Local((0.0, 40.0)), + speed: 300.0, + direction: 1.57080, + despawn_time: 0.3, + count: 1, + spread_pattern: Random(( + speed_range: ( + start: 0.75, + end: 1.25, + ), + angle_range: ( + start: 0.9, + end: 1.1, + ), + )), + size: 1.0, + sound: EnemyFireBlast, + ), + ), + ( + reload_time: 1.6, + initial_time: 2.0, + fire_mode: Automatic, + capacity: 1, + projectile_data: ( + ammunition: Bullet(Enemy), + damage: 10, + position: Local((28.28427, 28.28427)), + speed: 300.0, + direction: 0.78540, + despawn_time: 0.3, + count: 1, + spread_pattern: Random(( + speed_range: ( + start: 0.75, + end: 1.25, + ), + angle_range: ( + start: 0.9, + end: 1.1, + ), + )), + size: 1.0, + sound: EnemyFireBlast, + ), + ), + ( + reload_time: 1.6, + initial_time: 2.2, + fire_mode: Automatic, + capacity: 1, + projectile_data: ( + ammunition: Bullet(Enemy), + damage: 10, + position: Local((40.0, 0.0)), + speed: 300.0, + direction: 0.0, + despawn_time: 0.3, + count: 1, + spread_pattern: Random(( + speed_range: ( + start: 0.75, + end: 1.25, + ), + angle_range: ( + start: 0.9, + end: 1.1, + ), + )), + size: 1.0, + sound: EnemyFireBlast, + ), + ), + ( + reload_time: 1.6, + initial_time: 2.4, + fire_mode: Automatic, + capacity: 1, + projectile_data: ( + ammunition: Bullet(Enemy), + damage: 10, + position: Local((28.28427, -28.28427)), + speed: 300.0, + direction: 5.49779, + despawn_time: 0.3, + count: 1, + spread_pattern: Random(( + speed_range: ( + start: 0.75, + end: 1.25, + ), + angle_range: ( + start: 0.9, + end: 1.1, + ), + )), + size: 1.0, + sound: EnemyFireBlast, + ), + ), + ]), ), Ally(Hauler3): ( mob_type: Ally(Hauler3), @@ -743,7 +1383,7 @@ alpha: 1.0, ), )), - weapon: Some(( + weapons: Some([( reload_time: 3.0, initial_time: 1.0, fire_mode: Automatic, @@ -764,7 +1404,7 @@ size: 1.0, sound: EnemyFireBlast, ), - )), + )]), ), Enemy(StraferLeft): ( mob_type: Enemy(StraferLeft), @@ -806,7 +1446,7 @@ alpha: 1.0, ), )), - weapon: Some(( + weapons: Some([( reload_time: 3.0, initial_time: 1.0, fire_mode: Automatic, @@ -827,7 +1467,7 @@ size: 1.0, sound: EnemyFireBlast, ), - )), + )]), ), Neutral(MoneyAsteroid): ( mob_type: Neutral(MoneyAsteroid), @@ -835,6 +1475,7 @@ mob_behaviors: [DealDamageToPlayerOnImpact, ReceiveDamageOnImpact, DieAtZeroHealth], acceleration: (0.0, 2.0), deceleration: (2.0, 1.0), + can_rotate: true, speed: (0.0, 75.0), collision_damage: 7, z_level: 4.0, diff --git a/assets/data/premade_levels.ron b/assets/data/premade_levels.ron index 83cef845..21488e75 100644 --- a/assets/data/premade_levels.ron +++ b/assets/data/premade_levels.ron @@ -1,5 +1,42 @@ ( levels_data: { + "boss_test": ( + name: "Boss Test", + objective: Some(Defense(( + defense: 100, + max_defense: 100, + ))), + phases: [ + ( + intro_text: Some("Destroy the command ship!"), + phase_type: Boss( + mob_type: Enemy(MechaSaucetron), + position: (0.0, 600.0), + spawn_timer: ( + mode: Once, + duration: ( + secs: 5, + nanos: 0, + ), + stopwatch: ( + elapsed: ( + secs: 0, + nanos: 0, + ), + paused: false, + ), + finished: false, + times_finished_this_tick: 0, + ), + ), + bg_music_transition: Some(( + loop_from: Some(9.615), + bg_music_type: Some(Boss), + fade_out: Some(8.0), + )), + ) + ], + ), "test_level_1": ( name: "Test Level I", objective: Some(Defense(( @@ -8,7 +45,7 @@ ))), phases: [ ( - intro_text: Some("Decimate the invaders!"), + intro_text: Some("Destroy the invaders!"), phase_type: FormationSpawn( phase_timer: ( mode: Once, @@ -106,7 +143,7 @@ finished: false, times_finished_this_tick: 0, ), - formation_pool: "medium", + formation_pool: "easy", ), ), ( @@ -163,7 +200,7 @@ finished: false, times_finished_this_tick: 0, ), - formation_pool: "hard", + formation_pool: "medium", ), ), @@ -190,7 +227,7 @@ ( intro_text: Some("Destroy the command ship!"), phase_type: Boss( - mob_type: Enemy(Repeater), + mob_type: Enemy(Ferritharax), position: (0.0, 600.0), spawn_timer: ( mode: Once, @@ -225,7 +262,7 @@ ))), phases: [ ( - intro_text: Some("Decimate the invaders!"), + intro_text: Some("Destroy the invaders!"), phase_type: FormationSpawn( phase_timer: ( mode: Once, @@ -259,7 +296,7 @@ finished: false, times_finished_this_tick: 0, ), - formation_pool: "easy", + formation_pool: "medium", ), bg_music_transition: Some(( loop_from: Some(0.0), @@ -379,7 +416,7 @@ finished: false, times_finished_this_tick: 0, ), - formation_pool: "hard", + formation_pool: "medium", ), ), @@ -406,7 +443,7 @@ ( intro_text: Some("Destroy the command ship!"), phase_type: Boss( - mob_type: Enemy(Repeater), + mob_type: Enemy(MechaFerritharax), position: (0.0, 600.0), spawn_timer: ( mode: Once, @@ -441,7 +478,7 @@ ))), phases: [ ( - intro_text: Some("Decimate the invaders!"), + intro_text: Some("Harvest the Asteroids!"), phase_type: FormationSpawn( phase_timer: ( mode: Once, @@ -475,7 +512,71 @@ finished: false, times_finished_this_tick: 0, ), - formation_pool: "easy", + formation_pool: "asteroids", + ), + bg_music_transition: Some(( + loop_from: Some(0.0), + bg_music_type: Some(Game), + fade_out: Some(2.0), + fade_in: Some(2.0), + )), + ), + ( + phase_type: Break( + phase_timer: ( + mode: Once, + duration: ( + secs: 9, + nanos: 0, + ), + stopwatch: ( + elapsed: ( + secs: 0, + nanos: 0, + ), + paused: false, + ), + finished: false, + times_finished_this_tick: 0, + ), + ), + ), + ( + intro_text: Some("Destroy the invaders!"), + phase_type: FormationSpawn( + phase_timer: ( + mode: Once, + duration: ( + secs: 20, + nanos: 0, + ), + stopwatch: ( + elapsed: ( + secs: 0, + nanos: 0, + ), + paused: false, + ), + finished: false, + times_finished_this_tick: 0, + ), + spawn_timer: ( + mode: Once, + duration: ( + secs: 1, + nanos: 0, + ), + stopwatch: ( + elapsed: ( + secs: 0, + nanos: 0, + ), + paused: false, + ), + finished: false, + times_finished_this_tick: 0, + ), + formation_pool: "hard", ), bg_music_transition: Some(( loop_from: Some(0.0), @@ -538,7 +639,7 @@ finished: false, times_finished_this_tick: 0, ), - formation_pool: "medium", + formation_pool: "hard", ), ), ( @@ -622,7 +723,7 @@ ( intro_text: Some("Destroy the command ship!"), phase_type: Boss( - mob_type: Enemy(Repeater), + mob_type: Enemy(MechaSaucetron), position: (0.0, 600.0), spawn_timer: ( mode: Once, @@ -890,7 +991,7 @@ finished: false, times_finished_this_tick: 0, ), - formation_pool: "medium", + formation_pool: "test", ), ), ], diff --git a/assets/data/premade_runs.ron b/assets/data/premade_runs.ron index 947c3463..b5f26a49 100644 --- a/assets/data/premade_runs.ron +++ b/assets/data/premade_runs.ron @@ -1,5 +1,6 @@ ( runs: { + //"test_run": ["test"], "test_run": ["test_level_1", "test_level_2", "test_level_3"], } ) diff --git a/assets/mob_assets.assets.ron b/assets/mob_assets.assets.ron index e87f757b..2d5bbced 100644 --- a/assets/mob_assets.assets.ron +++ b/assets/mob_assets.assets.ron @@ -260,5 +260,150 @@ "repeater.left_claw.image": File ( path: "texture/repeater_left_claw_spritesheet.png" ), + "mecha_ferritharax.head.layout": TextureAtlasLayout ( + tile_size_x: 42., + tile_size_y: 48., + columns: 3, + rows: 1, + ), + "mecha_ferritharax.head.image": File ( + path: "texture/mecha_ferritharax_head.png" + ), + "mecha_ferritharax.body.layout": TextureAtlasLayout ( + tile_size_x: 80., + tile_size_y: 43., + columns: 3, + rows: 1, + ), + "mecha_ferritharax.body.image": File ( + path: "texture/mecha_ferritharax_body.png" + ), + "mecha_ferritharax.right_shoulder.layout": TextureAtlasLayout ( + tile_size_x: 62., + tile_size_y: 66., + columns: 3, + rows: 1, + ), + "mecha_ferritharax.right_shoulder.image": File ( + path: "texture/mecha_ferritharax_right_shoulder.png" + ), + "mecha_ferritharax.left_shoulder.layout": TextureAtlasLayout ( + tile_size_x: 62., + tile_size_y: 66., + columns: 3, + rows: 1, + ), + "mecha_ferritharax.left_shoulder.image": File ( + path: "texture/mecha_ferritharax_left_shoulder.png" + ), + "mecha_ferritharax.right_arm.layout": TextureAtlasLayout ( + tile_size_x: 40., + tile_size_y: 57., + columns: 3, + rows: 1, + ), + "mecha_ferritharax.right_arm.image": File ( + path: "texture/mecha_ferritharax_right_arm.png" + ), + "mecha_ferritharax.left_arm.layout": TextureAtlasLayout ( + tile_size_x: 40., + tile_size_y: 57., + columns: 3, + rows: 1, + ), + "mecha_ferritharax.left_arm.image": File ( + path: "texture/mecha_ferritharax_left_arm.png" + ), + "mecha_ferritharax.right_claw.layout": TextureAtlasLayout ( + tile_size_x: 44., + tile_size_y: 39., + columns: 3, + rows: 1, + ), + "mecha_ferritharax.right_claw.image": File ( + path: "texture/mecha_ferritharax_right_claw.png" + ), + "mecha_ferritharax.left_claw.layout": TextureAtlasLayout ( + tile_size_x: 44., + tile_size_y: 39., + columns: 3, + rows: 1, + ), + "mecha_ferritharax.left_claw.image": File ( + path: "texture/mecha_ferritharax_left_claw.png" + ), + "mecha_saucetron.head.layout": TextureAtlasLayout ( + tile_size_x: 46., + tile_size_y: 50., + columns: 3, + rows: 1, + ), + "mecha_saucetron.head.image": File ( + path: "texture/mecha_saucetron_head.png" + ), + "mecha_saucetron.body.layout": TextureAtlasLayout ( + tile_size_x: 80., + tile_size_y: 43., + columns: 3, + rows: 1, + ), + "mecha_saucetron.body.image": File ( + path: "texture/mecha_saucetron_body.png" + ), + "mecha_saucetron.right_shoulder.layout": TextureAtlasLayout ( + tile_size_x: 62., + tile_size_y: 66., + columns: 3, + rows: 1, + ), + "mecha_saucetron.right_shoulder.image": File ( + path: "texture/mecha_saucetron_right_shoulder.png" + ), + "mecha_saucetron.left_shoulder.layout": TextureAtlasLayout ( + tile_size_x: 62., + tile_size_y: 66., + columns: 3, + rows: 1, + ), + "mecha_saucetron.left_shoulder.image": File ( + path: "texture/mecha_saucetron_left_shoulder.png" + ), + "mecha_saucetron.right_arm.layout": TextureAtlasLayout ( + tile_size_x: 40., + tile_size_y: 57., + columns: 3, + rows: 1, + ), + "mecha_saucetron.right_arm.image": File ( + path: "texture/mecha_saucetron_right_arm.png" + ), + "mecha_saucetron.left_arm.layout": TextureAtlasLayout ( + tile_size_x: 40., + tile_size_y: 57., + columns: 3, + rows: 1, + ), + "mecha_saucetron.left_arm.image": File ( + path: "texture/mecha_saucetron_left_arm.png" + ), + "mecha_saucetron.right_claw.layout": TextureAtlasLayout ( + tile_size_x: 44., + tile_size_y: 39., + columns: 3, + rows: 1, + ), + "mecha_saucetron.right_claw.image": File ( + path: "texture/mecha_saucetron_right_claw.png" + ), + "mecha_saucetron.left_claw.layout": TextureAtlasLayout ( + tile_size_x: 44., + tile_size_y: 39., + columns: 3, + rows: 1, + ), + "mecha_saucetron.left_claw.image": File ( + path: "texture/mecha_saucetron_left_claw.png" + ), + }) diff --git a/crates/thetawave_interface/src/spawnable.rs b/crates/thetawave_interface/src/spawnable.rs index b4f47f73..3424865a 100644 --- a/crates/thetawave_interface/src/spawnable.rs +++ b/crates/thetawave_interface/src/spawnable.rs @@ -17,7 +17,9 @@ pub enum EnemyMobType { Missile, CrustlingRight, CrustlingLeft, - Repeater, + Ferritharax, + MechaFerritharax, + MechaSaucetron, Shelly, } @@ -81,7 +83,9 @@ impl MobType { EnemyMobType::MissileLauncher => "Missile Launcher", EnemyMobType::Missile => "Missile", EnemyMobType::CrustlingRight | EnemyMobType::CrustlingLeft => "Crustling", - EnemyMobType::Repeater => "Repeater", + EnemyMobType::Ferritharax => "Ferritharax", + EnemyMobType::MechaFerritharax => "Mecha-Ferritharax", + EnemyMobType::MechaSaucetron => "Mecha-Saucetron", EnemyMobType::Shelly => "Shelly", }, MobType::Ally(ally_type) => match ally_type { @@ -125,13 +129,27 @@ pub enum EnemyMobSegmentType { CrustlingTentacle1, CrustlingTentacle2, CrustlingTentacle3, - RepeaterBody, - RepeaterRightShoulder, - RepeaterLeftShoulder, - RepeaterRightArm, - RepeaterLeftArm, - RepeaterRightClaw, - RepeaterLeftClaw, + FerritharaxBody, + FerritharaxRightShoulder, + FerritharaxLeftShoulder, + FerritharaxRightArm, + FerritharaxLeftArm, + FerritharaxRightClaw, + FerritharaxLeftClaw, + MechaFerritharaxBody, + MechaFerritharaxRightShoulder, + MechaFerritharaxLeftShoulder, + MechaFerritharaxRightArm, + MechaFerritharaxLeftArm, + MechaFerritharaxRightClaw, + MechaFerritharaxLeftClaw, + MechaSaucetronBody, + MechaSaucetronRightShoulder, + MechaSaucetronLeftShoulder, + MechaSaucetronRightArm, + MechaSaucetronLeftArm, + MechaSaucetronRightClaw, + MechaSaucetronLeftClaw, } /// Type that encompasses all spawnable neutral mobs diff --git a/crates/thetawave_interface/src/weapon.rs b/crates/thetawave_interface/src/weapon.rs index 8dbaafca..db5e2143 100644 --- a/crates/thetawave_interface/src/weapon.rs +++ b/crates/thetawave_interface/src/weapon.rs @@ -79,7 +79,37 @@ pub struct WeaponProjectileData { /// Describes how projectiles are spawned #[derive(Component, Clone)] -pub struct WeaponComponent { +pub struct WeaponsComponent { + pub weapons: Vec, +} + +impl From> for WeaponsComponent { + fn from(value: Vec) -> Self { + let weapons = value + .iter() + .map(|weapon_data| Weapon::from(weapon_data)) + .collect(); + + WeaponsComponent { weapons } + } +} + +impl WeaponsComponent { + pub fn enable_all(&mut self) { + self.weapons + .iter_mut() + .for_each(|weapon| weapon.is_enabled = true); + } + + pub fn disable_all(&mut self) { + self.weapons + .iter_mut() + .for_each(|weapon| weapon.is_enabled = false); + } +} + +#[derive(Component, Clone)] +pub struct Weapon { /// Base reload time of the weapon pub base_reload_time: f32, /// Tracks time until next projectile(s) can be spawned @@ -96,26 +126,26 @@ pub struct WeaponComponent { pub projectile_data: WeaponProjectileData, } -impl From for WeaponComponent { - fn from(value: WeaponData) -> Self { - WeaponComponent { +impl From<&WeaponData> for Weapon { + fn from(value: &WeaponData) -> Self { + Weapon { base_reload_time: value.reload_time, reload_timer: Timer::from_seconds(value.reload_time, TimerMode::Once), initial_timer: Timer::from_seconds(value.initial_time, TimerMode::Once), - fire_mode: value.fire_mode, + fire_mode: value.fire_mode.clone(), capacity: value.capacity, - projectile_data: value.projectile_data, + projectile_data: value.projectile_data.clone(), is_enabled: true, } } } -impl WeaponComponent { +impl Weapon { pub fn enable(&mut self) { self.is_enabled = true; } - pub fn disable(&mut self) { + pub fn disable_all(&mut self) { self.is_enabled = false; } /// Returns ture if the weapon can be fired (<=> is currently reloaded) diff --git a/src/arena/barrier.rs b/src/arena/barrier.rs index 3d073238..ae85284e 100644 --- a/src/arena/barrier.rs +++ b/src/arena/barrier.rs @@ -24,8 +24,11 @@ pub(super) fn spawn_barriers_system( spawn_spawnables_pass_barrier(&mut commands, Vec2::new(0.0, -360.0), 1000.0, 30.0); // spawn vertical barriers at right and left of arena - spawn_barrier(&mut commands, Vec2::new(500.0, 0.0), 30.0, 3000.0); - spawn_barrier(&mut commands, Vec2::new(-500.0, 0.0), 30.0, 3000.0); + spawn_barrier(&mut commands, Vec2::new(500.0, 0.0), 30.0, 10000.0); + spawn_barrier(&mut commands, Vec2::new(-500.0, 0.0), 30.0, 10000.0); + + // spawn horizontal barriers + spawn_barrier(&mut commands, Vec2::new(0.0, 2250.0), 3000.0, 30.0); // spawn barrier glow effect spawn_effect.send(SpawnEffectEvent { diff --git a/src/arena/gate.rs b/src/arena/gate.rs index 130ce22b..10c9c5a1 100644 --- a/src/arena/gate.rs +++ b/src/arena/gate.rs @@ -10,7 +10,7 @@ pub(super) struct DespawnGateComponent; /// Spawn gates for despawning entities pub(super) fn spawn_despawn_gates_system(mut commands: Commands) { - spawn_despawn_gate(&mut commands, Vec2::new(0.0, -500.0), 1000.0, 50.0); + spawn_despawn_gate(&mut commands, Vec2::new(0.0, -600.0), 1000.0, 50.0); } /// Spawn a despawn gate diff --git a/src/assets/mob.rs b/src/assets/mob.rs index 81c0c1eb..7ccdb5f2 100644 --- a/src/assets/mob.rs +++ b/src/assets/mob.rs @@ -126,6 +126,70 @@ pub struct MobAssets { pub repeater_left_claw_layout: Handle, #[asset(key = "repeater.left_claw.image")] pub repeater_left_claw_image: Handle, + #[asset(key = "mecha_ferritharax.head.layout")] + pub mecha_ferritharax_head_layout: Handle, + #[asset(key = "mecha_ferritharax.head.image")] + pub mecha_ferritharax_head_image: Handle, + #[asset(key = "mecha_ferritharax.body.layout")] + pub mecha_ferritharax_body_layout: Handle, + #[asset(key = "mecha_ferritharax.body.image")] + pub mecha_ferritharax_body_image: Handle, + #[asset(key = "mecha_ferritharax.right_shoulder.layout")] + pub mecha_ferritharax_right_shoulder_layout: Handle, + #[asset(key = "mecha_ferritharax.right_shoulder.image")] + pub mecha_ferritharax_right_shoulder_image: Handle, + #[asset(key = "mecha_ferritharax.left_shoulder.layout")] + pub mecha_ferritharax_left_shoulder_layout: Handle, + #[asset(key = "mecha_ferritharax.left_shoulder.image")] + pub mecha_ferritharax_left_shoulder_image: Handle, + #[asset(key = "mecha_ferritharax.right_arm.layout")] + pub mecha_ferritharax_right_arm_layout: Handle, + #[asset(key = "mecha_ferritharax.right_arm.image")] + pub mecha_ferritharax_right_arm_image: Handle, + #[asset(key = "mecha_ferritharax.left_arm.layout")] + pub mecha_ferritharax_left_arm_layout: Handle, + #[asset(key = "mecha_ferritharax.left_arm.image")] + pub mecha_ferritharax_left_arm_image: Handle, + #[asset(key = "mecha_ferritharax.right_claw.layout")] + pub mecha_ferritharax_right_claw_layout: Handle, + #[asset(key = "mecha_ferritharax.right_claw.image")] + pub mecha_ferritharax_right_claw_image: Handle, + #[asset(key = "mecha_ferritharax.left_claw.layout")] + pub mecha_ferritharax_left_claw_layout: Handle, + #[asset(key = "mecha_ferritharax.left_claw.image")] + pub mecha_ferritharax_left_claw_image: Handle, + #[asset(key = "mecha_saucetron.head.layout")] + pub mecha_saucetron_head_layout: Handle, + #[asset(key = "mecha_saucetron.head.image")] + pub mecha_saucetron_head_image: Handle, + #[asset(key = "mecha_saucetron.body.layout")] + pub mecha_saucetron_body_layout: Handle, + #[asset(key = "mecha_saucetron.body.image")] + pub mecha_saucetron_body_image: Handle, + #[asset(key = "mecha_saucetron.right_shoulder.layout")] + pub mecha_saucetron_right_shoulder_layout: Handle, + #[asset(key = "mecha_saucetron.right_shoulder.image")] + pub mecha_saucetron_right_shoulder_image: Handle, + #[asset(key = "mecha_saucetron.left_shoulder.layout")] + pub mecha_saucetron_left_shoulder_layout: Handle, + #[asset(key = "mecha_saucetron.left_shoulder.image")] + pub mecha_saucetron_left_shoulder_image: Handle, + #[asset(key = "mecha_saucetron.right_arm.layout")] + pub mecha_saucetron_right_arm_layout: Handle, + #[asset(key = "mecha_saucetron.right_arm.image")] + pub mecha_saucetron_right_arm_image: Handle, + #[asset(key = "mecha_saucetron.left_arm.layout")] + pub mecha_saucetron_left_arm_layout: Handle, + #[asset(key = "mecha_saucetron.left_arm.image")] + pub mecha_saucetron_left_arm_image: Handle, + #[asset(key = "mecha_saucetron.right_claw.layout")] + pub mecha_saucetron_right_claw_layout: Handle, + #[asset(key = "mecha_saucetron.right_claw.image")] + pub mecha_saucetron_right_claw_image: Handle, + #[asset(key = "mecha_saucetron.left_claw.layout")] + pub mecha_saucetron_left_claw_layout: Handle, + #[asset(key = "mecha_saucetron.left_claw.image")] + pub mecha_saucetron_left_claw_image: Handle, } impl MobAssets { @@ -142,7 +206,9 @@ impl MobAssets { EnemyMobType::CrustlingRight | EnemyMobType::CrustlingLeft => { self.crustling_head_layout.clone() } - EnemyMobType::Repeater => self.repeater_head_layout.clone(), + EnemyMobType::Ferritharax => self.repeater_head_layout.clone(), + EnemyMobType::MechaFerritharax => self.mecha_ferritharax_head_layout.clone(), + EnemyMobType::MechaSaucetron => self.mecha_saucetron_head_layout.clone(), EnemyMobType::Shelly => self.shelly_layout.clone(), }, MobType::Ally(ally_type) => match ally_type { @@ -170,7 +236,9 @@ impl MobAssets { EnemyMobType::CrustlingRight | EnemyMobType::CrustlingLeft => { self.crustling_head_image.clone() } - EnemyMobType::Repeater => self.repeater_head_image.clone(), + EnemyMobType::Ferritharax => self.repeater_head_image.clone(), + EnemyMobType::MechaFerritharax => self.mecha_ferritharax_head_image.clone(), + EnemyMobType::MechaSaucetron => self.mecha_saucetron_head_image.clone(), EnemyMobType::Shelly => self.shelly_image.clone(), }, MobType::Ally(ally_type) => match ally_type { @@ -199,17 +267,59 @@ impl MobAssets { EnemyMobSegmentType::CrustlingTentacle1 => self.crustling_tentacle1_layout.clone(), EnemyMobSegmentType::CrustlingTentacle2 => self.crustling_tentacle2_layout.clone(), EnemyMobSegmentType::CrustlingTentacle3 => self.crustling_tentacle3_layout.clone(), - EnemyMobSegmentType::RepeaterBody => self.repeater_body_layout.clone(), - EnemyMobSegmentType::RepeaterRightShoulder => { + EnemyMobSegmentType::FerritharaxBody => self.repeater_body_layout.clone(), + EnemyMobSegmentType::FerritharaxRightShoulder => { self.repeater_right_shoulder_layout.clone() } - EnemyMobSegmentType::RepeaterLeftShoulder => { + EnemyMobSegmentType::FerritharaxLeftShoulder => { self.repeater_left_shoulder_layout.clone() } - EnemyMobSegmentType::RepeaterRightArm => self.repeater_right_arm_layout.clone(), - EnemyMobSegmentType::RepeaterLeftArm => self.repeater_left_arm_layout.clone(), - EnemyMobSegmentType::RepeaterRightClaw => self.repeater_right_claw_layout.clone(), - EnemyMobSegmentType::RepeaterLeftClaw => self.repeater_left_claw_layout.clone(), + EnemyMobSegmentType::FerritharaxRightArm => self.repeater_right_arm_layout.clone(), + EnemyMobSegmentType::FerritharaxLeftArm => self.repeater_left_arm_layout.clone(), + EnemyMobSegmentType::FerritharaxRightClaw => { + self.repeater_right_claw_layout.clone() + } + EnemyMobSegmentType::FerritharaxLeftClaw => self.repeater_left_claw_layout.clone(), + EnemyMobSegmentType::MechaFerritharaxBody => { + self.mecha_ferritharax_body_layout.clone() + } + EnemyMobSegmentType::MechaFerritharaxRightShoulder => { + self.mecha_ferritharax_right_shoulder_layout.clone() + } + EnemyMobSegmentType::MechaFerritharaxLeftShoulder => { + self.mecha_ferritharax_left_shoulder_layout.clone() + } + EnemyMobSegmentType::MechaFerritharaxRightArm => { + self.mecha_ferritharax_right_arm_layout.clone() + } + EnemyMobSegmentType::MechaFerritharaxLeftArm => { + self.mecha_ferritharax_left_arm_layout.clone() + } + EnemyMobSegmentType::MechaFerritharaxRightClaw => { + self.mecha_ferritharax_right_claw_layout.clone() + } + EnemyMobSegmentType::MechaFerritharaxLeftClaw => { + self.mecha_ferritharax_left_claw_layout.clone() + } + EnemyMobSegmentType::MechaSaucetronBody => self.mecha_saucetron_body_layout.clone(), + EnemyMobSegmentType::MechaSaucetronRightShoulder => { + self.mecha_saucetron_right_shoulder_layout.clone() + } + EnemyMobSegmentType::MechaSaucetronLeftShoulder => { + self.mecha_saucetron_left_shoulder_layout.clone() + } + EnemyMobSegmentType::MechaSaucetronRightArm => { + self.mecha_saucetron_right_arm_layout.clone() + } + EnemyMobSegmentType::MechaSaucetronLeftArm => { + self.mecha_saucetron_left_arm_layout.clone() + } + EnemyMobSegmentType::MechaSaucetronRightClaw => { + self.mecha_saucetron_right_claw_layout.clone() + } + EnemyMobSegmentType::MechaSaucetronLeftClaw => { + self.mecha_saucetron_left_claw_layout.clone() + } }, } } @@ -225,17 +335,57 @@ impl MobAssets { EnemyMobSegmentType::CrustlingTentacle1 => self.crustling_tentacle1_image.clone(), EnemyMobSegmentType::CrustlingTentacle2 => self.crustling_tentacle2_image.clone(), EnemyMobSegmentType::CrustlingTentacle3 => self.crustling_tentacle3_image.clone(), - EnemyMobSegmentType::RepeaterBody => self.repeater_body_image.clone(), - EnemyMobSegmentType::RepeaterRightShoulder => { + EnemyMobSegmentType::FerritharaxBody => self.repeater_body_image.clone(), + EnemyMobSegmentType::FerritharaxRightShoulder => { self.repeater_right_shoulder_image.clone() } - EnemyMobSegmentType::RepeaterLeftShoulder => { + EnemyMobSegmentType::FerritharaxLeftShoulder => { self.repeater_left_shoulder_image.clone() } - EnemyMobSegmentType::RepeaterRightArm => self.repeater_right_arm_image.clone(), - EnemyMobSegmentType::RepeaterLeftArm => self.repeater_left_arm_image.clone(), - EnemyMobSegmentType::RepeaterRightClaw => self.repeater_right_claw_image.clone(), - EnemyMobSegmentType::RepeaterLeftClaw => self.repeater_left_claw_image.clone(), + EnemyMobSegmentType::FerritharaxRightArm => self.repeater_right_arm_image.clone(), + EnemyMobSegmentType::FerritharaxLeftArm => self.repeater_left_arm_image.clone(), + EnemyMobSegmentType::FerritharaxRightClaw => self.repeater_right_claw_image.clone(), + EnemyMobSegmentType::FerritharaxLeftClaw => self.repeater_left_claw_image.clone(), + EnemyMobSegmentType::MechaFerritharaxBody => { + self.mecha_ferritharax_body_image.clone() + } + EnemyMobSegmentType::MechaFerritharaxRightShoulder => { + self.mecha_ferritharax_right_shoulder_image.clone() + } + EnemyMobSegmentType::MechaFerritharaxLeftShoulder => { + self.mecha_ferritharax_left_shoulder_image.clone() + } + EnemyMobSegmentType::MechaFerritharaxRightArm => { + self.mecha_ferritharax_right_arm_image.clone() + } + EnemyMobSegmentType::MechaFerritharaxLeftArm => { + self.mecha_ferritharax_left_arm_image.clone() + } + EnemyMobSegmentType::MechaFerritharaxRightClaw => { + self.mecha_ferritharax_right_claw_image.clone() + } + EnemyMobSegmentType::MechaFerritharaxLeftClaw => { + self.mecha_ferritharax_left_claw_image.clone() + } + EnemyMobSegmentType::MechaSaucetronBody => self.mecha_saucetron_body_image.clone(), + EnemyMobSegmentType::MechaSaucetronRightShoulder => { + self.mecha_saucetron_right_shoulder_image.clone() + } + EnemyMobSegmentType::MechaSaucetronLeftShoulder => { + self.mecha_saucetron_left_shoulder_image.clone() + } + EnemyMobSegmentType::MechaSaucetronRightArm => { + self.mecha_saucetron_right_arm_image.clone() + } + EnemyMobSegmentType::MechaSaucetronLeftArm => { + self.mecha_saucetron_left_arm_image.clone() + } + EnemyMobSegmentType::MechaSaucetronRightClaw => { + self.mecha_saucetron_right_claw_image.clone() + } + EnemyMobSegmentType::MechaSaucetronLeftClaw => { + self.mecha_saucetron_left_claw_image.clone() + } }, } } @@ -256,7 +406,9 @@ impl MobAssets { } EnemyMobType::Missile => Some(self.missile_thruster_layout.clone()), EnemyMobType::CrustlingRight | EnemyMobType::CrustlingLeft => None, - EnemyMobType::Repeater => None, + EnemyMobType::Ferritharax => None, + EnemyMobType::MechaFerritharax => None, + EnemyMobType::MechaSaucetron => None, EnemyMobType::Shelly => None, }, MobType::Ally(ally_type) => match ally_type { @@ -282,7 +434,9 @@ impl MobAssets { EnemyMobType::MissileLauncher => Some(self.missile_launcher_thruster_image.clone()), EnemyMobType::Missile => Some(self.missile_thruster_image.clone()), EnemyMobType::CrustlingRight | EnemyMobType::CrustlingLeft => None, - EnemyMobType::Repeater => None, + EnemyMobType::Ferritharax => None, + EnemyMobType::MechaFerritharax => None, + EnemyMobType::MechaSaucetron => None, EnemyMobType::Shelly => None, }, MobType::Ally(ally_type) => match ally_type { diff --git a/src/player/systems/movement.rs b/src/player/systems/movement.rs index 8c4f6942..b2ca5dbf 100644 --- a/src/player/systems/movement.rs +++ b/src/player/systems/movement.rs @@ -70,9 +70,9 @@ pub(in crate::player) fn player_tilt_system( for (vel, mut player_trans) in player_info.iter_mut() { let rotation_amount = -vel.linvel.x.atan2(vel.linvel.y.abs()) / PI; - player_trans.rotation.z += rotation_amount * 0.05; + player_trans.rotation.z += rotation_amount * 0.01; player_trans.rotation.z *= 0.9; - player_trans.rotation.z = player_trans.rotation.z.clamp(-0.25, 0.25); + player_trans.rotation.z = player_trans.rotation.z.clamp(-0.03, 0.02); if player_trans.rotation.z.abs() < 0.001 { player_trans.rotation.z = 0.0; } diff --git a/src/spawnable/behavior_sequence.rs b/src/spawnable/behavior_sequence.rs index 66ad136a..f1b0d30d 100644 --- a/src/spawnable/behavior_sequence.rs +++ b/src/spawnable/behavior_sequence.rs @@ -27,7 +27,9 @@ pub struct BehaviorSequenceResource { #[derive(Deserialize, Debug, Hash, PartialEq, Eq, Clone)] pub enum MobBehaviorSequenceType { - Repeater, + Ferritharax, + MechaFerritharax, + MechaSaucetron, } pub fn mob_behavior_sequence_tracker_system( diff --git a/src/spawnable/mob/behavior.rs b/src/spawnable/mob/behavior.rs index 34b584eb..f2fded8d 100644 --- a/src/spawnable/mob/behavior.rs +++ b/src/spawnable/mob/behavior.rs @@ -27,8 +27,8 @@ pub enum MobBehavior { #[derive(Deserialize, Hash, PartialEq, Eq, Clone)] pub enum MobSegmentControlBehavior { - RepeaterProtectHead, - RepeaterAttack, + FerritharaxProtectHead, + FerritharaxAttack, } #[allow(clippy::too_many_arguments)] diff --git a/src/spawnable/mob/mob_segment/behavior.rs b/src/spawnable/mob/mob_segment/behavior.rs index a99a8d4c..66dc0658 100644 --- a/src/spawnable/mob/mob_segment/behavior.rs +++ b/src/spawnable/mob/mob_segment/behavior.rs @@ -9,6 +9,7 @@ use thetawave_interface::{ spawnable::{ EffectType, MobDestroyedEvent, MobSegmentDestroyedEvent, SpawnItemEvent, SpawnPosition, }, + weapon::WeaponsComponent, }; use crate::{ @@ -29,20 +30,21 @@ pub enum MobSegmentBehavior { ReceiveDamageOnImpact, DieAtZeroHealth, RandomRotation(RandomRotationData), - RepeaterProtectHead(RepeaterSegmentProtectHeadData), // takes in angle to protect head - RepeaterAttack(RepeaterSegmentAttackData), + FerritharaxProtectHead(FerritharaxSegmentProtectHeadData), // takes in angle to protect head + FerritharaxAttack(FerritharaxSegmentAttackData), SpawnMob(String), + DisableWeapons, } #[derive(Deserialize, Clone)] -pub struct RepeaterSegmentProtectHeadData { +pub struct FerritharaxSegmentProtectHeadData { pub angle: f32, pub damping: f32, pub stiffness: f32, } #[derive(Deserialize, Clone)] -pub struct RepeaterSegmentAttackData { +pub struct FerritharaxSegmentAttackData { pub angle: f32, pub damping: f32, pub stiffness: f32, @@ -67,6 +69,7 @@ pub fn mob_segment_execute_behavior_system( &Transform, &mut ImpulseJoint, &HealthComponent, + Option<&mut WeaponsComponent>, )>, mut spawn_effect_event_writer: EventWriter, player_query: Query<(Entity, &PlayerIncomingDamageComponent)>, @@ -85,8 +88,14 @@ pub fn mob_segment_execute_behavior_system( collision_events_vec.push(collision_event); } - for (entity, mut mob_segment_component, mob_segment_transform, mut joint, mob_seg_health) in - mob_segment_query.iter_mut() + for ( + entity, + mut mob_segment_component, + mob_segment_transform, + mut joint, + mob_seg_health, + mut maybe_weapon, + ) in mob_segment_query.iter_mut() { let behaviors = mob_segment_component.behaviors.clone(); for behavior in behaviors { @@ -156,7 +165,7 @@ pub fn mob_segment_execute_behavior_system( ); } - MobSegmentBehavior::RepeaterProtectHead(data) => { + MobSegmentBehavior::FerritharaxProtectHead(data) => { joint.data.set_motor_position( JointAxis::AngX, data.angle, @@ -165,7 +174,7 @@ pub fn mob_segment_execute_behavior_system( ); } - MobSegmentBehavior::RepeaterAttack(data) => { + MobSegmentBehavior::FerritharaxAttack(data) => { joint.data.set_motor_position( JointAxis::AngX, data.angle, @@ -205,6 +214,12 @@ pub fn mob_segment_execute_behavior_system( } } } + + MobSegmentBehavior::DisableWeapons => { + if let Some(ref mut weapon_component) = maybe_weapon { + weapon_component.disable_all(); + } + } } } } diff --git a/src/spawnable/mob/mob_segment/mod.rs b/src/spawnable/mob/mob_segment/mod.rs index 382b4481..2d77a4fe 100644 --- a/src/spawnable/mob/mob_segment/mod.rs +++ b/src/spawnable/mob/mob_segment/mod.rs @@ -8,6 +8,7 @@ use thetawave_interface::{ objective::DefenseInteraction, spawnable::{MobSegmentType, SpawnableType}, states::GameCleanup, + weapon::{WeaponData, WeaponsComponent}, }; use crate::collision::{ @@ -96,6 +97,14 @@ pub struct MobSegmentData { pub behaviors: Vec, pub disconnected_behaviors: Option>, pub mob_spawners: Option>>, + #[serde(default)] + pub weapons: Option>, + #[serde(default = "default_mob_segment_density")] + pub density: f32, +} + +fn default_mob_segment_density() -> f32 { + 1.0 } impl From<&MobSegmentData> for HealthComponent { @@ -103,6 +112,13 @@ impl From<&MobSegmentData> for HealthComponent { HealthComponent::new(mob_segment_data.health, 0, 0.0) } } + +impl MobSegmentData { + pub fn get_weapon_component(&self) -> Option { + self.weapons.clone().map(WeaponsComponent::from) + } +} + /// Spawn a mob segment #[allow(clippy::too_many_arguments)] pub fn spawn_mob_segment( @@ -172,10 +188,16 @@ pub fn spawn_mob_segment( .insert(SpawnableComponent::new(SpawnableType::MobSegment( mob_segment_type.clone(), ))) + .insert(ColliderMassProperties::Density(mob_segment_data.density)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(GameCleanup) + .insert(Velocity::default()) .insert(Name::new(mob_segment_data.mob_segment_type.to_string())); + if let Some(weapon_component) = mob_segment_data.get_weapon_component() { + mob_segment.insert(weapon_component); + } + let mob_segment_entity = mob_segment.id(); if let Some(mob_segment_anchor_points) = mob_segment_data.mob_segment_anchor_points.clone() { diff --git a/src/spawnable/mob/mod.rs b/src/spawnable/mob/mod.rs index 22e10805..27d441e9 100644 --- a/src/spawnable/mob/mod.rs +++ b/src/spawnable/mob/mod.rs @@ -1,7 +1,10 @@ use bevy::prelude::*; -use bevy_rapier2d::prelude::{ - ActiveEvents, CoefficientCombineRule, Collider, CollisionGroups, Friction, Group, LockedAxes, - Restitution, RevoluteJointBuilder, RigidBody, Velocity, +use bevy_rapier2d::{ + geometry::ColliderMassProperties, + prelude::{ + ActiveEvents, CoefficientCombineRule, Collider, CollisionGroups, Friction, Group, + LockedAxes, Restitution, RevoluteJointBuilder, RigidBody, Velocity, + }, }; use serde::Deserialize; use std::collections::{hash_map::Entry, HashMap}; @@ -29,7 +32,7 @@ use thetawave_interface::{ objective::DefenseInteraction, spawnable::{MobDestroyedEvent, MobSegmentType, MobType, SpawnMobEvent, SpawnPosition}, states::GameCleanup, - weapon::{WeaponComponent, WeaponData}, + weapon::{WeaponData, WeaponsComponent}, }; /// Core component for mobs @@ -197,8 +200,15 @@ pub struct MobData { pub mob_spawners: HashMap>, /// projectile spawners that the mob can use #[serde(default)] - pub weapon: Option, + pub weapons: Option>, + #[serde(default = "default_mob_density")] + pub density: f32, } + +fn default_mob_density() -> f32 { + 1.0 +} + impl From<&MobData> for HealthComponent { fn from(mob_data: &MobData) -> Self { HealthComponent::new(mob_data.health, 0, 0.0) @@ -206,8 +216,8 @@ impl From<&MobData> for HealthComponent { } impl MobData { - pub fn get_weapon_component(&self) -> Option { - self.weapon.clone().map(WeaponComponent::from) + pub fn get_weapon_component(&self) -> Option { + self.weapons.clone().map(WeaponsComponent::from) } } @@ -360,6 +370,7 @@ pub fn spawn_mob( .insert(SpawnableComponent::from(mob_data)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(GameCleanup) + .insert(ColliderMassProperties::Density(mob_data.density)) .insert(Name::new(mob_data.mob_type.to_string())); if boss { diff --git a/src/spawnable/projectile/mod.rs b/src/spawnable/projectile/mod.rs index c267e876..cfe24be5 100644 --- a/src/spawnable/projectile/mod.rs +++ b/src/spawnable/projectile/mod.rs @@ -1,4 +1,5 @@ use bevy::{ + math::{EulerRot, Mat2}, prelude::{ Commands, Component, Entity, Event, EventReader, EventWriter, Name, Quat, Res, Resource, Sprite, SpriteSheetBundle, Timer, TimerMode, Transform, Vec2, Vec3Swizzles, @@ -154,12 +155,17 @@ pub fn spawn_projectile_from_weapon( translation: match weapon_projectile_data.position { thetawave_interface::spawnable::SpawnPosition::Global(pos) => pos, thetawave_interface::spawnable::SpawnPosition::Local(pos) => { - source_transform.translation.xy() + pos + // Apply the rotation to the local position + let rotated_pos = source_transform.rotation * pos.extend(0.0); + // Convert back to Vec2 and add to the source translation + source_transform.translation.xy() + rotated_pos.xy() } } .extend(projectile_data.z_level), scale: Vec2::splat(game_parameters.sprite_scale * weapon_projectile_data.size).extend(1.0), - rotation: Quat::from_rotation_z(weapon_projectile_data.direction), + rotation: Quat::from_rotation_z( + weapon_projectile_data.direction + source_transform.rotation.z, + ), }; // Set the correct collider group for the ammunition based on the faction @@ -172,8 +178,18 @@ pub fn spawn_projectile_from_weapon( for linvel in spread_linvels { let new_initial_motion = if let Some(mut initial_motion_linvel) = initial_motion.clone().linvel { - // Convert the angle to a velocity vector - initial_motion_linvel += linvel; + let rotation = source_transform.rotation.to_euler(EulerRot::ZYX).0; // Get the z-rotation (yaw) + let cos_theta = rotation.cos(); + let sin_theta = rotation.sin(); + + // Create the rotation matrix for 2D rotation + let rotation_matrix = + Mat2::from_cols_array(&[cos_theta, sin_theta, -sin_theta, cos_theta]); + + // Apply the rotation to the linvel + let rotated_linvel = rotation_matrix * linvel; + + initial_motion_linvel += rotated_linvel; InitialMotion { linvel: Some(initial_motion_linvel), diff --git a/src/weapon/mod.rs b/src/weapon/mod.rs index c764de74..ca3fb14c 100644 --- a/src/weapon/mod.rs +++ b/src/weapon/mod.rs @@ -15,7 +15,7 @@ use bevy_rapier2d::dynamics::Velocity; use std::time::Duration; use thetawave_interface::{ states::{AppStates, GameStates}, - weapon::{FireMode, SpreadPattern, WeaponComponent, WeaponProjectileData}, + weapon::{FireMode, SpreadPattern, Weapon, WeaponProjectileData, WeaponsComponent}, }; use crate::spawnable::{FireWeaponEvent, InitialMotion}; @@ -38,7 +38,7 @@ trait WeaponExt { /// Updates the weapon's timers. Returns Some iff the weapon can be fired fn update(&mut self, delta_time: Duration) -> Option; } -impl WeaponExt for WeaponComponent { +impl WeaponExt for Weapon { fn update(&mut self, delta_time: Duration) -> Option { if self.is_enabled { // tick the initial timer if there is still time remaining @@ -64,24 +64,26 @@ impl WeaponExt for WeaponComponent { /// Update all weapons, and fire weapons with the automatic fire mode fn update_weapon_system( - mut weapon_query: Query<(Entity, &mut WeaponComponent, &Transform, &Velocity)>, + mut weapon_query: Query<(Entity, &mut WeaponsComponent, &Transform, &Velocity)>, time: Res