diff --git a/assets/config/actor.ron b/assets/config/actor.ron index 35dd25d..5de3326 100644 --- a/assets/config/actor.ron +++ b/assets/config/actor.ron @@ -18,7 +18,7 @@ attack: Attack(color: Srgba(Srgba(red: 0.855, green: 0.576, blue: 0.800, alpha: 1.000))), health: Health(max: 100, current: 100), - deck: Deck(cards: ["step", "pair"]), + deck: Deck(cards: ["step", "pair", "half_rest"]), ), }, diff --git a/assets/config/card.ron b/assets/config/card.ron index 2ddf283..d03c4fa 100644 --- a/assets/config/card.ron +++ b/assets/config/card.ron @@ -304,7 +304,11 @@ max_level: 4, action: Heal, - action_modifier: CardActionModifier(heal_flat: 10, immunity: 0.7), + action_modifier: CardActionModifier( + heal_flat: 10, + immunity: 0.5, + attack: Attack(projectile: Some("eighth_rest"), offset: 8.0), + ), ), "quarter_rest": Card( name: "Quarter Rest", @@ -316,7 +320,11 @@ weight: 0.7, action: Heal, - action_modifier: CardActionModifier(heal_flat: 30, immunity: 0.8), + action_modifier: CardActionModifier( + heal_flat: 30, + immunity: 0.666, + attack: Attack(projectile: Some("quarter_rest"), offset: 8.0), + ), ), "half_rest": Card( name: "Half Rest", @@ -328,7 +336,11 @@ weight: 0.6, action: Heal, - action_modifier: CardActionModifier(heal_percent: 25, immunity: 0.9), + action_modifier: CardActionModifier( + heal_percent: 25, + immunity: 0.833, + attack: Attack(projectile: Some("half_rest"), offset: 8.0), + ), ), "whole_rest": Card( name: "Whole Rest", @@ -339,7 +351,11 @@ weight: 0.5, action: Heal, - action_modifier: CardActionModifier(heal_percent: 50, immunity: 1.0), + action_modifier: CardActionModifier( + heal_percent: 50, + immunity: 1.0, + attack: Attack(projectile: Some("whole_rest"), offset: 8.0), + ), ), } ) diff --git a/assets/config/projectile.ron b/assets/config/projectile.ron index 5e7f97f..4564085 100644 --- a/assets/config/projectile.ron +++ b/assets/config/projectile.ron @@ -1,5 +1,25 @@ ( projectiles: { + "eighth_rest": Projectile( + name: "Eighth Rest", + texture: "image/projectile/eighth_rest.png", + lifetime: 0.55, + ), + "quarter_rest": Projectile( + name: "Quarter Rest", + texture: "image/projectile/quarter_rest.png", + lifetime: 0.716, + ), + "half_rest": Projectile( + name: "Half Rest", + texture: "image/projectile/half_rest.png", + lifetime: 0.9, + ), + "whole_rest": Projectile( + name: "Whole Rest", + texture: "image/projectile/whole_rest.png", + lifetime: 1.05, + ), "eighth_note": Projectile( name: "Eighth Note", diff --git a/assets/image/card/icon/eighth_rest.png b/assets/image/card/icon/eighth_rest.png index 33744ca..4a7761c 100644 Binary files a/assets/image/card/icon/eighth_rest.png and b/assets/image/card/icon/eighth_rest.png differ diff --git a/assets/image/card/icon/icons.aseprite b/assets/image/card/icon/icons.aseprite index 7834cad..50f8dd5 100644 Binary files a/assets/image/card/icon/icons.aseprite and b/assets/image/card/icon/icons.aseprite differ diff --git a/assets/image/projectile/eighth_rest.png b/assets/image/projectile/eighth_rest.png new file mode 100644 index 0000000..2e194b3 Binary files /dev/null and b/assets/image/projectile/eighth_rest.png differ diff --git a/assets/image/projectile/half_rest.png b/assets/image/projectile/half_rest.png new file mode 100644 index 0000000..86b124a Binary files /dev/null and b/assets/image/projectile/half_rest.png differ diff --git a/assets/image/projectile/projectiles.aseprite b/assets/image/projectile/projectiles.aseprite index 54c304e..3849d54 100644 Binary files a/assets/image/projectile/projectiles.aseprite and b/assets/image/projectile/projectiles.aseprite differ diff --git a/assets/image/projectile/quarter_rest.png b/assets/image/projectile/quarter_rest.png new file mode 100644 index 0000000..fd705b5 Binary files /dev/null and b/assets/image/projectile/quarter_rest.png differ diff --git a/assets/image/projectile/whole_rest.png b/assets/image/projectile/whole_rest.png new file mode 100644 index 0000000..3b3809b Binary files /dev/null and b/assets/image/projectile/whole_rest.png differ diff --git a/src/game/card/action.rs b/src/game/card/action.rs index f844953..19d331a 100644 --- a/src/game/card/action.rs +++ b/src/game/card/action.rs @@ -5,6 +5,7 @@ use serde::Deserialize; use serde::Serialize; use crate::game::actor::attack::Attack; +use crate::game::actor::attack::AttackController; use crate::game::actor::health::Health; use crate::game::actor::movement::Movement; use crate::game::actor::player::IsPlayer; @@ -93,10 +94,19 @@ impl FromWorld for CardActionMap { |In((entity, modifier)): In<(Entity, CardActionModifier)>, world: &mut World| { let mut entity = r!(world.get_entity_mut(entity)); + let mut health = r!(entity.get_mut::()); health.current += modifier.heal_flat; health.current += modifier.heal_percent / 100.0 * health.max; + let mut attack_controller = r!(entity.get_mut::()); + attack_controller.aim = Vec2::Y; + attack_controller.fire = true; + + let mut attack = r!(entity.get_mut::()); + attack.projectile_key = modifier.attack.projectile_key.clone(); + attack.offset = modifier.attack.offset; + // Player actor has extra benefits: if entity.contains::() { if modifier.contact_damage > 0.0 { diff --git a/src/game/card/attack.rs b/src/game/card/attack.rs index 65beeba..d639b3e 100644 --- a/src/game/card/attack.rs +++ b/src/game/card/attack.rs @@ -64,6 +64,7 @@ fn attack_on_beat( attack.power = attack_on_beat.0.power; attack.force = attack_on_beat.0.force; + attack.offset = attack_on_beat.0.offset; attack.projectile_key = attack_on_beat.0.projectile_key.clone(); attack.multi_shot = attack_on_beat.0.multi_shot.clone(); attack.child_projectile = attack_on_beat.0.child_projectile.clone(); diff --git a/src/game/combat/projectile.rs b/src/game/combat/projectile.rs index fa35922..3bf4cb1 100644 --- a/src/game/combat/projectile.rs +++ b/src/game/combat/projectile.rs @@ -74,6 +74,7 @@ impl Config for ProjectileConfig { } #[derive(Reflect, Serialize, Deserialize, Clone)] +#[serde(deny_unknown_fields)] pub struct Projectile { pub name: String, @@ -88,12 +89,16 @@ pub struct Projectile { #[serde(default = "one")] pub spawn_sfx_volume: f64, - /// Lifetime in seconds, not beats. + /// Lifetime in seconds (not beats). pub lifetime: f32, /// Hitbox radius. + #[serde(default)] pub radius: f32, + #[serde(default)] pub speed: f32, + #[serde(default)] pub damage: f32, + #[serde(default)] pub knockback: f32, #[serde(default)] pub pierce: usize, @@ -168,7 +173,14 @@ pub fn projectile( ( RigidBody::Kinematic, Collider::circle(projectile.radius), - CollisionLayers::new(GameLayer::Projectile, target_layers), + CollisionLayers::new( + if projectile.radius == 0.0 { + LayerMask::NONE + } else { + GameLayer::Projectile.into() + }, + target_layers, + ), Sensor, LockedAxes::ROTATION_LOCKED, LinearVelocity(projectile.speed * force),