From f871ba4729dbb91cc4b74bf95edc5b25272af5c7 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sat, 27 Jun 2015 23:22:55 +0200 Subject: [PATCH] Create CExchangePost subclass --- src/CMakeLists.txt | 3 +- src/common/regex_utils.cpp | 46 ++ src/common/regex_utils.h | 38 ++ src/object/auto/autoinfo.cpp | 511 ------------------- src/object/auto/autoinfo.h | 71 --- src/object/level/parserexceptions.cpp | 17 +- src/object/level/parserexceptions.h | 12 +- src/object/object.cpp | 100 +--- src/object/object.h | 33 +- src/object/object_create_params.h | 38 ++ src/object/object_factory.cpp | 51 +- src/object/object_factory.h | 15 +- src/object/object_manager.cpp | 1 + src/object/robotmain.cpp | 23 +- src/object/subclass/exchange_post.cpp | 681 ++++++++++++++++++++++++++ src/object/subclass/exchange_post.h | 110 +++++ src/object/task/taskinfo.cpp | 100 ++-- src/object/task/taskinfo.h | 14 +- src/script/scriptfunc.cpp | 102 ++-- src/script/scriptfunc.h | 25 +- 20 files changed, 1032 insertions(+), 959 deletions(-) create mode 100644 src/common/regex_utils.cpp create mode 100644 src/common/regex_utils.h delete mode 100644 src/object/auto/autoinfo.cpp delete mode 100644 src/object/auto/autoinfo.h create mode 100644 src/object/object_create_params.h create mode 100644 src/object/subclass/exchange_post.cpp create mode 100644 src/object/subclass/exchange_post.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5eff4c1c..832c186e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -87,6 +87,7 @@ set(BASE_SOURCES common/misc.cpp common/pathman.cpp common/profile.cpp + common/regex_utils.cpp common/resources/inputstream.cpp common/resources/inputstreambuffer.cpp common/resources/outputstream.cpp @@ -127,7 +128,6 @@ set(BASE_SOURCES object/auto/autofactory.cpp object/auto/autoflag.cpp object/auto/autohuston.cpp - object/auto/autoinfo.cpp object/auto/autojostle.cpp object/auto/autokid.cpp object/auto/autolabo.cpp @@ -187,6 +187,7 @@ set(BASE_SOURCES object/task/taskturn.cpp object/task/taskwait.cpp object/tool_type.cpp + object/subclass/exchange_post.cpp physics/physics.cpp script/cbottoken.cpp script/cmdtoken.cpp diff --git a/src/common/regex_utils.cpp b/src/common/regex_utils.cpp new file mode 100644 index 00000000..e84aa225 --- /dev/null +++ b/src/common/regex_utils.cpp @@ -0,0 +1,46 @@ +/* + * 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 "common/regex_utils.h" + +std::string FormatAssertRegexMatchError(const std::string& text, + const std::string& pattern) +{ + return "Text \"" + text + "\" did not match regex \"" + pattern + "\""; +} + +RegexUtils::AssertRegexMatchError::AssertRegexMatchError( + const std::string& text, const std::string& pattern) NOEXCEPT + : std::runtime_error(FormatAssertRegexMatchError(text, pattern)) +{ +} + +boost::smatch RegexUtils::AssertRegexMatch(const std::string& text, const std::string& pattern) +{ + boost::regex regex(pattern); + boost::smatch matches; + bool ok = boost::regex_match(text, matches, regex); + if (!ok) + throw AssertRegexMatchError(text, pattern); + + return matches; +} + + /* + boost::cmatch matches;*/ \ No newline at end of file diff --git a/src/common/regex_utils.h b/src/common/regex_utils.h new file mode 100644 index 00000000..d70b4e55 --- /dev/null +++ b/src/common/regex_utils.h @@ -0,0 +1,38 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#pragma once + +#include + +#include + +namespace RegexUtils { + +class AssertRegexMatchError : public std::runtime_error +{ +public: + explicit AssertRegexMatchError(const std::string& text, + const std::string& pattern) NOEXCEPT; +}; + +//! Match string with regex and return list of matches; throw exception on mismatch +boost::smatch AssertRegexMatch(const std::string& text, const std::string& pattern); + +} // namespace RegexUtils diff --git a/src/object/auto/autoinfo.cpp b/src/object/auto/autoinfo.cpp deleted file mode 100644 index ccd1bc6e..00000000 --- a/src/object/auto/autoinfo.cpp +++ /dev/null @@ -1,511 +0,0 @@ -/* - * This file is part of the Colobot: Gold Edition source code - * Copyright (C) 2001-2014, 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/auto/autoinfo.h" - - -#include "object/level/parserline.h" -#include "object/level/parserparam.h" - -#include "script/cmdtoken.h" - -#include "ui/interface.h" -#include "ui/list.h" -#include "ui/window.h" - -#include -#include - - - -// Object's constructor. - -CAutoInfo::CAutoInfo(CObject* object) : CAuto(object) -{ - Init(); -} - -// Object's destructor. - -CAutoInfo::~CAutoInfo() -{ -} - - -// Destroys the object. - -void CAutoInfo::DeleteObject(bool bAll) -{ - CAuto::DeleteObject(bAll); -} - - -// Initialize the object. - -void CAutoInfo::Init() -{ - m_phase = AIP_WAIT; - m_time = 0.0f; - m_timeVirus = 0.0f; - m_bLastVirus = false; - - CAuto::Init(); -} - - -// Start a emission. - -void CAutoInfo::Start(int param) -{ - Math::Vector pos, speed; - Math::Point dim; - - if ( param == 0 ) // instruction "receive" ? - { - m_phase = AIP_EMETTE; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - else if ( param == 2 ) // instruction "send" ? - { - m_phase = AIP_RECEIVE; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - else - { - m_phase = AIP_ERROR; - m_progress = 0.0f; - m_speed = 1.0f/2.0f; - } - - m_lastParticle = 0; - m_goal = m_object->GetPosition(0); - - if ( m_phase == AIP_EMETTE ) - { - pos = m_goal; - pos.y += 9.5f; - speed = Math::Vector(0.0f, 0.0f, 0.0f); - dim.x = 30.0f; - dim.y = dim.x; - m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISPHERE4, 1.5f, 0.0f, 0.0f); - - m_sound->Play(SOUND_LABO, pos, 1.0f, 2.0f); - } - if ( m_phase == AIP_RECEIVE ) - { - pos = m_goal; - pos.y += 9.5f; - speed = Math::Vector(0.0f, 0.0f, 0.0f); - dim.x = 50.0f; - dim.y = dim.x; - m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISPHERE6, 1.5f, 0.0f, 0.0f); - - m_sound->Play(SOUND_LABO, pos, 1.0f, 2.0f); - } - if ( m_phase == AIP_ERROR ) - { - m_sound->Play(SOUND_GGG, pos, 1.0f, 0.5f); - } -} - - -// Management of an event. - -bool CAutoInfo::EventProcess(const Event &event) -{ - Math::Vector pos, speed; - Math::Point dim; - float duration, angle, rTime; - int i; - - CAuto::EventProcess(event); - - if ( m_engine->GetPause() ) return true; - if ( event.type != EVENT_FRAME ) return true; - - m_timeVirus -= event.rTime; - - if ( m_object->GetVirusMode() ) // contaminated by a virus? - { - if ( m_timeVirus <= 0.0f ) - { - m_timeVirus = 0.1f+Math::Rand()*0.3f; - - angle = m_object->GetAngleY(1); - angle += Math::Rand()*0.3f; - m_object->SetAngleY(1, angle); - - m_object->SetAngleX(2, (Math::Rand()-0.5f)*0.3f); - m_object->SetAngleX(4, (Math::Rand()-0.5f)*0.3f); - m_object->SetAngleX(6, (Math::Rand()-0.5f)*0.3f); - - m_object->SetAngleZ(2, (Math::Rand()-0.5f)*0.3f); - m_object->SetAngleZ(4, (Math::Rand()-0.5f)*0.3f); - m_object->SetAngleZ(6, (Math::Rand()-0.5f)*0.3f); - - UpdateListVirus(); - } - m_bLastVirus = true; - return true; - } - else - { - if ( m_bLastVirus ) - { - m_bLastVirus = false; - UpdateList(); // normally returns the list - } - else - { - if ( m_object->GetInfoUpdate() ) - { - UpdateList(); // updates the list - } - } - } - - UpdateInterface(event.rTime); - - rTime = event.rTime; - - if ( m_phase == AIP_EMETTE ) // instruction "receive" ? - { - if ( m_progress < 0.5f && - m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) - { - m_lastParticle = m_time; - - for ( i=0 ; i<4 ; i++ ) - { - pos = m_goal; - pos.y += 9.5f; - speed.x = (Math::Rand()-0.5f)*50.0f; - speed.z = (Math::Rand()-0.5f)*50.0f; - speed.y = (Math::Rand()-0.5f)*50.0f; - speed *= 0.5f+m_progress*0.5f; - dim.x = 0.6f; - dim.y = dim.x; - duration = Math::Rand()*0.5f+0.5f; - m_particle->CreateTrack(pos, speed, dim, Gfx::PARTITRACK6, - duration, 0.0f, - duration*0.9f, 0.7f); - } - } - - if ( m_progress < 1.0f ) - { - m_progress += rTime*m_speed; - - m_object->SetAngleZ(2, m_progress*2.0f*Math::PI); - m_object->SetAngleZ(4, m_progress*2.0f*Math::PI); - m_object->SetAngleZ(6, m_progress*2.0f*Math::PI); - } - else - { - m_phase = AIP_WAIT; - - m_object->SetAngleX(2, 0.0f); - m_object->SetAngleX(4, 0.0f); - m_object->SetAngleX(6, 0.0f); - - m_object->SetAngleZ(2, 0.0f); - m_object->SetAngleZ(4, 0.0f); - m_object->SetAngleZ(6, 0.0f); - } - } - - if ( m_phase == AIP_RECEIVE ) // instruction "send" ? - { - if ( m_progress < 0.5f && - m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) - { - m_lastParticle = m_time; - - for ( i=0 ; i<4 ; i++ ) - { - pos = m_goal; - pos.y += 9.5f; - speed = pos; - pos.x += (Math::Rand()-0.5f)*40.0f; - pos.y += (Math::Rand()-0.5f)*40.0f; - pos.z += (Math::Rand()-0.5f)*40.0f; - speed = (speed-pos)*1.0f; -//? speed *= 0.5f+m_progress*0.5f; - dim.x = 0.6f; - dim.y = dim.x; - duration = Math::Rand()*0.5f+0.5f; - m_particle->CreateTrack(pos, speed, dim, Gfx::PARTITRACK6, - duration, 0.0f, - duration*0.9f, 0.7f); - } - } - - if ( m_progress < 1.0f ) - { - m_progress += rTime*m_speed; - - m_object->SetAngleZ(2, m_progress*2.0f*Math::PI); - m_object->SetAngleZ(4, m_progress*2.0f*Math::PI); - m_object->SetAngleZ(6, m_progress*2.0f*Math::PI); - } - else - { - m_phase = AIP_WAIT; - - m_object->SetAngleX(2, 0.0f); - m_object->SetAngleX(4, 0.0f); - m_object->SetAngleX(6, 0.0f); - - m_object->SetAngleZ(2, 0.0f); - m_object->SetAngleZ(4, 0.0f); - m_object->SetAngleZ(6, 0.0f); - } - } - - if ( m_phase == AIP_ERROR ) - { - if ( m_progress < 0.5f && - m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) - { - m_lastParticle = m_time; - - pos = m_goal; - speed.x = (Math::Rand()-0.5f)*5.0f; - speed.z = (Math::Rand()-0.5f)*5.0f; - speed.y = 5.0f+Math::Rand()*5.0f; - dim.x = 5.0f+Math::Rand()*5.0f; - dim.y = dim.x; - duration = Math::Rand()*0.5f+0.5f; - m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE1, 4.0f); - } - - if ( m_progress < 1.0f ) - { - m_progress += rTime*m_speed; - rTime = 0.0f; // stops the rotation - - if ( m_progress < 0.5f ) - { - angle = m_progress/0.5f; - } - else - { - angle = 1.0f-(m_progress-0.5f)/0.5f; - } - m_object->SetAngleX(2, angle*0.5f); - m_object->SetAngleX(4, angle*0.5f); - m_object->SetAngleX(6, angle*0.5f); - - m_object->SetAngleZ(2, (Math::Rand()-0.5f)*0.2f); - m_object->SetAngleZ(4, (Math::Rand()-0.5f)*0.2f); - m_object->SetAngleZ(6, (Math::Rand()-0.5f)*0.2f); - } - else - { - m_phase = AIP_WAIT; - - m_object->SetAngleX(2, 0.0f); - m_object->SetAngleX(4, 0.0f); - m_object->SetAngleX(6, 0.0f); - - m_object->SetAngleZ(2, 0.0f); - m_object->SetAngleZ(4, 0.0f); - m_object->SetAngleZ(6, 0.0f); - } - } - - angle = m_object->GetAngleY(1); - angle += rTime*0.5f; - m_object->SetAngleY(1, angle); - - m_object->SetAngleX(3, sinf(m_time*6.0f+Math::PI*0.0f/3.0f)*0.3f); - m_object->SetAngleX(5, sinf(m_time*6.0f+Math::PI*2.0f/3.0f)*0.3f); - m_object->SetAngleX(7, sinf(m_time*6.0f+Math::PI*4.0f/3.0f)*0.3f); - - return true; -} - - -// Returns an error due the state of the automation. - -Error CAutoInfo::GetError() -{ - if ( m_object->GetVirusMode() ) - { - return ERR_BAT_VIRUS; - } - - return ERR_OK; -} - - -// Creates all the interface when the object is selected. - -bool CAutoInfo::CreateInterface(bool bSelect) -{ - Ui::CWindow* pw; - Ui::CList* pl; - Math::Point pos, ddim; - float ox, oy, sx, sy; - - CAuto::CreateInterface(bSelect); - - if ( !bSelect ) return true; - - pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); - if ( pw == 0 ) return false; - - ox = 3.0f/640.0f; - oy = 3.0f/480.0f; - sx = 33.0f/640.0f; - sy = 33.0f/480.0f; - - pos.x = ox+sx*7.0f; - pos.y = oy+sy*0.0f; - ddim.x = 160.0f/640.0f; - ddim.y = 66.0f/480.0f; - pl = pw->CreateList(pos, ddim, 1, EVENT_OBJECT_GINFO, 1.10f); - pl->SetSelectCap(false); - - pos.x = ox+sx*0.0f; - pos.y = oy+sy*0; - ddim.x = 66.0f/640.0f; - ddim.y = 66.0f/480.0f; - pw->CreateGroup(pos, ddim, 112, EVENT_OBJECT_TYPE); - - UpdateList(); - return true; -} - -// Updates the state of all buttons on the interface, -// following the time that elapses ... - -void CAutoInfo::UpdateInterface(float rTime) -{ - CAuto::UpdateInterface(rTime); -} - - -// Updates the contents of the list. - -void CAutoInfo::UpdateList() -{ - Ui::CWindow* pw; - Ui::CList* pl; - Info info; - int total, i; - char text[100]; - - pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); - if ( pw == nullptr ) return; - - pl = static_cast< Ui::CList* >(pw->SearchControl(EVENT_OBJECT_GINFO)); - if ( pl == nullptr ) return; - - pl->Flush(); - total = m_object->GetInfoTotal(); - if ( total == 0 ) - { - pl->ClearState(Ui::STATE_ENABLE); - } - else - { - pl->SetState(Ui::STATE_ENABLE); - - for ( i=0 ; iGetInfo(i); - sprintf(text, "%s = %.2f", info.name, info.value); - pl->SetItemName(i, text); - } - } - - m_object->SetInfoUpdate(false); -} - -// Updates the content of contaminating the list. - -void CAutoInfo::UpdateListVirus() -{ - Ui::CWindow* pw; - Ui::CList* pl; - int i, j, max; - char text[100]; - - pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); - if ( pw == 0 ) return; - - pl = static_cast< Ui::CList* >(pw->SearchControl(EVENT_OBJECT_GINFO)); - if ( pl == 0 ) return; - - pl->SetState(Ui::STATE_ENABLE); - - pl->Flush(); - for ( i=0 ; i<4 ; i++ ) - { - max = static_cast< int >(2.0f+Math::Rand()*10.0f); - for ( j=0 ; j(Math::Rand()*94.0f); - } - while ( text[j] == '\\' ); - } - text[j] = 0; - - pl->SetItemName(i, text); - } -} - - -// Saves all parameters of the controller. - -bool CAutoInfo::Write(CLevelParserLine* line) -{ - if ( m_phase == AIP_WAIT ) return false; - - line->AddParam("aExist", CLevelParserParamUPtr{new CLevelParserParam(true)}); - CAuto::Write(line); - line->AddParam("aPhase", CLevelParserParamUPtr{new CLevelParserParam(static_cast(m_phase))}); - line->AddParam("aProgress", CLevelParserParamUPtr{new CLevelParserParam(m_progress)}); - line->AddParam("aSpeed", CLevelParserParamUPtr{new CLevelParserParam(m_speed)}); - - return true; -} - -// Restores all parameters of the controller. - -bool CAutoInfo::Read(CLevelParserLine* line) -{ - if ( !line->GetParam("aExist")->AsBool(false) ) return false; - - CAuto::Read(line); - m_phase = static_cast< AutoInfoPhase >(line->GetParam("aPhase")->AsInt(AIP_WAIT)); - m_progress = line->GetParam("aProgress")->AsFloat(0.0f); - m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); - - m_lastParticle = 0.0f; - - return true; -} - diff --git a/src/object/auto/autoinfo.h b/src/object/auto/autoinfo.h deleted file mode 100644 index ac9f729d..00000000 --- a/src/object/auto/autoinfo.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of the Colobot: Gold Edition source code - * Copyright (C) 2001-2014, 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 - */ - -// autoinfo.h - -#pragma once - - -#include "object/auto/auto.h" - - - -enum AutoInfoPhase -{ - AIP_WAIT = 1, - AIP_EMETTE = 2, - AIP_RECEIVE = 3, - AIP_ERROR = 4, -}; - - - -class CAutoInfo : public CAuto -{ -public: - CAutoInfo(CObject* object); - ~CAutoInfo(); - - void DeleteObject(bool bAll=false); - - void Init(); - void Start(int param); - bool EventProcess(const Event &event); - Error GetError(); - - bool CreateInterface(bool bSelect); - - bool Write(CLevelParserLine* line); - bool Read(CLevelParserLine* line); - -protected: - void UpdateInterface(float rTime); - void UpdateList(); - void UpdateListVirus(); - -protected: - AutoInfoPhase m_phase; - float m_progress; - float m_speed; - float m_timeVirus; - float m_lastParticle; - Math::Vector m_goal; - bool m_bLastVirus; -}; - diff --git a/src/object/level/parserexceptions.cpp b/src/object/level/parserexceptions.cpp index 2747f0db..1869a774 100644 --- a/src/object/level/parserexceptions.cpp +++ b/src/object/level/parserexceptions.cpp @@ -23,17 +23,8 @@ #include -CLevelParserException::CLevelParserException(std::string message) NOEXCEPT - : m_message(message) -{ -} -const char* CLevelParserException::what() const NOEXCEPT -{ - return m_message.c_str(); -} - -std::string formatMissingParamError(CLevelParserParam* thisParam) NOEXCEPT +std::string FormatMissingParamError(CLevelParserParam* thisParam) NOEXCEPT { auto paramName = thisParam->GetName(); auto lineNumber = boost::lexical_cast(thisParam->GetLine()->GetLineNumber()); @@ -42,11 +33,11 @@ std::string formatMissingParamError(CLevelParserParam* thisParam) NOEXCEPT } CLevelParserExceptionMissingParam::CLevelParserExceptionMissingParam(CLevelParserParam* thisParam) NOEXCEPT -: CLevelParserException(formatMissingParamError(thisParam)) +: CLevelParserException(FormatMissingParamError(thisParam)) { } -std::string formatBadParamError(CLevelParserParam* thisParam, std::string requestedType) NOEXCEPT +std::string FormatBadParamError(CLevelParserParam* thisParam, std::string requestedType) NOEXCEPT { auto paramName = thisParam->GetName(); auto paramValue = thisParam->GetValue(); @@ -56,6 +47,6 @@ std::string formatBadParamError(CLevelParserParam* thisParam, std::string reques } CLevelParserExceptionBadParam::CLevelParserExceptionBadParam(CLevelParserParam* thisParam, std::string requestedType) NOEXCEPT -: CLevelParserException(formatBadParamError(thisParam, requestedType)) +: CLevelParserException(FormatBadParamError(thisParam, requestedType)) { } diff --git a/src/object/level/parserexceptions.h b/src/object/level/parserexceptions.h index ddb82935..b4a4d634 100644 --- a/src/object/level/parserexceptions.h +++ b/src/object/level/parserexceptions.h @@ -24,20 +24,16 @@ #pragma once -#include +#include #include class CLevelParserParam; -class CLevelParserException : public std::exception +class CLevelParserException : public std::runtime_error { public: - CLevelParserException(std::string message) NOEXCEPT; - virtual ~CLevelParserException() NOEXCEPT {} - const char* what() const NOEXCEPT; - -protected: - std::string m_message; + CLevelParserException(const std::string& message) NOEXCEPT + : std::runtime_error(message) {} }; class CLevelParserExceptionMissingParam : public CLevelParserException diff --git a/src/object/object.cpp b/src/object/object.cpp index 8cbfebd8..0981b778 100644 --- a/src/object/object.cpp +++ b/src/object/object.cpp @@ -251,6 +251,7 @@ CObject::CObject(int id) m_magnifyDamage = 1.0f; m_proxyDistance = 60.0f; m_param = 0.0f; + m_infoReturn = NAN; m_team = 0; memset(&m_character, 0, sizeof(m_character)); @@ -269,10 +270,6 @@ CObject::CObject(int id) m_cameraDist = 50.0f; m_bCameraLock = false; - m_infoTotal = 0; - m_infoReturn = NAN; - m_bInfoUpdate = false; - for (int i=0 ; iAddParam("virusTime", CLevelParserParamUPtr{new CLevelParserParam(m_virusTime)}); - // Puts information in terminal (OBJECT_INFO). - for ( i=0 ; iAddParam("info"+boost::lexical_cast(i+1), CLevelParserParamUPtr{new CLevelParserParam(std::string(info.name)+"="+boost::lexical_cast(info.value))}); - } - // Sets the parameters of the command line. CLevelParserParamVec cmdline; for ( i=0 ; iWrite(line); } - - return true; } // Returns all parameters of the object. -bool CObject::Read(CLevelParserLine* line) +void CObject::Read(CLevelParserLine* line) { Math::Vector pos, dir; - Gfx::CameraType cType; - int i; - cType = line->GetParam("camera")->AsCameraType(Gfx::CAM_TYPE_NULL); + Gfx::CameraType cType = line->GetParam("camera")->AsCameraType(Gfx::CAM_TYPE_NULL); if ( cType != Gfx::CAM_TYPE_NULL ) { SetCameraType(cType); @@ -1064,34 +1047,10 @@ bool CObject::Read(CLevelParserLine* line) m_bVirusMode = line->GetParam("virusMode")->AsBool(false); m_virusTime = line->GetParam("virusTime")->AsFloat(0.0f); - // Puts information in terminal (OBJECT_INFO). - for ( i=0 ; i(i+1); - if (!line->GetParam(op)->IsDefined()) break; - std::string text = line->GetParam(op)->AsString(); - - std::size_t p = text.find_first_of("="); - if (p == std::string::npos) - throw CLevelParserExceptionBadParam(line->GetParam(op), "info"); - Info info; - strcpy(info.name, text.substr(0, p).c_str()); - try - { - info.value = boost::lexical_cast(text.substr(p+1).c_str()); - } - catch (...) - { - throw CLevelParserExceptionBadParam(line->GetParam(op), "info.value (float)"); - } - - SetInfo(i, info); - } - // Sets the parameters of the command line. - i = 0; if (line->GetParam("cmdline")->IsDefined()) { + int i = 0; for (auto& p : line->GetParam("cmdline")->AsArray()) { if (i >= OBJECTMAXCMDLINE) break; @@ -1119,8 +1078,6 @@ bool CObject::Read(CLevelParserLine* line) { m_auto->Read(line); } - - return true; } @@ -1809,42 +1766,6 @@ void CObject::SetTruckPart(int part) m_truckLink = part; } -// Management of user information. - -void CObject::DeleteInfo(int rank) -{ - int i; - - if ( rank < 0 || rank >= m_infoTotal ) return; - - for ( i=rank ; i= OBJECTMAXINFO ) return; - m_info[rank] = info; - - if ( rank+1 > m_infoTotal ) m_infoTotal = rank+1; - m_bInfoUpdate = true; -} - -Info CObject::GetInfo(int rank) -{ - if ( rank < 0 || rank >= OBJECTMAXINFO ) rank = 0; - return m_info[rank]; -} - -int CObject::GetInfoTotal() -{ - return m_infoTotal; -} - void CObject::SetInfoReturn(float value) { m_infoReturn = value; @@ -1855,17 +1776,6 @@ float CObject::GetInfoReturn() return m_infoReturn; } -void CObject::SetInfoUpdate(bool bUpdate) -{ - m_bInfoUpdate = bUpdate; -} - -bool CObject::GetInfoUpdate() -{ - return m_bInfoUpdate; -} - - bool CObject::SetCmdLine(int rank, float value) { if ( rank < 0 || rank >= OBJECTMAXCMDLINE ) return false; diff --git a/src/object/object.h b/src/object/object.h index 4928431c..98dc4044 100644 --- a/src/object/object.h +++ b/src/object/object.h @@ -50,7 +50,6 @@ struct Program; const int OBJECTMAXPART = 40; const int MAXCRASHSPHERE = 40; const int OBJECTMAXDESELLIST = 10; -const int OBJECTMAXINFO = 10; const int OBJECTMAXCMDLINE = 20; struct ObjectPart @@ -81,12 +80,6 @@ struct Character Math::Vector posPower; // position of the battery }; -struct Info -{ - char name[20]; // name of the information - float value; // value of the information -}; - enum class ExplosionType { Bang = 1, @@ -127,7 +120,7 @@ public: CObject(const CObject&) = delete; CObject& operator=(const CObject&) = delete; - ~CObject(); + virtual ~CObject(); void Simplify(); bool ExplodeObject(ExplosionType type, float force, float decay=1.0f); @@ -147,8 +140,8 @@ public: int GetID(); - bool Write(CLevelParserLine* line); - bool Read(CLevelParserLine* line); + virtual void Write(CLevelParserLine* line); + virtual void Read(CLevelParserLine* line); void SetDrawWorld(bool bDraw); void SetDrawFront(bool bDraw); @@ -235,15 +228,6 @@ public: CObject* GetTruck(); void SetTruckPart(int part); - void DeleteInfo(int rank); - void SetInfo(int rank, Info info); - Info GetInfo(int rank); - int GetInfoTotal(); - void SetInfoReturn(float value); - float GetInfoReturn(); - void SetInfoUpdate(bool bUpdate); - bool GetInfoUpdate(); - bool SetCmdLine(int rank, float value); float GetCmdLine(int rank); @@ -375,6 +359,12 @@ public: void FlatParent(); + // TODO: move to more appropriate place + //! Set value to be returned by receive() CBOT function + void SetInfoReturn(float value); + //! Return value to be returned by receive() CBOT function + float GetInfoReturn(); + bool GetTraceDown(); void SetTraceDown(bool bDown); int GetTraceColor(); @@ -498,10 +488,7 @@ protected: Math::Vector m_resetAngle; Program* m_resetRun; - int m_infoTotal; - Info m_info[OBJECTMAXINFO]; - float m_infoReturn; - bool m_bInfoUpdate; + float m_infoReturn; float m_cmdLine[OBJECTMAXCMDLINE]; }; diff --git a/src/object/object_create_params.h b/src/object/object_create_params.h new file mode 100644 index 00000000..05d2db25 --- /dev/null +++ b/src/object/object_create_params.h @@ -0,0 +1,38 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#pragma once + +#include "math/vector.h" + +#include "object/object_type.h" + +struct ObjectCreateParams +{ + Math::Vector pos; + float angle; + ObjectType type; + float power; + float zoom; + float height; + bool trainer; + bool toy; + int option; + int id; +}; diff --git a/src/object/object_factory.cpp b/src/object/object_factory.cpp index a72eb531..4489e29f 100644 --- a/src/object/object_factory.cpp +++ b/src/object/object_factory.cpp @@ -25,6 +25,7 @@ #include "graphics/engine/lightning.h" #include "object/brain.h" +#include "object/object_create_params.h" #include "object/robotmain.h" #include "object/auto/autobase.h" #include "object/auto/autoconvert.h" @@ -35,7 +36,6 @@ #include "object/auto/autofactory.h" #include "object/auto/autoflag.h" #include "object/auto/autohuston.h" -#include "object/auto/autoinfo.h" #include "object/auto/autojostle.h" #include "object/auto/autokid.h" #include "object/auto/autolabo.h" @@ -60,6 +60,7 @@ #include "object/motion/motiontoto.h" #include "object/motion/motionvehicle.h" #include "object/motion/motionworm.h" +#include "object/subclass/exchange_post.h" #include "math/geometry.h" @@ -84,6 +85,9 @@ CObjectUPtr CObjectFactory::CreateObject(const ObjectCreateParams& params) case OBJECT_NULL: return nullptr; + case OBJECT_INFO: + return CExchangePost::Create(params, m_modelManager, m_engine); + case OBJECT_PORTICO: case OBJECT_BASE: case OBJECT_DERRICK: @@ -96,7 +100,6 @@ CObjectUPtr CObjectFactory::CreateObject(const ObjectCreateParams& params) case OBJECT_NEST: case OBJECT_RESEARCH: case OBJECT_RADAR: - case OBJECT_INFO: case OBJECT_ENERGY: case OBJECT_LABO: case OBJECT_NUCLEAR: @@ -604,46 +607,6 @@ CObjectUPtr CObjectFactory::CreateBuilding(const ObjectCreateParams& params) obj->CreateShadowCircle(8.0f, 1.0f); } - if ( type == OBJECT_INFO ) - { - m_modelManager->AddModelReference("info1.mod", false, rank); - obj->SetPosition(0, pos); - obj->SetAngleY(0, angle); - obj->SetFloorHeight(0.0f); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); - obj->SetObjectRank(1, rank); - obj->SetObjectParent(1, 0); - m_modelManager->AddModelReference("info2.mod", false, rank); - obj->SetPosition(1, Math::Vector(0.0f, 5.0f, 0.0f)); - - for (int i=0 ; i<3 ; i++ ) - { - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); - obj->SetObjectRank(2+i*2, rank); - obj->SetObjectParent(2+i*2, 1); - m_modelManager->AddModelReference("info3.mod", false, rank); - obj->SetPosition(2+i*2, Math::Vector(0.0f, 4.5f, 0.0f)); - - rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); - obj->SetObjectRank(3+i*2, rank); - obj->SetObjectParent(3+i*2, 2+i*2); - m_modelManager->AddModelReference("radar4.mod", false, rank); - obj->SetPosition(3+i*2, Math::Vector(0.0f, 0.0f, -4.0f)); - - obj->SetAngleY(2+i*2, 2.0f*Math::PI/3.0f*i); - } - - obj->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f); - obj->CreateCrashSphere(Math::Vector(0.0f, 11.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f); - obj->SetGlobalSphere(Math::Vector(0.0f, 5.0f, 0.0f), 6.0f); - - obj->CreateShadowCircle(8.0f, 1.0f); - } - if ( type == OBJECT_ENERGY ) { m_modelManager->AddModelCopy("energy.mod", false, rank); @@ -3672,10 +3635,6 @@ void CObjectFactory::AddObjectAuto(CObject* obj) { objAuto.reset(new CAutoRadar(obj)); } - if ( type == OBJECT_INFO ) - { - objAuto.reset(new CAutoInfo(obj)); - } if ( type == OBJECT_ENERGY ) { objAuto.reset(new CAutoEnergy(obj)); diff --git a/src/object/object_factory.h b/src/object/object_factory.h index de1f7dde..8b4edaa8 100644 --- a/src/object/object_factory.h +++ b/src/object/object_factory.h @@ -39,23 +39,10 @@ class CTerrain; class CObject; class CRobotMain; +struct ObjectCreateParams; using CObjectUPtr = std::unique_ptr; -struct ObjectCreateParams -{ - Math::Vector pos; - float angle; - ObjectType type; - float power; - float zoom; - float height; - bool trainer; - bool toy; - int option; - int id; -}; - class CObjectFactory { public: diff --git a/src/object/object_manager.cpp b/src/object/object_manager.cpp index fcedd438..fd421d92 100644 --- a/src/object/object_manager.cpp +++ b/src/object/object_manager.cpp @@ -23,6 +23,7 @@ #include "math/all.h" #include "object/object.h" +#include "object/object_create_params.h" #include "object/object_factory.h" #include "object/auto/auto.h" diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp index cafd3cf4..b31d2b5f 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -68,6 +68,7 @@ #include "object/task/taskbuild.h" #include "object/task/taskmanip.h" #include "object/level/parser.h" +#include "object/subclass/exchange_post.h" #include "physics/physics.h" @@ -3545,26 +3546,10 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) m_engine->GetPyroManager()->Create(pType, obj); } - // Puts information in terminal (OBJECT_INFO). - for (int i = 0; i < OBJECTMAXINFO; i++) + if (type == OBJECT_INFO) { - std::string op = "info" + boost::lexical_cast(i+1); - if (!line->GetParam(op)->IsDefined()) break; - std::string text = line->GetParam(op)->AsString(); - std::size_t p = text.find_first_of("="); - if (p == std::string::npos) - throw CLevelParserExceptionBadParam(line->GetParam(op), "info"); - Info info; - strcpy(info.name, text.substr(0, p).c_str()); - try - { - info.value = boost::lexical_cast(text.substr(p+1).c_str()); - } - catch (...) - { - throw CLevelParserExceptionBadParam(line->GetParam(op), "info.value (float)"); - } - obj->SetInfo(i, info); + CExchangePost* exchangePost = static_cast(obj); + exchangePost->ReadInfo(line.get()); } // Sets the parameters of the command line. diff --git a/src/object/subclass/exchange_post.cpp b/src/object/subclass/exchange_post.cpp new file mode 100644 index 00000000..29b2dfca --- /dev/null +++ b/src/object/subclass/exchange_post.cpp @@ -0,0 +1,681 @@ +/* + * 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/subclass/exchange_post.h" + +#include "common/regex_utils.h" + +#include "graphics/engine/modelmanager.h" + +#include "object/object_create_params.h" +#include "object/level/parserline.h" +#include "object/level/parserparam.h" +#include "object/level/parserexceptions.h" + +#include "script/cmdtoken.h" + +#include "ui/interface.h" +#include "ui/list.h" +#include "ui/window.h" + +#include + + +CExchangePost::CExchangePost(int id) + : CObject(id) + , m_infoUpdate(false) +{ + m_type = OBJECT_INFO; +} + +std::unique_ptr CExchangePost::Create( + const ObjectCreateParams& params, + Gfx::CModelManager* modelManager, + Gfx::CEngine* engine) +{ + std::unique_ptr obj{new CExchangePost(params.id)}; + + int rank = engine->CreateObject(); + engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); // it is a stationary object + obj->SetObjectRank(0, rank); + + modelManager->AddModelReference("info1.mod", false, rank); + obj->SetPosition(0, params.pos); + obj->SetAngleY(0, params.angle); + obj->SetFloorHeight(0.0f); + + rank = engine->CreateObject(); + engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); + obj->SetObjectRank(1, rank); + obj->SetObjectParent(1, 0); + modelManager->AddModelReference("info2.mod", false, rank); + obj->SetPosition(1, Math::Vector(0.0f, 5.0f, 0.0f)); + + for (int i = 0; i < 3; ++i) + { + rank = engine->CreateObject(); + engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); + obj->SetObjectRank(2+i*2, rank); + obj->SetObjectParent(2+i*2, 1); + modelManager->AddModelReference("info3.mod", false, rank); + obj->SetPosition(2+i*2, Math::Vector(0.0f, 4.5f, 0.0f)); + + rank = engine->CreateObject(); + engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); + obj->SetObjectRank(3+i*2, rank); + obj->SetObjectParent(3+i*2, 2+i*2); + modelManager->AddModelReference("radar4.mod", false, rank); + obj->SetPosition(3+i*2, Math::Vector(0.0f, 0.0f, -4.0f)); + + obj->SetAngleY(2+i*2, 2.0f*Math::PI/3.0f*i); + } + + obj->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f); + obj->CreateCrashSphere(Math::Vector(0.0f, 11.0f, 0.0f), 6.0f, SOUND_BOUMm, 0.45f); + obj->SetGlobalSphere(Math::Vector(0.0f, 5.0f, 0.0f), 6.0f); + + obj->CreateShadowCircle(8.0f, 1.0f); + + Math::Vector pos = obj->GetPosition(0); + pos.y += params.height; + obj->SetPosition(0, pos); // to display the shadows immediately + + std::unique_ptr objAuto{new CAutoInfo(obj.get())}; + objAuto->Init(); + obj->SetAuto(std::move(objAuto)); + + engine->LoadAllTextures(); + + return obj; +} + +int CExchangePost::GetMaximumInfoListSize() +{ + return 10; +} + +bool CExchangePost::SetInfo(const std::string& name, float value) +{ + for (auto& info : m_infoList) + { + if (info.name == name) + { + info.value = value; + return true; + } + } + + if (static_cast(m_infoList.size()) == GetMaximumInfoListSize()) + { + return false; + } + + ExchangePostInfo info; + info.name = name; + info.value = value; + m_infoList.push_back(info); + return true; +} + +const std::vector& CExchangePost::GetInfoList() +{ + return m_infoList; +} + +boost::optional CExchangePost::GetInfoValue(const std::string& name) +{ + for (auto& info : m_infoList) + { + if (info.name == name) + { + return info.value; + } + } + return boost::none; +} + +bool CExchangePost::HasInfo(const std::string& name) +{ + for (auto& info : m_infoList) + { + if (info.name == name) + { + return true; + } + } + return false; +} + +bool CExchangePost::DeleteInfo(const std::string& name) +{ + for (auto it = m_infoList.begin(); it != m_infoList.end(); ++it) + { + if (it->name == name) + { + m_infoList.erase(it); + return true; + } + } + return false; +} + +bool CExchangePost::GetInfoUpdate() +{ + return m_infoUpdate; +} + +void CExchangePost::SetInfoUpdate(bool update) +{ + m_infoUpdate = update; +} + +void CExchangePost::Write(CLevelParserLine* line) +{ + CObject::Write(line); + + int i = 0; + for (const auto& info : m_infoList) + { + ++i; + if (info.name.empty()) + { + auto key = "info" + boost::lexical_cast(i); + auto paramValue = info.name + "=" + boost::lexical_cast(info.value); + line->AddParam(key, CLevelParserParamUPtr{new CLevelParserParam(paramValue)}); + } + } +} + +void CExchangePost::Read(CLevelParserLine* line) +{ + CObject::Read(line); + + ReadInfo(line); +} + +void CExchangePost::ReadInfo(CLevelParserLine* line) +{ + for (int i = 1; i <= GetMaximumInfoListSize(); i++) + { + std::string op = std::string("info") + boost::lexical_cast(i); + + if (!line->GetParam(op)->IsDefined()) + break; + + std::string text = line->GetParam(op)->AsString(); + + ExchangePostInfo info; + + try + { + auto matches = RegexUtils::AssertRegexMatch(text, "([^=]+)=(.*)"); + info.name = matches[1]; + info.value = boost::lexical_cast(matches[2]); + } + catch (...) + { + throw CLevelParserExceptionBadParam(line->GetParam(op), op); + } + + + m_infoList.push_back(info); + } +} + +////////////////// + +enum class CAutoInfo::Phase : unsigned int +{ + Wait = 1, + Send = 2, + Receive = 3, + Error = 4, +}; + +// Object's constructor. + +CAutoInfo::CAutoInfo(CExchangePost* object) + : CAuto(object) + , m_exchangePost(object) +{ + Init(); +} + +CAutoInfo::~CAutoInfo() +{ +} + +void CAutoInfo::DeleteObject(bool all) +{ + CAuto::DeleteObject(all); +} + + +void CAutoInfo::Init() +{ + m_phase = Phase::Wait; + m_time = 0.0f; + m_timeVirus = 0.0f; + m_lastVirus = false; + + CAuto::Init(); +} + +void CAutoInfo::Start(int param) +{ + if (param == 0) // instruction "receive" ? + { + m_phase = Phase::Send; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + else if (param == 2) // instruction "send" ? + { + m_phase = Phase::Receive; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + else + { + m_phase = Phase::Error; + m_progress = 0.0f; + m_speed = 1.0f/2.0f; + } + + m_lastParticle = 0; + m_goal = m_object->GetPosition(0); + + Math::Vector pos, speed; + Math::Point dim; + + if (m_phase == Phase::Send) + { + pos = m_goal; + pos.y += 9.5f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 30.0f; + dim.y = dim.x; + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISPHERE4, 1.5f, 0.0f, 0.0f); + + m_sound->Play(SOUND_LABO, pos, 1.0f, 2.0f); + } + if (m_phase == Phase::Receive) + { + pos = m_goal; + pos.y += 9.5f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 50.0f; + dim.y = dim.x; + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISPHERE6, 1.5f, 0.0f, 0.0f); + + m_sound->Play(SOUND_LABO, pos, 1.0f, 2.0f); + } + if (m_phase == Phase::Error) + { + m_sound->Play(SOUND_GGG, pos, 1.0f, 0.5f); + } +} + +bool CAutoInfo::EventProcess(const Event &event) +{ + CAuto::EventProcess(event); + + if (m_engine->GetPause()) return true; + if (event.type != EVENT_FRAME) return true; + + m_timeVirus -= event.rTime; + + if (m_exchangePost->GetVirusMode()) // contaminated by a virus? + { + if (m_timeVirus <= 0.0f) + { + m_timeVirus = 0.1f+Math::Rand()*0.3f; + + float angle = m_exchangePost->GetAngleY(1); + angle += Math::Rand()*0.3f; + m_exchangePost->SetAngleY(1, angle); + + m_exchangePost->SetAngleX(2, (Math::Rand()-0.5f)*0.3f); + m_exchangePost->SetAngleX(4, (Math::Rand()-0.5f)*0.3f); + m_exchangePost->SetAngleX(6, (Math::Rand()-0.5f)*0.3f); + + m_exchangePost->SetAngleZ(2, (Math::Rand()-0.5f)*0.3f); + m_exchangePost->SetAngleZ(4, (Math::Rand()-0.5f)*0.3f); + m_exchangePost->SetAngleZ(6, (Math::Rand()-0.5f)*0.3f); + + UpdateListVirus(); + } + m_lastVirus = true; + return true; + } + else + { + if (m_lastVirus) + { + m_lastVirus = false; + UpdateList(); // normally returns the list + } + else + { + if (m_exchangePost->GetInfoUpdate()) + { + UpdateList(); // updates the list + } + } + } + + UpdateInterface(event.rTime); + + float rTime = event.rTime; + + if (m_phase == Phase::Send) // instruction "receive" ? + { + if (m_progress < 0.5f && + m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time) + { + m_lastParticle = m_time; + + for (int i = 0; i < 4; i++) + { + Math::Vector pos = m_goal; + pos.y += 9.5f; + Math::Vector speed; + speed.x = (Math::Rand()-0.5f)*50.0f; + speed.z = (Math::Rand()-0.5f)*50.0f; + speed.y = (Math::Rand()-0.5f)*50.0f; + speed *= 0.5f+m_progress*0.5f; + Math::Point dim(0.6f, 0.6f); + float duration = Math::Rand()*0.5f+0.5f; + m_particle->CreateTrack(pos, speed, dim, Gfx::PARTITRACK6, + duration, 0.0f, + duration*0.9f, 0.7f); + } + } + + if (m_progress < 1.0f) + { + m_progress += rTime*m_speed; + + m_exchangePost->SetAngleZ(2, m_progress*2.0f*Math::PI); + m_exchangePost->SetAngleZ(4, m_progress*2.0f*Math::PI); + m_exchangePost->SetAngleZ(6, m_progress*2.0f*Math::PI); + } + else + { + m_phase = Phase::Wait; + + m_exchangePost->SetAngleX(2, 0.0f); + m_exchangePost->SetAngleX(4, 0.0f); + m_exchangePost->SetAngleX(6, 0.0f); + + m_exchangePost->SetAngleZ(2, 0.0f); + m_exchangePost->SetAngleZ(4, 0.0f); + m_exchangePost->SetAngleZ(6, 0.0f); + } + } + + if (m_phase == Phase::Receive) // instruction "send" ? + { + if (m_progress < 0.5f && + m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time) + { + m_lastParticle = m_time; + + for (int i = 0; i < 4; i++) + { + Math::Vector pos = m_goal; + pos.y += 9.5f; + Math::Vector speed = pos; + pos.x += (Math::Rand()-0.5f)*40.0f; + pos.y += (Math::Rand()-0.5f)*40.0f; + pos.z += (Math::Rand()-0.5f)*40.0f; + speed = (speed-pos)*1.0f; +//? speed *= 0.5f+m_progress*0.5f; + Math::Point dim(0.6f, 0.6f); + float duration = Math::Rand()*0.5f+0.5f; + m_particle->CreateTrack(pos, speed, dim, Gfx::PARTITRACK6, + duration, 0.0f, + duration*0.9f, 0.7f); + } + } + + if (m_progress < 1.0f) + { + m_progress += rTime*m_speed; + + m_exchangePost->SetAngleZ(2, m_progress*2.0f*Math::PI); + m_exchangePost->SetAngleZ(4, m_progress*2.0f*Math::PI); + m_exchangePost->SetAngleZ(6, m_progress*2.0f*Math::PI); + } + else + { + m_phase = Phase::Wait; + + m_exchangePost->SetAngleX(2, 0.0f); + m_exchangePost->SetAngleX(4, 0.0f); + m_exchangePost->SetAngleX(6, 0.0f); + + m_exchangePost->SetAngleZ(2, 0.0f); + m_exchangePost->SetAngleZ(4, 0.0f); + m_exchangePost->SetAngleZ(6, 0.0f); + } + } + + if ( m_phase == Phase::Error ) + { + if (m_progress < 0.5f && + m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time) + { + m_lastParticle = m_time; + + Math::Vector pos = m_goal; + Math::Vector speed; + speed.x = (Math::Rand()-0.5f)*5.0f; + speed.z = (Math::Rand()-0.5f)*5.0f; + speed.y = 5.0f+Math::Rand()*5.0f; + Math::Point dim; + dim.x = 5.0f+Math::Rand()*5.0f; + dim.y = dim.x; + float duration = 4.0f; + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE1, duration); + } + + if (m_progress < 1.0f) + { + m_progress += rTime*m_speed; + rTime = 0.0f; // stops the rotation + + float angle = 0.0f; + if ( m_progress < 0.5f ) + { + angle = m_progress/0.5f; + } + else + { + angle = 1.0f-(m_progress-0.5f)/0.5f; + } + m_exchangePost->SetAngleX(2, angle*0.5f); + m_exchangePost->SetAngleX(4, angle*0.5f); + m_exchangePost->SetAngleX(6, angle*0.5f); + + m_exchangePost->SetAngleZ(2, (Math::Rand()-0.5f)*0.2f); + m_exchangePost->SetAngleZ(4, (Math::Rand()-0.5f)*0.2f); + m_exchangePost->SetAngleZ(6, (Math::Rand()-0.5f)*0.2f); + } + else + { + m_phase = Phase::Wait; + + m_exchangePost->SetAngleX(2, 0.0f); + m_exchangePost->SetAngleX(4, 0.0f); + m_exchangePost->SetAngleX(6, 0.0f); + + m_exchangePost->SetAngleZ(2, 0.0f); + m_exchangePost->SetAngleZ(4, 0.0f); + m_exchangePost->SetAngleZ(6, 0.0f); + } + } + + float angle = m_exchangePost->GetAngleY(1); + angle += rTime*0.5f; + m_exchangePost->SetAngleY(1, angle); + + m_exchangePost->SetAngleX(3, sinf(m_time*6.0f+Math::PI*0.0f/3.0f)*0.3f); + m_exchangePost->SetAngleX(5, sinf(m_time*6.0f+Math::PI*2.0f/3.0f)*0.3f); + m_exchangePost->SetAngleX(7, sinf(m_time*6.0f+Math::PI*4.0f/3.0f)*0.3f); + + return true; +} + +Error CAutoInfo::GetError() +{ + if (m_object->GetVirusMode()) + { + return ERR_BAT_VIRUS; + } + + return ERR_OK; +} + +bool CAutoInfo::CreateInterface(bool select) +{ + CAuto::CreateInterface(select); + + if (!select) return true; + + Ui::CWindow* pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); + if (pw == nullptr) return false; + + float ox = 3.0f/640.0f; + float oy = 3.0f/480.0f; + float sx = 33.0f/640.0f; + float sy = 33.0f/480.0f; + + Math::Point pos, ddim; + + pos.x = ox+sx*7.0f; + pos.y = oy+sy*0.0f; + ddim.x = 160.0f/640.0f; + ddim.y = 66.0f/480.0f; + Ui::CList* pl = pw->CreateList(pos, ddim, 1, EVENT_OBJECT_GINFO, 1.10f); + pl->SetSelectCap(false); + + pos.x = ox+sx*0.0f; + pos.y = oy+sy*0; + ddim.x = 66.0f/640.0f; + ddim.y = 66.0f/480.0f; + pw->CreateGroup(pos, ddim, 112, EVENT_OBJECT_TYPE); + + UpdateList(); + return true; +} + +void CAutoInfo::UpdateInterface(float rTime) +{ + CAuto::UpdateInterface(rTime); +} + +void CAutoInfo::UpdateList() +{ + CExchangePost* object = static_cast(m_object); + + Ui::CWindow* pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); + if (pw == nullptr) return; + + Ui::CList* pl = static_cast< Ui::CList* >(pw->SearchControl(EVENT_OBJECT_GINFO)); + if (pl == nullptr) return; + + pl->Flush(); + const auto& infoList = object->GetInfoList(); + if (infoList.empty()) + { + pl->ClearState(Ui::STATE_ENABLE); + } + else + { + pl->SetState(Ui::STATE_ENABLE); + + for (int i = 0; i < static_cast(infoList.size()); i++) + { + char text[100]; + sprintf(text, "%s = %.2f", infoList[i].name.c_str(), infoList[i].value); + pl->SetItemName(i, text); + } + } + + object->SetInfoUpdate(false); +} + +void CAutoInfo::UpdateListVirus() +{ + Ui::CWindow* pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); + if (pw == nullptr) return; + + Ui::CList* pl = static_cast< Ui::CList* >(pw->SearchControl(EVENT_OBJECT_GINFO)); + if (pl == nullptr) return; + + pl->SetState(Ui::STATE_ENABLE); + + pl->Flush(); + for (int i = 0; i < 4; ++i) + { + char text[100]; + int max = static_cast< int >(2.0f+Math::Rand()*10.0f); + for (int j = 0; j < max; ++j) + { + do + { + text[j] = ' '+static_cast(Math::Rand()*94.0f); + } + while (text[j] == '\\'); + } + text[max] = 0; + + pl->SetItemName(i, text); + } +} + +bool CAutoInfo::Write(CLevelParserLine* line) +{ + if (m_phase == Phase::Wait) + return false; + + line->AddParam("aExist", CLevelParserParamUPtr{new CLevelParserParam(true)}); + CAuto::Write(line); + line->AddParam("aPhase", CLevelParserParamUPtr{new CLevelParserParam(static_cast(m_phase))}); + line->AddParam("aProgress", CLevelParserParamUPtr{new CLevelParserParam(m_progress)}); + line->AddParam("aSpeed", CLevelParserParamUPtr{new CLevelParserParam(m_speed)}); + + return true; +} + +bool CAutoInfo::Read(CLevelParserLine* line) +{ + if (!line->GetParam("aExist")->AsBool(false)) + return false; + + CAuto::Read(line); + m_phase = static_cast(line->GetParam("aPhase")->AsInt(static_cast(Phase::Wait))); + m_progress = line->GetParam("aProgress")->AsFloat(0.0f); + m_speed = line->GetParam("aSpeed")->AsFloat(1.0f); + + m_lastParticle = 0.0f; + + return true; +} diff --git a/src/object/subclass/exchange_post.h b/src/object/subclass/exchange_post.h new file mode 100644 index 00000000..a04664c0 --- /dev/null +++ b/src/object/subclass/exchange_post.h @@ -0,0 +1,110 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsiteс.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + + +#pragma once + +#include "object/object.h" +#include "object/auto/auto.h" + +#include +#include + +#include + +struct ExchangePostInfo +{ + std::string name; //!< name of the information + float value = 0.0f; //!< value of the information +}; + +struct ObjectCreateParams; + +namespace Gfx { +class CModelManager; +class CEngine; +} + +class CExchangePost : public CObject +{ +public: + CExchangePost(int id); + + static std::unique_ptr Create( + const ObjectCreateParams& params, + Gfx::CModelManager* modelManager, + Gfx::CEngine* engine); + + static int GetMaximumInfoListSize(); + + bool SetInfo(const std::string& name, float value); + const std::vector& GetInfoList(); + boost::optional GetInfoValue(const std::string& name); + bool HasInfo(const std::string& name); + bool DeleteInfo(const std::string& name); + + void SetInfoUpdate(bool update); + bool GetInfoUpdate(); + + void Write(CLevelParserLine* line) override; + void Read(CLevelParserLine* line) override; + + void ReadInfo(CLevelParserLine* line); + +private: + std::vector m_infoList; + float m_infoReturn; + bool m_infoUpdate; +}; + +// TODO: integrate this with CExchangePost +class CAutoInfo : public CAuto +{ +public: + CAutoInfo(CExchangePost* object); + ~CAutoInfo(); + + void DeleteObject(bool all=false) override; + + void Init() override; + void Start(int param) override; + bool EventProcess(const Event &event) override; + Error GetError() override; + + bool CreateInterface(bool select) override; + + bool Write(CLevelParserLine* line) override; + bool Read(CLevelParserLine* line) override; + +protected: + void UpdateInterface(float rTime); + void UpdateList(); + void UpdateListVirus(); + +protected: + CExchangePost* m_exchangePost; + enum class Phase : unsigned int; + Phase m_phase; + float m_progress; + float m_speed; + float m_timeVirus; + float m_lastParticle; + Math::Vector m_goal; + bool m_lastVirus; +}; diff --git a/src/object/task/taskinfo.cpp b/src/object/task/taskinfo.cpp index 762f7157..dbe45445 100644 --- a/src/object/task/taskinfo.cpp +++ b/src/object/task/taskinfo.cpp @@ -23,7 +23,7 @@ #include "graphics/engine/particle.h" #include "object/object_manager.h" -#include "object/auto/autoinfo.h" +#include "object/subclass/exchange_post.h" #include @@ -32,6 +32,10 @@ // Object's constructor. CTaskInfo::CTaskInfo(CObject* object) : CTask(object) + , m_progress(0.0f) + , m_speed(0.0f) + , m_time(0.0f) + , m_error(false) { } @@ -46,9 +50,9 @@ CTaskInfo::~CTaskInfo() bool CTaskInfo::EventProcess(const Event &event) { - if ( m_engine->GetPause() ) return true; - if ( event.type != EVENT_FRAME ) return true; - if ( m_bError ) return false; + if (m_engine->GetPause()) return true; + if (event.type != EVENT_FRAME) return true; + if (m_error) return false; m_progress += event.rTime*m_speed; // other advance m_time += event.rTime; @@ -59,89 +63,50 @@ bool CTaskInfo::EventProcess(const Event &event) // Assigns the goal was achieved. -Error CTaskInfo::Start(const char *name, float value, float power, bool bSend) +Error CTaskInfo::Start(const char *name, float value, float power, bool send) { - CObject* pInfo; - CAutoInfo* pAuto; - Math::Vector pos, goal; - Info info; - int i, total, op; - - m_bError = true; + m_error = true; m_object->SetInfoReturn(NAN); - pInfo = SearchInfo(power); // seeks terminal - if ( pInfo == 0 ) + CExchangePost* exchangePost = FindExchangePost(power); + if (exchangePost == nullptr) { return ERR_INFO_NULL; } - pAuto = static_cast(pInfo->GetAuto()); - if ( pAuto == 0 ) + int op = 1; // transmission impossible + if (send) // send? { - return ERR_INFO_NULL; - } - - op = 1; // transmission impossible - if ( bSend ) // send? - { - total = pInfo->GetInfoTotal(); - for ( i=0 ; iGetInfo(i); - if ( strcmp(info.name, name) == 0 ) - { - info.value = value; - pInfo->SetInfo(i, info); - break; - } - } - if ( i == total ) - { - if ( total < OBJECTMAXINFO ) - { - strcpy(info.name, name); - info.value = value; - pInfo->SetInfo(total, info); - op = 2; // start of reception (for terminal) - } - } - else + bool infoValueSet = exchangePost->SetInfo(name, value); + if (infoValueSet) { op = 2; // start of reception (for terminal) } } else // receive? { - total = pInfo->GetInfoTotal(); - for ( i=0 ; iGetInfo(i); - if ( strcmp(info.name, name) == 0 ) - { - m_object->SetInfoReturn(info.value); - break; - } - } - if ( i < total ) + auto infoValue = exchangePost->GetInfoValue(name); + if (infoValue != boost::none) { + m_object->SetInfoReturn(*infoValue); op = 0; // beginning of transmission (for terminal) } } - pAuto->Start(op); + exchangePost->GetAuto()->Start(op); - if ( op == 0 ) // transmission? + Math::Vector pos, goal; + if (op == 0) // transmission? { - pos = pInfo->GetPosition(0); + pos = exchangePost->GetPosition(0); pos.y += 9.5f; goal = m_object->GetPosition(0); goal.y += 4.0f; m_particle->CreateRay(pos, goal, Gfx::PARTIRAY3, Math::Point(2.0f, 2.0f), 1.0f); } - if ( op == 2 ) // reception? + if (op == 2) // reception? { - goal = pInfo->GetPosition(0); + goal = exchangePost->GetPosition(0); goal.y += 9.5f; pos = m_object->GetPosition(0); pos.y += 4.0f; @@ -149,10 +114,10 @@ Error CTaskInfo::Start(const char *name, float value, float power, bool bSend) } m_progress = 0.0f; - m_speed = 1.0f/1.0f; + m_speed = 1.0f; m_time = 0.0f; - m_bError = false; // ok + m_error = false; // ok return ERR_OK; } @@ -161,10 +126,10 @@ Error CTaskInfo::Start(const char *name, float value, float power, bool bSend) Error CTaskInfo::IsEnded() { - if ( m_engine->GetPause() ) return ERR_CONTINUE; - if ( m_bError ) return ERR_STOP; + if (m_engine->GetPause()) return ERR_CONTINUE; + if (m_error) return ERR_STOP; - if ( m_progress < 1.0f ) return ERR_CONTINUE; + if (m_progress < 1.0f) return ERR_CONTINUE; m_progress = 0.0f; Abort(); @@ -181,8 +146,9 @@ bool CTaskInfo::Abort() // Seeks the nearest information terminal. -CObject* CTaskInfo::SearchInfo(float power) +CExchangePost* CTaskInfo::FindExchangePost(float power) { - return CObjectManager::GetInstancePointer()->FindNearest(m_object, OBJECT_INFO, power/g_unit); + return dynamic_cast( + CObjectManager::GetInstancePointer()->FindNearest(m_object, OBJECT_INFO, power/g_unit)); } diff --git a/src/object/task/taskinfo.h b/src/object/task/taskinfo.h index 5fdb9741..c1fc0321 100644 --- a/src/object/task/taskinfo.h +++ b/src/object/task/taskinfo.h @@ -24,7 +24,7 @@ #include "object/task/task.h" - +class CExchangePost; class CTaskInfo : public CTask { @@ -32,19 +32,19 @@ public: CTaskInfo(CObject* object); ~CTaskInfo(); - bool EventProcess(const Event &event); + bool EventProcess(const Event &event) override; - Error Start(const char *name, float value, float power, bool bSend); - Error IsEnded(); - bool Abort(); + Error Start(const char *name, float value, float power, bool send); + Error IsEnded() override; + bool Abort() override; protected: - CObject* SearchInfo(float power); + CExchangePost* FindExchangePost(float power); protected: float m_progress; float m_speed; float m_time; - bool m_bError; + bool m_error; }; diff --git a/src/script/scriptfunc.cpp b/src/script/scriptfunc.cpp index ee6c437f..02b24456 100644 --- a/src/script/scriptfunc.cpp +++ b/src/script/scriptfunc.cpp @@ -37,6 +37,7 @@ #include "object/object_manager.h" #include "object/robotmain.h" #include "object/task/taskmanager.h" +#include "object/subclass/exchange_post.h" #include "object/auto/auto.h" #include "object/auto/autofactory.h" @@ -2395,24 +2396,13 @@ bool CScriptFunctions::rSend(CBotVar* var, CBotVar* result, int& exception, void // Seeks the nearest information terminal. -CObject* CScriptFunctions::SearchInfo(CScript* script, CObject* object, float power) +CExchangePost* CScriptFunctions::FindExchangePost(CObject* object, float power) { - CObject *pBest; - Math::Vector iPos, oPos; - - iPos = object->GetPosition(0); - pBest = CObjectManager::GetInstancePointer()->Radar(object, OBJECT_INFO); - if (pBest == nullptr) - return nullptr; - oPos = object->GetPosition(0); - - if (Math::DistanceProjected(iPos, oPos) > power) - return nullptr; - - return pBest; + CObject* exchangePost = CObjectManager::GetInstancePointer()->FindNearest(object, OBJECT_INFO, power/g_unit); + return dynamic_cast(exchangePost); } -// Compilation of the instruction "deleteinfo(nom, power)". +// Compilation of the instruction "deleteinfo(name, power)". CBotTypResult CScriptFunctions::cDeleteInfo(CBotVar* &var, void* user) { @@ -2420,59 +2410,43 @@ CBotTypResult CScriptFunctions::cDeleteInfo(CBotVar* &var, void* user) if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); var = var->GetNext(); - if ( var == 0 ) return CBotTypResult(CBotTypFloat); + if ( var == 0 ) return CBotTypResult(CBotTypBoolean); if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); - return CBotTypResult(CBotTypFloat); + return CBotTypResult(CBotTypBoolean); } -// Instruction "deleteinfo(nom, power)". +// Instruction "deleteinfo(name, power)". bool CScriptFunctions::rDeleteInfo(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - CObject* pInfo; - CBotString cbs; - Info info; - const char* p; - float power; - int i, total; + CObject* pThis = static_cast(user); exception = 0; - cbs = var->GetValString(); - p = cbs; + CBotString infoNameCbs = var->GetValString(); + std::string infoName = std::string(static_cast(infoNameCbs)); var = var->GetNext(); - power = 10.0f*g_unit; - if ( var != 0 ) + float power = 10.0f*g_unit; + if (var != nullptr) { power = var->GetValFloat()*g_unit; var = var->GetNext(); } - pInfo = SearchInfo(script, pThis, power); - if ( pInfo == 0 ) + CExchangePost* exchangePost = FindExchangePost(pThis, power); + if (exchangePost == nullptr) { - result->SetValFloat(0.0f); // false + result->SetValInt(false); return true; } - total = pInfo->GetInfoTotal(); - for ( i=0 ; iGetInfo(i); - if ( strcmp(info.name, p) == 0 ) - { - pInfo->DeleteInfo(i); - result->SetValFloat(1.0f); // true - return true; - } - } - result->SetValFloat(0.0f); // false + bool infoDeleted = exchangePost->DeleteInfo(infoName); + result->SetValInt(infoDeleted); + return true; } @@ -2492,50 +2466,34 @@ CBotTypResult CScriptFunctions::cTestInfo(CBotVar* &var, void* user) return CBotTypResult(CBotTypBoolean); } -// Instruction "testinfo(nom, power)". +// Instruction "testinfo(name, power)". bool CScriptFunctions::rTestInfo(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = (static_cast(user))->GetRunScript(); - CObject* pThis = static_cast(user); - CObject* pInfo; - CBotString cbs; - Info info; - const char* p; - float power; - int i, total; + CObject* pThis = static_cast(user); exception = 0; - cbs = var->GetValString(); - p = cbs; + CBotString infoNameCbs = var->GetValString(); + std::string infoName = std::string(static_cast(infoNameCbs)); var = var->GetNext(); - power = 10.0f*g_unit; - if ( var != 0 ) + float power = 10.0f*g_unit; + if (var != nullptr) { power = var->GetValFloat()*g_unit; var = var->GetNext(); } - pInfo = SearchInfo(script, pThis, power); - if ( pInfo == 0 ) + CExchangePost* exchangePost = FindExchangePost(pThis, power); + if (exchangePost == nullptr) { result->SetValInt(false); return true; } - total = pInfo->GetInfoTotal(); - for ( i=0 ; iGetInfo(i); - if ( strcmp(info.name, p) == 0 ) - { - result->SetValInt(true); - return true; - } - } - result->SetValInt(false); + bool foundInfo = exchangePost->HasInfo(infoName); + result->SetValInt(foundInfo); return true; } @@ -4009,4 +3967,4 @@ void CScriptFunctions::Init() CBotProgram::AddFunction("canbuild", rCanBuild, CScriptFunctions::cCanBuild); CBotProgram::AddFunction("build", rBuild, CScriptFunctions::cOneFloat); -} \ No newline at end of file +} diff --git a/src/script/scriptfunc.h b/src/script/scriptfunc.h index ef9e8d59..3160a6e2 100644 --- a/src/script/scriptfunc.h +++ b/src/script/scriptfunc.h @@ -30,9 +30,10 @@ #include #include - + class CObject; class CScript; +class CExchangePost; class CScriptFunctions @@ -75,8 +76,8 @@ private: static CBotTypResult cOnePoint(CBotVar* &var, void* user); static CBotTypResult cPoint(CBotVar* &var, void* user); static CBotTypResult cOneObject(CBotVar* &var, void* user); - - + + static bool rSin(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rCos(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rTan(CBotVar* var, CBotVar* result, int& exception, void* user); @@ -144,20 +145,20 @@ private: static bool rPenColor(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rPenWidth(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rCameraFocus(CBotVar* var, CBotVar* result, int& exception, void* user); - - + + static CBotTypResult cBusy(CBotVar* thisclass, CBotVar* &var); static CBotTypResult cFactory(CBotVar* thisclass, CBotVar* &var); static CBotTypResult cClassNull(CBotVar* thisclass, CBotVar* &var); static CBotTypResult cClassOneFloat(CBotVar* thisclass, CBotVar* &var); - + static bool rBusy(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception); static bool rFactory(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception); static bool rResearch(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception); static bool rTakeOff(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception); static bool rDestroy(CBotVar* thisclass, CBotVar* var, CBotVar* result, int& exception); - - + + static CBotTypResult cfconstruct (CBotVar* pThis, CBotVar* &pVar); static CBotTypResult cfopen (CBotVar* pThis, CBotVar* &pVar); static CBotTypResult cfclose (CBotVar* pThis, CBotVar* &pVar); @@ -171,18 +172,18 @@ private: static bool rfwrite (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); static bool rfread (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); static bool rfeof (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception); - + static CBotTypResult cPointConstructor(CBotVar* pThis, CBotVar* &var); static bool rPointConstructor(CBotVar* pThis, CBotVar* var, CBotVar* pResult, int& Exception); - + public: static int m_CompteurFileOpen; static std::string m_filesDir; - + private: static bool Process(CScript* script, CBotVar* result, int &exception); static bool ShouldProcessStop(Error err, int errMode); - static CObject* SearchInfo(CScript* script, CObject* object, float power); + static CExchangePost* FindExchangePost(CObject* object, float power); static std::unordered_map m_files; static int m_nextFile;