Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bow of Artemis + Lots of small refactors #41

Merged
merged 38 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
f2946a4
refactor: remove damage component from player bundle
umut-sahin Jan 1, 2024
8d8ec78
style: improve naming of player constants
umut-sahin Jan 1, 2024
b265c63
refactor: simplify hit box creation
umut-sahin Jan 1, 2024
a780fab
refactor: move player size constant to player implementations
umut-sahin Jan 1, 2024
ef43a34
feat: initial bow of artemis
umut-sahin Dec 31, 2023
d2dfb90
feat: require collider method for players
umut-sahin Jan 1, 2024
559806b
feat: add typed builder as a dependency
umut-sahin Jan 1, 2024
597da56
refactor: improve the api of spawning players
umut-sahin Jan 1, 2024
5edd438
refactor: improve the api of spawning enemies
umut-sahin Jan 1, 2024
d8bd03d
style: fix ordering of content modules in the top level library
umut-sahin Jan 2, 2024
2c746a3
feat: create enemies content module in the top level library
umut-sahin Jan 2, 2024
036956f
ci: only cancel ci runs in pull requests
umut-sahin Jan 2, 2024
df24dda
fix: use correct project name on the title of the main window
umut-sahin Jan 2, 2024
71bd926
style: improve style of item interface
umut-sahin Jan 2, 2024
a0ae14d
refactor: remove explicit position component from the player and let …
umut-sahin Jan 2, 2024
e413cc3
feat: make spawned items the child of the player automatically
umut-sahin Jan 2, 2024
9eaaa88
style: improve naming of interfaces
umut-sahin Jan 2, 2024
f4356b4
refactor: add getters for number of items in registries
umut-sahin Jan 2, 2024
6a19849
fix: check for development feature instead of debug assertions
umut-sahin Jan 2, 2024
6a2c809
feat: physics debugging in development mode
umut-sahin Jan 2, 2024
af13f96
feat: spawn map bounds automatically
umut-sahin Jan 2, 2024
10046b9
refactor: improve survival mode
umut-sahin Jan 2, 2024
aa4a664
refactor: improve greek items
umut-sahin Jan 2, 2024
aab423c
feat: introduce structured depth for entities that might overlap
umut-sahin Jan 3, 2024
8445cfd
refactor: use extend when creating transforms
umut-sahin Jan 3, 2024
2c8569d
refactor: improve greek players
umut-sahin Jan 3, 2024
f542708
refactor: improve sweet enemies
umut-sahin Jan 3, 2024
6bda5ae
ci: allow tweak commits
umut-sahin Jan 3, 2024
9d50d8b
tweak: reduce base projectile speed of bow of artemis
umut-sahin Jan 3, 2024
0463593
chore: bump `bevy_editor_pls` dependency to v0.7
umut-sahin Jan 3, 2024
c354443
refactor: improve bow of artemis
umut-sahin Jan 3, 2024
869fba2
chore: configure clippy using workspace lints
umut-sahin Jan 3, 2024
9729f5e
refactor: improve naming of constructor of widget selected component
umut-sahin Jan 3, 2024
9ae55df
refactor: improve registry architecture
umut-sahin Jan 6, 2024
a3b39ba
fix: (de)initialize game mode before/after everything else
umut-sahin Jan 9, 2024
1619972
refactor: improve the implementation of attack with bow of artemis
umut-sahin Jan 9, 2024
c851f35
refactor: rename find enemies in range to be more descriptive
umut-sahin Jan 9, 2024
154237f
refactor: make name component of items consistent with other name com…
umut-sahin Jan 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
cancel-in-progress: ${{ github.event_name != 'pull_request' }}

jobs:
conformance:
Expand Down Expand Up @@ -46,7 +46,7 @@ jobs:
- name: Commit Lint
uses: gsactions/commit-message-checker@v1
with:
pattern: "^(feat|fix|refactor|style|test|docs|ci|chore): "
pattern: "^(feat|fix|refactor|tweak|style|test|docs|ci|chore): "
error: "One of the commit messages doesn't conform to the commit style of the project."
excludeTitle: "true"
excludeDescription: "true"
Expand Down
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ members = [
"players/greek",
]

[workspace.lints.clippy]
derivable_impls = "allow"
type_complexity = "allow"

[profile.dev]
opt-level = 1

Expand Down
3 changes: 3 additions & 0 deletions enemies/sweet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ edition = "2021"
[dependencies]
mythmallow = { path = "../../game", package = "mythmallow-game" }
survival-mode = { path = "../../modes/survival", package = "mythmallow-mode-survival" }

[lints]
workspace = true
99 changes: 48 additions & 51 deletions enemies/sweet/src/gummy_bear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,27 @@ use {
},
};

/// Tag component for the enemy "Gummy Bear".
#[derive(Component, Debug, Reflect)]
/// Size of the enemy.
pub const SIZE: f32 = 15.00;

/// Health of the enemy.
pub const HEALTH: f32 = 5.00;

/// Speed of the enemy.
pub const SPEED: f32 = 100.00;

