From 678f10ebb17facee6e704d0511e55f1ad2097d73 Mon Sep 17 00:00:00 2001 From: "sigonasr2, Sig, Sigo" Date: Wed, 28 Feb 2024 17:33:16 +0000 Subject: [PATCH] Setup tutorial and tutorial task features. Co-authored-by: sigonasr2 --- Adventures in Lestoria/ItemLoadoutWindow.cpp | 4 +- Adventures in Lestoria/Tutorial.cpp | 95 ++++++++++++++ Adventures in Lestoria/Tutorial.h | 129 +++++++++++++++++++ 3 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 Adventures in Lestoria/Tutorial.cpp create mode 100644 Adventures in Lestoria/Tutorial.h diff --git a/Adventures in Lestoria/ItemLoadoutWindow.cpp b/Adventures in Lestoria/ItemLoadoutWindow.cpp index 548802bd..684346c2 100644 --- a/Adventures in Lestoria/ItemLoadoutWindow.cpp +++ b/Adventures in Lestoria/ItemLoadoutWindow.cpp @@ -50,7 +50,9 @@ void Menu::InitializeItemLoadoutWindow(){ float itemLoadoutWindowWidth=(game->GetScreenSize().x-5.f); - itemLoadoutWindow->ADD("Loadout Label",MenuLabel)(geom2d::rect{{0,24},{itemLoadoutWindowWidth,24}},"Loadout",2,ComponentAttr::SHADOW|ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)END; + itemLoadoutWindow->ADD("Loadout Label",MenuLabel)(geom2d::rect{{0,24},{itemLoadoutWindowWidth,24}},"Setup Item Loadout",2,ComponentAttr::SHADOW|ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)END; + + itemLoadoutWindow->ADD("Loadout Description Label",MenuLabel)(geom2d::rect{{0,48},{itemLoadoutWindowWidth,24}},"Bring up to 3 items with you.",1,ComponentAttr::SHADOW)END; float buttonBorderPadding=64; diff --git a/Adventures in Lestoria/Tutorial.cpp b/Adventures in Lestoria/Tutorial.cpp new file mode 100644 index 00000000..7f270d2e --- /dev/null +++ b/Adventures in Lestoria/Tutorial.cpp @@ -0,0 +1,95 @@ +#pragma region License +/* +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2024 Joshua Sigona + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions or derivations of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions or derivative works in binary form must reproduce the above +copyright notice. This list of conditions and the following disclaimer must be +reproduced in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may +be used to endorse or promote products derived from this software without specific +prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +Portions of this software are copyright © 2024 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion +#include "Error.h" +#include "Tutorial.h" + +TutorialTaskName Tutorial::currentTaskState=TutorialTaskName::CHANGE_LOADOUT; + +void Tutorial::Initialize(){ + using enum TutorialTaskName; + #define CREATETASK(enum,class) taskList.insert(enum,std::make_unique()); + CREATETASK(CHANGE_LOADOUT,ChangeLoadoutTask); + CREATETASK(SET_LOADOUT_ITEM,SetLoadoutItemTask); + CREATETASK(MOVE_AROUND,MoveAroundTask); + ResetTasks(); +} + +TutorialTask::TutorialTask(){ + _Initialize(); +} + +void TutorialTask::_Initialize(){ + completed=false; + systemInitializeCalled=true; + Initialize(); +} + +void TutorialTask::Initialize(){ + if(!systemInitializeCalled)ERR("WARNING! Did not call _Initialize() first! Use TutorialTask::_Initialize() instead!"); + systemInitializeCalled=false; +} + +const bool TutorialTask::IsComplete()const{ + return completed; +} + +void TutorialTask::Update(){} + +void Tutorial::ResetTasks(){ + for(TutorialTask&tt:taskList){ + tt._Initialize(); + } +} + +void Tutorial::Update(){ + for(TutorialTask&tt:taskList){ + if(!tt.completed){ + tt.Update(); + if(tt.CompleteCondition()){ + tt.completed=true; + tt.OnComplete(); + } + } + } +} + +void Tutorial::Draw(){} + +const bool Tutorial::TaskIsComplete(TutorialTaskName task){ + return taskList.at(task)->IsComplete(); +} \ No newline at end of file diff --git a/Adventures in Lestoria/Tutorial.h b/Adventures in Lestoria/Tutorial.h new file mode 100644 index 00000000..1eb2d410 --- /dev/null +++ b/Adventures in Lestoria/Tutorial.h @@ -0,0 +1,129 @@ +#pragma region License +/* +License (OLC-3) +~~~~~~~~~~~~~~~ + +Copyright 2024 Joshua Sigona + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions or derivations of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions or derivative works in binary form must reproduce the above +copyright notice. This list of conditions and the following disclaimer must be +reproduced in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may +be used to endorse or promote products derived from this software without specific +prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +Portions of this software are copyright © 2024 The FreeType +Project (www.freetype.org). Please see LICENSE_FT.txt for more information. +All rights reserved. +*/ +#pragma endregion +#pragma once +#include +#include +#include "AdventuresInLestoria.h" + +INCLUDE_game + +enum class TutorialTaskName{ + CHANGE_LOADOUT, + SET_LOADOUT_ITEM, + MOVE_AROUND, +}; + +class TutorialTask{ + friend class Tutorial; + protected: + bool completed=false; + bool systemInitializeCalled=false; + TutorialTask(); + private: + void _Initialize(); + //Actions that occur when this task is reset/locked. DO NOT CALL DIRECTLY, USE _Initialize()! + virtual void Initialize(); + virtual void Update(); + //Returns true when the task has detected it is completed. + virtual bool CompleteCondition()=0; + //Action occurs when the task completes. + virtual void OnComplete()=0; + const bool IsComplete()const; +}; + +class Tutorial{ +public: + static void Initialize(); + static void ResetTasks(); + static void Update(); + static void Draw(); + static const bool TaskIsComplete(TutorialTaskName task); +private: + static TutorialTaskName currentTaskState; + static std::unordered_map>taskList; +}; + +class ChangeLoadoutTask:protected TutorialTask{ + inline ChangeLoadoutTask():TutorialTask(){}; + virtual inline void Initialize()override final{ + Component(OVERWORLD_LEVEL_SELECT,"Enter Button")->SetGrayedOut(true); + } + virtual inline bool CompleteCondition()override final{ + return GameState::STATE==GameState::states[States::GAME_RUN]; + } + virtual inline void OnComplete()override final{ + Component(OVERWORLD_LEVEL_SELECT,"Enter Button")->SetGrayedOut(false); + } +}; + +class SetLoadoutItemTask:protected TutorialTask{ + inline SetLoadoutItemTask():TutorialTask(){}; + virtual inline void Initialize()override final{ + Component(ITEM_LOADOUT,"Start Level Button")->SetGrayedOut(true); + } + virtual inline bool CompleteCondition()override final{ + for(int i=0;iGetLoadoutSize();i++){ + if(!ISBLANK(game->GetLoadoutItem(i))){ + return true; + } + } + return false; + } + virtual inline void OnComplete()override final{ + Component(ITEM_LOADOUT,"Start Level Button")->SetGrayedOut(false); + } +}; + +class MoveAroundTask:protected TutorialTask{ + vf2d initialPlayerPos={}; + inline MoveAroundTask():TutorialTask(){}; + virtual inline void Initialize()override final{ + initialPlayerPos={}; + } + virtual inline void Update()override final{ + if(!LoadingScreen::loading&&initialPlayerPos=={}){ + initialPlayerPos=game->GetPlayer()->GetPos(); + } + } + virtual inline bool CompleteCondition()override final{ + return initialPlayerPos!={}&&geom2d::line(initialPlayerPos,game->GetPlayer()).length()>60; + } + virtual inline void OnComplete()override final{ + initialPlayerPos={}; + } +}; \ No newline at end of file