Skip to content

Commit 61cbd9c

Browse files
committed
spawn beam using range stat and offset position
1 parent e4505cb commit 61cbd9c

10 files changed

Lines changed: 115 additions & 21 deletions

File tree

assets/data/effects.ron

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@
4444
frame_duration: 0.1,
4545
),
4646
),
47+
EnemyBeamSpawn: (
48+
effect_type: EnemyBeamSpawn,
49+
behaviors: [FadeInAndDespawnAfterAnimation, FollowSource, SpawnProjectileOnDespawn(Beam(Enemy))],
50+
z_level: 9.0,
51+
animation: (
52+
direction: Forward,
53+
frame_duration: 0.1,
54+
),
55+
),
4756
AllyBeamDespawn: (
4857
effect_type: AllyBeamDespawn,
4958
behaviors: [FadeOutAndDespawnAfterAnimation, FollowSource],

assets/data/mobs.ron

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@
400400
spawn_animation_time: 0.5,
401401
despawn_animation_time: 0.3,
402402
inherit_motion: false,
403+
range: 100.0,
403404
)
404405
]
405406
}
@@ -454,6 +455,7 @@
454455
spawn_animation_time: 0.3,
455456
despawn_animation_time: 0.4,
456457
inherit_motion: true,
458+
range: 0.0,
457459
)
458460
],
459461
"blast": [
@@ -470,6 +472,7 @@
470472
spawn_animation_time: 0.3,
471473
despawn_animation_time: 0.4,
472474
inherit_motion: true,
475+
range: 0.0,
473476
)
474477
]
475478
}
@@ -517,6 +520,7 @@
517520
spawn_animation_time: 0.3,
518521
despawn_animation_time: 0.4,
519522
inherit_motion: true,
523+
range: 0.0,
520524
)
521525
],
522526
}
@@ -764,6 +768,7 @@
764768
spawn_animation_time: 0.3,
765769
despawn_animation_time: 0.4,
766770
inherit_motion: true,
771+
range: 0.0,
767772
)
768773
]
769774
}
@@ -818,6 +823,7 @@
818823
spawn_animation_time: 0.3,
819824
despawn_animation_time: 0.4,
820825
inherit_motion: true,
826+
range: 0.0,
821827
)
822828
]
823829
}

assets/effect_assets.assets.ron

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@
9090
columns: 8,
9191
rows: 1,
9292
),
93+
"enemy_beam_spawn": TextureAtlas (
94+
path: "texture/enemy_beam_spawn_spritesheet.png",
95+
tile_size_x: 9.,
96+
tile_size_y: 1.,
97+
columns: 8,
98+
rows: 1,
99+
),
93100
"enemy_beam_despawn": TextureAtlas (
94101
path: "texture/enemy_beam_despawn_spritesheet.png",
95102
tile_size_x: 9.,

crates/thetawave_interface/src/spawnable.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ pub enum EffectType {
196196
Text(TextEffectType),
197197
AllyBeamDespawn,
198198
EnemyBeamDespawn,
199+
EnemyBeamSpawn,
199200
}
200201

201202
/// Subtype of effect for text effects

src/assets/effect.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ pub struct EffectAssets {
1919
pub enemy_bullet_despawn: Handle<TextureAtlas>,
2020
#[asset(key = "ally_beam_spawn")]
2121
pub ally_beam_spawn: Handle<TextureAtlas>,
22+
#[asset(key = "enemy_beam_spawn")]
23+
pub enemy_beam_spawn: Handle<TextureAtlas>,
2224
#[asset(key = "ally_beam_despawn")]
2325
pub ally_beam_despawn: Handle<TextureAtlas>,
2426
#[asset(key = "ally_bullet_explosion")]
@@ -52,6 +54,7 @@ impl EffectAssets {
5254
EffectType::Text(_) => None,
5355
EffectType::AllyBeamDespawn => Some(self.ally_beam_despawn.clone()),
5456
EffectType::AllyBeamSpawn => Some(self.ally_beam_spawn.clone()),
57+
EffectType::EnemyBeamSpawn => Some(self.enemy_beam_spawn.clone()),
5558
EffectType::EnemyBeamDespawn => Some(self.enemy_beam_despawn.clone()),
5659
}
5760
}
@@ -73,6 +76,7 @@ impl EffectAssets {
7376
EffectType::AllyBeamDespawn => Color::rgb(7.5, 7.5, 7.5),
7477
EffectType::EnemyBeamDespawn => Color::rgb(7.5, 7.5, 7.5),
7578
EffectType::AllyBeamSpawn => Color::rgba(2.0, 2.0, 2.0, 0.0),
79+
EffectType::EnemyBeamSpawn => Color::rgba(2.0, 2.0, 2.0, 0.0),
7680
}
7781
}
7882
}