/// Contact damage of the enemy.
pub const CONTACT_DAMAGE: f32 = 3.00;

/// Cooldown of contact damage of the enemy.
pub const CONTACT_DAMAGE_COOLDOWN: Duration = Duration::from_millis(1000);

/// Component for the enemy "Gummy Bear".
#[derive(Clone, Component, Debug, Default, Reflect)]
#[reflect(Component)]
pub struct GummyBear;

impl Munchie for GummyBear {
impl IEnemy for GummyBear {
fn id(&self) -> SmolStr {
"gummy-bear".into()
}
Expand All @@ -19,12 +35,24 @@ impl Munchie for GummyBear {
"Gummy Bear".into()
}

fn contact_damage(&self) -> Option<(Damage, DamageCooldown)> {
Some((Damage(CONTACT_DAMAGE), DamageCooldown::new(CONTACT_DAMAGE_COOLDOWN)))
}

fn health(&self) -> Health {
Health(HEALTH)
}

fn speed(&self) -> Speed {
Speed(SPEED)
}

fn collider(&self) -> Collider {
Collider::ball(SIZE)
}

fn spawn(&self, world: &mut World, position: Position) {
world.run_system_once_with(position, spawn);
world.run_system_once_with((self.clone(), position), spawn);
}
}

Expand All @@ -34,9 +62,8 @@ pub struct GummyBearPlugin;
impl Plugin for GummyBearPlugin {
fn build(&self, app: &mut App) {
// Register the enemy.
let mut enemy_registry = ENEMY_REGISTRY.lock().unwrap();
enemy_registry.register(SweetMunchiesPack, GummyBear).add_tag(MELEE_ENEMY_TAG);
drop(enemy_registry);
let mut enemy_registry = app.world.resource_mut::<EnemyRegistry>();
enemy_registry.register(SweetEnemyPack, GummyBear).add_tag(MELEE_ENEMY_TAG);

// Register components.
app.register_type::<GummyBear>();
Expand All @@ -46,55 +73,25 @@ impl Plugin for GummyBearPlugin {
}
}

/// Size of the enemy.
pub const SIZE: f32 = 15.00;

/// Initial damage of the enemy.
pub const INITIAL_DAMAGE: f32 = 3.00;

/// Initial health of the enemy.
pub const INITIAL_HEALTH: f32 = 5.00;

/// Initial speed of the enemy.
pub const INITIAL_SPEED: f32 = 100.00;

/// Spawns the enemy.
pub fn spawn(
In(position): In<Position>,
In((enemy, position)): In<(GummyBear, Position)>,
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
mut counter: ResMut<EnemyCounter>,
) {
counter.increment();
commands.spawn((
GummyBear,
EnemyBundle {
// Tags
name: Name::new(format!("Enemy {} [Gummy Bear]", counter.get())),
tag: Enemy,
// Properties
damage: Damage(INITIAL_DAMAGE),
health: Health(INITIAL_HEALTH),
speed: Speed(INITIAL_SPEED),
// Combat
remaining_health: RemainingHealth(INITIAL_HEALTH),
// Physics
body: RigidBody::Dynamic,
restitution: Restitution::PERFECTLY_INELASTIC,
position,
collider: GummyBear.collider(),
layers: CollisionLayers::new(
[Layer::Enemy],
[Layer::MapBound, Layer::Enemy, Layer::PlayerHitBox],
),
// Texture
mesh: MaterialMesh2dBundle {
mesh: meshes.add(shape::Circle::new(SIZE).into()).into(),
material: materials.add(ColorMaterial::from(Color::RED)),
transform: Transform::from_translation(Vec3::new(position.x, position.y, 1.00)),
..default()
},
},
));
let mesh = MaterialMesh2dBundle {
mesh: meshes.add(shape::Circle::new(SIZE).into()).into(),
material: materials.add(ColorMaterial::from(Color::RED)),
transform: Transform::from_translation(position.extend(Depth::Enemy.z())),
..default()
};

EnemyBundle::builder()
.enemy(enemy)
.position(position)
.mesh(mesh)
.build()
.spawn(&mut commands, &mut counter);
}
9 changes: 5 additions & 4 deletions enemies/sweet/src/pack.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use mythmallow::prelude::*;

/// Sweet enemies.
#[derive(Debug)]
pub struct SweetMunchiesPack;
/// Resource for "Sweet" enemy pack.
#[derive(Debug, Default, Reflect, Resource)]
#[reflect(Resource)]
pub struct SweetEnemyPack;

impl MunchiePack for SweetMunchiesPack {
impl IEnemyPack for SweetEnemyPack {
fn id(&self) -> SmolStr {
"sweet".into()
}
Expand Down
2 changes: 1 addition & 1 deletion enemies/sweet/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use {
mythmallow::prelude::*,
};

/// Plugin for managing the enemies from Sweet enemy pack.
/// Plugin for managing the enemies from "Sweet" enemy pack.
pub struct SweetEnemiesPlugin;

impl Plugin for SweetEnemiesPlugin {
Expand Down
2 changes: 1 addition & 1 deletion enemies/sweet/src/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub use crate::{
gummy_bear::GummyBear,
pack::SweetMunchiesPack,
pack::SweetEnemyPack,
plugin::SweetEnemiesPlugin,
};
6 changes: 5 additions & 1 deletion game/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
bevy = { version = "0.12", features = ["serialize"] }
bevy-persistent = { version = "0.4" }
bevy_editor_pls = { version = "0.6", optional = true }
bevy_editor_pls = { version = "0.7", optional = true }
bevy_prng = { version = "0.2", features = ["rand_chacha"] }
bevy_rand = { version = "0.4" }
bevy_xpbd_2d = { version = "0.3" }
Expand All @@ -19,6 +19,7 @@ smallvec = { version = "1.11", features = ["serde"] }
smol_str = { version = "0.2" }
strum = { version = "0.25" }
strum_macros = { version = "0.25" }
typed-builder = { version = "0.18" }

[target.'cfg(not(target_family = "wasm"))'.dependencies]
bevy-persistent-windows = { version = "0.4" }
Expand All @@ -39,3 +40,6 @@ native-release = ["native"]
wasm = ["bevy-persistent/json"]
wasm-development = ["wasm", "development"]
wasm-release = ["wasm"]

[lints]
workspace = true
78 changes: 77 additions & 1 deletion game/src/combat/components.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,87 @@
use crate::prelude::*;


/// Tag component for basic attacks.
/// Tag component for attacks.
#[derive(Component, Debug, Reflect)]
pub struct Attack;


/// Component for cooldown of applying damage.
#[derive(Component, Debug, Deref, DerefMut, Reflect)]
pub struct DamageCooldown {
pub duration: Duration,
}

impl DamageCooldown {
/// Creates a new damage cooldown.
pub fn new(duration: Duration) -> DamageCooldown {
DamageCooldown { duration }
}
}


/// Tag component for projectiles.
#[derive(Component, Debug, Reflect)]
pub struct Projectile;


/// Bundle for projectiles.
#[derive(Bundle, TypedBuilder)]
pub struct ProjectileBundle {
pub mesh: MaterialMesh2dBundle<ColorMaterial>,
pub collider: Collider,
pub position: Position,
pub velocity: LinearVelocity,
pub damage: Damage,
}

impl ProjectileBundle {
/// Spawns the projectile.
fn spawn<'w, 's, 'a>(
self,
commands: &'a mut Commands<'w, 's>,
layers: CollisionLayers,
additional_components: impl Bundle,
) -> EntityCommands<'w, 's, 'a> {
commands.spawn((
// Tags
Name::new("Projectile"),
Projectile,
// Projectile
self,
additional_components,
// Physics
RigidBody::Dynamic,
layers,
))
}

/// Spawns the projectile toward the player.
pub fn spawn_toward_player<'w, 's, 'a>(
self,
commands: &'a mut Commands<'w, 's>,
) -> EntityCommands<'w, 's, 'a> {
let layers = CollisionLayers::new(
[Layer::Projectile, Layer::DamagePlayer],
[Layer::MapBound, Layer::MapObstacle, Layer::PlayerHitBox],
);
self.spawn(commands, layers, DamagePlayerOnContact)
}

/// Spawns the projectile toward enemies.
pub fn spawn_toward_enemies<'w, 's, 'a>(
self,
commands: &'a mut Commands<'w, 's>,
) -> EntityCommands<'w, 's, 'a> {
let layers = CollisionLayers::new(
[Layer::Projectile, Layer::DamageEnemies],
[Layer::MapBound, Layer::MapObstacle, Layer::EnemyHitBox],
);
self.spawn(commands, layers, DamageEnemiesOnContact)
}
}


/// Component for remaining health.
#[derive(Clone, Copy, Component, Debug, Deref, DerefMut, Reflect)]
pub struct RemainingHealth(pub f32);
1 change: 1 addition & 0 deletions game/src/combat/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod components;
pub mod plugin;
pub mod systems;
pub mod utils;
11 changes: 6 additions & 5 deletions game/src/combat/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ pub struct CombatPlugin;
impl Plugin for CombatPlugin {
fn build(&self, app: &mut App) {
// Register components.
app.register_type::<RemainingHealth>();
app.register_type::<DamageCooldown>();
app.register_type::<Cooldown<Attack>>();
app.register_type::<Projectile>();
app.register_type::<RemainingHealth>();

// Add systems.
app.add_systems(PreUpdate, cooldown::<Attack>.in_set(GameplaySystems::Combat));
app.add_systems(Update, (damage_player, damage_enemies).in_set(GameplaySystems::Combat));
app.add_systems(
Update,
(damage_player_on_contact_with_enemies, player_death)
.chain()
.in_set(GameplaySystems::Combat),
PostUpdate,
(player_death, enemy_death, despawn_projectiles).in_set(GameplaySystems::Combat),
);
}
}
Loading
Loading