Commit 0761cdeb authored by Rahix's avatar Rahix 🦀
Browse files

Add cheats!

parent d7cf3670
use crate::gamestate;
use anyhow::Context;
use wasm_bindgen::prelude::*;
static mut SMHANDLE: Option<gamestate::StateMachineHandle> = None;
static mut CHEAT_PASSWORD: Option<String> = None;
pub fn initialize_cheats(handle: gamestate::StateMachineHandle) {
// SAFETY: We know that concurrency is impossible because Javascript is (in this case)
// single-threaded.
unsafe {
SMHANDLE = Some(handle);
}
}
#[non_exhaustive]
#[derive(Debug, Clone)]
pub enum CheatCommand {
SetSanity(f32),
}
fn get_cheat_state() -> anyhow::Result<&'static gamestate::StateMachineHandle> {
// SAFETY: We know that concurrency is impossible because Javascript is (in this case)
// single-threaded.
unsafe {
if CHEAT_PASSWORD.as_deref() != Some(option_env!("ENGEL_CHEAT_CODE").unwrap_or("uhagre7")) {
anyhow::bail!("you shall not cheat!");
}
SMHANDLE.as_ref().context("cheats not initialized")
}
}
#[wasm_bindgen]
pub fn cheat_enable(password: &str) {
// SAFETY: We know that concurrency is impossible because Javascript is (in this case)
// single-threaded.
unsafe {
CHEAT_PASSWORD = Some(
password
.chars()
.map(|c| match c {
'A'...'M' | 'a'...'m' => ((c as u8) + 13) as char,
'N'...'Z' | 'n'...'z' => ((c as u8) - 13) as char,
'0'...'9' => (0x39 - (c as u8) + 0x30) as char,
_ => c,
})
.collect(),
);
}
}
#[wasm_bindgen]
pub fn cheat_set_sanity(val: f32) -> Result<(), wasm_bindgen::JsValue> {
match || -> anyhow::Result<()> {
// this is nice
let state = get_cheat_state()?;
state.do_cheat(CheatCommand::SetSanity(val));
Ok(())
}() {
// this is not nice
Ok(()) => Ok(()),
Err(err) => Err(wasm_bindgen::JsValue::from_str(&format!("{}", err))),
}
}
......@@ -59,6 +59,7 @@ pub trait State {
}
}
#[non_exhaustive]
#[derive(Debug, Clone)]
pub enum Event<'a> {
MouseClick {
......@@ -67,6 +68,7 @@ pub enum Event<'a> {
},
KeyDown(&'a str),
KeyUp(&'a str),
Cheat(crate::cheats::CheatCommand),
}
struct EventHandlers {
......@@ -179,6 +181,14 @@ impl StateMachineHandle {
let t = StateMachine::active(&self.0).event(event);
self.do_transition(t)
}
pub fn do_cheat(&self, cheat: crate::cheats::CheatCommand) {
self.do_event(Event::Cheat(cheat))
}
pub fn active_state(&self) -> std::cell::RefMut<Box<dyn State>> {
std::cell::RefMut::map(StateMachine::active(&self.0), |storage| &mut storage.state)
}
}
pub struct StateInitializer<'a> {
......@@ -284,6 +294,8 @@ impl StateMachine {
loop_scheduled: false,
}));
crate::cheats::initialize_cheats(StateMachineHandle::new(&this));
// Sadly Rc::new_cyclic() isn't stable yet ...
let loop_handler = {
let this = this.clone();
......
......@@ -3,6 +3,7 @@ use js_sys;
use wasm_bindgen::prelude::*;
pub mod angel_shifts;
pub mod cheats;
pub mod colliders;
pub mod colors;
pub mod components;
......
use crate::angel_shifts;
use crate::cheats;
use crate::colors;
use crate::components;
use crate::gamestate;
......@@ -120,8 +121,12 @@ impl gamestate::State for HeavenState {
self.player.clone(),
self.assigned_shift.take().unwrap(),
)),
gamestate::Event::Cheat(cheats::CheatCommand::SetSanity(val)) => {
self.player.sanity = val;
gamestate::Transition::Keep
}
event => {
crate::console_log!("unknown event {:?}", event);
crate::console_warn!("unknown event: {:?}", event);
gamestate::Transition::Keep
}
}
......
use crate::angel_shifts;
use crate::cheats;
use crate::colliders;
use crate::colors;
use crate::components;
......@@ -110,10 +111,11 @@ impl gamestate::State for InGameState {
fn event(&mut self, event: gamestate::Event) -> gamestate::Transition {
use legion::IntoQuery;
let player = self.resources.get::<resources::Player>().unwrap().0.clone();
let player_movable = <&mut components::Movable>::query()
.get_mut(&mut self.world, player)
.unwrap();
let player_id = self.resources.get::<resources::Player>().unwrap().0.clone();
let (player_movable, player) =
<(&mut components::Movable, &mut components::Player)>::query()
.get_mut(&mut self.world, player_id)
.unwrap();
match event {
gamestate::Event::KeyDown("w") | gamestate::Event::KeyDown("ArrowUp") => {
player_movable.velocity.y = -300.0
......@@ -139,7 +141,12 @@ impl gamestate::State for InGameState {
gamestate::Event::KeyUp("d") | gamestate::Event::KeyUp("ArrowRight") => {
player_movable.velocity.x = 0.0
}
_ => (),
gamestate::Event::Cheat(cheats::CheatCommand::SetSanity(val)) => {
player.sanity = val;
}
event => {
crate::console_warn!("unknown event: {:?}", event);
}
}
if player_movable.velocity.x != 0.0 || player_movable.velocity.y != 0.0 {
player_movable.velocity = player_movable.velocity.normalize() * 300.0;
......
......@@ -3,3 +3,8 @@ import * as wasm from "engel-simulator-2020";
import "./styles.scss";
wasm.start();
(window as any).cheats = {
set_sanity: wasm.cheat_set_sanity,
enable: wasm.cheat_enable,
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment