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

Make player able to grab Big Bass bomb while fusing #291

Merged
merged 6 commits into from
Jan 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion assets/items/bomb/bomb.item.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ kind: !Bomb
columns: 11
rows: 3

#TODO: return and find another way to extend duration after animation system changes
animation_fps: 0.12
animations:
explosion:
frames: [0, 10]
bomb:
frames: [11, 11]
bomb_fuse:
frames: [22, 24]
frames: [22, 28]
attack_frames:
startup: 0
active: 3
Expand Down
Binary file modified assets/items/bomb/bomb_144_112.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
127 changes: 71 additions & 56 deletions src/fighter_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use bevy_mod_js_scripting::ActiveScripts;
use bevy_rapier2d::prelude::CollisionGroups;
use iyes_loopless::prelude::*;
use leafwing_input_manager::{plugin::InputManagerSystem, prelude::ActionState};
use rand::Rng;

use crate::{
animation::{AnimatedSpriteSheetBundle, Animation, Facing},
Expand All @@ -23,7 +24,7 @@ use crate::{
},
lifetime::Lifetime,
metadata::{AttackMeta, AudioMeta, FighterMeta, ItemKind, ItemMeta, ItemSpawnMeta},
movement::LinearVelocity,
movement::{AngularVelocity, Force, LinearVelocity},
player::Player,
Collider, GameState, Stats,
};
Expand Down Expand Up @@ -86,7 +87,6 @@ impl Plugin for FighterStatePlugin {
.with_system(grabbing)
.with_system(hitstun)
.with_system(dying)
.with_system(holding)
.with_system(melee_attacking)
.with_system(shooting)
.with_system(bomb_throw)
Expand Down Expand Up @@ -335,9 +335,7 @@ impl ProjectileAttacking {
/// Component indicating the player is holding a item on it's head
#[derive(Component, Reflect, Default, Debug)]
#[component(storage = "SparseSet")]
pub struct Holding {
item: Handle<ItemMeta>,
}
pub struct Holding;
impl Holding {
pub const PRIORITY: i32 = 35;
}
Expand Down Expand Up @@ -1435,6 +1433,12 @@ fn bomb_throw(
fusing: false,
animated_sprite,
explosion_frames: *attack_frames,
attack_enemy: false,
})
.insert(ItemBundle {
item: Item,
item_meta_handle: attack.item_handle.clone(),
name: Name::new("Bomb Item"),
});
bomb_throw.thrown = !bomb_throw.thrown;
}
Expand Down Expand Up @@ -1545,7 +1549,10 @@ fn throwing(
),
With<Throwing>,
>,
being_held: Query<(Entity, &Parent), With<BeingHeld>>,
mut being_held: Query<
(Entity, &Parent, &GlobalTransform, Option<&mut Explodable>),
With<BeingHeld>,
>,
weapon_held: Query<(Entity, &Parent), With<MeleeWeapon>>,
pweapon_held: Query<(Entity, &Parent), With<ProjectileWeapon>>,
mut items_assets: ResMut<Assets<ItemMeta>>,
Expand Down Expand Up @@ -1594,7 +1601,7 @@ fn throwing(
});

// Despawn head sprite
for (head_ent, parent) in being_held.iter() {
for (head_ent, parent, ..) in being_held.iter() {
if parent.get() == entity {
commands.entity(head_ent).despawn_recursive();
}
Expand Down Expand Up @@ -1658,7 +1665,47 @@ fn throwing(
}
}
ItemKind::Bomb { .. } => {
panic!("Can't throw bomb")
for (head_ent, parent, g_transform, explodable) in being_held.iter_mut() {
if parent.get() == entity {
commands.entity(entity).remove_children(&[head_ent]);
commands
.entity(head_ent)
.insert(g_transform.compute_transform());
if let Some(mut explodable) = explodable {
explodable.timer.reset();
explodable.attack_enemy = true;
}

let direction_mul = if facing.is_left() {
Vec2::new(-1.0, 1.0)
} else {
Vec2::ONE
};
let mut rng = rand::thread_rng();

commands.entity(head_ent).insert((
LinearVelocity(
consts::THROW_ITEM_SPEED
* direction_mul
* rng.gen_range(0.8..1.2),
),
Force(Vec2::new(0.0, -consts::THROW_ITEM_GRAVITY)),
AngularVelocity(
consts::THROW_ITEM_ROTATION_SPEED
* direction_mul.x
* rng.gen_range(0.8..1.2),
),
CollisionGroups::new(
BodyLayers::PLAYER_ATTACK,
BodyLayers::PLAYER
| BodyLayers::ENEMY
| BodyLayers::BREAKABLE_ITEM,
),
Collider::cuboid(consts::ITEM_WIDTH / 2., consts::ITEM_HEIGHT / 2.),
));
}
}
commands.entity(entity).remove::<Holding>();
}
}
}
Expand Down Expand Up @@ -1725,18 +1772,31 @@ fn grabbing(
Some(items_assets.get(item).expect("Item not loaded!").clone());
commands.entity(item_ent).despawn_recursive();
}
ItemKind::BreakableBox { .. } => {
ItemKind::BreakableBox { .. } | ItemKind::Bomb { .. } => {
// Transition to holding state
transition_intents.push_back(StateTransition::new(
Holding { item: item.clone() },
Holding,
Holding::PRIORITY,
true,
));

let image = items_assets
.get(item)
.expect("Item not loaded!")
.clone()
.image;

commands.entity(item_ent).insert(Transform::from_xyz(
0.,
consts::THROW_ITEM_OFFSET.y + image.image_size.y,
consts::PROJECTILE_Z,
));

picked_item_ids.insert(item_ent);
**fighter_inventory =
Some(items_assets.get(item).expect("Item not loaded!").clone());
commands.entity(item_ent).despawn_recursive();
commands.entity(item_ent).remove::<Item>().insert(BeingHeld);
commands.entity(fighter_ent).add_child(item_ent);
odecay marked this conversation as resolved.
Show resolved Hide resolved
}
ItemKind::MeleeWeapon {
ref attack,
Expand Down Expand Up @@ -1860,9 +1920,6 @@ fn grabbing(
.id();
commands.entity(fighter_ent).add_child(weapon);
}
ItemKind::Bomb { .. } => {
panic!("Can't pick up bomb")
}
}
}
break;
Expand All @@ -1875,48 +1932,6 @@ fn grabbing(
}
}

