CPlayerProgress

Extracted most operations on user profile from CRobotMain and CMainDialog to a dedicated class
master
krzys-h 2015-07-18 23:14:20 +02:00
parent 86f473ac16
commit 3e1fc06d6c
9 changed files with 707 additions and 582 deletions

View File

@ -170,6 +170,7 @@ set(BASE_SOURCES
object/object_manager.cpp
object/old_object.cpp
object/old_object_interface.cpp
object/player_progress.cpp
object/robotmain.cpp
object/scene_conditions.cpp
object/task/task.cpp

View File

@ -20,7 +20,7 @@
#include <map>
const std::map<LevelCategory, std::string> category_dir_map = {
const std::map<LevelCategory, std::string> CATEGORY_DIR_MAP = {
{ LevelCategory::Missions, "missions" },
{ LevelCategory::FreeGame, "freemissions" },
{ LevelCategory::Exercises, "exercises" },
@ -34,12 +34,12 @@ const std::map<LevelCategory, std::string> category_dir_map = {
std::string GetLevelCategoryDir(LevelCategory category)
{
return category_dir_map.at(category);
return CATEGORY_DIR_MAP.at(category);
}
LevelCategory GetLevelCategoryFromDir(std::string dir)
{
for(auto it = category_dir_map.begin(); it != category_dir_map.end(); ++it)
for(auto it = CATEGORY_DIR_MAP.begin(); it != CATEGORY_DIR_MAP.end(); ++it)
{
if(it->second == dir)
{

View File

@ -0,0 +1,425 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
#include "object/player_progress.h"
#include "common/logger.h"
#include "common/make_unique.h"
#include "common/profile.h"
#include "common/resources/resourcemanager.h"
#include "common/resources/inputstream.h"
#include "common/resources/outputstream.h"
#include "common/restext.h"
#include "object/level/parser.h"
#include "object/robotmain.h"
void PlayerApperance::DefPerso()
{
this->colorCombi.r = 206.0f/256.0f;
this->colorCombi.g = 206.0f/256.0f;
this->colorCombi.b = 204.0f/256.0f; // ~white
this->colorBand.r = 255.0f/256.0f;
this->colorBand.g = 132.0f/256.0f;
this->colorBand.b = 1.0f/256.0f; // orange
if ( this->face == 0 ) // normal ?
{
this->glasses = 0;
this->colorHair.r = 90.0f/256.0f;
this->colorHair.g = 95.0f/256.0f;
this->colorHair.b = 85.0f/256.0f; // black
}
if ( this->face == 1 ) // bald ?
{
this->glasses = 0;
this->colorHair.r = 83.0f/256.0f;
this->colorHair.g = 64.0f/256.0f;
this->colorHair.b = 51.0f/256.0f; // brown
}
if ( this->face == 2 ) // carlos ?
{
this->glasses = 1;
this->colorHair.r = 85.0f/256.0f;
this->colorHair.g = 48.0f/256.0f;
this->colorHair.b = 9.0f/256.0f; // brown
}
if ( this->face == 3 ) // blond ?
{
this->glasses = 4;
this->colorHair.r = 255.0f/256.0f;
this->colorHair.g = 255.0f/256.0f;
this->colorHair.b = 181.0f/256.0f; // yellow
}
this->colorHair.a = 0.0f;
this->colorCombi.a = 0.0f;
this->colorBand.a = 0.0f;
}
CPlayerProgress::CPlayerProgress(std::string playerName)
{
m_playerName = playerName;
GetProfile().SetStringProperty("Gamer", "LastName", m_playerName);
if (!CResourceManager::DirectoryExists(GetSaveDir()))
{
CResourceManager::CreateDirectory(GetSaveDir());
}
m_freegameLoaded = false;
for(int i = 0; i < static_cast<int>(LevelCategory::Max); i++)
{
m_levelInfoLoaded[static_cast<LevelCategory>(i)] = false;
}
LoadApperance();
}
std::string CPlayerProgress::GetLastName()
{
std::string name;
if(!GetProfile().GetStringProperty("Gamer", "LastName", name))
GetResource(RES_TEXT, RT_NAME_DEFAULT, name);
return name;
}
CPlayerProgress::~CPlayerProgress()
{
}
bool CPlayerProgress::Delete()
{
return CResourceManager::RemoveDirectory(GetSaveDir());
}
std::string CPlayerProgress::GetName()
{
return m_playerName;
}
std::string CPlayerProgress::GetSaveDir()
{
return std::string(CRobotMain::GetInstancePointer()->GetSavegameDir()) + "/" + m_playerName;
}
std::string CPlayerProgress::GetSaveFile(std::string filename)
{
return GetSaveDir() + "/" + filename;
}
// FINISHED LEVELS
void CPlayerProgress::IncrementLevelTryCount(LevelCategory cat, int chap, int rank)
{
m_levelInfo[cat][chap][rank].numTry ++;
SaveFinishedLevels(cat);
}
int CPlayerProgress::GetLevelTryCount(LevelCategory cat, int chap, int rank)
{
if(!m_levelInfoLoaded[cat])
LoadFinishedLevels(cat);
return m_levelInfo[cat][chap][rank].numTry;
}
void CPlayerProgress::SetLevelPassed(LevelCategory cat, int chap, int rank, bool bPassed)
{
m_levelInfo[cat][chap][rank].bPassed = bPassed;
SaveFinishedLevels(cat);
if (bPassed && rank != 0)
{
assert(cat == CRobotMain::GetInstancePointer()->GetLevelCategory() && chap == CRobotMain::GetInstancePointer()->GetLevelChap()); //TODO: Refactor UpdateChapterPassed
CRobotMain::GetInstancePointer()->UpdateChapterPassed();
}
}
bool CPlayerProgress::GetLevelPassed(LevelCategory cat, int chap, int rank)
{
if(!m_levelInfoLoaded[cat])
LoadFinishedLevels(cat);
return m_levelInfo[cat][chap][rank].bPassed;
}
int CPlayerProgress::GetChapPassed(LevelCategory cat)
{
if ( CRobotMain::GetInstancePointer()->GetShowAll() ) return MAXSCENE;
for ( int j = 1; j <= MAXSCENE; j++ )
{
if ( !GetLevelPassed(cat, j, 0) )
{
return j;
}
}
return MAXSCENE;
}
void CPlayerProgress::SetSelectedChap(LevelCategory category, int chap)
{
m_selectChap[category] = chap;
SaveFinishedLevels(category);
}
int CPlayerProgress::GetSelectedChap(LevelCategory category)
{
if(!m_levelInfoLoaded[category])
LoadFinishedLevels(category);
if(m_selectChap[category] < 1) return 1;
return m_selectChap[category];
}
void CPlayerProgress::SetSelectedRank(LevelCategory category, int rank)
{
m_selectRank[category] = rank;
SaveFinishedLevels(category);
}
int CPlayerProgress::GetSelectedRank(LevelCategory category)
{
if(!m_levelInfoLoaded[category])
LoadFinishedLevels(category);
if(m_selectRank[category] < 1) return 1;
return m_selectRank[category];
}
void CPlayerProgress::LoadFinishedLevels(LevelCategory category)
{
m_levelInfo[category].clear();
std::string filename = GetSaveFile(GetLevelCategoryDir(category)+".gam");
if (!CResourceManager::Exists(filename))
return;
CInputStream file;
file.open(filename);
if (!file.is_open())
{
GetLogger()->Error("Unable to read list of finished levels from '%s'\n", filename.c_str());
return;
}
std::string line;
std::getline(file, line);
sscanf(line.c_str(), "CurrentChapter=%d CurrentSel=%d\n", &m_selectChap[category], &m_selectRank[category]);
while (!file.eof())
{
std::getline(file, line);
if (line == "")
{
break;
}
int chap, rank, numTry, passed;
sscanf(line.c_str(), "Chapter %d: Scene %d: numTry=%d passed=%d\n",
&chap, &rank, &numTry, &passed);
if ( chap < 0 || chap > MAXSCENE ) continue;
if ( rank < 0 || rank > MAXSCENE ) continue;
m_levelInfo[category][chap][rank].numTry = numTry;
m_levelInfo[category][chap][rank].bPassed = passed;
}
file.close();
m_levelInfoLoaded[category] = true;
}
void CPlayerProgress::SaveFinishedLevels(LevelCategory category)
{
std::string filename = GetSaveFile(GetLevelCategoryDir(category)+".gam");
COutputStream file;
file.open(filename);
if (!file.is_open())
{
GetLogger()->Error("Unable to read list of finished missions from '%s'\n", filename.c_str());
return;
}
file << "CurrentChapter=" << m_selectChap[category] << " CurrentSel=" << m_selectRank[category] << "\n";
for (int chap = 0; chap <= MAXSCENE ; chap++)
{
if (m_levelInfo[category].find(chap) == m_levelInfo[category].end()) continue;
for(int rank = 0; rank <= MAXSCENE; rank++)
{
if (m_levelInfo[category][chap].find(rank) == m_levelInfo[category][chap].end()) continue;
if (m_levelInfo[category][chap][rank].numTry == 0 && !m_levelInfo[category][chap][rank].bPassed) continue;
file << "Chapter " << chap << ": Scene " << rank << ": numTry=" << m_levelInfo[category][chap][rank].numTry << " passed=" << (m_levelInfo[category][chap][rank].bPassed ? "1" : "0") << "\n";
}
}
file.close();
}
// FREE GAME UNLOCK
int CPlayerProgress::GetFreeGameBuildUnlock()
{
if(!m_freegameLoaded)
LoadFreeGameUnlock();
return m_freegameBuild;
}
void CPlayerProgress::SetFreeGameBuildUnlock(int freeBuild)
{
m_freegameBuild = freeBuild;
SaveFreeGameUnlock();
}
int CPlayerProgress::GetFreeGameResearchUnlock()
{
if(!m_freegameLoaded)
LoadFreeGameUnlock();
return m_freegameResearch;
}
void CPlayerProgress::SetFreeGameResearchUnlock(int freeResearch)
{
m_freegameResearch = freeResearch;
SaveFreeGameUnlock();
}
void CPlayerProgress::LoadFreeGameUnlock()
{
m_freegameResearch = 0;
m_freegameBuild = 0;
std::string filename = GetSaveFile("research.gam");
if (!CResourceManager::Exists(filename))
return;
CInputStream file;
file.open(filename);
if (!file.is_open())
{
GetLogger()->Error("Unable to read free game unlock state from '%s'\n", filename.c_str());
return;
}
std::string line;
std::getline(file, line);
sscanf(line.c_str(), "research=%d build=%d\n", &m_freegameResearch, &m_freegameBuild);
file.close();
m_freegameLoaded = false;
}
void CPlayerProgress::SaveFreeGameUnlock()
{
std::string filename = GetSaveFile("research.gam");
COutputStream file;
file.open(filename);
if (!file.is_open())
{
GetLogger()->Error("Unable to write free game unlock state to '%s'\n", filename.c_str());
return;
}
file << "research=" << m_freegameResearch << " build=" << m_freegameBuild << "\n";
file.close();
}
// APPERANCE
PlayerApperance& CPlayerProgress::GetApperance()
{
return m_apperance;
}
void CPlayerProgress::LoadApperance()
{
m_apperance.face = 0;
m_apperance.DefPerso();
std::string filename = GetSaveFile("face.gam");
if (!CResourceManager::Exists(filename))
return;
try
{
CLevelParser apperanceParser(filename);
apperanceParser.Load();
CLevelParserLine* line;
line = apperanceParser.Get("Head");
m_apperance.face = line->GetParam("face")->AsInt();
m_apperance.glasses = line->GetParam("glasses")->AsInt();
m_apperance.colorHair = line->GetParam("hair")->AsColor();
line = apperanceParser.Get("Body");
m_apperance.colorCombi = line->GetParam("combi")->AsColor();
m_apperance.colorBand = line->GetParam("band")->AsColor();
}
catch (CLevelParserException& e)
{
GetLogger()->Error("Unable to read personalized player apperance: %s\n", e.what());
}
}
void CPlayerProgress::SaveApperance()
{
try
{
CLevelParser apperanceParser(GetSaveFile("face.gam"));
CLevelParserLineUPtr line;
line = MakeUnique<CLevelParserLine>("Head");
line->AddParam("face", MakeUnique<CLevelParserParam>(m_apperance.face));
line->AddParam("glasses", MakeUnique<CLevelParserParam>(m_apperance.glasses));
line->AddParam("hair", MakeUnique<CLevelParserParam>(m_apperance.colorHair));
apperanceParser.AddLine(std::move(line));
line = MakeUnique<CLevelParserLine>("Body");
line->AddParam("combi", MakeUnique<CLevelParserParam>(m_apperance.colorCombi));
line->AddParam("band", MakeUnique<CLevelParserParam>(m_apperance.colorBand));
apperanceParser.AddLine(std::move(line));
apperanceParser.Save();
}
catch (CLevelParserException& e)
{
GetLogger()->Error("Unable to write personalized player apperance: %s\n", e.what());
}
}
// SAVE / LOAD SCENE
void CPlayerProgress::SaveScene(std::string dir, std::string info)
{
if (!CResourceManager::DirectoryExists(dir))
{
CResourceManager::CreateDirectory(dir);
}
std::string savegameFileName = dir + "/data.sav";
std::string fileCBot = CResourceManager::GetSaveLocation() + "/" + dir + "/cbot.run";
CRobotMain::GetInstancePointer()->IOWriteScene(savegameFileName.c_str(), fileCBot.c_str(), const_cast<char*>(info.c_str()));
CRobotMain::GetInstancePointer()->MakeSaveScreenshot(dir + "/screen.png");
}

View File

@ -0,0 +1,110 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
#pragma once
#include "graphics/core/color.h"
#include "object/level_category.h"
#include <string>
#include <map>
struct LevelInfo
{
int numTry;
bool bPassed;
};
struct PlayerApperance
{
int face; // face
int glasses; // glasses
Gfx::Color colorHair; // hair color
Gfx::Color colorCombi; // spacesuit volor
Gfx::Color colorBand; // strips color
void DefPerso();
};
class CPlayerProgress
{
public:
CPlayerProgress(std::string playerName);
static std::string GetLastName();
~CPlayerProgress();
bool Delete();
std::string GetName();
std::string GetSaveDir();
std::string GetSaveFile(std::string filename);
void IncrementLevelTryCount(LevelCategory cat, int chap, int rank);
int GetLevelTryCount(LevelCategory cat, int chap, int rank);
void SetLevelPassed(LevelCategory cat, int chap, int rank, bool bPassed);
bool GetLevelPassed(LevelCategory cat, int chap, int rank);
int GetChapPassed(LevelCategory cat);
void SetSelectedChap(LevelCategory category, int chap);
int GetSelectedChap(LevelCategory category);
void SetSelectedRank(LevelCategory category, int rank);
int GetSelectedRank(LevelCategory category);
int GetFreeGameBuildUnlock();
void SetFreeGameBuildUnlock(int freeBuild);
int GetFreeGameResearchUnlock();
void SetFreeGameResearchUnlock(int freeResearch);
PlayerApperance& GetApperance();
void LoadApperance();
void SaveApperance();
void SaveScene(std::string dir, std::string info);
protected:
void LoadFinishedLevels(LevelCategory category);
void SaveFinishedLevels(LevelCategory category);
void LoadFreeGameUnlock();
void SaveFreeGameUnlock();
protected:
//! Player name
std::string m_playerName;
//! Is finished levels file loaded already?
std::map<LevelCategory, bool> m_levelInfoLoaded;
//! Level completion info
std::map<LevelCategory, std::map<int, std::map<int, LevelInfo>>> m_levelInfo;
//! Selected level chapter
std::map<LevelCategory, int> m_selectChap;
//! Selected level rank
std::map<LevelCategory, int> m_selectRank;
//! Is freegame save file loaded already?
bool m_freegameLoaded;
//! Buildings unlocked for free game
int m_freegameBuild;
//! Researches unlocked for free game
int m_freegameResearch;
//! Player apperance
PlayerApperance m_apperance;
};

View File

@ -67,6 +67,7 @@
#include "object/object.h"
#include "object/object_create_exception.h"
#include "object/object_manager.h"
#include "object/player_progress.h"
#include "object/scene_conditions.h"
#include "object/task/task.h"
#include "object/task/taskbuild.h"
@ -238,8 +239,6 @@ CRobotMain::CRobotMain(CController* controller)
m_researchEnable = 0;
g_unit = UNIT;
m_gamerName = "";
for (int i = 0; i < MAXSHOWLIMIT; i++)
{
m_showLimit[i].used = false;
@ -324,9 +323,7 @@ void CRobotMain::Create(bool loadProfile)
m_engine->SetTracePrecision(1.0f);
if (loadProfile) GetProfile().GetStringProperty("Gamer", "LastName", m_gamerName);
SetGlobalGamerName(m_gamerName);
ReadFreeParam();
SelectPlayer(CPlayerProgress::GetLastName());
CScriptFunctions::m_filesDir = CResourceManager::GetSaveLocation() + "/" + m_dialog->GetFilesDir(); //TODO: Refactor to PHYSFS while rewriting CBot engine
CScriptFunctions::Init();
@ -442,21 +439,20 @@ void CRobotMain::ChangePhase(Phase phase)
if (m_gameTime > 10.0f) // did you play at least 10 seconds?
{
LevelCategory cat = m_dialog->GetLevelCategory();
int chap = m_dialog->GetLevelChap();
int rank = m_dialog->GetLevelRank();
int numTry = m_dialog->GetGamerInfoTry(chap, rank);
m_dialog->SetGamerInfoTry(chap, rank, numTry+1);
m_dialog->WriteGamerInfo();
m_playerProgress->IncrementLevelTryCount(cat, chap, rank);
}
}
if (phase == PHASE_WIN) // wins a simulation?
{
LevelCategory cat = m_dialog->GetLevelCategory();
int chap = m_dialog->GetLevelChap();
int rank = m_dialog->GetLevelRank();
m_dialog->SetGamerInfoPassed(chap, rank, true);
m_playerProgress->SetLevelPassed(cat, chap, rank, true);
m_dialog->NextMission(); // passes to the next mission
m_dialog->WriteGamerInfo();
}
m_app->SetLowCPU(true); // doesn't use much CPU in interface phases
@ -3898,13 +3894,16 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
CompileScript(soluce); // compiles all scripts
if (category == LevelCategory::Missions && !resetObject) // mission?
WriteFreeParam();
{
m_playerProgress->SetFreeGameResearchUnlock(m_playerProgress->GetFreeGameResearchUnlock() | m_researchDone[0]);
m_playerProgress->SetFreeGameBuildUnlock(m_playerProgress->GetFreeGameBuildUnlock() | m_build);
}
if (category == LevelCategory::FreeGame && !resetObject) // free play?
{
m_researchDone[0] = m_freeResearch;
m_researchDone[0] = m_playerProgress->GetFreeGameResearchUnlock();
m_build = m_freeBuild;
m_build = m_playerProgress->GetFreeGameBuildUnlock();
m_build &= ~BUILD_RESEARCH;
m_build &= ~BUILD_LABO;
m_build |= BUILD_FACTORY;
@ -4035,11 +4034,11 @@ void CRobotMain::ChangeColor()
colorRef1.r = 206.0f/256.0f;
colorRef1.g = 206.0f/256.0f;
colorRef1.b = 204.0f/256.0f; // ~white
colorNew1 = m_dialog->GetGamerColorCombi();
colorNew1 = m_playerProgress->GetApperance().colorCombi;
colorRef2.r = 255.0f/256.0f;
colorRef2.g = 132.0f/256.0f;
colorRef2.b = 1.0f/256.0f; // orange
colorNew2 = m_dialog->GetGamerColorBand();
colorNew2 = m_playerProgress->GetApperance().colorBand;
Math::Point exclu[6];
exclu[0] = Math::Point(192.0f/256.0f, 0.0f/256.0f);
@ -4081,7 +4080,7 @@ void CRobotMain::ChangeColor()
colorRef1.b = 0.0f/256.0f; // yellow
tolerance = 0.20f;
}
colorNew1 = m_dialog->GetGamerColorHair();
colorNew1 = m_playerProgress->GetApperance().colorHair;
colorRef2.r = 0.0f;
colorRef2.g = 0.0f;
colorRef2.b = 0.0f;
@ -4611,14 +4610,14 @@ void CRobotMain::LoadOneScript(CObject *obj, int &nbError)
{
//? if (brain->GetCompile(i)) continue;
char filename[MAX_FNAME];
sprintf(filename, "%s/%s/%c%.3d%.3d%.3d%.3d.txt",
GetSavegameDir(), m_gamerName.c_str(), categoryChar, chap, rank, objRank, i);
char file[MAX_FNAME];
sprintf(file, "%c%.3d%.3d%.3d%.3d.txt", categoryChar, chap, rank, objRank, i);
std::string filename = m_playerProgress->GetSaveFile(file);
if (CResourceManager::Exists(filename))
{
Program* program = brain->GetOrAddProgram(i);
brain->ReadProgram(program, filename);
brain->ReadProgram(program, filename.c_str());
if (!brain->GetCompile(program)) nbError++;
}
}
@ -4686,12 +4685,13 @@ void CRobotMain::SaveOneScript(CObject *obj)
// TODO: Find a better way to do that
for (unsigned int i = 0; i <= 999; i++)
{
char filename[MAX_FNAME];
sprintf(filename, "%s/%s/%c%.3d%.3d%.3d%.3d.txt",
GetSavegameDir(), m_gamerName.c_str(), categoryChar, chap, rank, objRank, i);
char file[MAX_FNAME];
sprintf(file, "%c%.3d%.3d%.3d%.3d.txt", categoryChar, chap, rank, objRank, i);
std::string filename = m_playerProgress->GetSaveFile(file);
if (i < programs.size())
{
brain->WriteProgram(programs[i].get(), filename);
brain->WriteProgram(programs[i].get(), filename.c_str());
}
else
{
@ -5240,52 +5240,18 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot)
}
//! Writes the global parameters for free play
void CRobotMain::WriteFreeParam()
//! Changes current player
void CRobotMain::SelectPlayer(std::string playerName)
{
m_freeResearch |= m_researchDone[0];
m_freeBuild |= m_build;
assert(!playerName.empty());
if (m_gamerName == "") return;
COutputStream file;
file.open(std::string(GetSavegameDir()) + "/" + m_gamerName + "/research.gam");
if (!file.is_open())
{
GetLogger()->Error("Unable to write free game unlock state\n");
return;
}
file << "research=" << m_freeResearch << " build=" << m_freeBuild << "\n";
file.close();
m_playerProgress = MakeUnique<CPlayerProgress>(playerName);
SetGlobalGamerName(playerName);
}
//! Reads the global parameters for free play
void CRobotMain::ReadFreeParam()
CPlayerProgress* CRobotMain::GetPlayerProgress()
{
m_freeResearch = 0;
m_freeBuild = 0;
if (m_gamerName == "") return;
if (!CResourceManager::Exists(std::string(GetSavegameDir()) + "/" + m_gamerName + "/research.gam"))
return;
CInputStream file;
file.open(std::string(GetSavegameDir()) + "/" + m_gamerName + "/research.gam");
if (!file.is_open())
{
GetLogger()->Error("Unable to read free game unlock state\n");
return;
}
std::string line;
std::getline(file, line);
sscanf(line.c_str(), "research=%d build=%d\n", &m_freeResearch, &m_freeBuild);
file.close();
return m_playerProgress.get();
}
@ -5704,31 +5670,17 @@ MissionType CRobotMain::GetMissionType()
return m_missionType;
}
//! Change the player's name
void CRobotMain::SetGamerName(const char *name)
{
m_gamerName = std::string(name);
SetGlobalGamerName(m_gamerName);
ReadFreeParam();
}
//! Gets the player's name
char* CRobotMain::GetGamerName()
{
return const_cast<char*>(m_gamerName.c_str());
}
//! Returns the representation to use for the player
int CRobotMain::GetGamerFace()
{
return m_dialog->GetGamerFace();
return m_playerProgress->GetApperance().face;
}
//! Returns the representation to use for the player
int CRobotMain::GetGamerGlasses()
{
return m_dialog->GetGamerGlasses();
return m_playerProgress->GetApperance().glasses;
}
//! Returns the mode with just the head
@ -5758,6 +5710,16 @@ int CRobotMain::GetLevelRank()
return m_dialog->GetLevelRank();
}
void CRobotMain::UpdateChapterPassed()
{
return m_dialog->UpdateChapterPassed();
}
void CRobotMain::MakeSaveScreenshot(const std::string& name)
{
return m_dialog->MakeSaveScreenshot(name);
}
//! Changes on the pause mode
void CRobotMain::ChangePause(PauseType pause)
@ -6027,7 +5989,7 @@ int CRobotMain::AutosaveRotate(bool freeOne)
{
GetLogger()->Debug("Rotate autosaves...\n");
// Find autosave dirs
auto saveDirs = CResourceManager::ListDirectories(std::string(GetSavegameDir()) + "/" + GetGamerName());
auto saveDirs = CResourceManager::ListDirectories(m_playerProgress->GetSaveDir());
std::map<int, std::string> autosaveDirs;
for (auto& dir : saveDirs)
{
@ -6037,7 +5999,7 @@ int CRobotMain::AutosaveRotate(bool freeOne)
if (dir.substr(0, autosavePrefix.length()) == "autosave")
{
int id = boost::lexical_cast<int>(dir.substr(autosavePrefix.length()));
autosaveDirs[id] = std::string(GetSavegameDir()) + "/" + GetGamerName() + "/" + dir;
autosaveDirs[id] = m_playerProgress->GetSaveFile(dir);
}
}
catch (...)
@ -6079,7 +6041,7 @@ int CRobotMain::AutosaveRotate(bool freeOne)
{
for (auto& save : autosavesToKeep)
{
std::string newDir = std::string(GetSavegameDir()) + "/" + GetGamerName() + "/autosave" + boost::lexical_cast<std::string>(save.first);
std::string newDir = m_playerProgress->GetSaveFile("autosave" + boost::lexical_cast<std::string>(save.first));
GetLogger()->Trace("Rename %s -> %s\n", save.second.c_str(), newDir.c_str());
CResourceManager::Move(save.second, newDir);
}
@ -6093,20 +6055,13 @@ void CRobotMain::Autosave()
int id = AutosaveRotate(true);
GetLogger()->Info("Autosave!\n");
std::string dir = std::string(GetSavegameDir()) + "/" + GetGamerName() + "/autosave" + boost::lexical_cast<std::string>(id);
std::string dir = m_playerProgress->GetSaveFile("autosave" + boost::lexical_cast<std::string>(id));
if (!CResourceManager::DirectoryExists(dir))
{
CResourceManager::CreateDirectory(dir);
}
std::string savegameFileName = dir + "/data.sav";
std::string fileCBot = CResourceManager::GetSaveLocation() + "/" + dir + "/cbot.run";
char timestr[100];
TimeToAscii(time(NULL), timestr);
IOWriteScene(savegameFileName.c_str(), fileCBot.c_str(), const_cast<char*>((std::string("[AUTOSAVE] ")+timestr).c_str()));
std::string info = std::string("[AUTOSAVE] ")+timestr;
m_dialog->MakeSaveScreenshot(dir + "/screen.png");
m_playerProgress->SaveScene(dir, info);
}
void CRobotMain::SetExitAfterMission(bool exit)
@ -6214,7 +6169,7 @@ void CRobotMain::MarkResearchDone(ResearchType type, int team)
if(team == 0)
{
WriteFreeParam();
m_playerProgress->SetFreeGameResearchUnlock(m_playerProgress->GetFreeGameResearchUnlock() | m_researchDone[0]);
}
}

View File

@ -86,6 +86,7 @@ class CInput;
class CObjectManager;
class CSceneEndCondition;
class CAudioChangeCondition;
class CPlayerProgress;
namespace Gfx {
class CEngine;
@ -121,6 +122,8 @@ const int MAXSHOWLIMIT = 5;
const int MAXSHOWPARTI = 200;
const float SHOWLIMITTIME = 20.0f;
const int MAXSCENE = 999;
struct ShowLimit
{
bool used;
@ -227,16 +230,16 @@ public:
void SetFontSize(float size);
float GetFontSize();
void SetWindowPos(Math::Point pos);
Math::Point GetWindowPos();
Math::Point GetWindowPos();
void SetWindowDim(Math::Point dim);
Math::Point GetWindowDim();
Math::Point GetWindowDim();
void SetIOPublic(bool mode);
bool GetIOPublic();
void SetIOPos(Math::Point pos);
Math::Point GetIOPos();
Math::Point GetIOPos();
void SetIODim(Math::Point dim);
Math::Point GetIODim();
Math::Point GetIODim();
char* GetTitle();
char* GetResume();
@ -258,16 +261,16 @@ public:
const char* GetFilesDir();
MissionType GetMissionType();
void SetGamerName(const char *name);
char* GetGamerName();
int GetGamerFace();
int GetGamerGlasses();
bool GetGamerOnlyHead();
float GetPersoAngle();
LevelCategory GetLevelCategory();
int GetLevelChap();
int GetLevelRank();
void UpdateChapterPassed();
void MakeSaveScreenshot(const std::string& name);
void StartMusic();
void StartPauseMusic(PauseType pause);
@ -299,8 +302,8 @@ public:
bool AddNewScriptName(ObjectType type, char *name);
char* GetNewScriptName(ObjectType type, int rank);
void WriteFreeParam();
void ReadFreeParam();
void SelectPlayer(std::string playerName);
CPlayerProgress* GetPlayerProgress();
bool IsBusy();
bool IOWriteScene(const char *filename, const char *filecbot, char *info);
@ -447,6 +450,9 @@ protected:
CPauseManager* m_pause;
CInput* m_input;
//! Progress of loaded player
std::unique_ptr<CPlayerProgress> m_playerProgress;
//! Time since level start, including pause and intro movie
float m_time;
@ -560,8 +566,6 @@ protected:
int m_prohibitedTotal;
char m_prohibitedToken[100][20];
std::string m_gamerName;
//! Enabled buildings
int m_build;
//! Available researches
@ -569,11 +573,6 @@ protected:
//! Done researches for each team
std::map<int, int> m_researchDone;
//! Buildings unlocked for free game
int m_freeBuild;
//! Researches unlocked for free game
int m_freeResearch;
Error m_missionResult;
ShowLimit m_showLimit[MAXSHOWLIMIT];

View File

@ -40,6 +40,7 @@
#include "object/level/parser.h"
#include "object/player_progress.h"
#include "object/robotmain.h"
#include "sound/sound.h"
@ -150,9 +151,6 @@ CMainDialog::CMainDialog()
m_category = LevelCategory::Exercises;
m_maxList = 0;
memset(&m_perso, 0, sizeof(GamerPerso));
DefPerso();
m_bTooltip = true;
m_bGlint = true;
m_bRain = true;
@ -228,7 +226,6 @@ void CMainDialog::ChangePhase(Phase phase)
Math::Point pos, dim, ddim;
float ox, oy, sx, sy;
std::string name;
char* gamer;
int res, i, j;
m_camera->SetType(Gfx::CAM_TYPE_DIALOG);
@ -421,14 +418,13 @@ void CMainDialog::ChangePhase(Phase phase)
ddim.y = 18.0f/480.0f;
pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_NEDIT);
pe->SetMaxChar(15);
gamer = m_main->GetGamerName();
if ( gamer[0] == 0 )
if(m_main->GetPlayerProgress() != nullptr)
{
GetResource(RES_TEXT, RT_NAME_DEFAULT, name);
name = m_main->GetPlayerProgress()->GetName();
}
else
{
name = gamer;
name = CPlayerProgress::GetLastName();
}
pe->SetText(name.c_str());
pe->SetCursor(name.length(), 0);
@ -475,7 +471,6 @@ void CMainDialog::ChangePhase(Phase phase)
ReadNameList();
UpdateNameList();
UpdateNameControl();
UpdateNameFace();
m_engine->SetBackground("interface/interface.png",
Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f),
@ -700,9 +695,9 @@ void CMainDialog::ChangePhase(Phase phase)
pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PDEF);
pb->SetState(STATE_SHADOW);
m_persoCopy = m_perso;
m_persoTab = 0;
m_persoAngle = -0.6f;
m_apperanceTab = 0;
m_apperanceAngle = -0.6f;
m_main->GetPlayerProgress()->LoadApperance();
UpdatePerso();
m_main->ScenePerso();
CameraPerso();
@ -740,17 +735,9 @@ void CMainDialog::ChangePhase(Phase phase)
if ( m_phase == PHASE_FREE )
{
LevelCategory temp = m_category;
m_category = LevelCategory::Missions;
ReadGamerInfo();
m_accessChap = GetChapPassed();
m_category = temp;
m_accessChap = m_main->GetPlayerProgress()->GetChapPassed(LevelCategory::Missions);
}
ReadGamerInfo();
pos.x = 0.10f;
pos.y = 0.10f;
ddim.x = 0.80f;
@ -795,6 +782,7 @@ void CMainDialog::ChangePhase(Phase phase)
ddim.x = dim.x*6.5f;
pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_CHAP);
pli->SetState(STATE_SHADOW);
m_chap[m_category] = m_main->GetPlayerProgress()->GetSelectedChap(m_category)-1;
UpdateSceneChap(m_chap[m_category]);
if ( m_phase != PHASE_USER ) pli->SetState(STATE_EXTEND);
@ -817,6 +805,7 @@ void CMainDialog::ChangePhase(Phase phase)
ddim.x = dim.x*6.5f;
pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_LIST);
pli->SetState(STATE_SHADOW);
m_sel[m_category] = m_main->GetPlayerProgress()->GetSelectedRank(m_category)-1;
UpdateSceneList(m_chap[m_category], m_sel[m_category]);
if ( m_phase != PHASE_USER ) pli->SetState(STATE_EXTEND);
pos = pli->GetPos();
@ -2089,6 +2078,7 @@ bool CMainDialog::EventProcess(const Event &event)
if ( m_phase == PHASE_PERSO )
{
PlayerApperance& apperance = m_main->GetPlayerProgress()->GetApperance();
switch( event.type )
{
case EVENT_KEY_DOWN:
@ -2103,13 +2093,13 @@ bool CMainDialog::EventProcess(const Event &event)
break;
case EVENT_INTERFACE_PHEAD:
m_persoTab = 0;
m_apperanceTab = 0;
UpdatePerso();
m_main->ScenePerso();
CameraPerso();
break;
case EVENT_INTERFACE_PBODY:
m_persoTab = 1;
m_apperanceTab = 1;
UpdatePerso();
m_main->ScenePerso();
CameraPerso();
@ -2119,8 +2109,7 @@ bool CMainDialog::EventProcess(const Event &event)
case EVENT_INTERFACE_PFACE2:
case EVENT_INTERFACE_PFACE3:
case EVENT_INTERFACE_PFACE4:
m_perso.face = event.type-EVENT_INTERFACE_PFACE1;
WriteGamerPerso(m_main->GetGamerName());
apperance.face = event.type-EVENT_INTERFACE_PFACE1;
UpdatePerso();
m_main->ScenePerso();
break;
@ -2135,8 +2124,7 @@ bool CMainDialog::EventProcess(const Event &event)
case EVENT_INTERFACE_PGLASS7:
case EVENT_INTERFACE_PGLASS8:
case EVENT_INTERFACE_PGLASS9:
m_perso.glasses = event.type-EVENT_INTERFACE_PGLASS0;
WriteGamerPerso(m_main->GetGamerName());
apperance.glasses = event.type-EVENT_INTERFACE_PGLASS0;
UpdatePerso();
m_main->ScenePerso();
break;
@ -2152,7 +2140,6 @@ bool CMainDialog::EventProcess(const Event &event)
case EVENT_INTERFACE_PC8a:
case EVENT_INTERFACE_PC9a:
FixPerso(event.type-EVENT_INTERFACE_PC0a, 0);
WriteGamerPerso(m_main->GetGamerName());
UpdatePerso();
m_main->ScenePerso();
break;
@ -2168,7 +2155,6 @@ bool CMainDialog::EventProcess(const Event &event)
case EVENT_INTERFACE_PC8b:
case EVENT_INTERFACE_PC9b:
FixPerso(event.type-EVENT_INTERFACE_PC0b, 1);
WriteGamerPerso(m_main->GetGamerName());
UpdatePerso();
m_main->ScenePerso();
break;
@ -2180,32 +2166,30 @@ bool CMainDialog::EventProcess(const Event &event)
case EVENT_INTERFACE_PCGb:
case EVENT_INTERFACE_PCBb:
ColorPerso();
WriteGamerPerso(m_main->GetGamerName());
UpdatePerso();
m_main->ScenePerso();
break;
case EVENT_INTERFACE_PDEF:
DefPerso();
WriteGamerPerso(m_main->GetGamerName());
apperance.DefPerso();
UpdatePerso();
m_main->ScenePerso();
break;
case EVENT_INTERFACE_PLROT:
m_persoAngle += 0.2f;
m_apperanceAngle += 0.2f;
break;
case EVENT_INTERFACE_PRROT:
m_persoAngle -= 0.2f;
m_apperanceAngle -= 0.2f;
break;
case EVENT_INTERFACE_POK:
m_main->GetPlayerProgress()->SaveApperance();
m_main->ChangePhase(PHASE_INIT);
break;
case EVENT_INTERFACE_PCANCEL:
m_perso = m_persoCopy;
WriteGamerPerso(m_main->GetGamerName());
m_main->GetPlayerProgress()->LoadApperance(); // reload apperance from file
m_main->ChangePhase(PHASE_NAME);
break;
@ -2245,6 +2229,7 @@ bool CMainDialog::EventProcess(const Event &event)
pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_CHAP));
if ( pl == 0 ) break;
m_chap[m_category] = pl->GetSelect();
m_main->GetPlayerProgress()->SetSelectedChap(m_category, m_chap[m_category]+1);
UpdateSceneList(m_chap[m_category], m_sel[m_category]);
UpdateSceneResume(m_chap[m_category]+1, m_sel[m_category]+1);
break;
@ -2253,6 +2238,7 @@ bool CMainDialog::EventProcess(const Event &event)
pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_LIST));
if ( pl == 0 ) break;
m_sel[m_category] = pl->GetSelect();
m_main->GetPlayerProgress()->SetSelectedRank(m_category, m_sel[m_category]+1);
UpdateSceneResume(m_chap[m_category]+1, m_sel[m_category]+1);
break;
@ -3394,7 +3380,6 @@ void CMainDialog::UpdateNameControl()
CButton* pb;
CEdit* pe;
char name[100];
char* gamer;
int total, sel;
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
@ -3404,7 +3389,7 @@ void CMainDialog::UpdateNameControl()
pe = static_cast<CEdit*>(pw->SearchControl(EVENT_INTERFACE_NEDIT));
if ( pe == 0 ) return;
gamer = m_main->GetGamerName();
std::string gamer = m_main->GetPlayerProgress()->GetName();
total = pl->GetTotal();
sel = pl->GetSelect();
pe->GetText(name, 100);
@ -3412,7 +3397,7 @@ void CMainDialog::UpdateNameControl()
pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_NCANCEL));
if ( pb != 0 )
{
pb->SetState(STATE_ENABLE, gamer[0]!=0);
pb->SetState(STATE_ENABLE, !gamer.empty());
}
pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_NDELETE));
@ -3501,27 +3486,6 @@ void CMainDialog::UpdateNameEdit()
UpdateNameControl();
}
// Updates the representation of the player depending on the selected list.
void CMainDialog::UpdateNameFace()
{
CWindow* pw;
CList* pl;
char* name;
int sel;
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw == 0 ) return;
pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_NLIST));
if ( pl == 0 ) return;
sel = pl->GetSelect();
if ( sel == -1 ) return;
name = pl->GetItemName(sel);
ReadGamerPerso(name);
}
// Selects a player.
void CMainDialog::NameSelect()
@ -3548,18 +3512,15 @@ void CMainDialog::NameSelect()
}
else
{
m_main->SetGamerName(pl->GetItemName(sel));
m_main->ChangePhase(PHASE_INIT);
m_main->SelectPlayer(pl->GetItemName(sel));
}
GetGamerFace(m_main->GetGamerName());
GetProfile().SetStringProperty("Gamer", "LastName", m_main->GetGamerName());
m_main->ChangePhase(PHASE_INIT);
}
// Creates a new player.
void CMainDialog::NameCreate()
bool CMainDialog::NameCreate()
{
CWindow* pw;
CEdit* pe;
@ -3569,15 +3530,15 @@ void CMainDialog::NameCreate()
GetLogger()->Info("Creating new player\n");
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw == 0 ) return;
if ( pw == 0 ) return false;
pe = static_cast<CEdit*>(pw->SearchControl(EVENT_INTERFACE_NEDIT));
if ( pe == 0 ) return;
if ( pe == 0 ) return false;
pe->GetText(name, 100);
if ( name[0] == 0 )
{
m_sound->Play(SOUND_TZOING);
return;
return false;
}
len = strlen(name);
@ -3601,27 +3562,12 @@ void CMainDialog::NameCreate()
if ( j == 0 )
{
m_sound->Play(SOUND_TZOING);
return;
return false;
}
std::string userSaveDir = m_savegameDir + "/" + name;
if (!CResourceManager::DirectoryExists(userSaveDir))
{
CResourceManager::CreateDirectory(userSaveDir);
}
else
{
m_sound->Play(SOUND_TZOING);
pe->SetText(name);
pe->SetCursor(strlen(name), 0);
m_interface->SetFocus(pe);
return;
}
m_main->SelectPlayer(name);
SetGamerFace(name, 0);
m_main->SetGamerName(name);
m_main->ChangePhase(PHASE_INIT);
return true;
}
// Removes a player.
@ -3642,14 +3588,13 @@ void CMainDialog::NameDelete()
char* gamer = pl->GetItemName(sel);
std::string userSaveDir = m_savegameDir + "/" + gamer;
if (!CResourceManager::RemoveDirectory(userSaveDir))
m_main->SelectPlayer(gamer);
if (!m_main->GetPlayerProgress()->Delete())
{
m_sound->Play(SOUND_TZOING);
return;
}
m_main->SetGamerName("");
pl->SetSelect(-1);
ReadNameList();
@ -3681,24 +3626,26 @@ void CMainDialog::UpdatePerso()
std::string name;
int i;
PlayerApperance& apperance = m_main->GetPlayerProgress()->GetApperance();
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw == 0 ) return;
pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_PHEAD));
if ( pb != 0 )
{
pb->SetState(STATE_CHECK, m_persoTab==0);
pb->SetState(STATE_CHECK, m_apperanceTab==0);
}
pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_PBODY));
if ( pb != 0 )
{
pb->SetState(STATE_CHECK, m_persoTab==1);
pb->SetState(STATE_CHECK, m_apperanceTab==1);
}
pl = static_cast<CLabel*>(pw->SearchControl(EVENT_LABEL11));
if ( pl != 0 )
{
if ( m_persoTab == 0 )
if ( m_apperanceTab == 0 )
{
pl->SetState(STATE_VISIBLE);
GetResource(RES_TEXT, RT_PERSO_FACE, name);
@ -3713,7 +3660,7 @@ void CMainDialog::UpdatePerso()
pl = static_cast<CLabel*>(pw->SearchControl(EVENT_LABEL12));
if ( pl != 0 )
{
if ( m_persoTab == 0 )
if ( m_apperanceTab == 0 )
{
pl->SetState(STATE_VISIBLE);
GetResource(RES_TEXT, RT_PERSO_GLASSES, name);
@ -3728,7 +3675,7 @@ void CMainDialog::UpdatePerso()
pl = static_cast<CLabel*>(pw->SearchControl(EVENT_LABEL13));
if ( pl != 0 )
{
if ( m_persoTab == 0 ) GetResource(RES_TEXT, RT_PERSO_HAIR, name);
if ( m_apperanceTab == 0 ) GetResource(RES_TEXT, RT_PERSO_HAIR, name);
else GetResource(RES_TEXT, RT_PERSO_BAND, name);
pl->SetName(name);
}
@ -3736,7 +3683,7 @@ void CMainDialog::UpdatePerso()
pl = static_cast<CLabel*>(pw->SearchControl(EVENT_LABEL14));
if ( pl != 0 )
{
if ( m_persoTab == 0 )
if ( m_apperanceTab == 0 )
{
pl->ClearState(STATE_VISIBLE);
}
@ -3752,23 +3699,23 @@ void CMainDialog::UpdatePerso()
{
pb = static_cast<CButton*>(pw->SearchControl(static_cast<EventType>(EVENT_INTERFACE_PFACE1+i)));
if ( pb == 0 ) break;
pb->SetState(STATE_VISIBLE, m_persoTab==0);
pb->SetState(STATE_CHECK, i==m_perso.face);
pb->SetState(STATE_VISIBLE, m_apperanceTab==0);
pb->SetState(STATE_CHECK, i==apperance.face);
}
for ( i=0 ; i<10 ; i++ )
{
pb = static_cast<CButton*>(pw->SearchControl(static_cast<EventType>(EVENT_INTERFACE_PGLASS0+i)));
if ( pb == 0 ) break;
pb->SetState(STATE_VISIBLE, m_persoTab==0);
pb->SetState(STATE_CHECK, i==m_perso.glasses);
pb->SetState(STATE_VISIBLE, m_apperanceTab==0);
pb->SetState(STATE_CHECK, i==apperance.glasses);
}
for ( i=0 ; i<3*3 ; i++ )
{
pc = static_cast<CColor*>(pw->SearchControl(static_cast<EventType>(EVENT_INTERFACE_PC0a+i)));
if ( pc == 0 ) break;
if ( m_persoTab == 0 )
if ( m_apperanceTab == 0 )
{
pc->ClearState(STATE_VISIBLE);
}
@ -3780,29 +3727,29 @@ void CMainDialog::UpdatePerso()
color.b = perso_color[3*10*1+3*i+2]/255.0f;
color.a = 0.0f;
pc->SetColor(color);
pc->SetState(STATE_CHECK, EqColor(color, m_perso.colorCombi));
pc->SetState(STATE_CHECK, EqColor(color, apperance.colorCombi));
}
pc = static_cast<CColor*>(pw->SearchControl(static_cast<EventType>(EVENT_INTERFACE_PC0b+i)));
if ( pc == 0 ) break;
color.r = perso_color[3*10*2*m_persoTab+3*i+0]/255.0f;
color.g = perso_color[3*10*2*m_persoTab+3*i+1]/255.0f;
color.b = perso_color[3*10*2*m_persoTab+3*i+2]/255.0f;
color.r = perso_color[3*10*2*m_apperanceTab+3*i+0]/255.0f;
color.g = perso_color[3*10*2*m_apperanceTab+3*i+1]/255.0f;
color.b = perso_color[3*10*2*m_apperanceTab+3*i+2]/255.0f;
color.a = 0.0f;
pc->SetColor(color);
pc->SetState(STATE_CHECK, EqColor(color, m_persoTab?m_perso.colorBand:m_perso.colorHair));
pc->SetState(STATE_CHECK, EqColor(color, m_apperanceTab?apperance.colorBand:apperance.colorHair));
}
for ( i=0 ; i<3 ; i++ )
{
ps = static_cast<CSlider*>(pw->SearchControl(static_cast<EventType>(EVENT_INTERFACE_PCRa+i)));
if ( ps == 0 ) break;
ps->SetState(STATE_VISIBLE, m_persoTab==1);
ps->SetState(STATE_VISIBLE, m_apperanceTab==1);
}
if ( m_persoTab == 1 )
if ( m_apperanceTab == 1 )
{
color = m_perso.colorCombi;
color = apperance.colorCombi;
ps = static_cast<CSlider*>(pw->SearchControl(EVENT_INTERFACE_PCRa));
if ( ps != 0 ) ps->SetVisibleValue(color.r*255.0f);
ps = static_cast<CSlider*>(pw->SearchControl(EVENT_INTERFACE_PCGa));
@ -3811,8 +3758,8 @@ void CMainDialog::UpdatePerso()
if ( ps != 0 ) ps->SetVisibleValue(color.b*255.0f);
}
if ( m_persoTab == 0 ) color = m_perso.colorHair;
else color = m_perso.colorBand;
if ( m_apperanceTab == 0 ) color = apperance.colorHair;
else color = apperance.colorBand;
ps = static_cast<CSlider*>(pw->SearchControl(EVENT_INTERFACE_PCRb));
if ( ps != 0 ) ps->SetVisibleValue(color.r*255.0f);
ps = static_cast<CSlider*>(pw->SearchControl(EVENT_INTERFACE_PCGb));
@ -3825,7 +3772,7 @@ void CMainDialog::UpdatePerso()
void CMainDialog::CameraPerso()
{
if ( m_persoTab == 0 )
if ( m_apperanceTab == 0 )
{
//? m_camera->Init(Math::Vector(4.0f, 0.0f, 0.0f),
//? Math::Vector(0.0f, 0.0f, 1.0f), 0.0f);
@ -3846,28 +3793,29 @@ void CMainDialog::CameraPerso()
void CMainDialog::FixPerso(int rank, int index)
{
if ( m_persoTab == 0 )
PlayerApperance& apperance = m_main->GetPlayerProgress()->GetApperance();
if ( m_apperanceTab == 0 )
{
if ( index == 1 )
{
m_perso.colorHair.r = perso_color[3*10*0+rank*3+0]/255.0f;
m_perso.colorHair.g = perso_color[3*10*0+rank*3+1]/255.0f;
m_perso.colorHair.b = perso_color[3*10*0+rank*3+2]/255.0f;
apperance.colorHair.r = perso_color[3*10*0+rank*3+0]/255.0f;
apperance.colorHair.g = perso_color[3*10*0+rank*3+1]/255.0f;
apperance.colorHair.b = perso_color[3*10*0+rank*3+2]/255.0f;
}
}
if ( m_persoTab == 1 )
if ( m_apperanceTab == 1 )
{
if ( index == 0 )
{
m_perso.colorCombi.r = perso_color[3*10*1+rank*3+0]/255.0f;
m_perso.colorCombi.g = perso_color[3*10*1+rank*3+1]/255.0f;
m_perso.colorCombi.b = perso_color[3*10*1+rank*3+2]/255.0f;
apperance.colorCombi.r = perso_color[3*10*1+rank*3+0]/255.0f;
apperance.colorCombi.g = perso_color[3*10*1+rank*3+1]/255.0f;
apperance.colorCombi.b = perso_color[3*10*1+rank*3+2]/255.0f;
}
if ( index == 1 )
{
m_perso.colorBand.r = perso_color[3*10*2+rank*3+0]/255.0f;
m_perso.colorBand.g = perso_color[3*10*2+rank*3+1]/255.0f;
m_perso.colorBand.b = perso_color[3*10*2+rank*3+2]/255.0f;
apperance.colorBand.r = perso_color[3*10*2+rank*3+0]/255.0f;
apperance.colorBand.g = perso_color[3*10*2+rank*3+1]/255.0f;
apperance.colorBand.b = perso_color[3*10*2+rank*3+2]/255.0f;
}
}
}
@ -3880,6 +3828,8 @@ void CMainDialog::ColorPerso()
CSlider* ps;
Gfx::Color color;
PlayerApperance& apperance = m_main->GetPlayerProgress()->GetApperance();
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw == 0 ) return;
@ -3891,7 +3841,7 @@ void CMainDialog::ColorPerso()
if ( ps != 0 ) color.g = ps->GetVisibleValue()/255.0f;
ps = static_cast<CSlider*>(pw->SearchControl(EVENT_INTERFACE_PCBa));
if ( ps != 0 ) color.b = ps->GetVisibleValue()/255.0f;
if ( m_persoTab == 1 ) m_perso.colorCombi = color;
if ( m_apperanceTab == 1 ) apperance.colorCombi = color;
ps = static_cast<CSlider*>(pw->SearchControl(EVENT_INTERFACE_PCRb));
if ( ps != 0 ) color.r = ps->GetVisibleValue()/255.0f;
@ -3899,53 +3849,8 @@ void CMainDialog::ColorPerso()
if ( ps != 0 ) color.g = ps->GetVisibleValue()/255.0f;
ps = static_cast<CSlider*>(pw->SearchControl(EVENT_INTERFACE_PCBb));
if ( ps != 0 ) color.b = ps->GetVisibleValue()/255.0f;
if ( m_persoTab == 0 ) m_perso.colorHair = color;
else m_perso.colorBand = color;
}
// Updates the default settings of the character.
void CMainDialog::DefPerso()
{
m_perso.colorCombi.r = 206.0f/256.0f;
m_perso.colorCombi.g = 206.0f/256.0f;
m_perso.colorCombi.b = 204.0f/256.0f; // ~white
m_perso.colorBand.r = 255.0f/256.0f;
m_perso.colorBand.g = 132.0f/256.0f;
m_perso.colorBand.b = 1.0f/256.0f; // orange
if ( m_perso.face == 0 ) // normal ?
{
m_perso.glasses = 0;
m_perso.colorHair.r = 90.0f/256.0f;
m_perso.colorHair.g = 95.0f/256.0f;
m_perso.colorHair.b = 85.0f/256.0f; // black
}
if ( m_perso.face == 1 ) // bald ?
{
m_perso.glasses = 0;
m_perso.colorHair.r = 83.0f/256.0f;
m_perso.colorHair.g = 64.0f/256.0f;
m_perso.colorHair.b = 51.0f/256.0f; // brown
}
if ( m_perso.face == 2 ) // carlos ?
{
m_perso.glasses = 1;
m_perso.colorHair.r = 85.0f/256.0f;
m_perso.colorHair.g = 48.0f/256.0f;
m_perso.colorHair.b = 9.0f/256.0f; // brown
}
if ( m_perso.face == 3 ) // blond ?
{
m_perso.glasses = 4;
m_perso.colorHair.r = 255.0f/256.0f;
m_perso.colorHair.g = 255.0f/256.0f;
m_perso.colorHair.b = 181.0f/256.0f; // yellow
}
m_perso.colorHair.a = 0.0f;
m_perso.colorCombi.a = 0.0f;
m_perso.colorBand.a = 0.0f;
if ( m_apperanceTab == 0 ) apperance.colorHair = color;
else apperance.colorBand = color;
}
@ -3953,7 +3858,7 @@ void CMainDialog::DefPerso()
bool CMainDialog::IsIOReadScene()
{
std::string userSaveDir = m_savegameDir + "/" + m_main->GetGamerName();
std::string userSaveDir = m_savegameDir + "/" + m_main->GetPlayerProgress()->GetName();
auto saveDirs = CResourceManager::ListDirectories(userSaveDir);
for (auto dir : saveDirs)
{
@ -4017,7 +3922,7 @@ void CMainDialog::IOReadList()
m_saveList.clear();
std::string userSaveDir = m_savegameDir + "/" + m_main->GetGamerName();
std::string userSaveDir = m_savegameDir + "/" + m_main->GetPlayerProgress()->GetName();
auto saveDirs = CResourceManager::ListDirectories(userSaveDir);
//std::sort(saveDirs.begin(), saveDirs.end());
@ -4182,23 +4087,14 @@ bool CMainDialog::IOWriteScene()
pe->GetText(info, 100);
if (static_cast<unsigned int>(sel) >= m_saveList.size())
{
dir = m_savegameDir + "/" + m_main->GetGamerName() + "/save" + clearName(info);
dir = m_savegameDir + "/" + m_main->GetPlayerProgress()->GetName() + "/save" + clearName(info);
}
else
{
dir = m_saveList.at(sel);
}
if (!CResourceManager::DirectoryExists(dir))
{
CResourceManager::CreateDirectory(dir);
}
std::string savegameFileName = dir + "/data.sav";
std::string fileCBot = CResourceManager::GetSaveLocation() + "/" + dir + "/cbot.run";
m_main->IOWriteScene(savegameFileName.c_str(), fileCBot.c_str(), info);
MakeSaveScreenshot(dir + "/screen.png");
m_main->GetPlayerProgress()->SaveScene(dir, info);
return true;
}
@ -4278,23 +4174,6 @@ bool CMainDialog::IOReadScene()
return true;
}
// Returns the number of accessible chapters.
int CMainDialog::GetChapPassed()
{
if ( m_main->GetShowAll() ) return MAXSCENE;
for ( int j = 1; j <= MAXSCENE; j++ )
{
if ( !GetGamerInfoPassed(j, 0) )
{
return j;
}
}
return MAXSCENE;
}
// Updates the lists according to the cheat code.
void CMainDialog::AllMissionUpdate()
@ -4370,7 +4249,7 @@ void CMainDialog::UpdateSceneChap(int &chap)
sprintf(line, "%s", (std::string("[ERROR]: ")+e.what()).c_str());
}
bPassed = GetGamerInfoPassed(j+1, 0);
bPassed = m_main->GetPlayerProgress()->GetLevelPassed(m_category, j+1, 0);
pl->SetItemName(j, line);
pl->SetCheck(j, bPassed);
pl->SetEnable(j, true);
@ -4441,7 +4320,7 @@ void CMainDialog::UpdateSceneList(int chap, int &sel)
sprintf(line, "%s", (std::string("[ERROR]: ")+e.what()).c_str());
}
bPassed = GetGamerInfoPassed(chap+1, j+1);
bPassed = m_main->GetPlayerProgress()->GetLevelPassed(m_category, chap+1, j+1);
pl->SetItemName(j, line);
pl->SetCheck(j, bPassed);
pl->SetEnable(j, true);
@ -4528,8 +4407,8 @@ void CMainDialog::UpdateSceneResume(int chap, int rank)
}
else
{
numTry = GetGamerInfoTry(chap, rank);
bPassed = GetGamerInfoPassed(chap, rank);
numTry = m_main->GetPlayerProgress()->GetLevelTryCount(m_category, chap, rank);
bPassed = m_main->GetPlayerProgress()->GetLevelPassed(m_category, chap, rank);
bVisible = ( numTry > 2 || bPassed || m_main->GetShowSoluce() );
if ( !GetSoluce4() ) bVisible = false;
pc->SetState(STATE_VISIBLE, bVisible);
@ -5997,237 +5876,30 @@ bool CMainDialog::GetHimselfDamage()
return m_bHimselfDamage;
}
// Saves the personalized player.
void CMainDialog::WriteGamerPerso(char *gamer)
{
try
{
CLevelParser persoParser(GetSavegameDir()+"/"+gamer+"/face.gam");
CLevelParserLineUPtr line;
line = MakeUnique<CLevelParserLine>("Head");
line->AddParam("face", MakeUnique<CLevelParserParam>(m_perso.face));
line->AddParam("glasses", MakeUnique<CLevelParserParam>(m_perso.glasses));
line->AddParam("hair", MakeUnique<CLevelParserParam>(m_perso.colorHair));
persoParser.AddLine(std::move(line));
line = MakeUnique<CLevelParserLine>("Body");
line->AddParam("combi", MakeUnique<CLevelParserParam>(m_perso.colorCombi));
line->AddParam("band", MakeUnique<CLevelParserParam>(m_perso.colorBand));
persoParser.AddLine(std::move(line));
persoParser.Save();
}
catch (CLevelParserException& e)
{
GetLogger()->Error("Unable to write personalized player apperance: %s\n", e.what());
}
}
// Reads the personalized player.
void CMainDialog::ReadGamerPerso(char *gamer)
{
m_perso.face = 0;
DefPerso();
if (!CResourceManager::Exists(GetSavegameDir()+"/"+gamer+"/face.gam"))
return;
try
{
CLevelParser persoParser(GetSavegameDir()+"/"+gamer+"/face.gam");
persoParser.Load();
CLevelParserLine* line;
line = persoParser.Get("Head");
m_perso.face = line->GetParam("face")->AsInt();
m_perso.glasses = line->GetParam("glasses")->AsInt();
m_perso.colorHair = line->GetParam("hair")->AsColor();
line = persoParser.Get("Body");
m_perso.colorCombi = line->GetParam("combi")->AsColor();
m_perso.colorBand = line->GetParam("band")->AsColor();
}
catch (CLevelParserException& e)
{
GetLogger()->Error("Unable to read personalized player apperance: %s\n", e.what());
}
}
// Specifies the face of the player.
void CMainDialog::SetGamerFace(char *gamer, int face)
{
m_perso.face = face;
WriteGamerPerso(gamer);
}
// Gives the face of the player.
int CMainDialog::GetGamerFace(char *gamer)
{
ReadGamerPerso(gamer);
return m_perso.face;
}
// Gives the face of the player.
int CMainDialog::GetGamerFace()
{
return m_perso.face;
}
int CMainDialog::GetGamerGlasses()
{
return m_perso.glasses;
}
bool CMainDialog::GetGamerOnlyHead()
{
return (m_phase == PHASE_PERSO && m_persoTab == 0);
return (m_phase == PHASE_PERSO && m_apperanceTab == 0);
}
float CMainDialog::GetPersoAngle()
{
return m_persoAngle;
return m_apperanceAngle;
}
Gfx::Color CMainDialog::GetGamerColorHair()
void CMainDialog::UpdateChapterPassed()
{
return m_perso.colorHair;
}
Gfx::Color CMainDialog::GetGamerColorCombi()
{
return m_perso.colorCombi;
}
Gfx::Color CMainDialog::GetGamerColorBand()
{
return m_perso.colorBand;
}
// Reads the file of the player.
bool CMainDialog::ReadGamerInfo()
{
std::string line;
m_sceneInfo.clear();
if (!CResourceManager::Exists(GetSavegameDir()+"/"+m_main->GetGamerName()+"/"+GetLevelCategoryDir(m_category)+".gam"))
return false;
CInputStream file;
file.open(GetSavegameDir()+"/"+m_main->GetGamerName()+"/"+GetLevelCategoryDir(m_category)+".gam");
if (!file.is_open())
// TODO: CMainDialog is a bad place for this function
bool bAll = true;
for ( int i=0 ; i<m_maxList ; i++ )
{
GetLogger()->Error("Unable to read list of finished missions\n");
return false;
}
std::getline(file, line);
int chap, rank;
sscanf(line.c_str(), "CurrentChapter=%d CurrentSel=%d\n", &chap, &rank);
m_chap[m_category] = chap-1;
m_sel[m_category] = rank-1;
while (!file.eof())
{
std::getline(file, line);
if (line == "")
if (!m_main->GetPlayerProgress()->GetLevelPassed(m_category, m_chap[m_category]+1, i+1))
{
bAll = false;
break;
}
int numTry, passed;
sscanf(line.c_str(), "Chapter %d: Scene %d: numTry=%d passed=%d\n",
&chap, &rank, &numTry, &passed);
if ( chap < 0 || chap > MAXSCENE ) continue;
if ( rank < 0 || rank > MAXSCENE ) continue;
m_sceneInfo[chap][rank].numTry = numTry;
m_sceneInfo[chap][rank].bPassed = passed;
}
file.close();
return true;
}
// Writes the file of the player.
bool CMainDialog::WriteGamerInfo()
{
COutputStream file;
file.open(GetSavegameDir()+"/"+m_main->GetGamerName()+"/"+GetLevelCategoryDir(m_category)+".gam");
if (!file.is_open())
{
GetLogger()->Error("Unable to read list of finished missions\n");
return false;
}
file << "CurrentChapter=" << m_chap[m_category]+1 << " CurrentSel=" << m_sel[m_category]+1 << "\n";
for ( int i=0 ; i<MAXSCENE ; i++ )
{
if (m_sceneInfo.find(i) == m_sceneInfo.end()) continue;
for ( int j=0 ; j<MAXSCENE ; j++ )
{
if (m_sceneInfo[i].find(j) == m_sceneInfo[i].end()) continue;
if ( m_sceneInfo[i][j].numTry == 0 && !m_sceneInfo[i][j].bPassed ) continue;
file << "Chapter " << i << ": Scene " << j << ": numTry=" << m_sceneInfo[i][j].numTry << " passed=" << (m_sceneInfo[i][j].bPassed ? "1" : "0") << "\n";
}
}
file.close();
return true;
}
void CMainDialog::SetGamerInfoTry(int chap, int rank, int numTry)
{
if ( chap < 0 || chap > MAXSCENE ) return;
if ( rank < 0 || rank > MAXSCENE ) return;
m_sceneInfo[chap][rank].numTry = numTry;
}
int CMainDialog::GetGamerInfoTry(int chap, int rank)
{
if ( chap < 0 || chap > MAXSCENE ) return 0;
if ( rank < 0 || rank > MAXSCENE ) return 0;
return m_sceneInfo[chap][rank].numTry;
}
void CMainDialog::SetGamerInfoPassed(int chap, int rank, bool bPassed)
{
if ( chap < 0 || chap > MAXSCENE ) return;
if ( rank < 0 || rank > MAXSCENE ) return;
m_sceneInfo[chap][rank].bPassed = bPassed;
if ( bPassed )
{
bool bAll = true;
for ( int i=0 ; i<m_maxList ; i++ )
{
bAll &= m_sceneInfo[chap][i+1].bPassed;
}
m_sceneInfo[chap][0].numTry ++;
m_sceneInfo[chap][0].bPassed = bAll;
}
}
bool CMainDialog::GetGamerInfoPassed(int chap, int rank)
{
if ( chap < 0 || chap > MAXSCENE ) return false;
if ( rank < 0 || rank > MAXSCENE ) return false;
return m_sceneInfo[chap][rank].bPassed;
m_main->GetPlayerProgress()->IncrementLevelTryCount(m_category, m_chap[m_category]+1, 0);
m_main->GetPlayerProgress()->SetLevelPassed(m_category, m_chap[m_category]+1, 0, bAll);
}
@ -6243,6 +5915,9 @@ bool CMainDialog::NextMission()
m_sel[m_category] = 0; // first mission
}
m_main->GetPlayerProgress()->SetSelectedChap(m_category, m_chap[m_category]+1);
m_main->GetPlayerProgress()->SetSelectedRank(m_category, m_sel[m_category]+1);
return true;
}

