Skip to content

Commit

Permalink
refactor inventory
Browse files Browse the repository at this point in the history
  • Loading branch information
aratama committed Nov 16, 2024
1 parent fa7903d commit c8b9d0f
Show file tree
Hide file tree
Showing 12 changed files with 225 additions and 116 deletions.
7 changes: 6 additions & 1 deletion src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ pub const MAX_WANDS: usize = 4;

pub const MAX_SPELLS_IN_WAND: usize = 8;

pub const MAX_ITEMS_IN_INVENTORY: usize = 64;
pub const MAX_ITEMS_IN_INVENTORY_ROW: usize = 8;

pub const MAX_ITEMS_IN_INVENTORY_COLUMN: usize = 8;

pub const MAX_ITEMS_IN_INVENTORY: usize =
MAX_ITEMS_IN_INVENTORY_ROW * MAX_ITEMS_IN_INVENTORY_COLUMN;

/// level.aseprite のスライスの最大値 - 1
pub const LEVELS: i32 = 4;
Expand Down
36 changes: 3 additions & 33 deletions src/controller/player.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use crate::asset::GameAssets;
use crate::command::GameCommand;
use crate::constant::{MAX_ITEMS_IN_INVENTORY, MAX_WANDS};
use crate::constant::MAX_WANDS;
use crate::controller::remote::RemoteMessage;
use crate::entity::actor::{Actor, ActorFireState};
use crate::entity::gold::{spawn_gold, Gold};
use crate::input::{get_direction, get_fire_trigger, MyGamepad};
use crate::inventory_item::InventoryItem;
use crate::inventory::Inventory;
use crate::states::{GameMenuState, GameState};
use crate::wand::Wand;
use bevy::core::FrameCount;
use bevy::input::mouse::MouseWheel;
use bevy::prelude::*;
Expand All @@ -26,36 +25,7 @@ pub struct Player {
pub last_idle_vy: f32,
pub last_idle_life: i32,
pub last_idle_max_life: i32,
pub inventory: [Option<InventoryItem>; MAX_ITEMS_IN_INVENTORY],
}

impl Player {
pub fn insert_inventory_item(&mut self, item: InventoryItem) -> bool {
for i in 0..MAX_ITEMS_IN_INVENTORY {
if self.inventory[i].is_none() {
self.inventory[i] = Some(item);
return true;
}
}
return false;
}

pub fn insert_wand_to_inventory(&mut self, wand: &Wand) -> Vec<InventoryItem> {
let mut items = Vec::new();
items.push(InventoryItem::Wand(wand.wand_type));
for spell in wand.slots.iter() {
if let Some(spell) = spell {
items.push(InventoryItem::Spell(*spell));
}
}
let mut not_inserted = Vec::new();
for item in items.iter() {
if !self.insert_inventory_item(*item) {
not_inserted.push(*item);
}
}
return not_inserted;
}
pub inventory: Inventory,
}