src/player/systems/attacks.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use bevy::prelude::*;
44
use bevy_rapier2d::prelude::*;
55
use leafwing_input_manager::prelude::ActionState;
66
use thetawave_interface::input::PlayerAction;
7+
use thetawave_interface::player;
78
use thetawave_interface::spawnable::{EffectType, ProjectileType};
89
use thetawave_interface::{
910
audio::{PlaySoundEffectEvent, SoundEffectType},
@@ -81,6 +82,7 @@ pub fn player_fire_weapon_system(
8182
projectile_spawn: Some(ProjectileSpawnData {
8283
damage: player_component.attack_damage,
8384
despawn_time: player_component.projectile_despawn_time,
85+
offset_position: player_component.projectile_offset_position,
8486
}),
8587
..default()
8688
})

src/spawnable/effect/behavior.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::animation::{AnimationCompleteEvent, AnimationComponent};
22
use crate::spawnable::behavior::DespawnSpawnableEvent;
3-
use crate::spawnable::{SpawnProjectileEvent, TransformType};
3+
use crate::spawnable::{MobComponent, SpawnProjectileEvent, TransformType};
44
use crate::GameUpdateSet;
55
use bevy::math::Vec3Swizzles;
66
use bevy::prelude::*;
@@ -69,6 +69,7 @@ pub struct FadeInAndDespawnAfterAnimation(pub Stopwatch);
6969
pub struct FollowSource {
7070
pub source: Entity,
7171
pub pos_vec: Vec2,
72+
pub offset_pos: Vec2,
7273
}
7374