/// Holding item
fn holding(
mut commands: Commands,
mut fighters: Query<(Entity, &Holding)>,
being_held: Query<&Parent, With<BeingHeld>>,
items_assets: Res<Assets<ItemMeta>>,
) {
for (entity, holding) in &mut fighters {
let mut already_holding = false;
for parent in being_held.iter() {
if parent.get() == entity {
already_holding = true;
break;
}
}

if !already_holding {
let image = items_assets
.get(&holding.item)
.expect("Item not loaded!")
.clone()
.image;

let child = commands
.spawn((
SpriteBundle {
texture: image.image_handle.clone(),
transform: Transform::from_xyz(
0.,
consts::THROW_ITEM_OFFSET.y + image.image_size.y,
consts::PROJECTILE_Z,
),
..default()
},
BeingHeld,
))
.id();
commands.entity(entity).add_child(child);
}
}
}

fn melee_attacking(
mut commands: Commands,
mut fighters: Query<(
Expand Down
38 changes: 33 additions & 5 deletions src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
attack::{Attack, AttackFrames, Breakable, BrokeEvent},
collision::{BodyLayers, PhysicsBundle},
consts,
fighter::Inventory,
lifetime::{Lifetime, LifetimeExpired},
metadata::{AttackMeta, ItemKind, ItemMeta, ItemSpawnMeta},
movement::{AngularVelocity, Force, LinearVelocity},
Expand Down Expand Up @@ -41,9 +42,9 @@ pub struct Item;

#[derive(Bundle)]
pub struct ItemBundle {
item: Item,
item_meta_handle: Handle<ItemMeta>,
name: Name,
pub item: Item,
pub item_meta_handle: Handle<ItemMeta>,
pub name: Name,
}

impl ItemBundle {
Expand Down Expand Up @@ -253,6 +254,7 @@ pub struct Explodable {
pub fusing: bool,
pub animated_sprite: AnimatedSpriteSheetBundle,
pub explosion_frames: AttackFrames,
pub attack_enemy: bool,
}

fn explodable_system(
Expand All @@ -264,10 +266,13 @@ fn explodable_system(
&mut LinearVelocity,
&mut AngularVelocity,
&mut Transform,
&GlobalTransform,
&mut Animation,
Entity,
Option<&Parent>,
)>,
time: Res<Time>,
mut inventory: Query<&mut Inventory>,
) {
let mut explosions = Vec::new();

Expand All @@ -283,8 +288,10 @@ fn explodable_system(
mut velocity,
mut ang_vel,
mut transform,
g_transform,
mut animation,
entity,
parent,
) in &mut explodables
{
explodable.timer.tick(time.delta());
Expand All @@ -298,8 +305,18 @@ fn explodable_system(

animation.play("bomb_fuse", false);
explodable.fusing = true;

//Remove explosion on contact
commands.entity(entity).remove::<Collider>();
} else if animation.is_finished() && explodable.fusing {
explosions.push((*transform, explodable.clone()));
explosions.push((g_transform.compute_transform(), explodable.clone()));

if let Some(parent) = parent {
if let Ok(mut inventory) = inventory.get_mut(parent.get()) {
**inventory = None;
}
}

commands.entity(entity).despawn_recursive();
}
}
Expand All @@ -325,7 +342,18 @@ fn explodable_system(
Sensor,
ActiveEvents::COLLISION_EVENTS,
ActiveCollisionTypes::default() | ActiveCollisionTypes::STATIC_STATIC,
CollisionGroups::new(BodyLayers::ENEMY_ATTACK, BodyLayers::PLAYER),
CollisionGroups::new(
if explodable.attack_enemy {
BodyLayers::PLAYER_ATTACK
} else {
BodyLayers::ENEMY_ATTACK
},
if explodable.attack_enemy {
BodyLayers::PLAYER | BodyLayers::ENEMY | BodyLayers::BREAKABLE_ITEM
} else {
BodyLayers::PLAYER
},
),
Attack {
damage: attack.damage,
pushback: attack.velocity.unwrap_or(Vec2::ZERO),
Expand Down