diff --git a/SpaceCadetPinball/TBlocker.cpp b/SpaceCadetPinball/TBlocker.cpp index 5e92388..d0d77ce 100644 --- a/SpaceCadetPinball/TBlocker.cpp +++ b/SpaceCadetPinball/TBlocker.cpp @@ -48,7 +48,9 @@ int TBlocker::Message(MessageCode code, float value) SpriteSet(0); if (Timer) timer::kill(Timer); - Timer = timer::set(std::max(value, 0.0f), this, TimerExpired); + Timer = 0; + if (value >= 0) + Timer = timer::set(value, this, TimerExpired); break; case MessageCode::TBlockerRestartTimeout: if (Timer) diff --git a/SpaceCadetPinball/TPinballTable.cpp b/SpaceCadetPinball/TPinballTable.cpp index 5c7ce71..5638ccc 100644 --- a/SpaceCadetPinball/TPinballTable.cpp +++ b/SpaceCadetPinball/TPinballTable.cpp @@ -393,6 +393,8 @@ int TPinballTable::Message(MessageCode code, float value) } else { + // Some of the control cheats persist across games. + // Was this loose anti-cheat by design? CheatsUsed = 0; Message(MessageCode::Reset, 0.0); auto ball = BallList[0]; diff --git a/SpaceCadetPinball/control.cpp b/SpaceCadetPinball/control.cpp index f32672f..df1ae4c 100644 --- a/SpaceCadetPinball/control.cpp +++ b/SpaceCadetPinball/control.cpp @@ -771,7 +771,7 @@ component_tag_base* control::simple_components[145] }; int control::waiting_deployment_flag; -bool control::table_unlimited_balls = false; +bool control::table_unlimited_balls = false, control::easyMode = false; int control::extraball_light_flag; Msg control::RankRcArray[9] = { @@ -903,7 +903,7 @@ void control::pbctrl_bdoor_controller(char key) { // Buffer large enough for longest cheat + null static char cheatBuffer[11 + 1]{}; - static char* bufferEnd = &cheatBuffer[11]; + static const char* bufferEnd = &cheatBuffer[11]; static const char* quotes[8] { "Hey, is that a screen saver?", @@ -949,6 +949,18 @@ void control::pbctrl_bdoor_controller(char key) mission_text_box->Display(quote, time += 3); return; } + else if (strcmp(bufferEnd - 9, "easy mode") == 0) + { + easyMode ^= true; + if (easyMode) + { + DrainBallBlockerControl(MessageCode::TBlockerEnable, block1); + gate1->Message(MessageCode::TGateDisable, 0.0); + gate2->Message(MessageCode::TGateDisable, 0.0); + } + else + DrainBallBlockerControl(MessageCode::ControlTimerExpired, block1); + } else { return; @@ -1165,13 +1177,13 @@ void control::BumperControl(MessageCode code, TPinballComponent* caller) void control::LeftKickerControl(MessageCode code, TPinballComponent* caller) { - if (code == MessageCode::ControlTimerExpired) + if (code == MessageCode::ControlTimerExpired && !easyMode) gate1->Message(MessageCode::TGateEnable, 0.0); } void control::RightKickerControl(MessageCode code, TPinballComponent* caller) { - if (code == MessageCode::ControlTimerExpired) + if (code == MessageCode::ControlTimerExpired && !easyMode) gate2->Message(MessageCode::TGateEnable, 0.0); } @@ -1235,33 +1247,35 @@ void control::DeploymentChuteToTableOneWayControl(MessageCode code, TPinballComp void control::DrainBallBlockerControl(MessageCode code, TPinballComponent* caller) { - MessageCode lightMessage; - float blockerDuration; - auto block = static_cast(caller); - if (code == MessageCode::TBlockerEnable) + switch (code) { - block->MessageField = 1; - blockerDuration = static_cast(block->InitialDuration); - block->Message(MessageCode::TBlockerEnable, blockerDuration); - lightMessage = MessageCode::TLightTurnOnTimed; - } - else - { - if (code != MessageCode::ControlTimerExpired) - return; - if (block->MessageField != 1) + case MessageCode::TBlockerEnable: { - block->MessageField = 0; - block->Message(MessageCode::TBlockerDisable, 0.0); - return; + block->MessageField = 1; + auto blockerDuration = !easyMode ? static_cast(block->InitialDuration) : -1; + block->Message(MessageCode::TBlockerEnable, blockerDuration); + lite1->Message(MessageCode::TLightTurnOnTimed, blockerDuration); + break; + } + case MessageCode::ControlTimerExpired: + { + if (block->MessageField == 1) + { + block->MessageField = 2; + auto blockerDuration = static_cast(block->ExtendedDuration); + block->Message(MessageCode::TBlockerRestartTimeout, blockerDuration); + lite1->Message(MessageCode::TLightFlasherStartTimed, blockerDuration); + break; + } + else + { + block->MessageField = 0; + block->Message(MessageCode::TBlockerDisable, 0.0); + break; + } } - block->MessageField = 2; - blockerDuration = static_cast(block->ExtendedDuration); - block->Message(MessageCode::TBlockerRestartTimeout, blockerDuration); - lightMessage = MessageCode::TLightFlasherStartTimed; } - lite1->Message(lightMessage, blockerDuration); } void control::LaunchRampControl(MessageCode code, TPinballComponent* caller) @@ -2478,6 +2492,8 @@ void control::PlungerControl(MessageCode code, TPinballComponent* caller) if (code == MessageCode::PlungerFeedBall) { MissionControl(MessageCode::ControlMissionStarted, nullptr); + if (easyMode && !block1->ActiveFlag) + DrainBallBlockerControl(MessageCode::TBlockerEnable, block1); } else if (code == MessageCode::PlungerStartFeedTimer) { diff --git a/SpaceCadetPinball/control.h b/SpaceCadetPinball/control.h index 021238c..a5999e1 100644 --- a/SpaceCadetPinball/control.h +++ b/SpaceCadetPinball/control.h @@ -68,7 +68,7 @@ public: static component_info score_components[88]; static component_tag_base* simple_components[145]; static int waiting_deployment_flag; - static bool table_unlimited_balls; + static bool table_unlimited_balls, easyMode; static Msg RankRcArray[9], MissionRcArray[17]; static int mission_select_scores[17]; static std::reference_wrapper WormholeSinkArray[3]; diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index 22dee7b..74be159 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -732,6 +732,8 @@ void winmain::RenderUi() pb::PushCheat("rmax"); if (pb::FullTiltMode && ImGui::MenuItem("quote")) pb::PushCheat("quote"); + if (ImGui::MenuItem("easy mode", nullptr, control::easyMode)) + pb::PushCheat("easy mode"); ImGui::EndMenu(); }