summaryrefslogtreecommitdiffstats
path: root/src/object/robotmain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/object/robotmain.cpp')
-rw-r--r--src/object/robotmain.cpp756
1 files changed, 619 insertions, 137 deletions
diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp
index c1e4140..b58e5f8 100644
--- a/src/object/robotmain.cpp
+++ b/src/object/robotmain.cpp
@@ -34,7 +34,7 @@
#include "graphics/engine/engine.h"
#include "graphics/engine/lightman.h"
#include "graphics/engine/lightning.h"
-#include "graphics/engine/modelfile.h"
+#include "graphics/engine/modelmanager.h"
#include "graphics/engine/particle.h"
#include "graphics/engine/planet.h"
#include "graphics/engine/pyro.h"
@@ -79,6 +79,7 @@
#include "ui/slider.h"
#include "ui/window.h"
+#include <iomanip>
template<> CRobotMain* CSingleton<CRobotMain>::m_instance = nullptr;
@@ -602,11 +603,8 @@ bool rPoint(CBotVar* pThis, CBotVar* var, CBotVar* pResult, int& Exception)
return true; // no interruption
}
-
-
-
//! Constructor of robot application
-CRobotMain::CRobotMain(CApplication* app)
+CRobotMain::CRobotMain(CApplication* app, bool loadProfile)
{
m_app = app;
@@ -643,7 +641,7 @@ CRobotMain::CRobotMain(CApplication* app)
m_visitLast = EVENT_NULL;
m_visitObject = 0;
m_visitArrow = 0;
- m_audioTrack = 0;
+ m_audioTrack = "";
m_audioRepeat = true;
m_delayWriteMessage = 0;
m_selectObject = 0;
@@ -656,6 +654,7 @@ CRobotMain::CRobotMain(CApplication* app)
m_terrainCreate = false;
m_version = 1;
+ m_controller = nullptr;
m_retroStyle = false;
m_immediatSatCom = false;
m_beginSatCom = false;
@@ -670,11 +669,13 @@ CRobotMain::CRobotMain(CApplication* app)
m_showPos = false;
m_selectInsect = false;
m_showSoluce = false;
- #ifdef NDEBUG
- m_showAll = false;
- #else
+
+ #if DEV_BUILD
m_showAll = true; // for development
+ #else
+ m_showAll = false;
#endif
+
m_cheatRadar = false;
m_fixScene = false;
m_trainerPilot = false;
@@ -705,27 +706,31 @@ CRobotMain::CRobotMain(CApplication* app)
m_windowPos = Math::Point(0.15f, 0.17f);
m_windowDim = Math::Point(0.70f, 0.66f);
- // TODO: profile
- // float fValue;
- // int iValue;
+ float fValue;
+ int iValue;
- // if (GetLocalProfileFloat("Edit", "FontSize", fValue)) m_fontSize = fValue;
- // if (GetLocalProfileFloat("Edit", "WindowPos.x", fValue)) m_windowPos.x = fValue;
- // if (GetLocalProfileFloat("Edit", "WindowPos.y", fValue)) m_windowPos.y = fValue;
- // if (GetLocalProfileFloat("Edit", "WindowDim.x", fValue)) m_windowDim.x = fValue;
- // if (GetLocalProfileFloat("Edit", "WindowDim.y", fValue)) m_windowDim.y = fValue;
+ if (loadProfile)
+ {
+ if (GetProfile().GetLocalProfileFloat("Edit", "FontSize", fValue)) m_fontSize = fValue;
+ if (GetProfile().GetLocalProfileFloat("Edit", "WindowPosX", fValue)) m_windowPos.x = fValue;
+ if (GetProfile().GetLocalProfileFloat("Edit", "WindowPosY", fValue)) m_windowPos.y = fValue;
+ if (GetProfile().GetLocalProfileFloat("Edit", "WindowDimX", fValue)) m_windowDim.x = fValue;
+ if (GetProfile().GetLocalProfileFloat("Edit", "WindowDimY", fValue)) m_windowDim.y = fValue;
+ }
m_IOPublic = false;
m_IODim = Math::Point(320.0f/640.0f, (121.0f+18.0f*8)/480.0f);
m_IOPos.x = (1.0f-m_IODim.x)/2.0f; // in the middle
m_IOPos.y = (1.0f-m_IODim.y)/2.0f;
- /* TODO: profile
- if (GetLocalProfileInt ("Edit", "IOPublic", iValue)) m_IOPublic = iValue;
- if (GetLocalProfileFloat("Edit", "IOPos.x", fValue)) m_IOPos.x = fValue;
- if (GetLocalProfileFloat("Edit", "IOPos.y", fValue)) m_IOPos.y = fValue;
- if (GetLocalProfileFloat("Edit", "IODim.x", fValue)) m_IODim.x = fValue;
- if (GetLocalProfileFloat("Edit", "IODim.y", fValue)) m_IODim.y = fValue; */
+ if (loadProfile)
+ {
+ if (GetProfile().GetLocalProfileInt ("Edit", "IOPublic", iValue)) m_IOPublic = iValue;
+ if (GetProfile().GetLocalProfileFloat("Edit", "IOPosX", fValue)) m_IOPos.x = fValue;
+ if (GetProfile().GetLocalProfileFloat("Edit", "IOPosY", fValue)) m_IOPos.y = fValue;
+ if (GetProfile().GetLocalProfileFloat("Edit", "IODimX", fValue)) m_IODim.x = fValue;
+ if (GetProfile().GetLocalProfileFloat("Edit", "IODimY", fValue)) m_IODim.y = fValue;
+ }
m_short->FlushShortcuts();
InitEye();
@@ -741,12 +746,11 @@ CRobotMain::CRobotMain(CApplication* app)
g_researchEnable = 0;
g_unit = UNIT;
- m_gamerName[0] = 0;
- /* TODO: profile
- GetLocalProfileString("Gamer", "LastName", m_gamerName, 100); */
+ m_gamerName = "";
+ if (loadProfile) GetProfile().GetLocalProfileString("Gamer", "LastName", m_gamerName);
SetGlobalGamerName(m_gamerName);
ReadFreeParam();
- m_dialog->SetupRecall();
+ if (loadProfile) m_dialog->SetupRecall();
for (int i = 0; i < MAXSHOWLIMIT; i++)
{
@@ -805,6 +809,48 @@ CRobotMain::CRobotMain(CApplication* app)
CBotProgram::DefineNum("FilterOnlyLanding", FILTER_ONLYLANDING);
CBotProgram::DefineNum("FilterOnlyFliying", FILTER_ONLYFLYING);
+ CBotProgram::DefineNum("ExploNone", 0);
+ CBotProgram::DefineNum("ExploBoum", EXPLO_BOUM);
+ CBotProgram::DefineNum("ExploBurn", EXPLO_BURN);
+ CBotProgram::DefineNum("ExploWater", EXPLO_WATER);
+
+ CBotProgram::DefineNum("ResultNotEnded", ERR_MISSION_NOTERM);
+ CBotProgram::DefineNum("ResultLost", INFO_LOST);
+ CBotProgram::DefineNum("ResultLostQuick", INFO_LOSTq);
+ CBotProgram::DefineNum("ResultWin", ERR_OK);
+
+ CBotProgram::DefineNum("BuildBotFactory", BUILD_FACTORY);
+ CBotProgram::DefineNum("BuildDerrick", BUILD_DERRICK);
+ CBotProgram::DefineNum("BuildConverter", BUILD_CONVERT);
+ CBotProgram::DefineNum("BuildRadarStation", BUILD_RADAR);
+ CBotProgram::DefineNum("BuildPowerPlant", BUILD_ENERGY);
+ CBotProgram::DefineNum("BuildNuclearPlant", BUILD_NUCLEAR);
+ CBotProgram::DefineNum("BuildPowerStation", BUILD_STATION);
+ CBotProgram::DefineNum("BuildRepairCenter", BUILD_REPAIR);
+ CBotProgram::DefineNum("BuildDefenseTower", BUILD_TOWER);
+ CBotProgram::DefineNum("BuildResearchCenter", BUILD_RESEARCH);
+ CBotProgram::DefineNum("BuildAutoLab", BUILD_LABO);
+ CBotProgram::DefineNum("BuildPowerCaptor", BUILD_PARA);
+ CBotProgram::DefineNum("BuildExchangePost", BUILD_INFO);
+ CBotProgram::DefineNum("BuildDestroyer", BUILD_DESTROYER);
+ CBotProgram::DefineNum("FlatGround", BUILD_GFLAT);
+ CBotProgram::DefineNum("UseFlags", BUILD_FLAG);
+ CBotProgram::DefineNum("ResearchTracked", RESEARCH_TANK);
+ CBotProgram::DefineNum("ResearchWinged", RESEARCH_FLY);
+ CBotProgram::DefineNum("ResearchShooter", RESEARCH_CANON);
+ CBotProgram::DefineNum("ResearchDefenseTower", RESEARCH_TOWER);
+ CBotProgram::DefineNum("ResearchNuclearPlant", RESEARCH_ATOMIC);
+ CBotProgram::DefineNum("ResearchThumper", RESEARCH_THUMP);
+ CBotProgram::DefineNum("ResearchShielder", RESEARCH_SHIELD);
+ CBotProgram::DefineNum("ResearchPhazerShooter", RESEARCH_PHAZER);
+ CBotProgram::DefineNum("ResearchLegged", RESEARCH_iPAW);
+ CBotProgram::DefineNum("ResearchOrgaShooter", RESEARCH_iGUN);
+ CBotProgram::DefineNum("ResearchRecycler", RESEARCH_RECYCLER);
+ CBotProgram::DefineNum("ResearchSubber", RESEARCH_SUBM);
+ CBotProgram::DefineNum("ResearchSniffer", RESEARCH_SNIFFER);
+
+//? CBotProgram::
+
CBotProgram::DefineNum("PolskiPortalColobota", 1337);
CBotClass* bc;
@@ -831,6 +877,11 @@ CRobotMain::CRobotMain(CApplication* app)
bc->AddItem("material", CBotTypResult(CBotTypInt), PR_READ);
bc->AddItem("energyCell", CBotTypResult(CBotTypPointer, "object"), PR_READ);
bc->AddItem("load", CBotTypResult(CBotTypPointer, "object"), PR_READ);
+ bc->AddItem("id", CBotTypResult(CBotTypInt), PR_READ);
+ bc->AddFunction("busy", CScript::rBusy, CScript::cBusy);
+ bc->AddFunction("factory", CScript::rFactory, CScript::cFactory);
+ bc->AddFunction("research", CScript::rResearch, CScript::cClassOneFloat);
+ bc->AddFunction("destroy", CScript::rDestroy, CScript::cClassNull);
// Initializes the class FILE.
InitClassFILE();
@@ -891,15 +942,32 @@ Ui::CDisplayText* CRobotMain::GetDisplayText()
return m_displayText;
}
+void CRobotMain::LoadSceneOnStart(const std::string& name, int rank)
+{
+ // TODO: fix this ugly dependency :(
+ m_dialog->SetSceneName(name.c_str());
+ m_dialog->SetSceneRank(rank);
+ ChangePhase(PHASE_LOADING);
+}
+
//! Creates the file colobot.ini at the first time
void CRobotMain::CreateIni()
{
- /* TODO: profile
- int iValue;
- // colobot.ini doesn't exist?
- if (!GetLocalProfileInt("Setup", "TotoMode", iValue))
- m_dialog->SetupMemorize();*/
+ m_dialog->SetupMemorize();
+
+ GetProfile().SetLocalProfileFloat("Edit", "FontSize", m_fontSize);
+ GetProfile().SetLocalProfileFloat("Edit", "WindowPosX", m_windowPos.x);
+ GetProfile().SetLocalProfileFloat("Edit", "WindowPosY", m_windowPos.y);
+ GetProfile().SetLocalProfileFloat("Edit", "WindowDimX", m_windowDim.x);
+ GetProfile().SetLocalProfileFloat("Edit", "WindowDimY", m_windowDim.y);
+ GetProfile().SetLocalProfileInt("Edit", "IOPublic", m_IOPublic);
+ GetProfile().SetLocalProfileFloat("Edit", "IOPosX", m_IOPos.x);
+ GetProfile().SetLocalProfileFloat("Edit", "IOPosY", m_IOPos.y);
+ GetProfile().SetLocalProfileFloat("Edit", "IODimX", m_IODim.x);
+ GetProfile().SetLocalProfileFloat("Edit", "IODimY", m_IODim.y);
+
+ GetProfile().SaveCurrentDirectory();
}
void CRobotMain::SetDefaultInputBindings()
@@ -952,28 +1020,24 @@ void CRobotMain::SetDefaultInputBindings()
void CRobotMain::SetInputBinding(InputSlot slot, InputBinding binding)
{
unsigned int index = static_cast<unsigned int>(slot);
- assert(index >= 0 && index < INPUT_SLOT_MAX);
m_inputBindings[index] = binding;
}
const InputBinding& CRobotMain::GetInputBinding(InputSlot slot)
{
unsigned int index = static_cast<unsigned int>(slot);
- assert(index >= 0 && index < INPUT_SLOT_MAX);
return m_inputBindings[index];
}
void CRobotMain::SetJoyAxisBinding(JoyAxisSlot slot, JoyAxisBinding binding)
{
unsigned int index = static_cast<unsigned int>(slot);
- assert(index >= 0 && index < JOY_AXIS_SLOT_MAX);
m_joyAxisBindings[index] = binding;
}
const JoyAxisBinding& CRobotMain::GetJoyAxisBinding(JoyAxisSlot slot)
{
unsigned int index = static_cast<unsigned int>(slot);
- assert(index >= 0 && index < JOY_AXIS_SLOT_MAX);
return m_joyAxisBindings[index];
}
@@ -1041,6 +1105,7 @@ void CRobotMain::ChangePhase(Phase phase)
FlushDisplayInfo();
m_engine->SetRankView(0);
m_engine->DeleteAllObjects();
+ Gfx::CModelManager::GetInstancePointer()->DeleteAllModelCopies();
m_engine->SetWaterAddColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f));
m_engine->SetBackground("");
m_engine->SetBackForce(false);
@@ -1137,6 +1202,8 @@ void CRobotMain::ChangePhase(Phase phase)
if (m_mapImage)
m_map->SetFixImage(m_mapFilename);
+ m_app->ResetTimeAfterLoading();
+
/*Math::Point ddim;
pos.x = 620.0f/640.0f;
@@ -1225,7 +1292,7 @@ void CRobotMain::ChangePhase(Phase phase)
ddim.x = dim.x*2; ddim.y = dim.y*2;
m_interface->CreateButton(pos, ddim, 16, EVENT_BUTTON_OK);
m_displayText->DisplayError(INFO_LOST, Math::Vector(0.0f,0.0f,0.0f), 15.0f, 60.0f, 1000.0f);
-
+
StartMusic();
}
}
@@ -1239,7 +1306,7 @@ void CRobotMain::ChangePhase(Phase phase)
}
//! Processes an event
-bool CRobotMain::EventProcess(Event &event)
+bool CRobotMain::ProcessEvent(Event &event)
{
/* Motion vector management */
@@ -1332,7 +1399,7 @@ bool CRobotMain::EventProcess(Event &event)
// Management of the console.
if (m_phase != PHASE_NAME &&
!m_movie->IsExist() &&
- !m_movieLock && !m_editLock &&
+ !m_movieLock && !m_editLock && !m_engine->GetPause() &&
event.type == EVENT_KEY_DOWN &&
event.key.key == KEY(PAUSE)) // Pause ?
{
@@ -1474,7 +1541,7 @@ bool CRobotMain::EventProcess(Event &event)
ChangePhase(PHASE_WIN);
else if (m_lostDelay > 0.0f)
ChangePhase(PHASE_LOST);
- else
+ else if (!m_cmdEdit)
m_dialog->StartAbort(); // do you want to leave?
}
if (event.key.key == KEY(PAUSE))
@@ -1760,12 +1827,47 @@ void CRobotMain::ExecuteCmd(char *cmd)
return;
}
+ if (strcmp(cmd, "allbuildings") == 0)
+ {
+ g_build = -1; // all buildings are available
+
+ m_eventQueue->AddEvent(Event(EVENT_UPDINTERFACE));
+ return;
+ }
+
+ if (strcmp(cmd, "all") == 0)
+ {
+ g_researchDone = -1; // all research are done
+ g_build = -1; // all buildings are available
+
+ m_eventQueue->AddEvent(Event(EVENT_UPDINTERFACE));
+ return;
+ }
+
if (strcmp(cmd, "nolimit") == 0)
{
m_terrain->SetFlyingMaxHeight(280.0f);
return;
}
+ if (strcmp(cmd, "controller") == 0)
+ {
+ if (m_controller != nullptr)
+ {
+ // Don't use SelectObject because it checks if the object is selectable
+ if (m_camera->GetType() == Gfx::CAM_TYPE_VISIT)
+ StopDisplayVisit();
+
+ CObject* prev = DeselectAll();
+ if (prev != nullptr && prev != m_controller)
+ m_controller->AddDeselList(prev);
+
+ SelectOneObject(m_controller, true);
+ m_short->UpdateShortcuts();
+ }
+ return;
+ }
+
if (strcmp(cmd, "photo1") == 0)
{
m_freePhoto = !m_freePhoto;
@@ -1834,7 +1936,7 @@ void CRobotMain::ExecuteCmd(char *cmd)
object->SetRange(object->GetRange()*10.0f);
return;
}
-
+
if (strcmp(cmd, "\155\157\157") == 0)
{
// VGhpcyBpcyBlYXN0ZXItZWdnIGFuZCBzbyBpdCBzaG91bGQgYmUgb2JmdXNjYXRlZCEgRG8gbm90
@@ -1901,7 +2003,14 @@ void CRobotMain::ExecuteCmd(char *cmd)
if (strcmp(cmd, "debugmode") == 0)
{
- m_app->SetDebugMode(!m_app->GetDebugMode());
+ if (m_app->IsDebugModeActive(DEBUG_ALL))
+ {
+ m_app->SetDebugModeActive(DEBUG_ALL, false);
+ }
+ else
+ {
+ m_app->SetDebugModeActive(DEBUG_ALL, true);
+ }
return;
}
@@ -1988,15 +2097,23 @@ void CRobotMain::ExecuteCmd(char *cmd)
return;
}
- if (strcmp(cmd, "speed4") == 0) {
+ if (strcmp(cmd, "speed4") == 0)
+ {
SetSpeed(4.0f);
UpdateSpeedLabel();
- return;
+ return;
}
- if (strcmp(cmd, "speed8") == 0) {
+ if (strcmp(cmd, "speed8") == 0)
+ {
SetSpeed(8.0f);
UpdateSpeedLabel();
- return;
+ return;
+ }
+ if (strcmp(cmd, "crazy") == 0)
+ {
+ SetSpeed(1000.0f);
+ UpdateSpeedLabel();
+ return;
}
if (m_phase == PHASE_SIMUL)
@@ -2020,7 +2137,7 @@ void CRobotMain::FlushDisplayInfo()
m_infoFilename[i][0] = 0;
m_infoPos[i] = 0;
}
- strcpy(m_infoFilename[SATCOM_OBJECT], "help/") + m_app->GetLanguageChar() + std::string("/objects.txt");
+ strcpy(m_infoFilename[SATCOM_OBJECT], "objects.txt");
m_infoIndex = 0;
}
@@ -2093,7 +2210,7 @@ void CRobotMain::StartDisplayInfo(const char *filename, int index)
void CRobotMain::StopDisplayInfo()
{
if (m_cmdEdit) return;
-
+
if (m_movieInfoIndex != -1) // film to read the SatCom?
m_movie->Start(MM_SATCOMclose, 2.0f);
@@ -2182,8 +2299,7 @@ float CRobotMain::GetGameTime()
void CRobotMain::SetFontSize(float size)
{
m_fontSize = size;
- /* TODO: profile
- SetLocalProfileFloat("Edit", "FontSize", m_fontSize); */
+ GetProfile().SetLocalProfileFloat("Edit", "FontSize", m_fontSize);
}
float CRobotMain::GetFontSize()
@@ -2195,9 +2311,8 @@ float CRobotMain::GetFontSize()
void CRobotMain::SetWindowPos(Math::Point pos)
{
m_windowPos = pos;
- /* TODO: profile
- SetLocalProfileFloat("Edit", "WindowPos.x", m_windowPos.x);
- SetLocalProfileFloat("Edit", "WindowPos.y", m_windowPos.y); */
+ GetProfile().SetLocalProfileFloat("Edit", "WindowPosX", m_windowPos.x);
+ GetProfile().SetLocalProfileFloat("Edit", "WindowPosY", m_windowPos.y);
}
Math::Point CRobotMain::GetWindowPos()
@@ -2208,9 +2323,8 @@ Math::Point CRobotMain::GetWindowPos()
void CRobotMain::SetWindowDim(Math::Point dim)
{
m_windowDim = dim;
- /* TODO: profile
- SetLocalProfileFloat("Edit", "WindowDim.x", m_windowDim.x);
- SetLocalProfileFloat("Edit", "WindowDim.y", m_windowDim.y); */
+ GetProfile().SetLocalProfileFloat("Edit", "WindowDimX", m_windowDim.x);
+ GetProfile().SetLocalProfileFloat("Edit", "WindowDimY", m_windowDim.y);
}
Math::Point CRobotMain::GetWindowDim()
@@ -2223,8 +2337,7 @@ Math::Point CRobotMain::GetWindowDim()
void CRobotMain::SetIOPublic(bool mode)
{
m_IOPublic = mode;
- /* TODO: profile
- SetLocalProfileInt("Edit", "IOPublic", m_IOPublic); */
+ GetProfile().SetLocalProfileInt("Edit", "IOPublic", m_IOPublic);
}
bool CRobotMain::GetIOPublic()
@@ -2235,9 +2348,8 @@ bool CRobotMain::GetIOPublic()
void CRobotMain::SetIOPos(Math::Point pos)
{
m_IOPos = pos;
- /* TODO: profile
- SetLocalProfileFloat("Edit", "IOPos.x", m_IOPos.x);
- SetLocalProfileFloat("Edit", "IOPos.y", m_IOPos.y); */
+ GetProfile().SetLocalProfileFloat("Edit", "IOPosX", m_IOPos.x);
+ GetProfile().SetLocalProfileFloat("Edit", "IOPosY", m_IOPos.y);
}
Math::Point CRobotMain::GetIOPos()
@@ -2248,9 +2360,8 @@ Math::Point CRobotMain::GetIOPos()
void CRobotMain::SetIODim(Math::Point dim)
{
m_IODim = dim;
- /* TODO: profile
- SetLocalProfileFloat("Edit", "IODim.x", m_IODim.x);
- SetLocalProfileFloat("Edit", "IODim.y", m_IODim.y); */
+ GetProfile().SetLocalProfileFloat("Edit", "IODimX", m_IODim.x);
+ GetProfile().SetLocalProfileFloat("Edit", "IODimY", m_IODim.y);
}
Math::Point CRobotMain::GetIODim()
@@ -2680,6 +2791,8 @@ CObject* CRobotMain::DetectObject(Math::Point pos)
if (obj == nullptr) break;
if (!obj->GetActif()) continue;
+ CObject* truck = obj->GetTruck();
+ if (truck != nullptr) if (!truck->GetActif()) continue;
if (obj->GetProxyActivate()) continue;
CObject* target = nullptr;
@@ -3446,6 +3559,7 @@ bool CRobotMain::EventFrame(const Event &event)
{
m_checkEndTime = m_time;
CheckEndMission(true);
+ UpdateAudio(true);
}
if (m_winDelay > 0.0f && !m_editLock)
@@ -3635,7 +3749,7 @@ void CRobotMain::Convert()
}
}
- if (Cmd(line, "EndMissionTake"))
+ if (Cmd(line, "EndMissionTake") || Cmd(line, "AudioChange"))
{
char* p = strstr(line, "pos=");
if (p != 0)
@@ -3729,6 +3843,7 @@ void CRobotMain::ScenePerso()
{
DeleteAllObjects(); // removes all the current 3D Scene
m_engine->DeleteAllObjects();
+ Gfx::CModelManager::GetInstancePointer()->DeleteAllModelCopies();
m_terrain->FlushRelief(); // all flat
m_terrain->FlushBuildingLevel();
m_terrain->FlushFlyingLimit();
@@ -3785,7 +3900,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
FlushDisplayInfo();
m_terrain->FlushMaterials();
- m_audioTrack = 0;
+ m_audioTrack = "";
m_audioRepeat = true;
m_displayText->SetDelay(1.0f);
m_displayText->SetEnable(true);
@@ -3793,8 +3908,10 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_lockedSatCom = false;
m_endingWinRank = 0;
m_endingLostRank = 0;
+ m_audioChangeTotal = 0;
m_endTakeTotal = 0;
m_endTakeResearch = 0;
+ m_endTakeNever = false;
m_endTakeWinDelay = 2.0f;
m_endTakeLostDelay = 2.0f;
m_obligatoryTotal = 0;
@@ -3803,6 +3920,8 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_mapImage = false;
m_mapFilename[0] = 0;
+ m_controller = nullptr;
+
m_colorRefBot.r = 10.0f/256.0f;
m_colorRefBot.g = 166.0f/256.0f;
m_colorRefBot.b = 254.0f/256.0f; // blue
@@ -3840,6 +3959,8 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_version = 1;
m_retroStyle = false;
+
+ m_missionResult = ERR_MISSION_NOTERM;
}
char line[500];
@@ -3864,12 +3985,12 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
int rankGadget = 0;
CObject* sel = 0;
- std::string oldLocale;
- char *locale = setlocale(LC_NUMERIC, nullptr);
- if (locale != nullptr)
- oldLocale = locale;
+ SetNumericLocale();
- setlocale(LC_NUMERIC, "C");
+ /*
+ * NOTE: Moving frequently used lines to the top
+ * may speed up loading
+ */
while (fgets(line, 500, file) != NULL)
{
@@ -3890,18 +4011,34 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
// TODO: Fallback to an non-localized entry
sprintf(op, "Title.%c", m_app->GetLanguageChar());
if (Cmd(line, op) && !resetObject)
+ {
OpString(line, "text", m_title);
+ continue;
+ }
sprintf(op, "Resume.%c", m_app->GetLanguageChar());
if (Cmd(line, op) && !resetObject)
+ {
OpString(line, "text", m_resume);
+ continue;
+ }
sprintf(op, "ScriptName.%c", m_app->GetLanguageChar());
if (Cmd(line, op) && !resetObject)
+ {
OpString(line, "text", m_scriptName);
+ continue;
+ }
+
+ if (Cmd(line, "Title")) continue; // Ignore
+ if (Cmd(line, "Resume")) continue; // Ignore
+ if (Cmd(line, "ScriptName")) continue; // Ignore
if (Cmd(line, "ScriptFile") && !resetObject)
+ {
OpString(line, "name", m_scriptFile);
+ continue;
+ }
if (Cmd(line, "Instructions") && !resetObject)
{
@@ -3910,7 +4047,8 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
strcpy(m_infoFilename[SATCOM_HUSTON], path.c_str());
m_immediatSatCom = OpInt(line, "immediat", 0);
- if(m_version >= 2) m_beginSatCom = m_lockedSatCom = OpInt(line, "lock", 0);
+ if (m_version >= 2) m_beginSatCom = m_lockedSatCom = OpInt(line, "lock", 0);
+ continue;
}
if (Cmd(line, "Satellite") && !resetObject)
@@ -3918,6 +4056,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
OpString(line, "name", name);
std::string path = m_app->GetDataFilePath(DIR_HELP, name);
strcpy(m_infoFilename[SATCOM_SAT], path.c_str());
+ continue;
}
if (Cmd(line, "Loading") && !resetObject)
@@ -3925,6 +4064,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
OpString(line, "name", name);
std::string path = m_app->GetDataFilePath(DIR_HELP, name);
strcpy(m_infoFilename[SATCOM_LOADING], path.c_str());
+ continue;
}
if (Cmd(line, "HelpFile") && !resetObject)
@@ -3932,66 +4072,131 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
OpString(line, "name", name);
std::string path = m_app->GetDataFilePath(DIR_HELP, name);
strcpy(m_infoFilename[SATCOM_PROG], path.c_str());
+ continue;
}
if (Cmd(line, "SoluceFile") && !resetObject)
{
OpString(line, "name", name);
std::string path = m_app->GetDataFilePath(DIR_HELP, name);
strcpy(m_infoFilename[SATCOM_SOLUCE], path.c_str());
+ continue;
}
if (Cmd(line, "EndingFile") && !resetObject)
{
m_endingWinRank = OpInt(line, "win", 0);
m_endingLostRank = OpInt(line, "lost", 0);
+ continue;
}
if (Cmd(line, "MessageDelay") && !resetObject)
{
m_displayText->SetDelay(OpFloat(line, "factor", 1.0f));
+ continue;
+ }
+
+ if (Cmd(line, "CacheAudio") && !resetObject && m_version >= 2)
+ {
+ OpString(line, "filename", name);
+ m_sound->CacheMusic(name);
+ continue;
+ }
+
+ if (Cmd(line, "AudioChange") && !resetObject && m_version >= 2 && m_controller == nullptr)
+ {
+ int i = m_audioChangeTotal;
+ if (i < 10)
+ {
+ m_audioChange[i].pos = OpPos(line, "pos")*g_unit;
+ m_audioChange[i].dist = OpFloat(line, "dist", 8.0f)*g_unit;
+ m_audioChange[i].type = OpTypeObject(line, "type", OBJECT_NULL);
+ m_audioChange[i].min = OpInt(line, "min", 1);
+ m_audioChange[i].max = OpInt(line, "max", 9999);
+ m_audioChange[i].powermin = OpInt(line, "powermin", -1);
+ m_audioChange[i].powermax = OpInt(line, "powermax", 100);
+ OpString(line, "filename", m_audioChange[i].music);
+ m_audioChange[i].repeat = OpInt(line, "repeat", 1);
+ m_audioChange[i].changed = false;
+ m_sound->CacheMusic(m_audioChange[i].music);
+ m_audioChangeTotal ++;
+ }
+ continue;
}
- if (Cmd(line, "Audio") && !resetObject)
+ if (Cmd(line, "Audio") && !resetObject && m_controller == nullptr)
{
- m_audioTrack = OpInt(line, "track", 0);
+ if (m_version < 2)
+ {
+ int trackid = OpInt(line, "track", 0);
+ if (trackid != 0)
+ {
+ std::stringstream filenameStr;
+ filenameStr << "music" << std::setfill('0') << std::setw(3) << trackid << ".ogg";
+ m_audioTrack = filenameStr.str();
+ }
+ }
+ else
+ {
+ char trackname[100];
+ OpString(line, "filename", trackname);
+ m_audioTrack = trackname;
+ }
m_audioRepeat = OpInt(line, "repeat", 1);
+ if (m_audioTrack != "") m_sound->CacheMusic(m_audioTrack);
+ continue;
}
if (Cmd(line, "AmbientColor") && !resetObject)
{
m_engine->SetAmbientColor(OpColor(line, "air", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)), 0);
m_engine->SetAmbientColor(OpColor(line, "water", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)), 1);
+ continue;
}
if (Cmd(line, "FogColor") && !resetObject)
{
m_engine->SetFogColor(OpColor(line, "air", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)), 0);
m_engine->SetFogColor(OpColor(line, "water", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f)), 1);
+ continue;
}
if (Cmd(line, "VehicleColor") && !resetObject)
+ {
m_colorNewBot = OpColor(line, "color", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f));
+ continue;
+ }
if (Cmd(line, "InsectColor") && !resetObject)
+ {
m_colorNewAlien = OpColor(line, "color", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f));
+ continue;
+ }
if (Cmd(line, "GreeneryColor") && !resetObject)
+ {
m_colorNewGreen = OpColor(line, "color", Gfx::Color(0.533f, 0.533f, 0.533f, 0.533f));
+ continue;
+ }
if (Cmd(line, "DeepView") && !resetObject)
{
m_engine->SetDeepView(OpFloat(line, "air", 500.0f)*g_unit, 0, true);
m_engine->SetDeepView(OpFloat(line, "water", 100.0f)*g_unit, 1, true);
+ continue;
}
if (Cmd(line, "FogStart") && !resetObject)
{
m_engine->SetFogStart(OpFloat(line, "air", 0.5f), 0);
m_engine->SetFogStart(OpFloat(line, "water", 0.5f), 1);
+ continue;
}
if (Cmd(line, "SecondTexture") && !resetObject)
+ {
m_engine->SetSecondTexture(OpInt(line, "rank", 1));
+ continue;
+ }
if (Cmd(line, "Background") && !resetObject)
{
@@ -4002,6 +4207,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
OpColor(line, "cloudUp", Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)),
OpColor(line, "cloudDown", Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)),
OpInt(line, "full", 0));
+ continue;
}
if (Cmd(line, "Planet") && !resetObject)
@@ -4022,12 +4228,14 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
Math::Point(uv2.x, uv2.z),
strstr(name, "planet") != nullptr // TODO: add transparent op or modify textures
);
+ continue;
}
if (Cmd(line, "ForegroundName") && !resetObject)
{
OpString(line, "image", name);
m_engine->SetForegroundName(name);
+ continue;
}
if (((m_version == 1 && Cmd(line, "Global")) || (m_version >= 2 && Cmd(line, "Mission"))) && !resetObject)
@@ -4035,20 +4243,24 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
g_unit = OpFloat(line, "unitScale", 4.0f);
m_engine->SetTracePrecision(OpFloat(line, "traceQuality", 1.0f));
m_shortCut = OpInt(line, "shortcut", 1);
- if(m_version >= 2) {
+ if (m_version >= 2)
+ {
m_retroStyle = OpInt(line, "retro", 0);
- if(m_retroStyle) GetLogger()->Info("Retro mode enabled.\n");
+ if (m_retroStyle) GetLogger()->Info("Retro mode enabled.\n");
}
+ continue;
}
if (Cmd(line, "TerrainGenerate") && !resetObject)
{
- if(m_terrainCreate) {
+ if (m_terrainCreate)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainGenerate after TerrainCreate\n", filename, lineNum);
continue;
}
- if(m_terrainInit) {
+ if (m_terrainInit)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainGenerate after TerrainInit\n", filename, lineNum);
continue;
}
@@ -4061,67 +4273,81 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
OpFloat(line, "hard", 0.5f));
m_terrainGenerate = true;
+ continue;
}
- if (Cmd(line, "TerrainWind") && !resetObject) {
- if(m_terrainCreate) {
+ if (Cmd(line, "TerrainWind") && !resetObject)
+ {
+ if (m_terrainCreate)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainWind after TerrainCreate\n", filename, lineNum);
continue;
}
- if(m_terrainInit) {
+ if (m_terrainInit)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainWind after TerrainInit\n", filename, lineNum);
continue;
}
- if(!m_terrainGenerate) {
+ if (!m_terrainGenerate)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainWind before TerrainGenerate\n", filename, lineNum);
continue;
}
m_terrain->SetWind(OpPos(line, "speed"));
+ continue;
}
if (Cmd(line, "TerrainRelief") && !resetObject)
{
- if(m_terrainCreate) {
+ if (m_terrainCreate)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainRelief after TerrainCreate\n", filename, lineNum);
continue;
}
- if(m_terrainInit) {
+ if (m_terrainInit)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainRelief after TerrainInit\n", filename, lineNum);
continue;
}
- if(!m_terrainGenerate) {
+ if (!m_terrainGenerate)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainRelief before TerrainGenerate\n", filename, lineNum);
continue;
}
OpString(line, "image", name);
m_terrain->LoadRelief(name, OpFloat(line, "factor", 1.0f), OpInt(line, "border", 1));
+ continue;
}
if (Cmd(line, "TerrainResource") && !resetObject)
{
- if(m_terrainCreate) {
+ if (m_terrainCreate)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainResource after TerrainCreate\n", filename, lineNum);
continue;
}
- if(m_terrainInit) {
+ if (m_terrainInit)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainResource after TerrainInit\n", filename, lineNum);
continue;
}
- if(!m_terrainGenerate) {
+ if (!m_terrainGenerate)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainResource before TerrainGenerate\n", filename, lineNum);
continue;
}
OpString(line, "image", name);
m_terrain->LoadResources(name);
+ continue;
}
if (Cmd(line, "TerrainWater") && !resetObject)
@@ -4141,10 +4367,14 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
pos);
m_colorNewWater = OpColor(line, "color", m_colorRefWater);
m_colorShiftWater = OpFloat(line, "brightness", 0.0f);
+ continue;
}
if (Cmd(line, "TerrainLava") && !resetObject)
+ {
m_water->SetLava(OpInt(line, "mode", 0));
+ continue;
+ }
if (Cmd(line, "TerrainCloud") && !resetObject)
{
@@ -4153,6 +4383,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
OpColor(line, "diffuse", Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
OpColor(line, "ambient", Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)),
OpFloat(line, "level", 500.0f) * g_unit);
+ continue;
}
if (Cmd(line, "TerrainBlitz") && !resetObject)
@@ -4160,11 +4391,13 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_lightning->Create(OpFloat(line, "sleep", 0.0f),
OpFloat(line, "delay", 3.0f),
OpFloat(line, "magnetic", 50.0f) * g_unit);
+ continue;
}
if (Cmd(line, "TerrainInitTextures") && !resetObject)
{
- if(m_terrainInit) {
+ if (m_terrainInit)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainInitTextures and TerrainInit at same time\n", filename, lineNum);
continue;
}
@@ -4173,10 +4406,10 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
AddExt(name, ".png");
int dx = OpInt(line, "dx", 1);
int dy = OpInt(line, "dy", 1);
- char* op = SearchOp(line, "table");
+ char* opTable = SearchOp(line, "table");
int tt[100];
for (int i = 0; i < dx*dy; i++)
- tt[i] = GetInt(op, i, 0);
+ tt[i] = GetInt(opTable, i, 0);
if (strstr(name, "%user%") != 0)
CopyFileListToTemp(name, tt, dx*dy);
@@ -4184,38 +4417,46 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_terrain->InitTextures(name, tt, dx, dy);
m_terrainInitTextures = true;
+ continue;
}
- if (Cmd(line, "TerrainInit") && !resetObject) {
- if(m_terrainInitTextures) {
+ if (Cmd(line, "TerrainInit") && !resetObject)
+ {
+ if (m_terrainInitTextures)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainInit and TerrainInitTextures at same time\n", filename, lineNum);
continue;
}
m_terrain->InitMaterials(OpInt(line, "id", 1));
m_terrainInit = true;
+ continue;
}
if (Cmd(line, "TerrainMaterial") && !resetObject)
{
- if(m_terrainCreate) {
+ if (m_terrainCreate)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainMaterial after TerrainCreate\n", filename, lineNum);
continue;
}
- if(m_terrainInit) {
+ if (m_terrainInit)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainMaterial after TerrainInit\n", filename, lineNum);
continue;
}
- if(m_terrainInitTextures) {
+ if (m_terrainInitTextures)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainMaterial and TerrainInitTextures at same time\n", filename, lineNum);
continue;
}
OpString(line, "image", name);
AddExt(name, ".png");
- if (strstr(name, "%user%") != 0) {
+ if (strstr(name, "%user%") != 0)
+ {
GetProfile().CopyFileToTemp(std::string(name));
}
@@ -4228,36 +4469,41 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
OpInt(line, "down", 1),
OpInt(line, "left", 1),
OpFloat(line, "hard", 0.5f));
+ continue;
}
if (Cmd(line, "TerrainLevel") && !resetObject)
{
- if(m_terrainCreate) {
+ if (m_terrainCreate)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainLevel after TerrainCreate\n", filename, lineNum);
continue;
}
- if(!m_terrainInit) {
+ if (!m_terrainInit)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainLevel before TerrainInit\n", filename, lineNum);
continue;
}
- if(m_terrainInitTextures) {
+ if (m_terrainInitTextures)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainLevel and TerrainInitTextures at same time\n", filename, lineNum);
continue;
}
- if(!m_terrainGenerate) {
+ if (!m_terrainGenerate)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): TerrainLevel before TerrainGenerate\n", filename, lineNum);
continue;
}
- char* op = SearchOp(line, "id");
+ char* opId = SearchOp(line, "id");
int id[50];
int i = 0;
while (i < 50)
{
- id[i] = GetInt(op, i, 0);
+ id[i] = GetInt(opId, i, 0);
if (id[i++] == 0) break;
}
@@ -4268,11 +4514,14 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
OpFloat(line, "freq", 100.0f),
OpPos(line, "center")*g_unit,
OpFloat(line, "radius", 0.0f)*g_unit);
+ continue;
}
- if (Cmd(line, "TerrainCreate") && !resetObject) {
+ if (Cmd(line, "TerrainCreate") && !resetObject)
+ {
m_terrain->CreateObjects();
m_terrainCreate = true;
+ continue;
}
if (Cmd(line, "BeginObject"))
@@ -4284,11 +4533,35 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
sel = IOReadScene(read, stack);
m_beginObject = true;
+ continue;
+ }
+
+ if (Cmd(line, "MissionController") && read[0] == 0 && m_version >= 2)
+ {
+ /* TODO: ???
+ if (!m_beginObject)
+ {
+ GetLogger()->Error("Syntax error in file '%s' (line %d): MissionController before BeginObject\n", filename, lineNum);
+ continue;
+ }*/
+
+ m_controller = CreateObject(Math::Vector(0.0f, 0.0f, 0.0f), 0.0f, 1.0f, 0.0f, OBJECT_CONTROLLER, 100.0f, false, false, 0);
+ m_controller->SetMagnifyDamage(100.0f);
+ CBrain* brain = m_controller->GetBrain();
+ if (brain != nullptr)
+ {
+ OpString(line, "script", name);
+ if (name[0] != 0)
+ brain->SetScriptName(0, name);
+ brain->SetScriptRun(0);
+ }
+ continue;
}
if (Cmd(line, "CreateObject") && read[0] == 0)
{
- if (!m_beginObject) {
+ if (!m_beginObject)
+ {
GetLogger()->Error("Syntax error in file '%s' (line %d): CreateObject before BeginObject\n", filename, lineNum);
continue;
}
@@ -4330,9 +4603,9 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
}
Math::Vector pos = OpPos(line, "pos")*g_unit;
- float dir = OpFloat(line, "dir", 0.0f)*Math::PI;
+ float dirAngle = OpFloat(line, "dir", 0.0f)*Math::PI;
bool trainer = OpInt(line, "trainer", 0);
- CObject* obj = CreateObject(pos, dir,
+ CObject* obj = CreateObject(pos, dirAngle,
OpFloat(line, "z", 1.0f),
OpFloat(line, "h", 0.0f),
type,
@@ -4391,7 +4664,8 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
sel = obj;
}
- obj->SetSelectable(OpInt(line, "selectable", 1));
+ bool selectable = OpInt(line, "selectable", 1);
+ obj->SetSelectable(selectable);
obj->SetEnable(OpInt(line, "enable", 1));
obj->SetProxyActivate(OpInt(line, "proxyActivate", 0));
obj->SetProxyDistance(OpFloat(line, "proxyDistance", 15.0f)*g_unit);
@@ -4399,10 +4673,15 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
obj->SetShield(OpFloat(line, "shield", 1.0f));
obj->SetMagnifyDamage(OpFloat(line, "magnifyDamage", 1.0f));
obj->SetClip(OpInt(line, "clip", 1));
- obj->SetCheckToken(m_version >= 2 ? trainer : OpInt(line, "manual", 1));
- obj->SetManual(m_version >= 2 ? !trainer : OpInt(line, "manual", 0));
+ obj->SetCheckToken(m_version >= 2 ? trainer || !selectable : OpInt(line, "checkToken", 1));
+ // SetManual will affect bot speed
+ if (type == OBJECT_MOBILEdr)
+ {
+ obj->SetManual(m_version >= 2 ? !trainer : OpInt(line, "manual", 0));
+ }
- if(m_version >= 2) {
+ if (m_version >= 2)
+ {
Math::Vector zoom = OpDir(line, "zoom");
if (zoom.x != 0.0f || zoom.y != 0.0f || zoom.z != 0.0f)
obj->SetZoom(0, zoom);
@@ -4479,6 +4758,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
}
rankObj ++;
+ continue;
}
if (Cmd(line, "CreateFog") && !resetObject)
@@ -4494,6 +4774,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
dim.x = ddim;
dim.y = dim.x;
m_particle->CreateParticle(pos, Math::Vector(0.0f, 0.0f, 0.0f), dim, type, delay, 0.0f, 0.0f);
+ continue;
}
if (Cmd(line, "CreateLight") && !resetObject)
@@ -4505,7 +4786,10 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
type = OpTypeTerrain(line, "type", Gfx::ENG_OBJTYPE_NULL);
if (type == Gfx::ENG_OBJTYPE_TERRAIN)
+ {
+ m_lightMan->SetLightPriority(lightRank, Gfx::LIGHT_PRI_HIGHEST);
m_lightMan->SetLightIncludeType(lightRank, Gfx::ENG_OBJTYPE_TERRAIN);
+ }
if (type == Gfx::ENG_OBJTYPE_QUARTZ)
m_lightMan->SetLightIncludeType(lightRank, Gfx::ENG_OBJTYPE_QUARTZ);
@@ -4515,6 +4799,8 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
if (type == Gfx::ENG_OBJTYPE_FIX)
m_lightMan->SetLightExcludeType(lightRank, Gfx::ENG_OBJTYPE_TERRAIN);
+
+ continue;
}
if (Cmd(line, "CreateSpot") && !resetObject)
{
@@ -4535,6 +4821,8 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
if (type == Gfx::ENG_OBJTYPE_FIX)
m_lightMan->SetLightExcludeType(rankLight, Gfx::ENG_OBJTYPE_TERRAIN);
+
+ continue;
}
if (Cmd(line, "GroundSpot") && !resetObject)
@@ -4549,10 +4837,14 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_engine->SetObjectGroundSpotMinMax(rank, OpFloat(line, "min", 0.0f)*g_unit,
OpFloat(line, "max", 0.0f)*g_unit);
}
+ continue;
}
if (Cmd(line, "WaterColor") && !resetObject)
+ {
m_engine->SetWaterAddColor(OpColor(line, "color", Gfx::Color(0.0f, 0.0f, 0.0f, 1.0f)));
+ continue;
+ }
if (Cmd(line, "MapColor") && !resetObject)
{
@@ -4573,23 +4865,29 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
OpInt(line, "mode", 0),
OpInt(line, "debug", 0));
}
+ continue;
}
+
if (Cmd(line, "MapZoom") && !resetObject)
{
m_map->ZoomMap(OpFloat(line, "factor", 2.0f));
m_map->MapEnable(OpInt(line, "enable", 1));
+ continue;
}
if (Cmd(line, "MaxFlyingHeight") && !resetObject)
{
m_terrain->SetFlyingMaxHeight(OpFloat(line, "max", 280.0f)*g_unit);
+ continue;
}
+
if (Cmd(line, "AddFlyingHeight") && !resetObject)
{
m_terrain->AddFlyingLimit(OpPos(line, "center")*g_unit,
OpFloat(line, "extRadius", 20.0f)*g_unit,
OpFloat(line, "intRadius", 10.0f)*g_unit,
OpFloat(line, "maxHeight", 200.0f));
+ continue;
}
if (Cmd(line, "Camera"))
@@ -4602,32 +4900,51 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_camera->StartOver(Gfx::CAM_OVER_EFFECT_FADEIN_WHITE, Math::Vector(0.0f, 0.0f, 0.0f), 1.0f);
m_camera->SetFixDirection(OpFloat(line, "fixDirection", 0.25f)*Math::PI);
+ continue;
}
- if (Cmd(line, "EndMissionTake") && !resetObject)
+ if (Cmd(line, "EndMissionTake") && !resetObject && m_controller == nullptr)
{
int i = m_endTakeTotal;
if (i < 10)
{
- m_endTake[i].pos = OpPos(line, "pos")*g_unit;
- m_endTake[i].dist = OpFloat(line, "dist", 8.0f)*g_unit;
- m_endTake[i].type = OpTypeObject(line, "type", OBJECT_NULL);
- m_endTake[i].min = OpInt(line, "min", 1);
- m_endTake[i].max = OpInt(line, "max", 9999);
- m_endTake[i].lost = OpInt(line, "lost", -1);
+ m_endTake[i].pos = OpPos(line, "pos")*g_unit;
+ m_endTake[i].dist = OpFloat(line, "dist", 8.0f)*g_unit;
+ m_endTake[i].type = OpTypeObject(line, "type", OBJECT_NULL);
+ m_endTake[i].min = OpInt(line, "min", 1);
+ m_endTake[i].max = OpInt(line, "max", 9999);
+ if (m_version >= 2)
+ {
+ m_endTake[i].powermin = OpInt(line, "powermin", -1);
+ m_endTake[i].powermax = OpInt(line, "powermax", 100);
+ }
+ else
+ {
+ m_endTake[i].powermin = -1;
+ m_endTake[i].powermax = 100;
+ }
+ m_endTake[i].lost = OpInt(line, "lost", -1);
m_endTake[i].immediat = OpInt(line, "immediat", 0);
OpString(line, "message", m_endTake[i].message);
m_endTakeTotal ++;
}
+ continue;
}
- if (Cmd(line, "EndMissionDelay") && !resetObject)
+ if (Cmd(line, "EndMissionDelay") && !resetObject && m_controller == nullptr)
{
m_endTakeWinDelay = OpFloat(line, "win", 2.0f);
m_endTakeLostDelay = OpFloat(line, "lost", 2.0f);
+ continue;
}
- if (Cmd(line, "EndMissionResearch") && !resetObject)
+ if (Cmd(line, "EndMissionResearch") && !resetObject && m_controller == nullptr)
{
m_endTakeResearch |= OpResearch(line, "type");
+ continue;
+ }
+ if (Cmd(line, "EndMissionNever") && !resetObject && m_controller == nullptr)
+ {
+ m_endTakeNever = true;
+ continue;
}
if (Cmd(line, "ObligatoryToken") && !resetObject)
@@ -4638,6 +4955,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
OpString(line, "text", m_obligatoryToken[i]);
m_obligatoryTotal ++;
}
+ continue;
}
if (Cmd(line, "ProhibitedToken") && !resetObject)
@@ -4648,22 +4966,39 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
OpString(line, "text", m_prohibitedToken[i]);
m_prohibitedTotal ++;
}
+ continue;
}
if (Cmd(line, "EnableBuild") && !resetObject)
+ {
g_build |= OpBuild(line, "type");
+ continue;
+ }
if (Cmd(line, "EnableResearch") && !resetObject)
+ {
g_researchEnable |= OpResearch(line, "type");
+ continue;
+ }
- if (Cmd(line, "DoneResearch") && read[0] == 0 && !resetObject) // not loading file?
+ if (Cmd(line, "DoneResearch") && read[0] == 0 && !resetObject) // not loading file?
+ {
g_researchDone |= OpResearch(line, "type");
+ continue;
+ }
if (Cmd(line, "NewScript") && !resetObject)
{
OpString(line, "name", name);
AddNewScriptName(OpTypeObject(line, "type", OBJECT_NULL), name);
+ continue;
}
+
+ if (line[0] == '\n') continue; // Ignore empty lines
+ if (line[0] == '\0') continue; // Ignore empty lines
+ if (read[0] != 0) continue; // Ignore when loading saved game
+
+ GetLogger()->Error("Syntax error in file '%s' (line %d): Unknown command: %s", filename, lineNum, line); // Don't add \n at the end of log message - it's included in line variable
}
fclose(file);
@@ -4737,7 +5072,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_dialog->SetSceneRead("");
m_dialog->SetStackRead("");
- setlocale(LC_NUMERIC, oldLocale.c_str());
+ RestoreNumericLocale();
}
//! Creates an object of decoration mobile or stationary
@@ -5055,7 +5390,8 @@ CObject* CRobotMain::CreateObject(Math::Vector pos, float angle, float zoom, flo
type == OBJECT_MOBILEwt ||
type == OBJECT_MOBILEit ||
type == OBJECT_MOBILEdr ||
- type == OBJECT_APOLLO2 )
+ type == OBJECT_APOLLO2 ||
+ type == OBJECT_CONTROLLER )
{
object = new CObject();
object->SetOption(option);
@@ -5643,7 +5979,7 @@ char* SearchLastDir(char *filename)
while (p != filename)
{
- if (*(--p) == '/') return p;
+ if (*(--p) == '/' || *p == '\\') return p;
}
return 0;
}
@@ -5748,7 +6084,7 @@ void CRobotMain::LoadOneScript(CObject *obj, int &nbError)
char filename[MAX_FNAME];
sprintf(filename, "%s/%s/%c%.3d%.3d%.1d.txt",
- GetSavegameDir(), m_gamerName, name[0], rank, objRank, i);
+ GetSavegameDir(), m_gamerName.c_str(), name[0], rank, objRank, i);
brain->ReadProgram(i, filename);
if (!brain->GetCompile(i)) nbError++;
}
@@ -5818,7 +6154,7 @@ void CRobotMain::SaveOneScript(CObject *obj)
{
char filename[MAX_FNAME];
sprintf(filename, "%s/%s/%c%.3d%.3d%.1d.txt",
- GetSavegameDir(), m_gamerName, name[0], rank, objRank, i);
+ GetSavegameDir(), m_gamerName.c_str(), name[0], rank, objRank, i);
brain->WriteProgram(i, filename);
}
}
@@ -5945,6 +6281,8 @@ void CRobotMain::IOWriteObject(FILE *file, CObject* obj, const char *cmd)
{
if (obj->GetType() == OBJECT_FIX) return;
+ SetNumericLocale();
+
char line[3000];
char name[100];
@@ -6031,6 +6369,8 @@ void CRobotMain::IOWriteObject(FILE *file, CObject* obj, const char *cmd)
strcat(line, "\n");
fputs(line, file);
+
+ RestoreNumericLocale();
}
//! Saves the current game
@@ -6039,6 +6379,8 @@ bool CRobotMain::IOWriteScene(const char *filename, const char *filecbot, char *
FILE* file = fopen(filename, "w");
if (file == NULL) return false;
+ SetNumericLocale();
+
char line[500];
sprintf(line, "Title text=\"%s\"\n", info);
@@ -6101,6 +6443,8 @@ bool CRobotMain::IOWriteScene(const char *filename, const char *filecbot, char *
}
fclose(file);
+ RestoreNumericLocale();
+
#if CBOT_STACK
// Writes the file of stacks of execution.
file = fOpen(filecbot, "wb");
@@ -6145,6 +6489,8 @@ CObject* CRobotMain::IOReadObject(char *line, const char* filename, int objRank)
if (type == OBJECT_NULL)
return nullptr;
+ SetNumericLocale();
+
int trainer = OpInt(line, "trainer", 0);
int toy = OpInt(line, "toy", 0);
int option = OpInt(line, "option", 0);
@@ -6210,6 +6556,8 @@ CObject* CRobotMain::IOReadObject(char *line, const char* filename, int objRank)
automat->Start(run); // starts the film
}
+ RestoreNumericLocale();
+
return obj;
}
@@ -6221,6 +6569,8 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot)
FILE* file = fopen(filename, "r");
if (file == NULL) return 0;
+ SetNumericLocale();
+
CObject* fret = nullptr;
CObject* power = nullptr;
CObject* sel = nullptr;
@@ -6342,6 +6692,8 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot)
}
#endif
+ RestoreNumericLocale();
+
return sel;
}
@@ -6352,10 +6704,10 @@ void CRobotMain::WriteFreeParam()
m_freeResearch |= g_researchDone;
m_freeBuild |= g_build;
- if (m_gamerName[0] == 0) return;
+ if (m_gamerName == "") return;
char filename[MAX_FNAME];
- sprintf(filename, "%s/%s/research.gam", GetSavegameDir(), m_gamerName);
+ sprintf(filename, "%s/%s/research.gam", GetSavegameDir(), m_gamerName.c_str());
FILE* file = fopen(filename, "w");
if (file == NULL) return;
@@ -6371,10 +6723,10 @@ void CRobotMain::ReadFreeParam()
m_freeResearch = 0;
m_freeBuild = 0;
- if (m_gamerName[0] == 0) return;
+ if (m_gamerName == "") return;
char filename[MAX_FNAME];
- sprintf(filename, "%s/%s/research.gam", GetSavegameDir(), m_gamerName);
+ sprintf(filename, "%s/%s/research.gam", GetSavegameDir(), m_gamerName.c_str());
FILE* file = fopen(filename, "r");
if (file == NULL) return;
@@ -6525,9 +6877,113 @@ void CRobotMain::ResetCreate()
}
}
+//! Updates the audiotracks
+void CRobotMain::UpdateAudio(bool frame)
+{
+ CInstanceManager* iMan = CInstanceManager::GetInstancePointer();
+
+ for (int t = 0; t < m_audioChangeTotal; t++)
+ {
+ if (m_audioChange[t].changed) continue;
+
+ Math::Vector bPos = m_audioChange[t].pos;
+ bPos.y = 0.0f;
+
+ Math::Vector oPos;
+
+ int nb = 0;
+ for (int i = 0; i < 1000000; i++)
+ {
+ CObject* obj = static_cast<CObject*>(iMan->SearchInstance(CLASS_OBJECT, i));
+ if (obj == nullptr) break;
+
+ // Do not use GetActif () because an invisible worm (underground)
+ // should be regarded as existing here!
+ if (obj->GetLock()) continue;
+ if (obj->GetRuin()) continue;
+ if (!obj->GetEnable()) continue;
+
+ ObjectType type = obj->GetType();
+ if (type == OBJECT_SCRAP2 ||
+ type == OBJECT_SCRAP3 ||
+ type == OBJECT_SCRAP4 ||
+ type == OBJECT_SCRAP5) // wastes?
+ {
+ type = OBJECT_SCRAP1;
+ }
+
+ if (type != m_audioChange[t].type) continue;
+
+ float energyLevel = -1;
+ CObject* power = obj->GetPower();
+ if (power != nullptr)
+ {
+ energyLevel = power->GetEnergy();
+ if (power->GetType() == OBJECT_ATOMIC) energyLevel *= 100;
+ }
+ if (energyLevel < m_audioChange[t].powermin || energyLevel > m_audioChange[t].powermax) continue;
+
+ if (obj->GetTruck() == 0)
+ oPos = obj->GetPosition(0);
+ else
+ oPos = obj->GetTruck()->GetPosition(0);
+
+ oPos.y = 0.0f;
+
+ if (Math::DistanceProjected(oPos, bPos) <= m_audioChange[t].dist)
+ nb ++;
+ }
+
+ if (nb >= m_audioChange[t].min &&
+ nb <= m_audioChange[t].max)
+ {
+ CLogger::GetInstancePointer()->Debug("Changing music...\n");
+ m_sound->StopMusic();
+ m_sound->PlayMusic(std::string(m_audioChange[t].music), m_audioChange[t].repeat);
+ m_audioChange[t].changed = true;
+ }
+ }
+}
+
+void CRobotMain::SetEndMission(Error result, float delay)
+{
+ if (m_controller != nullptr)
+ {
+ m_endTakeWinDelay = delay;
+ m_endTakeLostDelay = delay;
+ m_missionResult = result;
+ }
+}
+
//! Checks if the mission is over
Error CRobotMain::CheckEndMission(bool frame)
{
+ if (m_controller != nullptr)
+ {
+ if (m_missionResult == INFO_LOST) //mission lost?
+ {
+ m_displayText->DisplayError(INFO_LOST, Math::Vector(0.0f,0.0f,0.0f));
+ m_winDelay = 0.0f;
+ if (m_lostDelay == 0) m_lostDelay = m_endTakeLostDelay;
+ m_displayText->SetEnable(false);
+ }
+ if (m_missionResult == INFO_LOSTq) //mission lost?
+ {
+ m_winDelay = 0.0f;
+ if (m_lostDelay == 0) m_lostDelay = 0.1f;
+ m_displayText->SetEnable(false);
+ }
+ if (frame && m_base) return ERR_MISSION_NOTERM;
+ if (m_missionResult == ERR_OK) { //mission win?
+ m_displayText->DisplayError(INFO_WIN, Math::Vector(0.0f,0.0f,0.0f));
+ if (m_winDelay == 0) m_winDelay = m_endTakeWinDelay;
+ m_lostDelay = 0.0f;
+ m_displayText->SetEnable(false);
+ }
+ if (m_missionResult == ERR_MISSION_NOTERM) m_displayText->SetEnable(true);
+ return m_missionResult;
+ }
+
CInstanceManager* iMan = CInstanceManager::GetInstancePointer();
for (int t = 0; t < m_endTakeTotal; t++)
@@ -6562,6 +7018,15 @@ Error CRobotMain::CheckEndMission(bool frame)
if (type != m_endTake[t].type) continue;
+ float energyLevel = -1;
+ CObject* power = obj->GetPower();
+ if (power != nullptr)
+ {
+ energyLevel = power->GetEnergy();
+ if (power->GetType() == OBJECT_ATOMIC) energyLevel *= 100;
+ }
+ if (energyLevel < m_endTake[t].powermin || energyLevel > m_endTake[t].powermax) continue;
+
if (obj->GetTruck() == 0)
oPos = obj->GetPosition(0);
else
@@ -6598,7 +7063,8 @@ Error CRobotMain::CheckEndMission(bool frame)
}
}
if (nb < m_endTake[t].min ||
- nb > m_endTake[t].max)
+ nb > m_endTake[t].max ||
+ m_endTakeNever )
{
m_displayText->SetEnable(true);
return ERR_MISSION_NOTERM;
@@ -6781,10 +7247,10 @@ bool CRobotMain::GetRadar()
for (int i = 0; i < 1000000; i++)
{
CObject* obj = static_cast<CObject*>(iMan->SearchInstance(CLASS_OBJECT, i));
- if (obj == 0) break;
+ if (obj == nullptr) break;
ObjectType type = obj->GetType();
- if (type == OBJECT_RADAR)
+ if (type == OBJECT_RADAR && !obj->GetLock())
return true;
}
return false;
@@ -6813,15 +7279,15 @@ bool CRobotMain::GetRetroMode()
//! Change the player's name
void CRobotMain::SetGamerName(const char *name)
{
- strcpy(m_gamerName, name);
+ m_gamerName = std::string(name);
SetGlobalGamerName(m_gamerName);
ReadFreeParam();
}
-//! Getes the player's name
+//! Gets the player's name
char* CRobotMain::GetGamerName()
{
- return m_gamerName;
+ return const_cast<char*>(m_gamerName.c_str());
}
@@ -7025,7 +7491,8 @@ float CRobotMain::GetTracePrecision()
//! Starts music with a mission
void CRobotMain::StartMusic()
{
- if (m_audioTrack != 0)
+ CLogger::GetInstancePointer()->Debug("Starting music...\n");
+ if (m_audioTrack != "")
{
m_sound->StopMusic();
m_sound->PlayMusic(m_audioTrack, m_audioRepeat);
@@ -7038,3 +7505,18 @@ void CRobotMain::ClearInterface()
HiliteClear(); // removes setting evidence
m_tooltipName[0] = 0; // really removes the tooltip
}
+
+void CRobotMain::SetNumericLocale()
+{
+ char *locale = setlocale(LC_NUMERIC, nullptr);
+ if (locale != nullptr)
+ m_oldLocale = locale;
+
+ setlocale(LC_NUMERIC, "C");
+}
+
+void CRobotMain::RestoreNumericLocale()
+{
+ setlocale(LC_NUMERIC, m_oldLocale.c_str());
+}
+