View File

@ -45,26 +45,6 @@ class CWindow;
class CControl;
const int USERLISTMAX = 100;
const int MAXSCENE = 999;
struct SceneInfo
{
int numTry;
bool bPassed;
};
struct GamerPerso
{
int face; // face
int glasses; // glasses
Gfx::Color colorHair; // hair color
Gfx::Color colorCombi; // spacesuit volor
Gfx::Color colorBand; // strips color
};
class CMainDialog
{
@ -117,25 +97,11 @@ public:
void SetupMemorize();
void SetupRecall();
bool ReadGamerInfo();
bool WriteGamerInfo();
void SetGamerInfoTry(int chap, int rank, int numTry);
int GetGamerInfoTry(int chap, int rank);
void SetGamerInfoPassed(int chap, int rank, bool bPassed);
bool GetGamerInfoPassed(int chap, int rank);
void UpdateChapterPassed();
bool NextMission();
void WriteGamerPerso(char *gamer);
void ReadGamerPerso(char *gamer);
void SetGamerFace(char *gamer, int face);
int GetGamerFace(char *gamer);
int GetGamerFace();
int GetGamerGlasses();
bool GetGamerOnlyHead();
float GetPersoAngle();
Gfx::Color GetGamerColorHair();
Gfx::Color GetGamerColorCombi();
Gfx::Color GetGamerColorBand();
void AllMissionUpdate();
void ShowSoluceUpdate();
@ -152,15 +118,13 @@ protected:
void UpdateNameList();
void UpdateNameEdit();
void UpdateNameControl();
void UpdateNameFace();
void NameSelect();
void NameCreate();
bool NameCreate();
void NameDelete();
void UpdatePerso();
void CameraPerso();
void FixPerso(int rank, int index);
void ColorPerso();
void DefPerso();
bool IsIOReadScene();
void IOReadName();
void IOReadList();
@ -197,10 +161,8 @@ protected:
Phase m_phaseTerm; // phase trainer/scene/proto
float m_phaseTime;
GamerPerso m_perso; // perso: description
GamerPerso m_persoCopy; // perso: copy for cancellation
int m_persoTab; // perso: tab selected
float m_persoAngle; // perso: angle of presentation
int m_apperanceTab; // perso: tab selected
float m_apperanceAngle; // perso: angle of presentation
std::string m_savegameDir; // savegame folder
std::string m_publicDir; // program folder
@ -263,8 +225,6 @@ protected:
float m_partiTime[10];
Math::Point m_partiPos[10];
std::map<int, std::map<int, SceneInfo>> m_sceneInfo;
std::vector<std::string> m_saveList;
};

View File

@ -35,6 +35,7 @@
#include "object/brain.h"
#include "object/object.h"
#include "object/player_progress.h"
#include "script/cbottoken.h"
#include "script/script.h"
@ -1582,7 +1583,7 @@ std::string CStudio::SearchDirectory(bool bCreate)
}
else
{
dir = std::string(m_main->GetSavegameDir()) + "/" + std::string(m_main->GetGamerName()) + "/program/";
dir = m_main->GetPlayerProgress()->GetSaveFile("program/");
}
if ( bCreate )
@ -1669,4 +1670,3 @@ bool CStudio::WriteProgram()
}
}