Add separate player hands
This commit is contained in:
parent
e119885dbc
commit
78e4dedf21
2 changed files with 85 additions and 52 deletions
135
src/main.rs
135
src/main.rs
|
@ -1,4 +1,9 @@
|
||||||
#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
|
#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
|
||||||
|
#![allow(
|
||||||
|
clippy::cast_possible_truncation,
|
||||||
|
clippy::cast_sign_loss,
|
||||||
|
clippy::too_many_lines
|
||||||
|
)]
|
||||||
|
|
||||||
mod card;
|
mod card;
|
||||||
mod player;
|
mod player;
|
||||||
|
@ -6,7 +11,7 @@ pub(crate) mod rect_helper;
|
||||||
|
|
||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
|
|
||||||
use crate::rect_helper::RectHelper;
|
use crate::{card::Stat, rect_helper::RectHelper};
|
||||||
use card::Card;
|
use card::Card;
|
||||||
use nannou::{
|
use nannou::{
|
||||||
image::{self, ImageFormat},
|
image::{self, ImageFormat},
|
||||||
|
@ -30,7 +35,8 @@ struct Model {
|
||||||
texture: wgpu::Texture,
|
texture: wgpu::Texture,
|
||||||
ups: f64,
|
ups: f64,
|
||||||
just_clicked: RwLock<bool>,
|
just_clicked: RwLock<bool>,
|
||||||
hand: RwLock<[Card; HAND_CARD_COUNT]>,
|
red_hand: RwLock<[Card; HAND_CARD_COUNT]>,
|
||||||
|
black_hand: RwLock<[Card; HAND_CARD_COUNT]>,
|
||||||
current_player: RwLock<Player>,
|
current_player: RwLock<Player>,
|
||||||
red_stats: RwLock<Stats>,
|
red_stats: RwLock<Stats>,
|
||||||
black_stats: RwLock<Stats>,
|
black_stats: RwLock<Stats>,
|
||||||
|
@ -68,7 +74,8 @@ impl Model {
|
||||||
.expect("Failed to load font"),
|
.expect("Failed to load font"),
|
||||||
ups: 0f64,
|
ups: 0f64,
|
||||||
just_clicked: RwLock::default(),
|
just_clicked: RwLock::default(),
|
||||||
hand: RwLock::new(random()),
|
red_hand: RwLock::new(random()),
|
||||||
|
black_hand: RwLock::new(random()),
|
||||||
current_player: RwLock::default(),
|
current_player: RwLock::default(),
|
||||||
red_stats: RwLock::default(),
|
red_stats: RwLock::default(),
|
||||||
black_stats: RwLock::default(),
|
black_stats: RwLock::default(),
|
||||||
|
@ -81,6 +88,13 @@ impl Model {
|
||||||
Player::Black => &self.black_stats,
|
Player::Black => &self.black_stats,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fn hand_of(&self, player: Player) -> &'_ RwLock<[Card; HAND_CARD_COUNT]> {
|
||||||
|
match player {
|
||||||
|
Player::Red => &self.red_hand,
|
||||||
|
Player::Black => &self.black_hand,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(_app: &App, model: &mut Model, update: Update) {
|
fn update(_app: &App, model: &mut Model, update: Update) {
|
||||||
|
@ -103,7 +117,15 @@ fn event(_app: &App, model: &mut Model, event: WindowEvent) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KeyPressed(Key::R) => {
|
KeyPressed(Key::R) => {
|
||||||
*model.hand.write().expect("hand poisoned") = random();
|
*model
|
||||||
|
.hand_of(
|
||||||
|
*model
|
||||||
|
.current_player
|
||||||
|
.read()
|
||||||
|
.expect("current player poisoned"),
|
||||||
|
)
|
||||||
|
.write()
|
||||||
|
.expect("hand poisoned") = random();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -123,16 +145,15 @@ fn player_panel(
|
||||||
font: Font,
|
font: Font,
|
||||||
) {
|
) {
|
||||||
let rect = Rect::from_x_y_w_h(bounds.x(), bounds.y(), 1f32, 5f32).fit_into(&bounds);
|
let rect = Rect::from_x_y_w_h(bounds.x(), bounds.y(), 1f32, 5f32).fit_into(&bounds);
|
||||||
let rect = if player == Player::Red {
|
let rect = match player {
|
||||||
rect.align_right_of(bounds)
|
Player::Red => rect.align_right_of(bounds),
|
||||||
} else {
|
Player::Black => rect.align_left_of(bounds),
|
||||||
rect.align_left_of(bounds)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let player_stats = player_stats.read().expect("player stats poisoned");
|
let player_stats = player_stats.read().expect("player stats poisoned");
|
||||||
|
|
||||||
let status = if player == Player::Red {
|
let status = match player {
|
||||||
format!(
|
Player::Red => format!(
|
||||||
"{:<3} Builders\n{:<5} Bricks\n{:<3} Soldiers\n{:<4} Weapons\n{:<7} Magi\n{:<3} Crystals\n{:<5} Castle\n{:<6} Fence",
|
"{:<3} Builders\n{:<5} Bricks\n{:<3} Soldiers\n{:<4} Weapons\n{:<7} Magi\n{:<3} Crystals\n{:<5} Castle\n{:<6} Fence",
|
||||||
player_stats.builders,
|
player_stats.builders,
|
||||||
player_stats.bricks,
|
player_stats.bricks,
|
||||||
|
@ -142,9 +163,8 @@ fn player_panel(
|
||||||
player_stats.crystals,
|
player_stats.crystals,
|
||||||
player_stats.castle,
|
player_stats.castle,
|
||||||
player_stats.fence,
|
player_stats.fence,
|
||||||
)
|
),
|
||||||
} else {
|
Player::Black => format!(
|
||||||
format!(
|
|
||||||
"Builders {:>3}\nBricks {:>5}\nSoldiers {:>3}\nWeapons {:>4}\nMagi {:>7}\nCrystals {:>3}\nCastle {:>5}\nFence {:>6}",
|
"Builders {:>3}\nBricks {:>5}\nSoldiers {:>3}\nWeapons {:>4}\nMagi {:>7}\nCrystals {:>3}\nCastle {:>5}\nFence {:>6}",
|
||||||
player_stats.builders,
|
player_stats.builders,
|
||||||
player_stats.bricks,
|
player_stats.bricks,
|
||||||
|
@ -166,12 +186,14 @@ fn player_panel(
|
||||||
.font_size((rect.h() * 0.02f32).trunc() as u32)
|
.font_size((rect.h() * 0.02f32).trunc() as u32)
|
||||||
.align_text_middle_y()
|
.align_text_middle_y()
|
||||||
.font(font)
|
.font(font)
|
||||||
.color(if player == Player::Red { RED } else { WHITE });
|
.color(match player {
|
||||||
|
Player::Red => RED,
|
||||||
|
Player::Black => WHITE,
|
||||||
|
});
|
||||||
|
|
||||||
let drawing = if player == Player::Red {
|
let drawing = match player {
|
||||||
drawing.right_justify()
|
Player::Red => drawing.right_justify(),
|
||||||
} else {
|
Player::Black => drawing.left_justify(),
|
||||||
drawing.left_justify()
|
|
||||||
};
|
};
|
||||||
drawing.finish();
|
drawing.finish();
|
||||||
}
|
}
|
||||||
|
@ -194,12 +216,16 @@ fn hand(
|
||||||
.fit_into(&bounds)
|
.fit_into(&bounds)
|
||||||
.align_bottom_of(bounds);
|
.align_bottom_of(bounds);
|
||||||
|
|
||||||
|
let current_player = *model
|
||||||
|
.current_player
|
||||||
|
.read()
|
||||||
|
.expect("current player poisoned");
|
||||||
for (idx, rect) in hand_rect
|
for (idx, rect) in hand_rect
|
||||||
.split_horizontal::<HAND_CARD_COUNT>()
|
.split_horizontal::<HAND_CARD_COUNT>()
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
{
|
{
|
||||||
let card = model.hand.read().expect("hand poisoned")[idx];
|
let card = model.hand_of(current_player).read().expect("hand poisoned")[idx];
|
||||||
draw.rect()
|
draw.rect()
|
||||||
.xy(rect.xy())
|
.xy(rect.xy())
|
||||||
.wh(rect.wh())
|
.wh(rect.wh())
|
||||||
|
@ -219,28 +245,35 @@ fn hand(
|
||||||
.fit_into(rect)
|
.fit_into(rect)
|
||||||
.align_bottom_of(*rect);
|
.align_bottom_of(*rect);
|
||||||
|
|
||||||
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
|
draw.text(&format!(
|
||||||
{
|
"{:?}\n{}{}",
|
||||||
draw.text(&format!("{:?}\n+{}", card.effect.0, card.effect.1))
|
card.effect.0,
|
||||||
.color(
|
if matches!(card.effect.0, Stat::Attack) {
|
||||||
if *model
|
""
|
||||||
.current_player
|
} else {
|
||||||
.read()
|
"+"
|
||||||
.expect("current player poisoned")
|
},
|
||||||
== Player::Red
|
card.effect.1
|
||||||
{
|
))
|
||||||
RED
|
.color(
|
||||||
} else {
|
if matches!(
|
||||||
BLACK
|
*model
|
||||||
},
|
.current_player
|
||||||
)
|
.read()
|
||||||
.align_text_top()
|
.expect("current player poisoned"),
|
||||||
.xy(rect.xy())
|
Player::Red
|
||||||
.wh(rect.wh())
|
) {
|
||||||
.font_size((rect.h() * 0.08f32).trunc() as u32)
|
RED
|
||||||
.font(model.font.clone())
|
} else {
|
||||||
.finish();
|
BLACK
|
||||||
}
|
},
|
||||||
|
)
|
||||||
|
.align_text_top()
|
||||||
|
.xy(rect.xy())
|
||||||
|
.wh(rect.wh())
|
||||||
|
.font_size((rect.h() * 0.08f32).trunc() as u32)
|
||||||
|
.font(model.font.clone())
|
||||||
|
.finish();
|
||||||
|
|
||||||
draw.texture(&model.texture)
|
draw.texture(&model.texture)
|
||||||
.xy(image_rect.xy())
|
.xy(image_rect.xy())
|
||||||
|
@ -252,22 +285,27 @@ fn hand(
|
||||||
|
|
||||||
if *can_click {
|
if *can_click {
|
||||||
*can_click = false;
|
*can_click = false;
|
||||||
let mut current_player = model
|
|
||||||
.current_player
|
|
||||||
.write()
|
|
||||||
.expect("current player poisoned");
|
|
||||||
|
|
||||||
let damage = if matches!(card.effect.0, card::Stat::Attack) {
|
let damage = if matches!(card.effect.0, card::Stat::Attack) {
|
||||||
card.effect.1
|
card.effect.1
|
||||||
} else {
|
} else {
|
||||||
model
|
model
|
||||||
.stats_of(*current_player)
|
.stats_of(current_player)
|
||||||
.write()
|
.write()
|
||||||
.expect("player stats poisoned")
|
.expect("player stats poisoned")
|
||||||
.apply(card.effect);
|
.apply(card.effect);
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
model
|
||||||
|
.hand_of(current_player)
|
||||||
|
.write()
|
||||||
|
.expect("hand poisoned")[idx] = random();
|
||||||
|
|
||||||
|
let mut current_player = model
|
||||||
|
.current_player
|
||||||
|
.write()
|
||||||
|
.expect("current player poisoned");
|
||||||
*current_player = (*current_player).next();
|
*current_player = (*current_player).next();
|
||||||
|
|
||||||
let mut other_player_stats = model
|
let mut other_player_stats = model
|
||||||
|
@ -277,11 +315,6 @@ fn hand(
|
||||||
drop(current_player);
|
drop(current_player);
|
||||||
other_player_stats.damage(damage);
|
other_player_stats.damage(damage);
|
||||||
other_player_stats.apply_gains();
|
other_player_stats.apply_gains();
|
||||||
drop(other_player_stats);
|
|
||||||
|
|
||||||
println!("Click! {idx} {card:?}");
|
|
||||||
model.hand.write().expect("hand poisoned")[idx] = random();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ impl Stats {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Default, Debug, Clone, Copy)]
|
||||||
pub enum Player {
|
pub enum Player {
|
||||||
#[default]
|
#[default]
|
||||||
Red,
|
Red,
|
||||||
|
|
Loading…
Reference in a new issue