diff --git a/README.md b/README.md index 26f2b25..64d933c 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,14 @@ specifically designed to be used when players share a deck definitely not a shameless untap clone # todo -+ Add drag-and-drop from hand and piles -+ Add hotkeys for every zone (Almost done!) ++ Add hotkeys for every zone (*Really* almost done!) + ~~Add untap all hotkey~~ + Add viewing top of deck ++ ~~Add searching deck~~ + Add score values (usable for life counters) ++ Make events visible # maybe todo ++ Add drag-and-drop from hand and piles + Make deck information, piles, and score info json-configurable + Use cookies instead of hardcoded url uuid diff --git a/src/game.rs b/src/game.rs index 457bc44..fc8c1d3 100644 --- a/src/game.rs +++ b/src/game.rs @@ -58,6 +58,9 @@ enum Event { Unkill(Uuid, bool), TransferDeadCard(Uuid, bool), UntapAll(Player), + ViewDeck(Player), + Yoink(Player), + YoinkMill(Uuid), } #[derive(Serialize, Clone, Debug)] @@ -168,6 +171,32 @@ pub fn draw(game_state: &mut GameState, count: usize, player: Player) { ); } +pub fn yoink(game_state: &mut GameState, deck_index: usize, player: Player) { + let player_hand = match player { + Player::A => &mut game_state.hands[0], + _ => &mut game_state.hands[1], + }; + game_state.events.push(CountedEvent { + id: game_state.events.len(), + event: Event::Yoink(player.clone()), + }); + player_hand.cards.push(game_state.deck.remove(deck_index).unwrap()); +} + +pub fn yoink_mill(game_state: &mut GameState, deck_index: usize, shadow: bool) { + let card = game_state.deck.remove(deck_index).unwrap(); + game_state.events.push(CountedEvent { + id: game_state.events.len(), + event: Event::YoinkMill(card.clone()), + }); + if shadow { + game_state.shadow_realm.push(card); + } else { + game_state.discard_pile.push(card); + } + +} + pub fn shuffle(game_state: &mut GameState, player: Player) { game_state.events.push(CountedEvent { id: game_state.events.len(), @@ -384,3 +413,15 @@ pub fn untap_all(game_state: &mut GameState, player: Player) { } } } + +pub fn get_deck(game_state: &mut GameState, player: Player) -> String { + game_state.events.push(CountedEvent { + id: game_state.events.len(), + event: Event::ViewDeck(player), + }); + let deck_copy = game_state.deck.clone(); + //let copy_slice = deck_copy.make_contiguous(); + //copy_slice.sort(); + /*let final_card_list = copy_slice.into_iter().map(|card| card.braced().to_string()).collect::>();*/ + serde_json::to_string(&deck_copy).unwrap() +} diff --git a/src/main.rs b/src/main.rs index a5f01ee..44e9a8a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,7 +26,7 @@ fn get_events(game_state_arc: &State) -> String { format!("{}", game::get_events(&game_state)) } -#[post("//shuffle")] +#[get("//shuffle")] fn shuffle( uuid: Uuid, game_state_arc: &State, @@ -247,6 +247,57 @@ fn unshadow( Ok(format!("{}", game::get_events(&game_state))) } +#[get("//yoink/")] +fn yoink( + uuid: Uuid, + index: usize, + game_state_arc: &State, + player_uuids: &State, +) -> Result> { + let player = match player_uuids.map.get(&uuid) { + Some(player) => player, + None => return Err(BadRequest(format!("Invalid player {}.", uuid))), + }; + let game_state_mutex = Arc::clone(&game_state_arc.state); + let mut game_state = game_state_mutex.lock().unwrap(); + game::yoink(&mut game_state, index, player.clone()); + Ok(format!("{}", game::get_events(&game_state))) +} + +#[get("//yoink_mill/")] +fn yoink_mill( + uuid: Uuid, + index: usize, + game_state_arc: &State, + player_uuids: &State, +) -> Result> { + match player_uuids.map.get(&uuid) { + Some(_) => (), + None => return Err(BadRequest(format!("Invalid player {}.", uuid))), + }; + let game_state_mutex = Arc::clone(&game_state_arc.state); + let mut game_state = game_state_mutex.lock().unwrap(); + game::yoink_mill(&mut game_state, index, false); + Ok(format!("{}", game::get_events(&game_state))) +} + +#[get("//yoink_xmill/")] +fn yoink_xmill( + uuid: Uuid, + index: usize, + game_state_arc: &State, + player_uuids: &State, +) -> Result> { + match player_uuids.map.get(&uuid) { + Some(_) => (), + None => return Err(BadRequest(format!("Invalid player {}.", uuid))), + }; + let game_state_mutex = Arc::clone(&game_state_arc.state); + let mut game_state = game_state_mutex.lock().unwrap(); + game::yoink_mill(&mut game_state, index, true); + Ok(format!("{}", game::get_events(&game_state))) +} + #[get("//undiscard/")] fn undiscard( uuid: Uuid, @@ -316,6 +367,24 @@ fn get_state( )) } +#[get("//get_deck")] +fn get_deck( + uuid: Uuid, + game_state_arc: &State, + player_uuids: &State, +) -> Result> { + let game_state_mutex = Arc::clone(&game_state_arc.state); + let mut game_state = game_state_mutex.lock().unwrap(); + let player = match player_uuids.map.get(&uuid) { + Some(player) => player, + None => return Err(BadRequest(format!("Invalid player {}.", uuid))), + }; + Ok(format!( + "{}", + game::get_deck(&mut game_state, player.clone()) + )) +} + #[get("//untap_all")] fn untap_all( uuid: Uuid, @@ -427,7 +496,7 @@ struct PlayerUuids { #[launch] fn rocket() -> _ { - let mut game_state = game::new(); + let game_state = game::new(); //game::draw(&mut game_state, 7, Player::A); //game::draw(&mut game_state, 7, Player::B); let game_state_arc = Arc::new(Mutex::new(game_state)); @@ -482,6 +551,10 @@ fn rocket() -> _ { undiscard, remember, untap_all, + get_deck, + yoink, + yoink_mill, + yoink_xmill, ], ) .manage(ArcMutexGameState { diff --git a/web/dynamic/index.html b/web/dynamic/index.html index faa9a53..569d3ca 100644 --- a/web/dynamic/index.html +++ b/web/dynamic/index.html @@ -26,7 +26,7 @@