From a32efc09a20b349672841555ea04536fe45d4e33 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Tue, 7 Jul 2015 16:17:19 +0200 Subject: [PATCH] Refactored EndMissionTake and AudioChange --- src/CMakeLists.txt | 1 + src/object/object_manager.h | 2 +- src/object/robotmain.cpp | 390 +++++++------------------------- src/object/robotmain.h | 44 +--- src/object/scene_conditions.cpp | 165 ++++++++++++++ src/object/scene_conditions.h | 102 +++++++++ src/script/scriptfunc.cpp | 1 - 7 files changed, 357 insertions(+), 348 deletions(-) create mode 100644 src/object/scene_conditions.cpp create mode 100644 src/object/scene_conditions.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 47ac897b..f7d79509 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -164,6 +164,7 @@ set(BASE_SOURCES object/object_manager.cpp object/old_object.cpp object/robotmain.cpp + object/scene_conditions.cpp object/task/task.cpp object/task/taskadvance.cpp object/task/taskbuild.cpp diff --git a/src/object/object_manager.h b/src/object/object_manager.h index fb4ae5b5..4b0b8def 100644 --- a/src/object/object_manager.h +++ b/src/object/object_manager.h @@ -109,7 +109,7 @@ private: }; /** - * \class ObjectManager + * \class CObjectManager * \brief Manages CObject instances */ class CObjectManager : public CSingleton diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp index a2c44d81..765e7483 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -64,6 +64,7 @@ #include "object/motion/motiontoto.h" #include "object/object.h" #include "object/object_manager.h" +#include "object/scene_conditions.h" #include "object/task/task.h" #include "object/task/taskbuild.h" #include "object/task/taskmanip.h" @@ -2894,8 +2895,8 @@ 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_audioChange.clear(); + m_endTake.clear(); m_endTakeResearch = 0; m_endTakeNever = false; m_endTakeWinDelay = 2.0f; @@ -3067,24 +3068,10 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) if (line->GetCommand() == "AudioChange" && !resetObject && m_controller == nullptr) { - int i = m_audioChangeTotal; - if (i < 10) - { - m_audioChange[i].pos = line->GetParam("pos")->AsPoint(Math::Vector(0.0f, 0.0f, 0.0f))*g_unit; - m_audioChange[i].dist = line->GetParam("dist")->AsFloat(1000.0f)*g_unit; - m_audioChange[i].type = line->GetParam("type")->AsObjectType(OBJECT_NULL); - m_audioChange[i].min = line->GetParam("min")->AsInt(1); - m_audioChange[i].max = line->GetParam("max")->AsInt(9999); - m_audioChange[i].powermin = line->GetParam("powermin")->AsFloat(-1); - m_audioChange[i].powermax = line->GetParam("powermax")->AsFloat(100); - m_audioChange[i].tool = line->GetParam("tool")->AsToolType(ToolType::Other); - m_audioChange[i].drive = line->GetParam("drive")->AsDriveType(DriveType::Other); - strcpy(m_audioChange[i].music, (std::string("../")+line->GetParam("filename")->AsPath("music")).c_str()); - m_audioChange[i].repeat = line->GetParam("repeat")->AsBool(true); - m_audioChange[i].changed = false; - m_sound->CacheMusic(m_audioChange[i].music); - m_audioChangeTotal ++; - } + auto audioChange = std::unique_ptr{new CAudioChangeCondition()}; + audioChange->Read(line.get()); + m_sound->CacheMusic(audioChange->music); + m_audioChange.push_back(std::move(audioChange)); continue; } @@ -3818,24 +3805,9 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) if (line->GetCommand() == "EndMissionTake" && !resetObject && m_controller == nullptr) { - int i = m_endTakeTotal; - if (i < 10) - { - m_endTake[i].pos = line->GetParam("pos")->AsPoint(Math::Vector(0.0f, 0.0f, 0.0f))*g_unit; - m_endTake[i].dist = line->GetParam("dist")->AsFloat(8.0f)*g_unit; - m_endTake[i].type = line->GetParam("type")->AsObjectType(OBJECT_NULL); - m_endTake[i].min = line->GetParam("min")->AsInt(1); - m_endTake[i].max = line->GetParam("max")->AsInt(9999); - m_endTake[i].powermin = line->GetParam("powermin")->AsFloat(-1); - m_endTake[i].powermax = line->GetParam("powermax")->AsFloat(100); - m_endTake[i].tool = line->GetParam("tool")->AsToolType(ToolType::Other); - m_endTake[i].drive = line->GetParam("drive")->AsDriveType(DriveType::Other); - m_endTake[i].lost = line->GetParam("lost")->AsInt(-1); - m_endTake[i].immediat = line->GetParam("immediat")->AsBool(false); - m_endTake[i].countTransported = line->GetParam("countTransported")->AsBool(true); - strcpy(m_endTake[i].message, line->GetParam("message")->AsString("").c_str()); //TODO: Really, ending mission on message()? Is this used anywhere? Do we need that? - m_endTakeTotal ++; - } + auto endTake = std::unique_ptr{new CSceneEndCondition()}; + endTake->Read(line.get()); + m_endTake.push_back(std::move(endTake)); continue; } if (line->GetCommand() == "EndMissionDelay" && !resetObject && m_controller == nullptr) @@ -5421,82 +5393,15 @@ void CRobotMain::ResetCreate() //! Updates the audiotracks void CRobotMain::UpdateAudio(bool frame) { - for (int t = 0; t < m_audioChangeTotal; t++) + for(std::unique_ptr& audioChange : m_audioChange) { - if (m_audioChange[t].changed) continue; + if (audioChange->changed) continue; - Math::Vector bPos = m_audioChange[t].pos; - bPos.y = 0.0f; - - Math::Vector oPos; - - int nb = 0; - for (CObject* obj : m_objMan->GetAllObjects()) + if (audioChange->Check()) { - // Do not use GetActive () 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; - } - - ToolType tool = GetToolFromObject(type); - DriveType drive = GetDriveFromObject(type); - if (m_audioChange[t].tool != ToolType::Other && - tool != m_audioChange[t].tool) - continue; - if (m_audioChange[t].drive != DriveType::Other && - drive != m_audioChange[t].drive) - continue; - - if (m_audioChange[t].tool == ToolType::Other && - m_audioChange[t].drive == DriveType::Other && - 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; - } - else - { - if (obj->GetType() == OBJECT_POWER || obj->GetType() == OBJECT_ATOMIC) - { - energyLevel = obj->GetEnergy(); - if (obj->GetType() == OBJECT_ATOMIC) energyLevel *= 100; - } - } - if (energyLevel < m_audioChange[t].powermin || energyLevel > m_audioChange[t].powermax) - continue; - - if (obj->GetTransporter() == 0) - oPos = obj->GetPosition(0); - else - oPos = obj->GetTransporter()->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()->Info("Changing music to \"%s\"\n", m_audioChange[t].music); - m_sound->PlayMusic(std::string(m_audioChange[t].music), m_audioChange[t].repeat); - m_audioChange[t].changed = true; + CLogger::GetInstancePointer()->Info("Changing music to \"%s\"\n", audioChange->music.c_str()); + m_sound->PlayMusic(audioChange->music, audioChange->repeat); + audioChange->changed = true; } } } @@ -5514,29 +5419,80 @@ void CRobotMain::SetEndMission(Error result, float delay) //! Checks if the mission is over Error CRobotMain::CheckEndMission(bool frame) { - if (m_controller != nullptr) + // Process EndMissionTake, unless we are using MissionController + if (m_controller == nullptr) { - if (m_missionResult == INFO_LOST) //mission lost? + m_missionResult = ERR_OK; + for (std::unique_ptr& endTake : m_endTake) + { + Error result = endTake->GetMissionResult(); + if(result != ERR_OK || endTake->immediat) { + m_missionResult = result; + break; + } + } + + if (m_missionResult != INFO_LOST && m_missionResult != INFO_LOSTq) + { + if (m_endTakeResearch != 0) + { + if (m_endTakeResearch != (m_endTakeResearch&g_researchDone)) + { + m_missionResult = ERR_MISSION_NOTERM; + } + } + } + + if(m_missionResult == ERR_OK && m_endTakeNever) m_missionResult = ERR_MISSION_NOTERM; + } + + // Take action depending on m_missionResult + + if(m_missionResult == INFO_LOSTq) + { + if (m_lostDelay == 0.0f) + { + m_lostDelay = 0.1f; // lost immediately + m_winDelay = 0.0f; + } + m_missionTimerEnabled = m_missionTimerStarted = false; + m_displayText->SetEnable(false); + if (m_exitAfterMission) + m_eventQueue->AddEvent(Event(EVENT_QUIT)); + return INFO_LOSTq; + } + + if(m_missionResult == INFO_LOST) + { + if (m_lostDelay == 0.0f) { m_displayText->DisplayError(INFO_LOST, Math::Vector(0.0f,0.0f,0.0f)); - m_missionTimerEnabled = m_missionTimerStarted = false; - m_winDelay = 0.0f; - if (m_lostDelay == 0) m_lostDelay = m_endTakeLostDelay; - m_displayText->SetEnable(false); - if (m_exitAfterMission) - m_eventQueue->AddEvent(Event(EVENT_QUIT)); + m_lostDelay = m_endTakeLostDelay; // lost in 6 seconds + m_winDelay = 0.0f; } - if (m_missionResult == INFO_LOSTq) //mission lost? + m_missionTimerEnabled = m_missionTimerStarted = false; + m_displayText->SetEnable(false); + if (m_exitAfterMission) + m_eventQueue->AddEvent(Event(EVENT_QUIT)); + return INFO_LOST; + } + + if (m_missionResult == ERR_OK) + { + if (m_endTakeWinDelay == -1.0f) { + m_winDelay = 1.0f; // wins in one second + m_lostDelay = 0.0f; m_missionTimerEnabled = m_missionTimerStarted = false; - m_winDelay = 0.0f; - if (m_lostDelay == 0) m_lostDelay = 0.1f; m_displayText->SetEnable(false); if (m_exitAfterMission) m_eventQueue->AddEvent(Event(EVENT_QUIT)); + return ERR_OK; // mission ended } + if (frame && m_base != nullptr && m_base->GetSelectable()) return ERR_MISSION_NOTERM; - if (m_missionResult == ERR_OK) //mission win? + + if (m_winDelay == 0.0f) { m_displayText->DisplayError(INFO_WIN, Math::Vector(0.0f,0.0f,0.0f)); if (m_missionTimerEnabled && m_missionTimerStarted) @@ -5545,196 +5501,18 @@ Error CRobotMain::CheckEndMission(bool frame) m_displayText->DisplayText(("Time: " + TimeFormat(m_missionTimer)).c_str(), Math::Vector(0.0f,0.0f,0.0f)); } m_missionTimerEnabled = m_missionTimerStarted = false; - if (m_winDelay == 0) m_winDelay = m_endTakeWinDelay; + m_winDelay = m_endTakeWinDelay; // wins in two seconds m_lostDelay = 0.0f; - m_displayText->SetEnable(false); - if (m_exitAfterMission) - m_eventQueue->AddEvent(Event(EVENT_QUIT)); } - if (m_missionResult == ERR_MISSION_NOTERM) m_displayText->SetEnable(true); - return m_missionResult; - } - - for (int t = 0; t < m_endTakeTotal; t++) - { - if (m_endTake[t].message[0] != 0) continue; - - Math::Vector bPos = m_endTake[t].pos; - bPos.y = 0.0f; - - Math::Vector oPos; - - int nb = 0; - for (CObject* obj : m_objMan->GetAllObjects()) - { - // Do not use GetActive () because an invisible worm (underground) - // should be regarded as existing here! - if (obj->GetLock()) continue; - if (obj->GetRuin()) continue; - if (!obj->GetEnable()) continue; - - if (!m_endTake[t].countTransported) - { - if (obj->GetTransporter() != nullptr) continue; - } - - ObjectType type = obj->GetType(); - if (type == OBJECT_SCRAP2 || - type == OBJECT_SCRAP3 || - type == OBJECT_SCRAP4 || - type == OBJECT_SCRAP5) // wastes? - { - type = OBJECT_SCRAP1; - } - - ToolType tool = GetToolFromObject(type); - DriveType drive = GetDriveFromObject(type); - if (m_endTake[t].tool != ToolType::Other && - tool != m_endTake[t].tool) - continue; - - if (m_endTake[t].drive != DriveType::Other && - drive != m_endTake[t].drive) - continue; - - if (m_endTake[t].tool == ToolType::Other && - m_endTake[t].drive == DriveType::Other && - 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; - } - else - { - if (obj->GetType() == OBJECT_POWER || obj->GetType() == OBJECT_ATOMIC) - { - energyLevel = obj->GetEnergy(); - if (obj->GetType() == OBJECT_ATOMIC) energyLevel *= 100; - } - } - if (energyLevel < m_endTake[t].powermin || energyLevel > m_endTake[t].powermax) continue; - - if (obj->GetTransporter() == 0) - oPos = obj->GetPosition(0); - else - oPos = obj->GetTransporter()->GetPosition(0); - - oPos.y = 0.0f; - - if (Math::DistanceProjected(oPos, bPos) <= m_endTake[t].dist) - nb ++; - } - - if (nb <= m_endTake[t].lost) - { - if (m_endTake[t].type == OBJECT_HUMAN) - { - if (m_lostDelay == 0.0f) - { - m_lostDelay = 0.1f; // lost immediately - m_winDelay = 0.0f; - } - m_missionTimerEnabled = m_missionTimerStarted = false; - m_displayText->SetEnable(false); - if (m_exitAfterMission) - m_eventQueue->AddEvent(Event(EVENT_QUIT)); - return INFO_LOSTq; - } - else - { - if (m_lostDelay == 0.0f) - { - m_displayText->DisplayError(INFO_LOST, Math::Vector(0.0f,0.0f,0.0f)); - m_lostDelay = m_endTakeLostDelay; // lost in 6 seconds - m_winDelay = 0.0f; - } - m_missionTimerEnabled = m_missionTimerStarted = false; - m_displayText->SetEnable(false); - if (m_exitAfterMission) - m_eventQueue->AddEvent(Event(EVENT_QUIT)); - return INFO_LOST; - } - } - if (nb < m_endTake[t].min || - nb > m_endTake[t].max || - m_endTakeNever ) - { - m_displayText->SetEnable(true); - return ERR_MISSION_NOTERM; - } - if (m_endTake[t].immediat) - { - if (m_winDelay == 0.0f) - { - m_winDelay = m_endTakeWinDelay; // wins in x seconds - m_lostDelay = 0.0f; - } - m_missionTimerEnabled = m_missionTimerStarted = false; - m_displayText->SetEnable(false); - if (m_exitAfterMission) - m_eventQueue->AddEvent(Event(EVENT_QUIT)); - return ERR_OK; // mission ended - } - } - - if (m_endTakeResearch != 0) - { - if (m_endTakeResearch != (m_endTakeResearch&g_researchDone)) - { - m_displayText->SetEnable(true); - return ERR_MISSION_NOTERM; - } - } - - if (m_endTakeWinDelay == -1.0f) - { - m_winDelay = 1.0f; // wins in one second - m_lostDelay = 0.0f; - m_missionTimerEnabled = m_missionTimerStarted = false; - m_displayText->SetEnable(false); if (m_exitAfterMission) m_eventQueue->AddEvent(Event(EVENT_QUIT)); + m_displayText->SetEnable(false); return ERR_OK; // mission ended } - - if (frame && m_base != nullptr && m_base->GetSelectable()) return ERR_MISSION_NOTERM; - - if (m_winDelay == 0.0f) + else { - m_displayText->DisplayError(INFO_WIN, Math::Vector(0.0f,0.0f,0.0f)); - if (m_missionTimerEnabled && m_missionTimerStarted) - { - CLogger::GetInstancePointer()->Info("Mission time: %s\n", TimeFormat(m_missionTimer).c_str()); - m_displayText->DisplayText(("Time: " + TimeFormat(m_missionTimer)).c_str(), Math::Vector(0.0f,0.0f,0.0f)); - } - m_missionTimerEnabled = m_missionTimerStarted = false; - m_winDelay = m_endTakeWinDelay; // wins in two seconds - m_lostDelay = 0.0f; - } - if (m_exitAfterMission) - m_eventQueue->AddEvent(Event(EVENT_QUIT)); - m_displayText->SetEnable(false); - return ERR_OK; // mission ended -} - -//! Checks if the mission is finished after displaying a message -void CRobotMain::CheckEndMessage(const char* message) -{ - for (int t = 0; t < m_endTakeTotal; t++) - { - if (m_endTake[t].message[0] == 0) continue; - - if (strcmp(m_endTake[t].message, message) == 0) - { - m_displayText->DisplayError(INFO_WIN, Math::Vector(0.0f,0.0f,0.0f)); - m_winDelay = m_endTakeWinDelay; // wins in 2 seconds - m_lostDelay = 0.0f; - } + m_displayText->SetEnable(true); + return ERR_MISSION_NOTERM; } } diff --git a/src/object/robotmain.h b/src/object/robotmain.h index 95fcc8ba..9afcc42b 100644 --- a/src/object/robotmain.h +++ b/src/object/robotmain.h @@ -83,6 +83,8 @@ class CSoundInterface; class CLevelParserLine; class CInput; class CObjectManager; +class CSceneEndCondition; +class CAudioChangeCondition; namespace Gfx { class CEngine; @@ -103,41 +105,6 @@ class CDisplayText; class CDisplayInfo; } - -struct EndTake -{ - Math::Vector pos; - float dist; - ObjectType type; - int min; // wins if > - int max; // wins if < - int lost; // lost if <= - float powermin; // wins if energy cell >= - float powermax; // wins if energy cell <= - ToolType tool; - DriveType drive; - bool immediat; - bool countTransported; - char message[100]; -}; - -struct AudioChange -{ - Math::Vector pos; - float dist; - ObjectType type; - int min; // change if > - int max; // change if < - float powermin; // change if energy cell >= - float powermax; // change if energy cell <= - ToolType tool; - DriveType drive; - char music[100]; - bool repeat; - bool changed; -}; - - const int MAXNEWSCRIPTNAME = 20; struct NewScriptName @@ -233,7 +200,6 @@ public: void UpdateAudio(bool frame); void SetEndMission(Error result, float delay); Error CheckEndMission(bool frame); - void CheckEndMessage(const char* message); int GetObligatoryToken(); char* GetObligatoryToken(int i); int IsObligatoryToken(const char* token); @@ -517,15 +483,13 @@ protected: Math::Vector m_visitPos; Math::Vector m_visitPosArrow; - int m_endTakeTotal; - EndTake m_endTake[10]; + std::vector> m_endTake; long m_endTakeResearch; bool m_endTakeNever; float m_endTakeWinDelay; float m_endTakeLostDelay; - int m_audioChangeTotal; - AudioChange m_audioChange[10]; + std::vector> m_audioChange; int m_obligatoryTotal; char m_obligatoryToken[100][20]; diff --git a/src/object/scene_conditions.cpp b/src/object/scene_conditions.cpp new file mode 100644 index 00000000..a415b0f6 --- /dev/null +++ b/src/object/scene_conditions.cpp @@ -0,0 +1,165 @@ +/* + * 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/scene_conditions.h" + +#include "math/geometry.h" + +#include "object/level/parserline.h" +#include "object/object_manager.h" +#include "object/object.h" + +void CSceneCondition::Read(CLevelParserLine* line) +{ + this->pos = line->GetParam("pos")->AsPoint(Math::Vector(0.0f, 0.0f, 0.0f))*g_unit; + this->dist = line->GetParam("dist")->AsFloat(8.0f)*g_unit; + this->type = line->GetParam("type")->AsObjectType(OBJECT_NULL); + this->powermin = line->GetParam("powermin")->AsFloat(-1); + this->powermax = line->GetParam("powermax")->AsFloat(100); + this->tool = line->GetParam("tool")->AsToolType(ToolType::Other); + this->drive = line->GetParam("drive")->AsDriveType(DriveType::Other); + this->countTransported = line->GetParam("countTransported")->AsBool(true); + + this->min = line->GetParam("min")->AsInt(1); + this->max = line->GetParam("max")->AsInt(9999); +} + +int CSceneCondition::CountObjects() +{ + Math::Vector bPos = this->pos; + bPos.y = 0.0f; + + Math::Vector oPos; + + int nb = 0; + for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects()) + { + // Do not use GetActive () because an invisible worm (underground) + // should be regarded as existing here! + if (obj->GetLock()) continue; + if (obj->GetRuin()) continue; + if (!obj->GetEnable()) continue; + + if (!this->countTransported) + { + if (obj->GetTransporter() != nullptr) continue; + } + + // TODO: I really hate those fragments that hardcode subcategories into one in random places in code, we should refactor that at some point + ObjectType type = obj->GetType(); + if (type == OBJECT_SCRAP2 || + type == OBJECT_SCRAP3 || + type == OBJECT_SCRAP4 || + type == OBJECT_SCRAP5) // wastes? + { + type = OBJECT_SCRAP1; + } + + ToolType tool = GetToolFromObject(type); + DriveType drive = GetDriveFromObject(type); + if (this->tool != ToolType::Other && + tool != this->tool) + continue; + + if (this->drive != DriveType::Other && + drive != this->drive) + continue; + + if (this->tool == ToolType::Other && + this->drive == DriveType::Other && + type != this->type && + this->type != OBJECT_NULL) + continue; + + float energyLevel = -1; + CObject* power = obj->GetPower(); + if (power != nullptr) + { + energyLevel = power->GetEnergy(); + if (power->GetType() == OBJECT_ATOMIC) energyLevel *= 100; + } + else + { + if (obj->GetType() == OBJECT_POWER || obj->GetType() == OBJECT_ATOMIC) + { + energyLevel = obj->GetEnergy(); + if (obj->GetType() == OBJECT_ATOMIC) energyLevel *= 100; + } + } + if (energyLevel < this->powermin || energyLevel > this->powermax) continue; + + if (obj->GetTransporter() == 0) + oPos = obj->GetPosition(0); + else + oPos = obj->GetTransporter()->GetPosition(0); + + oPos.y = 0.0f; + + if (Math::DistanceProjected(oPos, bPos) <= this->dist) + nb ++; + } + return nb; +} + +bool CSceneCondition::Check() +{ + int nb = CountObjects(); + return nb >= this->min && nb <= this->max; +} + + +void CSceneEndCondition::Read(CLevelParserLine* line) +{ + CSceneCondition::Read(line); + this->lost = line->GetParam("lost")->AsInt(-1); + this->immediat = line->GetParam("immediat")->AsBool(false); +} + +bool CSceneEndCondition::CheckLost() +{ + int nb = CountObjects(); + return nb <= this->lost; +} + +Error CSceneEndCondition::GetMissionResult() +{ + if (CheckLost()) + { + if (this->type == OBJECT_HUMAN) + return INFO_LOSTq; + else + return INFO_LOST; + } + + if (!Check()) + { + return ERR_MISSION_NOTERM; + } + + return ERR_OK; +} + + +void CAudioChangeCondition::Read(CLevelParserLine* line) +{ + CSceneCondition::Read(line); + this->music = std::string("../")+line->GetParam("filename")->AsPath("music"); + this->repeat = line->GetParam("repeat")->AsBool(true); +} \ No newline at end of file diff --git a/src/object/scene_conditions.h b/src/object/scene_conditions.h new file mode 100644 index 00000000..9590d6c4 --- /dev/null +++ b/src/object/scene_conditions.h @@ -0,0 +1,102 @@ +/* + * 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 + */ + +/** + * \file object/scene_conditions.h + * \brief Classes for managing conditions in scene files + */ + +#pragma once + +#include "common/global.h" + +#include "math/vector.h" + +#include "object/object_type.h" +#include "object/tool_type.h" +#include "object/drive_type.h" + +class CLevelParserLine; + +/** + * \class CSceneCondition + * \brief Base scene condition structure + */ +class CSceneCondition +{ +public: + Math::Vector pos = Math::Vector(0.0f, 0.0f, 0.0f)*g_unit; + float dist = 8.0f*g_unit; + ObjectType type = OBJECT_NULL; + float powermin = -1; // wins if energy cell >= + float powermax = 100; // wins if energy cell <= + ToolType tool = ToolType::Other; + DriveType drive = DriveType::Other; + bool countTransported = true; + + int min = 1; // wins if > + int max = 9999; // wins if < + + //! Read from line in scene file + virtual void Read(CLevelParserLine* line); + + //! Checks if this condition is met + bool Check(); + +protected: + //! Count all object matching the conditions + int CountObjects(); +}; + +/** + * \class CSceneEndCondition + * \brief Scene end condition + */ +class CSceneEndCondition : public CSceneCondition +{ +public: + int lost = -1; // lost if <= + + bool immediat = false; + + //! Read from line in scene file + virtual void Read(CLevelParserLine* line); + + //! Checks if lost condition is met + bool CheckLost(); + + //! Get mission result + Error GetMissionResult(); +}; + +/** + * \class CAudioChangeCondition + * \brief Audio change condition + */ +class CAudioChangeCondition : public CSceneCondition +{ +public: + std::string music = ""; + bool repeat = true; + + bool changed = false; + + //! Read from line in scene file + virtual void Read(CLevelParserLine* line); +}; \ No newline at end of file diff --git a/src/script/scriptfunc.cpp b/src/script/scriptfunc.cpp index 720ad188..cd08b762 100644 --- a/src/script/scriptfunc.cpp +++ b/src/script/scriptfunc.cpp @@ -2902,7 +2902,6 @@ bool CScriptFunctions::rMessage(CBotVar* var, CBotVar* result, int& exception, v } script->m_main->GetDisplayText()->DisplayText(p, script->m_object, 10.0f, type); - script->m_main->CheckEndMessage(p); return true; }