/// プレイヤーの移動
Expand Down
2 changes: 1 addition & 1 deletion src/interaction_sensor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ fn pick_up(
pick_nearest_drop_item(&mut spells, player_transform.translation.truncate())
{
if let Ok((_, DroppedItemEntity { item_type, .. }, _)) = spell_query.get(nearest) {
if player.insert_inventory_item(*item_type) {
if player.inventory.insert(*item_type) {
commands.entity(nearest).despawn_recursive();
global.send(GameCommand::SEPickUp(None));
// エンティティを削除すれば Stopped イベントが発生してリストから消えるので、
Expand Down
108 changes: 108 additions & 0 deletions src/inventory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
use bevy::log::info;

use crate::{
constant::{MAX_ITEMS_IN_INVENTORY, MAX_ITEMS_IN_INVENTORY_COLUMN, MAX_ITEMS_IN_INVENTORY_ROW},
inventory_item::InventoryItem,
wand::Wand,
};

#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd)]
pub struct Inventory([Option<InventoryItem>; MAX_ITEMS_IN_INVENTORY]);

impl Inventory {
pub fn new() -> Inventory {
Inventory([None; MAX_ITEMS_IN_INVENTORY])
}

pub fn get(&self, index: usize) -> Option<InventoryItem> {
let Inventory(inventory) = *self;
return inventory[index];
}

pub fn set(&mut self, index: usize, item: Option<InventoryItem>) {
let Inventory(ref mut inventory) = self;
inventory[index] = item;
}

pub fn is_settable(&self, index: usize, item: InventoryItem) -> bool {
let x = index % MAX_ITEMS_IN_INVENTORY_ROW;
let y = index / MAX_ITEMS_IN_INVENTORY_ROW;
if MAX_ITEMS_IN_INVENTORY_COLUMN <= y {
return false;
}
for i in 0..item.get_width() {
if MAX_ITEMS_IN_INVENTORY_ROW <= x + i {
return false;
}
if self.0[index + i].is_some() {
return false;
}
}
return true;
}

pub fn is_settable_optional(&self, index: usize, item: Option<InventoryItem>) -> bool {
if let Some(item) = item {
return self.is_settable(index, item);
}
return true;
}

pub fn insert(&mut self, item: InventoryItem) -> bool {
let Inventory(ref mut inventory) = *self;
for i in 0..MAX_ITEMS_IN_INVENTORY {
if inventory[i].is_none() {
inventory[i] = Some(item);
return true;
}
}
return false;
}

pub fn insert_wand(&mut self, wand: &Wand) -> Vec<InventoryItem> {
let mut items = Vec::new();
items.push(InventoryItem::Wand(wand.wand_type));
for spell in wand.slots.iter() {
if let Some(spell) = spell {
items.push(InventoryItem::Spell(*spell));
}
}
let mut not_inserted = Vec::new();
for item in items.iter() {
if !self.insert(*item) {
not_inserted.push(*item);
}
}
return not_inserted;
}

pub fn sort(&mut self) {
let mut cloned = self.0.clone();
cloned.sort_by(|a, b| {
if a.is_none() {
return std::cmp::Ordering::Greater;
}
if b.is_none() {
return std::cmp::Ordering::Less;
}
match (a.unwrap(), b.unwrap()) {
(a, b) => a.cmp(&b),
}
});
let mut i = 0;
for item in cloned {
if MAX_ITEMS_IN_INVENTORY <= i {
break;
}
let width = match item {
Some(item) => item.get_width(),
None => 1,
};
self.0[i] = item;
for j in 1..width {
self.0[i + j] = None;
}
i += width;
}
}
}
39 changes: 20 additions & 19 deletions src/inventory_item.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::{
asset::GameAssets,
constant::MAX_ITEMS_IN_INVENTORY,
entity::dropped_item::spawn_dropped_item,
language::{Dict, Languages},
spell::SpellType,
Expand All @@ -12,11 +11,21 @@ use bevy::prelude::*;

#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum InventoryItem {
Spell(SpellType),
Wand(WandType),
Spell(SpellType),
Lantern,
}

impl InventoryItem {
pub fn get_width(&self) -> usize {
match self {
InventoryItem::Spell(_) => 1,
InventoryItem::Wand(_) => 2,
InventoryItem::Lantern => 1,
}
}
}

pub fn spawn_inventory_item(
mut commands: &mut Commands,
assets: &Res<GameAssets>,
Expand All @@ -33,6 +42,15 @@ pub fn spawn_inventory_item(
InventoryItem::Spell(spell),
);
}
InventoryItem::Wand(wand_type) => {
spawn_dropped_item(
&mut commands,
&assets,
position.x,
position.y,
InventoryItem::Wand(wand_type),
);
}
InventoryItem::Lantern => {
spawn_dropped_item(
&mut commands,
Expand All @@ -42,7 +60,6 @@ pub fn spawn_inventory_item(
InventoryItem::Lantern,
);
}
_ => {}
}
}

Expand Down Expand Up @@ -117,19 +134,3 @@ pub fn get_inventory_item_description(item: InventoryItem, language: Languages)
.to_string(),
}
}

pub type Inventory = [Option<InventoryItem>; MAX_ITEMS_IN_INVENTORY];

pub fn sort_inventory(inventory: &mut Inventory) {
inventory.sort_by(|a, b| {
if a.is_none() {
return std::cmp::Ordering::Greater;
}
if b.is_none() {
return std::cmp::Ordering::Less;
}
match (a.unwrap(), b.unwrap()) {
(a, b) => a.cmp(&b),
}
});
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod game;
mod hud;
mod input;
mod interaction_sensor;
mod inventory;
mod inventory_item;
mod language;
mod page;
Expand Down
23 changes: 21 additions & 2 deletions src/ui/floating.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,25 @@ pub enum InventoryItemFloatingContent {
#[derive(Component)]
pub struct InventoryItemFloating(pub Option<InventoryItemFloatingContent>);

impl InventoryItemFloating {
pub fn get_item(&self, player: &Player, actor: &Actor) -> Option<InventoryItem> {
match self.0 {
None => None,
Some(InventoryItemFloatingContent::InventoryItem(index)) => player.inventory.get(index),
Some(InventoryItemFloatingContent::WandSpell {
wand_index,
spell_index,
}) => actor.wands[wand_index]
.clone()
.and_then(|ref w| w.slots[spell_index])
.map(|ref w| InventoryItem::Spell(*w)),
Some(InventoryItemFloatingContent::Wand(wand_index)) => actor.wands[wand_index]
.clone()
.map(|ref w| InventoryItem::Wand(w.wand_type)),
}
}
}

pub fn spawn_inventory_floating(commands: &mut Commands, assets: &Res<GameAssets>) {
commands.spawn((
InventoryItemFloating(None),
Expand Down Expand Up @@ -87,8 +106,8 @@ fn switch_floating_slice(
if let Ok((player, actor)) = player_query.get_single() {
let (floating, mut floating_slice, mut style) = floating_query.single_mut();
match floating.0 {
Some(InventoryItemFloatingContent::InventoryItem(slot)) => {
let item = player.inventory[slot];
Some(InventoryItemFloatingContent::InventoryItem(index)) => {
let item = player.inventory.get(index);

let slice = match item {
Some(item) => {
Expand Down
Loading

0 comments on commit c8b9d0f

Please sign in to comment.