1 /*
2  * This file is part of the Colobot: Gold Edition source code
3  * Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam
4  * http://epsitec.ch; http://colobot.info; http://github.com/colobot
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see http://gnu.org/licenses
18  */
19 
20 /**
21  * \file level/robotmain.h
22  * \brief CRobotMain - main class of Colobot game engine
23  */
24 
25 #pragma once
26 
27 #include "app/pausemanager.h"
28 
29 #include "common/error.h"
30 #include "common/event.h"
31 #include "common/singleton.h"
32 
33 #include "graphics/engine/camera.h"
34 #include "graphics/engine/particle.h"
35 
36 #include "level/build_type.h"
37 #include "level/level_category.h"
38 #include "level/mainmovie.h"
39 #include "level/research_type.h"
40 
41 #include "object/drive_type.h"
42 #include "object/mission_type.h"
43 #include "object/object_type.h"
44 #include "object/tool_type.h"
45 
46 #include <deque>
47 #include <stdexcept>
48 
49 enum Phase
50 {
51     PHASE_WELCOME1,
52     PHASE_WELCOME2,
53     PHASE_WELCOME3,
54     PHASE_PLAYER_SELECT,
55     PHASE_APPERANCE,
56     PHASE_MAIN_MENU,
57     PHASE_LEVEL_LIST,
58     PHASE_MOD_LIST,
59     PHASE_SIMUL,
60     PHASE_SETUPd,
61     PHASE_SETUPg,
62     PHASE_SETUPp,
63     PHASE_SETUPc,
64     PHASE_SETUPs,
65     PHASE_SETUPds,
66     PHASE_SETUPgs,
67     PHASE_SETUPps,
68     PHASE_SETUPcs,
69     PHASE_SETUPss,
70     PHASE_WRITEs,
71     PHASE_READ,
72     PHASE_READs,
73     PHASE_WIN,
74     PHASE_LOST,
75     PHASE_QUIT_SCREEN,
76     PHASE_SATCOM,
77 };
78 std::string PhaseToString(Phase phase);
79 bool IsInSimulationConfigPhase(Phase phase);
80 bool IsPhaseWithWorld(Phase phase);
81 bool IsMainMenuPhase(Phase phase);
82 
83 
84 class CEventQueue;
85 class CSoundInterface;
86 class CLevelParserLine;
87 class CInput;
88 class CObjectManager;
89 class CSceneEndCondition;
90 class CAudioChangeCondition;
91 class CScoreboard;
92 class CPlayerProfile;
93 class CSettings;
94 class COldObject;
95 class CPauseManager;
96 struct ActivePause;
97 
98 namespace Gfx
99 {
100 class CEngine;
101 class CLightManager;
102 class CWater;
103 class CCloud;
104 class CLightning;
105 class CPlanet;
106 class CTerrain;
107 class CModelManager;
108 }
109 
110 namespace Ui
111 {
112 class CMainUserInterface;
113 class CMainShort;
114 class CMainMap;
115 class CInterface;
116 class CDisplayText;
117 class CDisplayInfo;
118 class CDebugMenu;
119 }
120 
121 struct NewScriptName
122 {
123     ObjectType  type = OBJECT_NULL;
124     std::string name = "";
125 
NewScriptNameNewScriptName126     NewScriptName(ObjectType type, const std::string& name) : type(type), name(name) {}
127 };
128 
129 
130 const int MAXSHOWLIMIT      = 5;
131 const int MAXSHOWPARTI      = 200;
132 const float SHOWLIMITTIME   = 20.0f;
133 
134 const int MAXSCENE = 999;
135 
136 struct ShowLimit
137 {
138     bool            used = false;
139     Math::Vector    pos;
140     float           radius = 0.0f;
141     int             total = 0;
142     int             parti[MAXSHOWPARTI] = {};
143     CObject*        link = nullptr;
144     float           duration = 0.0f;
145     float           time = 0.0f;
146 };
147 
148 struct MinMax
149 {
150     int min = -1;
151     int max = -1;
152 };
153 
154 struct Viewpoint
155 {
156     Math::Vector    eye{};
157     Math::Vector    look{};
158     int             button = 13; // 13 is the camera button
159 };
160 
161 const int SATCOM_HUSTON     = 0;
162 const int SATCOM_SAT        = 1;
163 const int SATCOM_OBJECT     = 2;
164 const int SATCOM_LOADING    = 3;
165 const int SATCOM_PROG       = 4;
166 const int SATCOM_SOLUCE     = 5;
167 const int SATCOM_MAX        = 6;
168 
169 /**
170  * \brief Main class managing the game world
171  *
172  * This is the main class of the whole game engine. It's main job is to manage main parts of the gameplay,
173  * like loading levels and checking for win conditions, but it's also a place where all things that don't fit
174  * elsewhere have landed.
175  *
176  * \todo In the future, it would be nice to refactor this class to remove as much unrelated stuff as possible
177  *
178  * \nosubgrouping
179  */
180 class CRobotMain : public CSingleton<CRobotMain>
181 {
182 public:
183     CRobotMain();
184     virtual ~CRobotMain();
185 
186     Gfx::CCamera* GetCamera();
187     Gfx::CTerrain* GetTerrain();
188     Ui::CInterface* GetInterface();
189     Ui::CDisplayText* GetDisplayText();
190     CPauseManager* GetPauseManager();
191 
192     /**
193      * \name Phase management
194      */
195     //@{
196     void        ChangePhase(Phase phase);
197     bool        ProcessEvent(Event &event);
198     Phase       GetPhase();
199     //@}
200 
201     //! Load the scene for apperance customization
202     void        ScenePerso();
203 
204     void        SetMovieLock(bool lock);
205     bool        GetMovieLock();
206     bool        GetInfoLock();
207     void        SetSatComLock(bool lock);
208     bool        GetSatComLock();
209     void        SetEditLock(bool lock, bool edit);
210     bool        GetEditLock();
211     void        SetEditFull(bool full);
212     bool        GetEditFull();
213     void        SetFriendAim(bool friendAim);
214     bool        GetFriendAim();
215 
216     //! \name Simulation speed management
217     //@{
218     void        SetSpeed(float speed);
219     float       GetSpeed();
220     //@}
221 
222     //! \brief Create the shortcuts at the top of the screen, if they should be visible
223     //! \see CMainShort::CreateShortcuts
224     bool        CreateShortcuts();
225     //! \brief Update the shortcuts at the top of the screen
226     //! \see CMainShort::UpdateShortcuts
227     void        UpdateShortcuts();
228     //! Find the astronaut (::OBJECT_HUMAN) object
229     CObject*    SearchHuman();
230     /**
231      * \brief Select an object
232      * \param obj Object to select
233      * \param displayError If true and the object is currently in error state, automatically display the error message
234      *
235      * \note This function automatically adds objects to selection history (see PushToSelectionHistory())
236      */
237     bool        SelectObject(CObject* obj, bool displayError=true);
238     //! Return the object that was selected at the start of the scene
239     CObject*    GetSelectObject();
240     //! Deselect currently selected object
241     //! \return Object that was deselected
242     CObject*    DeselectAll();
243 
244     void        ResetObject();
245     void        UpdateAudio(bool frame);
246     void        SetMissionResultFromScript(Error result, float delay);
247     Error       CheckEndMission(bool frame);
248     Error       ProcessEndMissionTake();
249     Error       ProcessEndMissionTakeForGroup(std::vector<CSceneEndCondition*>& endTakes);
250     const std::map<std::string, MinMax>& GetObligatoryTokenList();
251     void        UpdateMap();
252     bool        GetShowMap();
253 
254     MainMovieType GetMainMovie();
255 
256     void        FlushDisplayInfo();
257     void        StartDisplayInfo(int index, bool movie);
258     void        StartDisplayInfo(const std::string& filename, int index);
259     void        StopDisplayInfo();
260     char*       GetDisplayInfoName(int index);
261 
262     void        StartSuspend();
263     void        StopSuspend();
264 
265     float       GetGameTime();
266 
267     const std::string& GetScriptName();
268     const std::string& GetScriptFile();
269     bool        GetTrainerPilot();
270     bool        GetPlusTrainer();
271     bool        GetPlusExplorer();
272     bool        GetFixScene();
273     bool        GetShowSoluce();
274     bool        GetSceneSoluce();
275     bool        GetShowAll();
276     bool        GetRadar();
277     MissionType GetMissionType();
278 
279     int         GetGamerFace();
280     int         GetGamerGlasses();
281     bool        GetGamerOnlyHead();
282     float       GetPersoAngle();
283 
284     void        SetLevel(LevelCategory cat, int chap, int rank);
285     LevelCategory GetLevelCategory();
286     int         GetLevelChap();
287     int         GetLevelRank();
288     std::string GetCustomLevelDir();
289     void        SetReadScene(std::string path);
290     void        UpdateChapterPassed();
291 
292     void        StartMusic();
293     void        UpdatePause(PauseType pause);
294     void        UpdatePauseMusic(PauseMusic music);
295     void        ClearInterface();
296     void        ChangeColor();
297 
298     bool        FreeSpace(Math::Vector &center, float minRadius, float maxRadius, float space, CObject *exclu);
299     bool        FlatFreeSpace(Math::Vector &center, float minFlat, float minRadius, float maxRadius, float space, CObject *exclu);
300     //! \name In-world indicators
301     //@{
302     float       GetFlatZoneRadius(Math::Vector center, float maxRadius, CObject *exclu);
303     void        HideDropZone(CObject* metal);
304     void        ShowDropZone(CObject* metal, CObject* transporter);
305     void        FlushShowLimit(int i);
306     void        SetShowLimit(int i, Gfx::ParticleType parti, CObject *obj, Math::Vector pos,
307                              float radius, float duration=SHOWLIMITTIME);
308     void        StartShowLimit();
309     void        FrameShowLimit(float rTime);
310     //@}
311 
312     void        SaveAllScript();
313     void        SaveOneScript(CObject *obj);
314     bool        SaveFileStack(CObject *obj, std::ostream &ostr);
315     bool        ReadFileStack(CObject *obj, std::istream &istr);
316 
317     //! Return list of scripts to load to robot created in BotFactory
318     std::vector<std::string> GetNewScriptNames(ObjectType type);
319 
320     //! Return the scoreboard manager
321     //! Note: this may return nullptr if the scoreboard is not enabled!
322     CScoreboard* GetScoreboard();
323 
324     void        SelectPlayer(std::string playerName);
325     CPlayerProfile* GetPlayerProfile();
326 
327     /**
328      * \name Saved game read/write
329      */
330     //@{
331     bool        IOIsBusy();
332     bool        IOWriteScene(std::string filename, std::string filecbot, std::string filescreenshot, const std::string& info, bool emergencySave = false);
333     void        IOWriteSceneFinished();
334     CObject*    IOReadScene(std::string filename, std::string filecbot);
335     void        IOWriteObject(CLevelParserLine *line, CObject* obj, const std::string& programDir, int objRank);
336     CObject*    IOReadObject(CLevelParserLine *line, const std::string& programDir, const std::string& objCounterText, float objectProgress, int objRank = -1);
337     //@}
338 
339     int         CreateSpot(Math::Vector pos, Gfx::Color color);
340 
341     //! Find the currently selected object
342     CObject*    GetSelect();
343 
344     void        DisplayError(Error err, CObject* pObj, float time=10.0f);
345     void        DisplayError(Error err, Math::Vector goal, float height=15.0f, float dist=60.0f, float time=10.0f);
346 
347     void        UpdateCustomLevelList();
348     std::string GetCustomLevelName(int id);
349     const std::vector<std::string>& GetCustomLevelList();
350 
351     //! Returns true if the game is on the loading screen
352     bool        IsLoading();
353 
354     void        StartMissionTimer();
355 
356     /**
357      * \name Autosave management
358      */
359     //@{
360     void        SetAutosave(bool enable);
361     bool        GetAutosave();
362     void        SetAutosaveInterval(int interval);
363     int         GetAutosaveInterval();
364     void        SetAutosaveSlots(int slots);
365     int         GetAutosaveSlots();
366     //@}
367 
368     //! Enable mode where completing mission closes the game
369     void        SetExitAfterMission(bool exit);
370 
371     //! Returns true if player can interact with things manually
372     bool        CanPlayerInteract();
373 
374     /**
375      * \name Team definition management
376      */
377     //@{
378     //! Returns team name for the given team id
379     const std::string& GetTeamName(int id);
380 
381     //! Returns true if team-specific colored texture is available
382     bool        IsTeamColorDefined(int id);
383     //@}
384 
385     /**
386      * \name EnableBuild/EnableResearch/DoneResearch
387      * Management of enabled buildings, enabled researches, and completed researches
388      */
389     //@{
390     /**
391      * \brief Get enabled buildings
392      * \return Bitmask of BuildType values
393      */
394     int         GetEnableBuild();
395     /**
396      * \brief Set enabled buildings
397      * \param enableBuild Bitmask of BuildType values
398      */
399     void        SetEnableBuild(int enableBuild);
400 
401     /**
402      * \brief Get enabled researches
403      * \return Bitmask of ResearchType values
404      */
405     int         GetEnableResearch();
406     /**
407      * \brief Set enabled researches
408      * \param enableResearch Bitmask of ResearchType values
409      */
410     void        SetEnableResearch(int enableResearch);
411     /**
412      * \brief Get done researches
413      * \param team Team to get researches for
414      * \return Bitmask of ResearchType values
415      */
416     int         GetDoneResearch(int team = 0);
417     /**
418      * \brief Set done researches
419      * \param doneResearch Bitmask of ResearchType values
420      * \param team Team to set researches for
421      */
422     void        SetDoneResearch(int doneResearch, int team = 0);
423 
424     //! \brief Check if the given building is enabled
425     bool        IsBuildingEnabled(BuildType type);
426     //! \brief Check if the given building is enabled
427     bool        IsBuildingEnabled(ObjectType type);
428     //! \brief Check if the given research is enabled
429     bool        IsResearchEnabled(ResearchType type);
430     //! \brief Check if the given research is done
431     bool        IsResearchDone(ResearchType type, int team);
432     //! \brief Mark given research as done
433     void        MarkResearchDone(ResearchType type, int team);
434 
435     /**
436      * \brief Check if all requirements to build this object are met (EnableBuild + DoneResearch)
437      * \return true if the building can be built, false otherwise
438      * \see CanBuildError() for a version which returns a specific reason for the build being denied
439      */
CanBuild(ObjectType type,int team)440     inline bool CanBuild(ObjectType type, int team)
441     {
442         return CanBuildError(type, team) == ERR_OK;
443     }
444     /**
445      * \brief Check if all requirements to build this object are met (EnableBuild + DoneResearch)
446      * \return One of Error values - ::ERR_OK if the building can be built, ::ERR_BUILD_DISABLED or ::ERR_BUILD_RESEARCH otherwise
447      * \see CanBuild() for a version which returns a boolean
448      */
449     Error       CanBuildError(ObjectType type, int team);
450 
451     /**
452      * \brief Check if all requirements to build this object in BotFactory are met (DoneResearch)
453      * \return true if the robot can be built, false otherwise
454      * \see CanFactoryError() for a version which returns a specific reason for the build being denied
455      */
CanFactory(ObjectType type,int team)456     inline bool CanFactory(ObjectType type, int team)
457     {
458         return CanFactoryError(type, team) == ERR_OK;
459     }
460     /**
461      * \brief Check if all requirements to build this object in BotFactory are met (DoneResearch)
462      * \return One of Error values - ::ERR_OK if the robot can be built, ::ERR_BUILD_DISABLED or ::ERR_BUILD_RESEARCH otherwise
463      * \see CanFactory() for a version which returns a boolean
464      */
465     Error       CanFactoryError(ObjectType type, int team);
466     //@}
467 
468     void        RemoveFromSelectionHistory(CObject* object);
469 
470     //! Returns global magnifyDamage setting
471     float       GetGlobalMagnifyDamage();
472 
473     //! Returns global NuclearCell capacity Setting
474     float       GetGlobalNuclearCapacity();
475     //! Returns global PowerCell capacity setting
476     float       GetGlobalCellCapacity();
477 
478     void        StartDetectEffect(COldObject* object, CObject* target);
479 
480     //! Enable crash sphere debug rendering
481     void SetDebugCrashSpheres(bool draw);
482     //! Check if crash sphere debug rendering is enabled
483     bool GetDebugCrashSpheres();
484 
485     //! Returns a set of all team IDs in the current level
486     std::set<int> GetAllTeams();
487     //! Returns a set of all team IDs in the current level that are still active
488     std::set<int> GetAllActiveTeams();
489 
490 protected:
491     bool        EventFrame(const Event &event);
492     bool        EventObject(const Event &event);
493     void        InitEye();
494 
495     void        ShowSaveIndicator(bool show);
496 
497     void        CreateScene(bool soluce, bool fixScene, bool resetObject);
498     void        ResetCreate();
499 
500     void        LevelLoadingError(const std::string& error, const std::runtime_error& exception, Phase exitPhase = PHASE_LEVEL_LIST);
501 
502     int         CreateLight(Math::Vector direction, Gfx::Color color);
503     void        HiliteClear();
504     void        HiliteObject(Math::Point pos);
505     void        HiliteFrame(float rTime);
506     void        CreateTooltip(Math::Point pos, const std::string& text);
507     void        ClearTooltip();
508     CObject*    DetectObject(Math::Point pos);
509     void        ChangeCamera();
510     void        AbortMovie();
511     //! \brief Select an object, without deselecting the previous one
512     void        SelectOneObject(CObject* obj, bool displayError=true);
513     void        HelpObject();
514     //! \brief Switch to previous object
515     //! \see PopFromSelectionHistory()
516     bool        DeselectObject();
517     void        DeleteAllObjects();
518     void        UpdateInfoText();
519     void        StartDisplayVisit(EventType event);
520     void        FrameVisit(float rTime);
521     void        StopDisplayVisit();
522     void        ExecuteCmd(const std::string& cmd);
523     void        UpdateSpeedLabel();
524 
525     void        AutosaveRotate();
526     void        Autosave();
527     void        QuickSave();
528     void        QuickLoad();
529     bool        DestroySelectedObject();
530     void        PushToSelectionHistory(CObject* obj);
531     CObject*    PopFromSelectionHistory();
532 
533     //! \name Code battle interface
534     //@{
535     void        CreateCodeBattleInterface();
536     void        UpdateCodeBattleInterface();
537     void        ApplyCodeBattleInterface();
538     void        DestroyCodeBattleInterface();
539     void        SetCodeBattleSpectatorMode(bool mode);
540     //@}
541 
542     void        UpdateDebugCrashSpheres();
543 
544     //! Adds element to the beginning of command history
545     void        PushToCommandHistory(std::string cmd);
546     //! Returns next/previous element from command history and updates index
547     //@{
548     std::string    GetNextFromCommandHistory();
549     std::string    GetPreviousFromCommandHistory();
550     //@}
551 
552 protected:
553     CApplication*       m_app = nullptr;
554     CEventQueue*        m_eventQueue = nullptr;
555     Gfx::CEngine*       m_engine = nullptr;
556     Gfx::CParticle*     m_particle = nullptr;
557     Gfx::CWater*        m_water = nullptr;
558     Gfx::CCloud*        m_cloud = nullptr;
559     Gfx::CLightning*    m_lightning = nullptr;
560     Gfx::CPlanet*       m_planet = nullptr;
561     Gfx::COldModelManager* m_oldModelManager = nullptr;
562     Gfx::CLightManager* m_lightMan = nullptr;
563     CSoundInterface*    m_sound = nullptr;
564     CInput*             m_input = nullptr;
565     std::unique_ptr<CObjectManager> m_objMan;
566     std::unique_ptr<CMainMovie> m_movie;
567     std::unique_ptr<CPauseManager> m_pause;
568     std::unique_ptr<Gfx::CModelManager> m_modelManager;
569     std::unique_ptr<Gfx::CTerrain> m_terrain;
570     std::unique_ptr<Gfx::CCamera> m_camera;
571     std::unique_ptr<Ui::CMainUserInterface> m_ui;
572     std::unique_ptr<Ui::CMainShort> m_short;
573     std::unique_ptr<Ui::CMainMap> m_map;
574     std::unique_ptr<Ui::CInterface> m_interface;
575     std::unique_ptr<Ui::CDisplayInfo> m_displayInfo;
576     std::unique_ptr<Ui::CDisplayText> m_displayText;
577     std::unique_ptr<Ui::CDebugMenu> m_debugMenu;
578     std::unique_ptr<CSettings> m_settings;
579 
580     //! Progress of loaded player
581     std::unique_ptr<CPlayerProfile> m_playerProfile;
582 
583 
584     //! Time since level start, including pause and intro movie
585     float           m_time = 0.0f;
586     //! Playing time since level start
587     float           m_gameTime = 0.0f;
588     //! Playing time since level start, not dependent on simulation speed
589     float           m_gameTimeAbsolute = 0.0f;
590 
591     LevelCategory   m_levelCategory;
592     int             m_levelChap = 0;
593     int             m_levelRank = 0;
594     //! if set, loads this file instead of building from category/chap/rank
595     std::string     m_levelFile = "";
596     std::string     m_sceneReadPath;
597 
598     float           m_winDelay = 0.0f;
599     float           m_lostDelay = 0.0f;
600     bool            m_fixScene = false;        // scene fixed, no interraction
601     CObject*        m_base = nullptr;        // OBJECT_BASE exists in mission
602     CObject*        m_selectObject = nullptr;
603 
604     Phase           m_phase = PHASE_WELCOME1;
605     ActivePause*    m_userPause = nullptr;
606     ActivePause*    m_focusPause = nullptr;
607     ActivePause*    m_freePhotoPause = nullptr;
608     bool            m_cmdEdit = false;
609     ActivePause*    m_cmdEditPause = nullptr;
610     bool            m_cheatSelectInsect = false;
611     bool            m_cheatShowSoluce = false;
612     bool            m_cheatAllMission = false;
613     bool            m_cheatRadar = false;
614     bool            m_shortCut = false;
615     std::string     m_audioTrack;
616     bool            m_audioRepeat = false;
617     std::string     m_satcomTrack;
618     bool            m_satcomRepeat = false;
619     std::string     m_editorTrack;
620     bool            m_editorRepeat = false;
621     int             m_movieInfoIndex = 0;
622 
623     CObject*        m_controller = nullptr;
624 
625     MissionType     m_missionType = MISSION_NORMAL;
626     bool            m_immediatSatCom = false;  // SatCom immediately?
627     bool            m_beginSatCom = false;     // messages SatCom poster?
628     bool            m_lockedSatCom = false;    // SatCom locked?
629     bool            m_movieLock = false;       // movie in progress?
630     bool            m_satComLock = false;      // call of SatCom is possible?
631     bool            m_editLock = false;        // edition in progress?
632     bool            m_editFull = false;        // edition in full screen?
633     bool            m_hilite = false;
634     bool            m_cheatTrainerPilot = false;    // remote trainer?
635     bool            m_friendAim = false;
636     bool            m_resetCreate = false;
637     bool            m_mapShow = false;
638     bool            m_mapImage = false;
639     char            m_mapFilename[100] = {};
640 
641     ActivePause*    m_suspend = nullptr;
642 
643     Math::Point     m_tooltipPos;
644     std::string     m_tooltipName;
645     float           m_tooltipTime = 0.0f;
646 
647     char            m_infoFilename[SATCOM_MAX][100] = {}; // names of text files
648     CObject*        m_infoObject = nullptr;
649     int             m_infoUsed = 0;
650     ActivePause*    m_satcomMoviePause = nullptr;
651 
652     std::string     m_scriptName = "";
653     std::string     m_scriptFile = "";
654     std::string     m_endingWin = "";
655     std::string     m_endingLost = "";
656     bool            m_winTerminate = false;
657 
658     float           m_globalMagnifyDamage = 0.0f;
659 
660     float           m_globalNuclearCapacity = 10.0f;
661     float           m_globalCellCapacity = 1.0f;
662 
663     bool            m_exitAfterMission = false;
664 
665     bool            m_codeBattleInit = false;
666     bool            m_codeBattleStarted = false;
667     //! Code battle spectator mode, hides object UI, changes camera to CAM_TYPE_PLANE and allows for switching to free camera by clicking outside of any object
668     bool            m_codeBattleSpectator = true;
669 
670     std::map<int, std::string> m_teamNames;
671 
672     std::vector<NewScriptName> m_newScriptName;
673 
674     EventType       m_visitLast = EVENT_NULL;
675     CObject*        m_visitObject = nullptr;
676     CObject*        m_visitArrow = nullptr;
677     float           m_visitTime = 0.0f;
678     float           m_visitParticle = 0.0f;
679     Math::Vector    m_visitPos;
680     Math::Vector    m_visitPosArrow;
681     ActivePause*    m_visitPause = nullptr;
682 
683     std::vector<std::unique_ptr<CSceneEndCondition>> m_endTake;
684     //! If true, the mission ends immediately after completing the requirements without requiring SpaceShip takeoff
685     bool            m_endTakeImmediat = false;
686     long            m_endTakeResearch = 0;
687     float           m_endTakeTimeout = -1.0f;
688     bool            m_endTakeTeamImmediateWin = false;
689     float           m_endTakeWinDelay = 0.0f;
690     float           m_endTakeLostDelay = 0.0f;
691     //! Set to true for teams that have already finished
692     std::map<int, bool> m_teamFinished;
693 
694     std::vector<std::unique_ptr<CAudioChangeCondition>> m_audioChange;
695 
696     //! The scoreboard
697     //! If the scoreboard is not enabled for this level, this will be null
698     std::unique_ptr<CScoreboard> m_scoreboard;
699 
700     std::map<std::string, MinMax> m_obligatoryTokens;
701 
702     //! Enabled buildings
703     int             m_build = 0;
704     //! Available researches
705     long            m_researchEnable = 0;
706     //! Done researches for each team
707     std::map<int, int>  m_researchDone;
708 
709     Error           m_missionResult = ERR_OK;
710     //! true if m_missionResult has been set by LevelController script, this disables normal EndMissionTake processing
711     bool            m_missionResultFromScript = false;
712 
713     ShowLimit       m_showLimit[MAXSHOWLIMIT];
714 
715     std::map<int, Gfx::Color> m_colorNewBot;
716     Gfx::Color      m_colorNewAlien;
717     Gfx::Color      m_colorNewGreen;
718     Gfx::Color      m_colorNewWater;
719     float           m_colorShiftWater = 0.0f;
720 
721     bool            m_missionTimerEnabled = false;
722     bool            m_missionTimerStarted = false;
723     float           m_missionTimer = 0.0f;
724 
725     bool            m_autosave = false;
726     int             m_autosaveInterval = 0;
727     int             m_autosaveSlots = 0;
728     float           m_autosaveLast = 0.0f;
729 
730     int             m_shotSaving = 0;
731 
732     std::deque<CObject*> m_selectionHistory;
733     bool            m_debugCrashSpheres;
734 
735     //! Cheat console command history
736     std::deque<std::string> m_commandHistory;
737     //! Index of currently selected element in command history
738     int             m_commandHistoryIndex;
739 
740     //! Vector of available viewpoints
741     std::vector<Viewpoint> m_viewpoints;
742 };
743