7475
#[derive(Component)]
@@ -258,6 +259,7 @@ fn fade_in_despawn_after_animation_effect_behavior_system(
258259
fn follow_source_system(
259260
mut projectile_query: Query<(&FollowSource, &mut Transform), With<EffectComponent>>,
260261
player_query: Query<(&Transform, &PlayerComponent), Without<EffectComponent>>,
262+
mob_query: Query<(&Transform, &MobComponent), Without<EffectComponent>>,
261263
) {
262264
for (follow_source, mut effect_transform) in projectile_query.iter_mut() {
263265
if let Ok((player_transform, player_component)) = player_query.get(follow_source.source) {
@@ -268,6 +270,16 @@ fn follow_source_system(
268270
// current difference between the effect position and the base spawn position for projectile
269271
let current_pos_diff = effect_transform.translation.xy() - player_offset_pos;
270272

273+
// update the effect transform by adding the difference between the follow position and the current difference in position
274+
//so that the effect consistently follows the source
275+
effect_transform.translation += (follow_source.pos_vec - current_pos_diff).extend(0.0);
276+
} else if let Ok((mob_transform, mob_component)) = mob_query.get(follow_source.source) {
277+
// get the base spawn point for a effect
278+
let mob_offset_pos = mob_transform.translation.xy() + follow_source.offset_pos; // TODO: offset position must be stored with follow source
279+
280+
// current difference between the effect position and the base spawn position for projectile
281+
let current_pos_diff = effect_transform.translation.xy() - mob_offset_pos;
282+
271283
// update the effect transform by adding the difference between the follow position and the current difference in position
272284
//so that the effect consistently follows the source
273285
effect_transform.translation += (follow_source.pos_vec - current_pos_diff).extend(0.0);

src/spawnable/effect/spawn.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,12 @@ fn spawn_text_effect(
142142
},
143143
};
144144

145+
let offset_pos = if let Some(ref projectile_spawn) = projectile_spawn {
146+
projectile_spawn.offset_position
147+
} else {
148+
Vec2::ZERO
149+
};
150+
145151
// spawn the effect
146152
let mut effect = commands.spawn_empty();
147153

@@ -173,6 +179,7 @@ fn spawn_text_effect(
173179
source,
174180
pos_vec: text_transform.translation.xy()
175181
- original_transform.translation.xy(),
182+
offset_pos,
176183
});
177184
} else {
178185
error!("Source must be Some in order to create FollowSource behavior.")
@@ -229,8 +236,17 @@ fn spawn_effect(
229236
};
230237
effect_transform.translation.z = effect_data.z_level;
231238

239+
let offset_pos = if let Some(ref projectile_spawn) = projectile_spawn {
240+
projectile_spawn.offset_position
241+
} else {
242+
Vec2::ZERO
243+
};
244+
232245
// TODO: Replace remove hard coded values and use a player stat instead
233-
if matches!(effect_type, EffectType::AllyBeamSpawn) {
246+
if matches!(
247+
effect_type,
248+
EffectType::AllyBeamSpawn | EffectType::EnemyBeamSpawn
249+
) {
234250
//effect_transform.scale.y *= 50.0;
235251
effect_transform.translation.y += effect_transform.scale.y / 2.0;
236252
}
@@ -284,6 +300,7 @@ fn spawn_effect(
284300
effect_transform.translation.x,
285301
effect_transform.translation.y - (effect_transform.scale.y / 2.0),
286302
),
303+
offset_pos,
287304
});
288305
} else {
289306
error!("Source must be Some in order to create FollowSource behavior.")
@@ -313,4 +330,5 @@ fn spawn_effect(
313330
pub struct ProjectileSpawnData {
314331
pub damage: usize,
315332
pub despawn_time: f32,
333+
pub offset_position: Vec2,
316334
}

src/spawnable/mob/behavior.rs

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ use crate::{
1515
collision::SortedCollisionEvent,
1616
loot::LootDropsResource,
1717
spawnable::{
18-
InitialMotion, SpawnConsumableEvent, SpawnEffectEvent, SpawnProjectileEvent, TransformType,
18+
InitialMotion, ProjectileSpawnData, SpawnConsumableEvent, SpawnEffectEvent,
19+
SpawnProjectileEvent, TransformType,
1920
},
2021
};
2122

@@ -147,23 +148,53 @@ pub fn mob_execute_behavior_system(
147148
sound_effect_type: SoundEffectType::EnemyFireBlast,
148149
});
149150

150-
spawn_projectile_event_writer.send(SpawnProjectileEvent {
151-
projectile_type: projectile_spawner.projectile_type.clone(),
152-
transform_type: TransformType::Initialized(projectile_transform),
153-
damage: projectile_spawner.damage,
154-
despawn_time: projectile_spawner.despawn_time,
155-
initial_motion,
156-
source: entity,
157-
offset_position: match projectile_spawner.position {
158-
SpawnPosition::Global(coords) => {
159-
coords - mob_transform.translation.xy()
160-
}
161-
SpawnPosition::Local(coords) => {
162-
mob_transform.local_x().xy() * coords.x
163-
+ mob_transform.local_y().xy() * coords.y
164-
}
165-
},
166-
});
151+
if let ProjectileType::Beam(_) = projectile_spawner.projectile_type {
152+
spawn_effect_event_writer.send(SpawnEffectEvent {
153+
effect_type: EffectType::EnemyBeamSpawn,
154+
transform_type: TransformType::Initialized(
155+
projectile_transform.with_scale(Vec3::new(
156+
projectile_transform.scale.x,
157+
projectile_transform.scale.y * projectile_spawner.range,
158+
projectile_transform.scale.z,
159+
)),
160+
),
161+
source: Some(entity),
162+
projectile_spawn: Some(ProjectileSpawnData {
163+
damage: projectile_spawner.damage,
164+
despawn_time: projectile_spawner.despawn_time,
165+
offset_position: match projectile_spawner.position {
166+
SpawnPosition::Global(coords) => {
167+
coords - mob_transform.translation.xy()
168+
}
169+
SpawnPosition::Local(coords) => {
170+
mob_transform.local_x().xy() * coords.x
171+
+ mob_transform.local_y().xy() * coords.y
172+
}
173+
},
174+
}),
175+
..default()
176+
});
177+
} else {
178+
spawn_projectile_event_writer.send(SpawnProjectileEvent {
179+
projectile_type: projectile_spawner.projectile_type.clone(),
180+
transform_type: TransformType::Initialized(
181+
projectile_transform,
182+
),
183+
damage: projectile_spawner.damage,
184+
despawn_time: projectile_spawner.despawn_time,
185+
initial_motion,
186+
source: entity,
187+
offset_position: match projectile_spawner.position {
188+
SpawnPosition::Global(coords) => {
189+
coords - mob_transform.translation.xy()
190+
}
191+
SpawnPosition::Local(coords) => {
192+
mob_transform.local_x().xy() * coords.x
193+
+ mob_transform.local_y().xy() * coords.y
194+
}
195+
},
196+
});
197+
}
167198
}
168199
}
169200
}

src/spawnable/mob/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ pub struct ProjectileSpawner {
140140
pub spawn_animation_time: f32,
141141
pub despawn_animation_time: f32,
142142
pub inherit_motion: bool,
143+
pub range: f32,
143144
}
144145

145146
impl From<ProjectileSpawnerData> for ProjectileSpawner {
@@ -154,6 +155,7 @@ impl From<ProjectileSpawnerData> for ProjectileSpawner {
154155
spawn_animation_time: value.spawn_animation_time,
155156
despawn_animation_time: value.despawn_animation_time,
156157
inherit_motion: value.inherit_motion,
158+
range: value.range,
157159
}
158160
}
159161
}
@@ -168,8 +170,10 @@ pub struct ProjectileSpawnerData {
168170
pub damage: usize,
169171
pub spawn_animation_time: f32,
170172
pub despawn_animation_time: f32,
171-
/// Whether to add motion the from entity spawning projectile to the projectile
173+
/// whether to add motion the from entity spawning projectile to the projectile
172174
pub inherit_motion: bool,
175+
/// used for certain projectiles (like the beam) to determine the length
176+
pub range: f32,
173177
}
174178

175179
#[derive(Deserialize, Clone)]

0 commit comments

Comments
 (0)