use rusting_engine::prelude::*;
#[derive(Clone, Copy, PartialEq)]
enum Kind {
Strike,
Guard,
Heal,
}
const DECK: [(Kind, i32); 10] = [
(Kind::Strike, 6),
(Kind::Strike, 6),
(Kind::Strike, 6),
(Kind::Strike, 6),
(Kind::Guard, 6),
(Kind::Guard, 6),
(Kind::Guard, 6),
(Kind::Heal, 5),
(Kind::Heal, 5),
(Kind::Heal, 5),
];
const FOE_MIN: i32 = 2;
const FOE_SPREAD: u64 = 6;
fn roll(scene: &GameScene<'_>, stream: u64, n: u64) -> u64 {
let mut z = scene
.seed()
.wrapping_add(stream << 32 | n)
.wrapping_mul(0x9E37_79B9_7F4A_7C15);
z = (z ^ (z >> 30)).wrapping_mul(0xBF58_476D_1CE4_E5B9);
z = (z ^ (z >> 27)).wrapping_mul(0x94D0_49BB_1331_11EB);
z ^ (z >> 31)
}
fn draw(scene: &mut GameScene<'_>) -> i32 {
let drawn = scene.add_to_counter("drawn", 1) - 1;
let (round, at) = (drawn as u64 / 10, drawn as usize % 10);
let mut order: Vec<i32> = (0..10).collect();
for i in (1..order.len()).rev() {
let j = roll(scene, round + 1, i as u64) as usize % (i + 1);
order.swap(i, j);
}
order[at]
}
fn show(scene: &mut GameScene<'_>, slot: usize) {
let (kind, power) =
DECK[scene.counter_value(&format!("hand_{slot}")) as usize];
let (label, color) = match kind {
Kind::Strike => ("Strike", [0.85, 0.25, 0.2, 1.0]),
Kind::Guard => ("Guard", [0.25, 0.45, 0.9, 1.0]),
Kind::Heal => ("Heal", [0.3, 0.8, 0.35, 1.0]),
};
scene.set_hud(&format!("Card {slot}"), |hud| {
hud.text = format!("{slot}: {label} {power}");
});
scene.set_color(&format!("Slot {slot}"), color);
}
pub fn update(scene: &mut GameScene<'_>, _time: &FrameTime) {
if scene.pressed("restart") {
scene.restart();
return;
}
if scene.counter_complete("foe_damage") || scene.counter_complete("damage")
{
return;
}
if scene.counter_or("drawn", 0) == 0 {
for slot in 1..=3 {
let card = draw(scene);
scene.set_counter(&format!("hand_{slot}"), card);
show(scene, slot);
}
let intent = FOE_MIN + (roll(scene, 0, 0) % FOE_SPREAD) as i32;
scene.set_counter("intent", intent);
}
let clicked = scene.clicked();
let Some(slot) = (1..=3).find(|slot| {
scene.pressed(&format!("play_{slot}"))
|| clicked.contains(&format!("Card {slot}"))
}) else {
return;
};
let (kind, power) =
DECK[scene.counter_value(&format!("hand_{slot}")) as usize];
scene.flash(&format!("Slot {slot}"));
let mut block = 0;
match kind {
Kind::Strike => {
scene.add_to_counter("foe_damage", power);
scene.flash("Foe");
}
Kind::Guard => block = power,
Kind::Heal => {
let healed = power.min(scene.counter_value("damage"));
scene.add_to_counter("damage", -healed);
}
}
if scene.counter_complete("foe_damage") {
return;
}
let hit = (scene.counter_value("intent") - block).max(0);
if hit > 0 {
scene.add_to_counter("damage", hit);
scene.add_trauma("Game Camera", 0.1 * hit as f32);
}
let turn = scene.add_to_counter("turn", 1) as u64;
let intent = FOE_MIN + (roll(scene, 0, turn) % FOE_SPREAD) as i32;
scene.set_counter("intent", intent);
let card = draw(scene);
scene.set_counter(&format!("hand_{slot}"), card);
show(scene, slot);
}
rusting_game!(update);