mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-04-28 15:57:59 +03:00
Savegame functions (#1217)
* Possibly make loading work * fix compile error * Move LevelComplete reset to more appropriate place * Implement Delete save and move functions to FlowHandler * Fixes and optimizations * Rename global * rename func names to more meaningful ones, correct grammar. * add a check to see if file actually exists before loading * correct. * add LogLevel for Delete() func * Revert "correct." This reverts commit5e332bba95
. * Revert "add a check to see if file actually exists before loading" This reverts commitef9fb63aa2
. * Fix attempts to load savegames from incorrect slots * Simplify savegame delete function * Update Changes.txt * Minor changes * Disable Save/Load quick actions when EnableLoadSave is false * Formatting * Implement enable load/save into lua * Fix merge * Update Changes.txt * Update savegame.cpp * Fix savegame count not properly increasing, don't reload headers every frame in menu * Update savegame.cpp * Set TimeInMenu default value to -1.0f * Minor changes --------- Co-authored-by: Lwmte <3331699+Lwmte@users.noreply.github.com> Co-authored-by: Sezz <sezzary@outlook.com>
This commit is contained in:
parent
ae03c3e046
commit
bfe545e375
15 changed files with 229 additions and 71 deletions
|
@ -12,6 +12,7 @@ Version 1.1.1
|
|||
* Fix TR2 doberman crashing the game when killed by explosive weapons.
|
||||
* Fix volume change in settings not affecting voice track.
|
||||
* Fix several lighting bugs.
|
||||
* Fix savegame count not properly increasing.
|
||||
* Overhaul look mode:
|
||||
- Allow for consistent and wider viewing angles while crawling, crouching, and hanging.
|
||||
- Improve movement and control.
|
||||
|
@ -25,10 +26,12 @@ Version 1.1.1
|
|||
- A negative value requires a trigger to activate.
|
||||
|
||||
Lua API changes:
|
||||
* Add Flow::EnableLoadSave() function to disable savegames.
|
||||
* Add Flow::EnablePointFilter() function to disable bilinear filtering.
|
||||
* Add Lara::GetAmmoType() function to read the ammo that Lara is using.
|
||||
* Add Lara::GetControlLock() and Lara::SetControlLock() functions to handle controls locking.
|
||||
* Add Logic.HandleEvent() function to call node events.
|
||||
* Add functions to load, save, and delete savegames.
|
||||
* Make Vec2 object float-based instead of integer-based.
|
||||
* Add Vec2 arithmetic for division with a number and multiplication with another Vec2.
|
||||
* Add log messages warnings to functions AddCallback and RemoveCallback.
|
||||
|
|
|
@ -93,7 +93,7 @@ bool ThreadEnded;
|
|||
|
||||
int RequiredStartPos;
|
||||
int CurrentLevel;
|
||||
int LevelComplete;
|
||||
int NextLevel;
|
||||
|
||||
int SystemNameHash = 0;
|
||||
|
||||
|
@ -614,16 +614,20 @@ GameStatus HandleMenuCalls(bool isTitle)
|
|||
|
||||
// Does the player want to enter inventory?
|
||||
if (IsClicked(In::Save) && LaraItem->HitPoints > 0 &&
|
||||
g_Gui.GetInventoryMode() != InventoryMode::Save)
|
||||
g_Gui.GetInventoryMode() != InventoryMode::Save &&
|
||||
g_GameFlow->IsLoadSaveEnabled())
|
||||
{
|
||||
SaveGame::LoadSavegameInfos();
|
||||
g_Gui.SetInventoryMode(InventoryMode::Save);
|
||||
|
||||
if (g_Gui.CallInventory(LaraItem, false))
|
||||
result = GameStatus::SaveGame;
|
||||
}
|
||||
else if (IsClicked(In::Load) &&
|
||||
g_Gui.GetInventoryMode() != InventoryMode::Load)
|
||||
g_Gui.GetInventoryMode() != InventoryMode::Load &&
|
||||
g_GameFlow->IsLoadSaveEnabled())
|
||||
{
|
||||
SaveGame::LoadSavegameInfos();
|
||||
g_Gui.SetInventoryMode(InventoryMode::Load);
|
||||
|
||||
if (g_Gui.CallInventory(LaraItem, false))
|
||||
|
@ -668,8 +672,16 @@ GameStatus HandleGlobalInputEvents(bool isTitle)
|
|||
}
|
||||
|
||||
// Check if level has been completed.
|
||||
if (LevelComplete)
|
||||
// Negative NextLevel indicates that a savegame must be loaded from corresponding slot.
|
||||
if (NextLevel > 0)
|
||||
{
|
||||
return GameStatus::LevelComplete;
|
||||
}
|
||||
else if (NextLevel < 0)
|
||||
{
|
||||
g_GameFlow->SelectedSaveGame = -(NextLevel + 1);
|
||||
return GameStatus::LoadGame;
|
||||
}
|
||||
|
||||
return GameStatus::None;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ extern bool ThreadEnded;
|
|||
|
||||
extern int RequiredStartPos;
|
||||
extern int CurrentLevel;
|
||||
extern int LevelComplete;
|
||||
extern int NextLevel;
|
||||
extern int SystemNameHash;
|
||||
|
||||
extern bool InItemControlLoop;
|
||||
|
|
|
@ -332,7 +332,7 @@ void Turn180(ItemInfo* item)
|
|||
|
||||
void FinishLevel(ItemInfo* item)
|
||||
{
|
||||
LevelComplete = CurrentLevel + 1;
|
||||
NextLevel = CurrentLevel + 1;
|
||||
}
|
||||
|
||||
void VoidEffect(ItemInfo* item)
|
||||
|
|
|
@ -751,7 +751,7 @@ void TestTriggers(int x, int y, int z, FloorInfo* floor, VolumeActivator activat
|
|||
|
||||
case TO_FINISH:
|
||||
RequiredStartPos = false;
|
||||
LevelComplete = CurrentLevel + 1;
|
||||
NextLevel = CurrentLevel + 1;
|
||||
break;
|
||||
|
||||
case TO_CD:
|
||||
|
|
|
@ -202,7 +202,7 @@ namespace TEN::Gui
|
|||
return Rings[(int)ringType];
|
||||
}
|
||||
|
||||
short GuiController::GetSelectedOption()
|
||||
int GuiController::GetSelectedOption()
|
||||
{
|
||||
return SelectedOption;
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ namespace TEN::Gui
|
|||
switch (MenuToDisplay)
|
||||
{
|
||||
case Menu::Title:
|
||||
OptionCount = numTitleOptions;
|
||||
OptionCount = g_GameFlow->IsLoadSaveEnabled() ? numTitleOptions : (numTitleOptions - 1);
|
||||
break;
|
||||
|
||||
case Menu::SelectLevel:
|
||||
|
@ -378,7 +378,12 @@ namespace TEN::Gui
|
|||
|
||||
if (MenuToDisplay == Menu::Title)
|
||||
{
|
||||
switch (SelectedOption)
|
||||
// Skip load game entry if loading and saving is disabled.
|
||||
int realSelectedOption = SelectedOption;
|
||||
if (!g_GameFlow->IsLoadSaveEnabled() && SelectedOption > TitleOption::NewGame)
|
||||
realSelectedOption++;
|
||||
|
||||
switch (realSelectedOption)
|
||||
{
|
||||
case TitleOption::NewGame:
|
||||
if (g_GameFlow->IsLevelSelectEnabled())
|
||||
|
@ -388,7 +393,9 @@ namespace TEN::Gui
|
|||
MenuToDisplay = Menu::SelectLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
inventoryResult = InventoryResult::NewGame;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
@ -396,6 +403,7 @@ namespace TEN::Gui
|
|||
selectedOptionBackup = SelectedOption;
|
||||
SelectedOption = 0;
|
||||
MenuToDisplay = Menu::LoadGame;
|
||||
SaveGame::LoadSavegameInfos();
|
||||
break;
|
||||
|
||||
case TitleOption::Options:
|
||||
|
@ -1680,7 +1688,7 @@ namespace TEN::Gui
|
|||
if (lara->Inventory.Diary.Present)
|
||||
InsertObjectIntoList(INV_OBJECT_DIARY);
|
||||
|
||||
if (g_GameFlow->EnableLoadSave)
|
||||
if (g_GameFlow->IsLoadSaveEnabled())
|
||||
{
|
||||
InsertObjectIntoList(INV_OBJECT_LOAD_FLOPPY);
|
||||
InsertObjectIntoList(INV_OBJECT_SAVE_FLOPPY);
|
||||
|
@ -2532,12 +2540,12 @@ namespace TEN::Gui
|
|||
break;
|
||||
|
||||
case MenuType::Load:
|
||||
// fill_up_savegames_array // Maybe not?
|
||||
SaveGame::LoadSavegameInfos();
|
||||
SetInventoryMode(InventoryMode::Load);
|
||||
break;
|
||||
|
||||
case MenuType::Save:
|
||||
// fill_up_savegames_array
|
||||
SaveGame::LoadSavegameInfos();
|
||||
SetInventoryMode(InventoryMode::Save);
|
||||
break;
|
||||
|
||||
|
@ -3386,7 +3394,7 @@ namespace TEN::Gui
|
|||
}
|
||||
}
|
||||
|
||||
short GuiController::GetLoadSaveSelection()
|
||||
int GuiController::GetLoadSaveSelection()
|
||||
{
|
||||
return SelectedSaveSlot;
|
||||
}
|
||||
|
@ -3456,7 +3464,6 @@ namespace TEN::Gui
|
|||
if (GuiIsSelected())
|
||||
{
|
||||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
g_GameScript->OnSave();
|
||||
SaveGame::Save(SelectedSaveSlot);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ namespace TEN::Gui
|
|||
int OptionCount;
|
||||
int SelectedSaveSlot;
|
||||
|
||||
float TimeInMenu = 0.0f;
|
||||
float TimeInMenu = -1.0f;
|
||||
SettingsData CurrentSettings;
|
||||
|
||||
// Inventory variables
|
||||
|
@ -183,14 +183,14 @@ namespace TEN::Gui
|
|||
|
||||
// Getters
|
||||
const InventoryRing& GetRing(RingTypes ringType);
|
||||
short GetSelectedOption();
|
||||
int GetSelectedOption();
|
||||
Menu GetMenuToDisplay();
|
||||
InventoryMode GetInventoryMode();
|
||||
int GetInventoryItemChosen();
|
||||
int GetEnterInventory();
|
||||
int GetLastInventoryItem();
|
||||
SettingsData& GetCurrentSettings();
|
||||
short GetLoadSaveSelection();
|
||||
int GetLoadSaveSelection();
|
||||
|
||||
// Setters
|
||||
void SetSelectedOption(int menu);
|
||||
|
|
|
@ -45,7 +45,9 @@ using namespace TEN::Entities::TR4;
|
|||
|
||||
namespace Save = TEN::Save;
|
||||
|
||||
const std::string SAVEGAME_PATH = "Save//";
|
||||
constexpr auto SAVEGAME_MAX_SLOT = 99;
|
||||
constexpr auto SAVEGAME_PATH = "Save//";
|
||||
constexpr auto SAVEGAME_FILE_MASK = "savegame.";
|
||||
|
||||
GameStats Statistics;
|
||||
SaveGameHeader SavegameInfos[SAVEGAME_MAX];
|
||||
|
@ -62,21 +64,20 @@ void SaveGame::LoadSavegameInfos()
|
|||
if (!std::filesystem::is_directory(FullSaveDirectory))
|
||||
return;
|
||||
|
||||
// Reset overall savegame count.
|
||||
LastSaveGame = 0;
|
||||
|
||||
// Try loading savegame.
|
||||
for (int i = 0; i < SAVEGAME_MAX; i++)
|
||||
{
|
||||
auto fileName = FullSaveDirectory + "savegame." + std::to_string(i);
|
||||
auto savegamePtr = fopen(fileName.c_str(), "rb");
|
||||
|
||||
if (savegamePtr == nullptr)
|
||||
if (!DoesSaveGameExist(i))
|
||||
continue;
|
||||
|
||||
fclose(savegamePtr);
|
||||
|
||||
SavegameInfos[i].Present = true;
|
||||
SaveGame::LoadHeader(i, &SavegameInfos[i]);
|
||||
|
||||
fclose(savegamePtr);
|
||||
if (SavegameInfos[i].Count > LastSaveGame)
|
||||
LastSaveGame = SavegameInfos[i].Count;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,6 +164,33 @@ Vector4 ToVector4(const Save::Vector4* vec)
|
|||
return Vector4(vec->x(), vec->y(), vec->z(), vec->w());
|
||||
}
|
||||
|
||||
bool SaveGame::IsSaveGameSlotValid(int slot)
|
||||
{
|
||||
if (slot < 0 || slot > SAVEGAME_MAX_SLOT)
|
||||
{
|
||||
TENLog("Attempted to access invalid savegame slot " + std::to_string(slot), LogLevel::Warning);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SaveGame::DoesSaveGameExist(int slot)
|
||||
{
|
||||
if (!std::filesystem::is_regular_file(GetSavegameFilename(slot)))
|
||||
{
|
||||
TENLog("Attempted to access missing savegame slot " + std::to_string(slot), LogLevel::Warning);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string SaveGame::GetSavegameFilename(int slot)
|
||||
{
|
||||
return (FullSaveDirectory + SAVEGAME_FILE_MASK + std::to_string(slot));
|
||||
}
|
||||
|
||||
#define SaveVec(Type, Data, TableBuilder, UnionType, SaveType, ConversionFunc) \
|
||||
auto data = std::get<(int)Type>(Data); \
|
||||
TableBuilder vtb{ fbb }; \
|
||||
|
@ -178,7 +206,15 @@ void SaveGame::Init(const std::string& gameDirectory)
|
|||
|
||||
bool SaveGame::Save(int slot)
|
||||
{
|
||||
auto fileName = FullSaveDirectory + "savegame." + std::to_string(slot);
|
||||
if (!IsSaveGameSlotValid(slot))
|
||||
return false;
|
||||
|
||||
g_GameScript->OnSave();
|
||||
|
||||
// Savegame infos need to be reloaded so that last savegame counter properly increases.
|
||||
SaveGame::LoadSavegameInfos();
|
||||
|
||||
auto fileName = GetSavegameFilename(slot);
|
||||
TENLog("Saving to savegame: " + fileName, LogLevel::Info);
|
||||
|
||||
ItemInfo itemToSerialize{};
|
||||
|
@ -1351,7 +1387,13 @@ bool SaveGame::Save(int slot)
|
|||
|
||||
bool SaveGame::Load(int slot)
|
||||
{
|
||||
auto fileName = FullSaveDirectory + "savegame." + std::to_string(slot);
|
||||
if (!IsSaveGameSlotValid(slot))
|
||||
return false;
|
||||
|
||||
if (!DoesSaveGameExist(slot))
|
||||
return false;
|
||||
|
||||
auto fileName = GetSavegameFilename(slot);
|
||||
TENLog("Loading from savegame: " + fileName, LogLevel::Info);
|
||||
|
||||
std::ifstream file;
|
||||
|
@ -1366,7 +1408,6 @@ bool SaveGame::Load(int slot)
|
|||
const Save::SaveGame* s = Save::GetSaveGame(buffer.get());
|
||||
|
||||
// Statistics
|
||||
LastSaveGame = s->header()->count();
|
||||
GameTimer = s->header()->timer();
|
||||
|
||||
Statistics.Game.AmmoHits = s->game()->ammo_hits();
|
||||
|
@ -2206,7 +2247,13 @@ bool SaveGame::Load(int slot)
|
|||
|
||||
bool SaveGame::LoadHeader(int slot, SaveGameHeader* header)
|
||||
{
|
||||
auto fileName = FullSaveDirectory + "savegame." + std::to_string(slot);
|
||||
if (!IsSaveGameSlotValid(slot))
|
||||
return false;
|
||||
|
||||
if (!DoesSaveGameExist(slot))
|
||||
return false;
|
||||
|
||||
auto fileName = GetSavegameFilename(slot);
|
||||
|
||||
std::ifstream file;
|
||||
file.open(fileName, std::ios_base::app | std::ios_base::binary);
|
||||
|
@ -2231,3 +2278,14 @@ bool SaveGame::LoadHeader(int slot, SaveGameHeader* header)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SaveGame::Delete(int slot)
|
||||
{
|
||||
if (!IsSaveGameSlotValid(slot))
|
||||
return;
|
||||
|
||||
if (!DoesSaveGameExist(slot))
|
||||
return;
|
||||
|
||||
std::filesystem::remove(GetSavegameFilename(slot));
|
||||
}
|
||||
|
|
|
@ -46,6 +46,9 @@ class SaveGame
|
|||
private:
|
||||
static FileStream* StreamPtr;
|
||||
static std::string FullSaveDirectory;
|
||||
|
||||
static std::string SaveGame::GetSavegameFilename(int slot);
|
||||
static bool IsSaveGameSlotValid(int slot);
|
||||
|
||||
public:
|
||||
static int LastSaveGame;
|
||||
|
@ -55,4 +58,7 @@ public:
|
|||
static bool LoadHeader(int slot, SaveGameHeader* header);
|
||||
static bool Save(int slot);
|
||||
static void LoadSavegameInfos();
|
||||
static void Delete(int slot);
|
||||
|
||||
static bool DoesSaveGameExist(int slot);
|
||||
};
|
||||
|
|
|
@ -456,30 +456,33 @@ namespace TEN::Renderer
|
|||
void Renderer11::RenderTitleMenu(Menu menu)
|
||||
{
|
||||
int y = MenuVerticalBottomCenter;
|
||||
auto titleOption = g_Gui.GetSelectedOption();
|
||||
|
||||
// HACK: Check if it works properly -- Lwmte, 07.06.22
|
||||
if (menu == Menu::LoadGame && !g_GameFlow->EnableLoadSave)
|
||||
menu = Menu::Title;
|
||||
int titleOption = g_Gui.GetSelectedOption();
|
||||
int selectedOption = 0;
|
||||
|
||||
switch (menu)
|
||||
{
|
||||
case Menu::Title:
|
||||
|
||||
// New game
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_NEW_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 0));
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_NEW_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == selectedOption));
|
||||
GetNextLinePosition(&y);
|
||||
selectedOption++;
|
||||
|
||||
// Load game
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_LOAD_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 1));
|
||||
GetNextLinePosition(&y);
|
||||
if (g_GameFlow->IsLoadSaveEnabled())
|
||||
{
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_LOAD_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == selectedOption));
|
||||
GetNextLinePosition(&y);
|
||||
selectedOption++;
|
||||
}
|
||||
|
||||
// Options
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OPTIONS), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 2));
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OPTIONS), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == selectedOption));
|
||||
GetNextLinePosition(&y);
|
||||
selectedOption++;
|
||||
|
||||
// Exit game
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_EXIT_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 3));
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_EXIT_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == selectedOption));
|
||||
break;
|
||||
|
||||
case Menu::LoadGame:
|
||||
|
@ -496,10 +499,10 @@ namespace TEN::Renderer
|
|||
GetNextBlockPosition(&y);
|
||||
|
||||
// Level listing (starts with 1 because 0 is always title)
|
||||
for (int i = 1; i < g_GameFlow->GetNumLevels(); i++)
|
||||
for (int i = 1; i < g_GameFlow->GetNumLevels(); i++, selectedOption++)
|
||||
{
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(g_GameFlow->GetLevel(i)->NameStringKey.c_str()),
|
||||
PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == i - 1));
|
||||
PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == selectedOption));
|
||||
GetNextNarrowLinePosition(&y);
|
||||
}
|
||||
break;
|
||||
|
@ -565,7 +568,7 @@ namespace TEN::Renderer
|
|||
|
||||
void Renderer11::RenderLoadSaveMenu()
|
||||
{
|
||||
if (!g_GameFlow->EnableLoadSave)
|
||||
if (!g_GameFlow->IsLoadSaveEnabled())
|
||||
{
|
||||
g_Gui.SetInventoryMode(InventoryMode::InGame);
|
||||
return;
|
||||
|
@ -575,7 +578,6 @@ namespace TEN::Renderer
|
|||
int y = MenuVerticalLineSpacing;
|
||||
short selection = g_Gui.GetLoadSaveSelection();
|
||||
char stringBuffer[255];
|
||||
SaveGame::LoadSavegameInfos();
|
||||
|
||||
// Title
|
||||
AddString(MenuCenterEntry, MenuVerticalNarrowLineSpacing, Str_LoadSave(g_Gui.GetInventoryMode() == InventoryMode::Save),
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
enum class TITLE_TYPE
|
||||
{
|
||||
FLYBY,
|
||||
BACKGROUND
|
||||
};
|
||||
|
||||
class ScriptInterfaceLevel;
|
||||
|
||||
enum class TitleType
|
||||
{
|
||||
Flyby,
|
||||
Background
|
||||
};
|
||||
|
||||
class ScriptInterfaceFlowHandler
|
||||
{
|
||||
public:
|
||||
std::string IntroImagePath{};
|
||||
int SelectedLevelForNewGame{ 0 };
|
||||
int SelectedSaveGame{ 0 };
|
||||
bool EnableLoadSave{ true };
|
||||
int TotalNumberOfSecrets{ 0 };
|
||||
std::string TitleScreenImagePath{};
|
||||
TITLE_TYPE TitleType{ TITLE_TYPE::FLYBY };
|
||||
TitleType TitleType = TitleType::Flyby;
|
||||
std::string IntroImagePath = {};
|
||||
std::string TitleScreenImagePath = {};
|
||||
|
||||
int SelectedLevelForNewGame = 0;
|
||||
int SelectedSaveGame = 0;
|
||||
|
||||
int TotalNumberOfSecrets = 0;
|
||||
|
||||
virtual ~ScriptInterfaceFlowHandler() = default;
|
||||
|
||||
|
@ -32,6 +33,7 @@ public:
|
|||
virtual bool IsMassPickupEnabled() const = 0;
|
||||
virtual bool IsPointFilterEnabled() const = 0;
|
||||
virtual bool IsLaraInTitleEnabled() const = 0;
|
||||
virtual bool IsLoadSaveEnabled() const = 0;
|
||||
virtual bool HasCrawlExtended() const = 0;
|
||||
virtual bool HasCrouchRoll() const = 0;
|
||||
virtual bool HasCrawlspaceDive() const = 0;
|
||||
|
|
|
@ -173,6 +173,9 @@ static constexpr char ScriptReserved_SetFarView[] = "SetFarView";
|
|||
static constexpr char ScriptReserved_SetSettings[] = "SetSettings";
|
||||
static constexpr char ScriptReserved_SetAnimations[] = "SetAnimations";
|
||||
static constexpr char ScriptReserved_EndLevel[] = "EndLevel";
|
||||
static constexpr char ScriptReserved_SaveGame[] = "SaveGame";
|
||||
static constexpr char ScriptReserved_LoadGame[] = "LoadGame";
|
||||
static constexpr char ScriptReserved_DeleteSaveGame[] = "DeleteSaveGame";
|
||||
static constexpr char ScriptReserved_GetSecretCount[] = "GetSecretCount";
|
||||
static constexpr char ScriptReserved_SetSecretCount[] = "SetSecretCount";
|
||||
static constexpr char ScriptReserved_SetTotalSecretCount[] = "SetTotalSecretCount";
|
||||
|
@ -181,6 +184,7 @@ static constexpr char ScriptReserved_EnableFlyCheat[] = "EnableFlyCheat";
|
|||
static constexpr char ScriptReserved_EnableMassPickup[] = "EnableMassPickup";
|
||||
static constexpr char ScriptReserved_EnableLaraInTitle[] = "EnableLaraInTitle";
|
||||
static constexpr char ScriptReserved_EnableLevelSelect[] = "EnableLevelSelect";
|
||||
static constexpr char ScriptReserved_EnableLoadSave[] = "EnableLoadSave";
|
||||
static constexpr char ScriptReserved_EnablePointFilter[] = "EnablePointFilter";
|
||||
|
||||
// Flow Functions
|
||||
|
|
|
@ -75,6 +75,12 @@ Must be true or false
|
|||
*/
|
||||
tableFlow.set_function(ScriptReserved_EnableLevelSelect, &FlowHandler::EnableLevelSelect, this);
|
||||
|
||||
/*** Enable or disable saving and loading of savegames.
|
||||
@function EnableLoadSave
|
||||
@tparam bool enabled true or false.
|
||||
*/
|
||||
tableFlow.set_function(ScriptReserved_EnableLoadSave, &FlowHandler::EnableLoadSave, this);
|
||||
|
||||
/*** gameflow.lua or level scripts.
|
||||
@section FlowluaOrScripts
|
||||
*/
|
||||
|
@ -124,6 +130,27 @@ level count, jumps to title.
|
|||
*/
|
||||
tableFlow.set_function(ScriptReserved_EndLevel, &FlowHandler::EndLevel, this);
|
||||
|
||||
/***
|
||||
Save the game to a savegame slot.
|
||||
@function SaveGame
|
||||
@tparam int slotID ID of the savegame slot to save to.
|
||||
*/
|
||||
tableFlow.set_function(ScriptReserved_SaveGame, &FlowHandler::SaveGame, this);
|
||||
|
||||
/***
|
||||
Load the game from a savegame slot.
|
||||
@function LoadGame
|
||||
@tparam int slotID ID of the savegame slot to load from.
|
||||
*/
|
||||
tableFlow.set_function(ScriptReserved_LoadGame, &FlowHandler::LoadGame, this);
|
||||
|
||||
/***
|
||||
Delete a savegame.
|
||||
@function DeleteSaveGame
|
||||
@tparam int slotID ID of the savegame slot to clear.
|
||||
*/
|
||||
tableFlow.set_function(ScriptReserved_DeleteSaveGame, &FlowHandler::DeleteSaveGame, this);
|
||||
|
||||
/***
|
||||
Returns the player's current per-game secret count.
|
||||
@function GetSecretCount
|
||||
|
@ -382,7 +409,25 @@ int FlowHandler::GetLevelNumber(const std::string& fileName)
|
|||
void FlowHandler::EndLevel(std::optional<int> nextLevel)
|
||||
{
|
||||
int index = (nextLevel.has_value() && nextLevel.value() != 0) ? nextLevel.value() : CurrentLevel + 1;
|
||||
LevelComplete = index;
|
||||
NextLevel = index;
|
||||
}
|
||||
|
||||
void FlowHandler::SaveGame(int slot)
|
||||
{
|
||||
SaveGame::Save(slot);
|
||||
}
|
||||
|
||||
void FlowHandler::LoadGame(int slot)
|
||||
{
|
||||
if (!SaveGame::DoesSaveGameExist(slot))
|
||||
return;
|
||||
|
||||
NextLevel = -(slot + 1);
|
||||
}
|
||||
|
||||
void FlowHandler::DeleteSaveGame(int slot)
|
||||
{
|
||||
SaveGame::Delete(slot);
|
||||
}
|
||||
|
||||
int FlowHandler::GetSecretCount() const
|
||||
|
@ -467,6 +512,16 @@ void FlowHandler::EnableLevelSelect(bool levelSelect)
|
|||
LevelSelect = levelSelect;
|
||||
}
|
||||
|
||||
bool FlowHandler::IsLoadSaveEnabled() const
|
||||
{
|
||||
return LoadSave;
|
||||
}
|
||||
|
||||
void FlowHandler::EnableLoadSave(bool loadSave)
|
||||
{
|
||||
LoadSave = loadSave;
|
||||
}
|
||||
|
||||
bool FlowHandler::DoFlow()
|
||||
{
|
||||
// We start with the title level, if no other index is specified
|
||||
|
@ -565,21 +620,22 @@ bool FlowHandler::DoFlow()
|
|||
|
||||
// Load level
|
||||
CurrentLevel = header.Level;
|
||||
NextLevel = 0;
|
||||
GameTimer = header.Timer;
|
||||
loadFromSavegame = true;
|
||||
break;
|
||||
|
||||
case GameStatus::LevelComplete:
|
||||
if (LevelComplete >= Levels.size())
|
||||
if (NextLevel >= Levels.size())
|
||||
{
|
||||
CurrentLevel = 0; // TODO: final credits
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentLevel = LevelComplete;
|
||||
CurrentLevel = NextLevel;
|
||||
}
|
||||
|
||||
LevelComplete = 0;
|
||||
NextLevel = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,17 +26,19 @@ private:
|
|||
LuaHandler m_handler;
|
||||
|
||||
public:
|
||||
int FogInDistance{ 0 };
|
||||
int FogOutDistance{ 0 };
|
||||
bool LevelSelect{ true };
|
||||
bool FlyCheat{ true };
|
||||
bool PointFilter{ false };
|
||||
bool MassPickup{ true };
|
||||
bool LaraInTitle{ false };
|
||||
bool DebugMode{ false };
|
||||
int FogInDistance = 0;
|
||||
int FogOutDistance = 0;
|
||||
|
||||
// New animation flag table
|
||||
Animations Anims{};
|
||||
bool LevelSelect = true;
|
||||
bool LoadSave = true;
|
||||
bool FlyCheat = true;
|
||||
bool PointFilter = false;
|
||||
bool MassPickup = true;
|
||||
bool LaraInTitle = false;
|
||||
bool DebugMode = false;
|
||||
|
||||
// Table for movesets.
|
||||
Animations Anims = {};
|
||||
|
||||
std::vector<Level*> Levels;
|
||||
|
||||
|
@ -58,6 +60,9 @@ public:
|
|||
int GetLevelNumber(const std::string& flieName);
|
||||
int GetNumLevels() const;
|
||||
void EndLevel(std::optional<int> nextLevel);
|
||||
void SaveGame(int slot);
|
||||
void LoadGame(int slot);
|
||||
void DeleteSaveGame(int slot);
|
||||
int GetSecretCount() const;
|
||||
void SetSecretCount(int secretsNum);
|
||||
void AddSecret(int levelSecretIndex);
|
||||
|
@ -74,6 +79,8 @@ public:
|
|||
void EnableLaraInTitle(bool laraInTitle);
|
||||
bool IsLevelSelectEnabled() const;
|
||||
void EnableLevelSelect(bool laraInTitle);
|
||||
bool IsLoadSaveEnabled() const;
|
||||
void EnableLoadSave(bool loadSave);
|
||||
|
||||
bool HasCrawlExtended() const override { return Anims.HasCrawlExtended; }
|
||||
bool HasCrouchRoll() const override { return Anims.HasCrouchRoll; }
|
||||
|
|
|
@ -455,6 +455,7 @@ namespace Misc
|
|||
tableMisc.set_function(ScriptReserved_FlipMap, &FlipMap);
|
||||
tableMisc.set_function(ScriptReserved_PlayFlyBy, &PlayFlyBy);
|
||||
tableMisc.set_function(ScriptReserved_ResetObjCamera, &ResetObjCamera);
|
||||
|
||||
tableMisc.set_function(ScriptReserved_PrintLog, &PrintLog);
|
||||
|
||||
LuaHandler handler{ state };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue