Merge branch 'dev' into dev-fix-macos-compilation

fix-squashed-planets
tomangelo2 2022-11-05 19:27:52 +01:00
commit 0e53336d61
33 changed files with 206 additions and 159 deletions

View File

@ -14,7 +14,7 @@ jobs:
fail-fast: false fail-fast: false
steps: steps:
- name: Install Colobot dependencies - name: Install Colobot dependencies
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends build-essential cmake libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsndfile1-dev libvorbis-dev libogg-dev libpng-dev libglew-dev libopenal-dev libboost-dev libboost-system-dev libboost-filesystem-dev libboost-regex-dev libphysfs-dev gettext git po4a vorbis-tools librsvg2-bin xmlstarlet run: sudo apt-get update && sudo apt-get install -y --no-install-recommends build-essential cmake libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsndfile1-dev libvorbis-dev libogg-dev libpng-dev libglew-dev libopenal-dev libboost-dev libboost-system-dev libboost-filesystem-dev libboost-regex-dev libphysfs-dev gettext git po4a vorbis-tools librsvg2-bin xmlstarlet libmpg123-dev
if: matrix.container == '' if: matrix.container == ''
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Checkout the Google Test submodule - name: Checkout the Google Test submodule
@ -134,11 +134,11 @@ jobs:
- name: Install Colobot dependencies - name: Install Colobot dependencies
uses: lukka/run-vcpkg@v7 uses: lukka/run-vcpkg@v7
with: with:
vcpkgGitCommitId: '210240b399fbc2f1363f4103b6a93629c207d7e3' vcpkgGitCommitId: 'e809a42f87565e803b2178a0c11263f462d1800a'
vcpkgTriplet: ${{ matrix.vcpkg_triplet }} vcpkgTriplet: ${{ matrix.vcpkg_triplet }}
vcpkgArguments: 'boost-system boost-filesystem boost-regex boost-lexical-cast boost-bimap boost-algorithm boost-property-tree boost-optional boost-range sdl2 sdl2-ttf sdl2-image glew libpng libwebp tiff gettext libsndfile libvorbis libogg openal-soft physfs' vcpkgArguments: 'boost-system boost-filesystem boost-regex boost-lexical-cast boost-bimap boost-algorithm boost-property-tree boost-optional boost-range sdl2 sdl2-ttf sdl2-image glew libpng libwebp tiff gettext libsndfile libvorbis libogg openal-soft physfs mpg123'
# SHA-256 hash of the list of packages above, for caching purposes # SHA-256 hash of the list of packages above, for caching purposes
appendedCacheKey: '35754367e6e6b4fb1b1ec24fa631e5234548fa1f9a59e4f2d80d2174a3a4e1b5' appendedCacheKey: '84402d9834b06a1b571e0fda32a791915777d47a394a1469d4773322bd71614b'
- name: Install external tools - name: Install external tools
working-directory: ${{ github.workspace }} working-directory: ${{ github.workspace }}
run: | run: |
@ -194,7 +194,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Install Colobot dependencies - name: Install Colobot dependencies
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends build-essential cmake libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsndfile1-dev libvorbis-dev libogg-dev libpng-dev libglew-dev libopenal-dev libboost-dev libboost-system-dev libboost-filesystem-dev libboost-regex-dev libphysfs-dev gettext git po4a vorbis-tools librsvg2-bin xmlstarlet doxygen graphviz run: sudo apt-get update && sudo apt-get install -y --no-install-recommends build-essential cmake libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev libsndfile1-dev libvorbis-dev libogg-dev libpng-dev libglew-dev libopenal-dev libboost-dev libboost-system-dev libboost-filesystem-dev libboost-regex-dev libphysfs-dev gettext git po4a vorbis-tools librsvg2-bin xmlstarlet doxygen graphviz libmpg123-dev
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Create build directory - name: Create build directory
run: cmake -E make_directory build run: cmake -E make_directory build

View File

@ -329,8 +329,11 @@ find_package(GLEW REQUIRED)
if (OPENAL_SOUND) if (OPENAL_SOUND)
find_package(OpenAL REQUIRED) find_package(OpenAL REQUIRED)
endif() endif()
find_package(SndFile REQUIRED) find_package(SndFile REQUIRED)
find_package(mpg123 QUIET)
find_package(mp3lame QUIET)
if(NOT ASSERTS) if(NOT ASSERTS)
add_definitions(-DNDEBUG) add_definitions(-DNDEBUG)

View File

@ -86,7 +86,7 @@ msgid "Access to solution\\Shows the solution (detailed instructions for mission
msgstr "Dostęp do rozwiązania\\Pokazuje rozwiązanie (szczegółowe instrukcje dotyczące misji)" msgstr "Dostęp do rozwiązania\\Pokazuje rozwiązanie (szczegółowe instrukcje dotyczące misji)"
msgid "Access to solutions\\Show program \"4: Solution\" in the exercises" msgid "Access to solutions\\Show program \"4: Solution\" in the exercises"
msgstr "Accčs aux solutions\\Programme \"4: Solution\" dans les exercices" msgstr "Dostęp do rozwiązań\\Pokaż program \"4: Rozwiązanie\" w ćwiczeniach"
msgid "Add new program" msgid "Add new program"
msgstr "Dodaj nowy program" msgstr "Dodaj nowy program"

View File

@ -23,6 +23,8 @@
#include "CBot/CBotVar/CBotVar.h" #include "CBot/CBotVar/CBotVar.h"
#include <cmath>
namespace CBot namespace CBot
{ {
@ -41,9 +43,9 @@ bool CBotExprLitNan::Execute(CBotStack* &pj)
CBotStack* pile = pj->AddStack(this); CBotStack* pile = pj->AddStack(this);
if (pile->IfStep()) return false; if (pile->IfStep()) return false;
CBotVar* var = CBotVar::Create("", CBotTypInt); CBotVar* var = CBotVar::Create("", CBotTypFloat);
var->SetInit(CBotVar::InitType::IS_NAN); // nan var->SetValFloat(nanf(""));
pile->SetVar(var); // put on the stack pile->SetVar(var); // put on the stack
return pj->Return(pile); // forward below return pj->Return(pile); // forward below
} }

View File

@ -206,12 +206,6 @@ bool CBotExpression::Execute(CBotStack* &pj)
if (m_token.GetType() != ID_ASS) if (m_token.GetType() != ID_ASS)
{ {
pVar = pile1->GetVar(); // recovers if interrupted pVar = pile1->GetVar(); // recovers if interrupted
initKind = pVar->GetInit();
if (initKind == CBotVar::InitType::IS_NAN)
{
pile2->SetError(CBotErrNan, m_leftop->GetToken());
return pj->Return(pile2);
}
result = CBotVar::Create("", pVar->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC)); result = CBotVar::Create("", pVar->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC));
} }

View File

@ -38,6 +38,8 @@
#include "CBot/CBotCStack.h" #include "CBot/CBotCStack.h"
#include <cmath>
namespace CBot namespace CBot
{ {
@ -217,8 +219,8 @@ CBotInstr* CBotParExpr::CompileLitExpr(CBotToken* &p, CBotCStack* pStack)
{ {
CBotInstr* inst = new CBotExprLitNan(); CBotInstr* inst = new CBotExprLitNan();
inst->SetToken(pp); inst->SetToken(pp);
CBotVar* var = CBotVar::Create("", CBotTypInt); CBotVar* var = CBotVar::Create("", CBotTypFloat);
var->SetInit(CBotVar::InitType::IS_NAN); var->SetValFloat(nanf(""));
pStk->SetVar(var); pStk->SetVar(var);
return pStack->Return(inst, pStk); return pStack->Return(inst, pStk);
} }

View File

@ -56,11 +56,6 @@ bool CBotPostIncExpr::Execute(CBotStack* &pj)
CBotStack* pile3 = pile2->AddStack(this); CBotStack* pile3 = pile2->AddStack(this);
if (pile3->IfStep()) return false; if (pile3->IfStep()) return false;
if (var1->IsNAN())
{
pile1->SetError(CBotErrNan, &m_token);
}
if (!var1->IsDefined()) if (!var1->IsDefined())
{ {
pile1->SetError(CBotErrNotInit, &m_token); pile1->SetError(CBotErrNotInit, &m_token);

View File

@ -55,12 +55,6 @@ bool CBotPreIncExpr::Execute(CBotStack* &pj)
// pile2 is modified on return // pile2 is modified on return
if (!(static_cast<CBotExprVar*>(m_instr))->ExecuteVar(var1, pile2, nullptr, true)) return false; if (!(static_cast<CBotExprVar*>(m_instr))->ExecuteVar(var1, pile2, nullptr, true)) return false;
if (var1->IsNAN())
{
pile->SetError(CBotErrNan, &m_token);
return pj->Return(pile); // operation performed
}
if (!var1->IsDefined()) if (!var1->IsDefined())
{ {
pile->SetError(CBotErrNotInit, &m_token); pile->SetError(CBotErrNotInit, &m_token);

View File

@ -31,6 +31,7 @@
#include "CBot/CBotVar/CBotVar.h" #include "CBot/CBotVar/CBotVar.h"
#include <cassert> #include <cassert>
#include <cmath>
#include <algorithm> #include <algorithm>
namespace CBot namespace CBot
@ -305,7 +306,13 @@ CBotInstr* CBotTwoOpExpr::Compile(CBotToken* &p, CBotCStack* pStack, int* pOpera
static bool VarIsNAN(const CBotVar* var) static bool VarIsNAN(const CBotVar* var)
{ {
return var->GetInit() > CBotVar::InitType::DEF; if (var->GetType() == CBotTypFloat)
return std::isnan(var->GetValFloat());
if (var->GetType() == CBotTypDouble)
return std::isnan(var->GetValDouble());
return false;
} }
static bool IsNan(CBotVar* left, CBotVar* right, CBotError* err = nullptr) static bool IsNan(CBotVar* left, CBotVar* right, CBotError* err = nullptr)
@ -475,13 +482,13 @@ bool CBotTwoOpExpr::Execute(CBotStack* &pStack)
break; break;
case ID_EQ: case ID_EQ:
if ( IsNan(left, right) ) if ( IsNan(left, right) )
result->SetValInt(left->GetInit() == right->GetInit()) ; result->SetValInt(VarIsNAN(left) == VarIsNAN(right));
else else
result->SetValInt(temp->Eq(left , right)); // equal result->SetValInt(temp->Eq(left , right)); // equal
break; break;
case ID_NE: case ID_NE:
if ( IsNan(left, right) ) if ( IsNan(left, right) )
result->SetValInt(left ->GetInit() != right->GetInit()) ; result->SetValInt(VarIsNAN(left) != VarIsNAN(right));
else else
result->SetValInt(temp->Ne(left , right)); // different result->SetValInt(temp->Ne(left , right)); // different
break; break;

View File

@ -355,7 +355,7 @@ CBotTypResult CBotVar::GetTypResult(GetTypeMode mode)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
CBotType CBotVar::GetType(GetTypeMode mode) CBotType CBotVar::GetType(GetTypeMode mode) const
{ {
if ( mode == GetTypeMode::CLASS_AS_POINTER && m_type.Eq(CBotTypClass) ) if ( mode == GetTypeMode::CLASS_AS_POINTER && m_type.Eq(CBotTypClass) )
return CBotTypPointer; return CBotTypPointer;
@ -584,43 +584,43 @@ CBotVarClass* CBotVar::GetPointer()
// All these functions must be defined in the subclasses // All these functions must be defined in the subclasses
// derived from class CBotVar // derived from class CBotVar
signed char CBotVar::GetValByte() signed char CBotVar::GetValByte() const
{ {
assert(0); assert(0);
return 0; return 0;
} }
short CBotVar::GetValShort() short CBotVar::GetValShort() const
{ {
assert(0); assert(0);
return 0; return 0;
} }
uint32_t CBotVar::GetValChar() uint32_t CBotVar::GetValChar() const
{ {
assert(0); assert(0);
return 0; return 0;
} }
int CBotVar::GetValInt() int CBotVar::GetValInt() const
{ {
assert(0); assert(0);
return 0; return 0;
} }
long CBotVar::GetValLong() long CBotVar::GetValLong() const
{ {
assert(0); assert(0);
return 0; return 0;
} }
float CBotVar::GetValFloat() float CBotVar::GetValFloat() const
{ {
assert(0); assert(0);
return 0; return 0;
} }
double CBotVar::GetValDouble() double CBotVar::GetValDouble() const
{ {
assert(0); assert(0);
return 0; return 0;
@ -822,7 +822,7 @@ void CBotVar::SetValString(const std::string& val)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string CBotVar::GetValString() std::string CBotVar::GetValString() const
{ {
assert(0); assert(0);
return std::string(); return std::string();

View File

@ -199,7 +199,7 @@ public:
* \brief GetType Returns the base type of the variable (::CBotType) * \brief GetType Returns the base type of the variable (::CBotType)
* \param mode Mode, see GetTypeMode enum * \param mode Mode, see GetTypeMode enum
*/ */
CBotType GetType(GetTypeMode mode = GetTypeMode::NORMAL); CBotType GetType(GetTypeMode mode = GetTypeMode::NORMAL) const;
/** /**
* \brief Returns the complete type of the variable (CBotTypResult) * \brief Returns the complete type of the variable (CBotTypResult)
@ -243,7 +243,6 @@ public:
UNDEF = 0, //!< the variable value is currently not defined UNDEF = 0, //!< the variable value is currently not defined
DEF = 1, //!< the variable value is defined DEF = 1, //!< the variable value is defined
IS_POINTER = 2, //!< the variable value is as a pointer IS_POINTER = 2, //!< the variable value is as a pointer
IS_NAN = 999 //!< the variable value is NAN
}; };
/** /**
@ -269,12 +268,6 @@ public:
*/ */
bool IsDefined() const { return GetInit() == InitType::DEF; } bool IsDefined() const { return GetInit() == InitType::DEF; }
/**
* \brief Checks if the variable is currently NAN
* \return InitType::NAN
*/
bool IsNAN() const { return GetInit() == InitType::IS_NAN; }
//@} //@}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -508,27 +501,27 @@ public:
*/ */
virtual void SetValString(const std::string& val); virtual void SetValString(const std::string& val);
virtual signed char GetValByte(); virtual signed char GetValByte() const;
virtual short GetValShort(); virtual short GetValShort() const;
virtual uint32_t GetValChar(); virtual uint32_t GetValChar() const;
/** /**
* \brief Get value as integer * \brief Get value as integer
* \return Current value * \return Current value
*/ */
virtual int GetValInt(); virtual int GetValInt() const;
virtual long GetValLong(); virtual long GetValLong() const;
/** /**
* \brief Get value as float * \brief Get value as float
* \return Current value * \return Current value
*/ */
virtual float GetValFloat(); virtual float GetValFloat() const;
virtual double GetValDouble(); virtual double GetValDouble() const;
/** /**
* \brief Get value as string * \brief Get value as string
@ -539,7 +532,7 @@ public:
* *
* \return Current value * \return Current value
*/ */
virtual std::string GetValString(); virtual std::string GetValString() const;
/** /**
* \brief Set value for pointer types * \brief Set value for pointer types

View File

@ -129,7 +129,7 @@ CBotVar* CBotVarArray::GetItemList()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string CBotVarArray::GetValString() std::string CBotVarArray::GetValString() const
{ {
if ( m_pInstance == nullptr ) return ( std::string( "Null pointer" ) ) ; if ( m_pInstance == nullptr ) return ( std::string( "Null pointer" ) ) ;
return m_pInstance->GetValString(); return m_pInstance->GetValString();

View File

@ -49,7 +49,7 @@ public:
CBotVar* GetItem(int n, bool grow = false) override; CBotVar* GetItem(int n, bool grow = false) override;
CBotVar* GetItemList() override; CBotVar* GetItemList() override;
std::string GetValString() override; std::string GetValString() const override;
bool Save1State(std::ostream &ostr) override; bool Save1State(std::ostream &ostr) override;

View File

@ -32,12 +32,10 @@ class CBotVarChar : public CBotVarInteger<uint32_t, CBotTypChar>
public: public:
CBotVarChar(const CBotToken &name) : CBotVarInteger(name) {} CBotVarChar(const CBotToken &name) : CBotVarInteger(name) {}
std::string GetValString() override std::string GetValString() const override
{ {
if (m_binit == CBotVar::InitType::UNDEF) if (m_binit == CBotVar::InitType::UNDEF)
return LoadString(TX_UNDEF); return LoadString(TX_UNDEF);
if (m_binit == CBotVar::InitType::IS_NAN)
return LoadString(TX_NAN);
if (0x10FFFF < m_val || (0xD7FF < m_val && m_val < 0xE000)) if (0x10FFFF < m_val || (0xD7FF < m_val && m_val < 0xE000))
return "\xEF\xBF\xBD"; // replacement character U+FFFD return "\xEF\xBF\xBD"; // replacement character U+FFFD

View File

@ -291,7 +291,7 @@ CBotVar* CBotVarClass::GetItemList()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string CBotVarClass::GetValString() std::string CBotVarClass::GetValString() const
{ {
std::string res; std::string res;

View File

@ -52,7 +52,7 @@ public:
CBotVar* GetItemRef(int nIdent) override; CBotVar* GetItemRef(int nIdent) override;
CBotVar* GetItem(int n, bool bExtend) override; CBotVar* GetItem(int n, bool bExtend) override;
CBotVar* GetItemList() override; CBotVar* GetItemList() override;
std::string GetValString() override; std::string GetValString() const override;
bool Save1State(std::ostream &ostr) override; bool Save1State(std::ostream &ostr) override;

View File

@ -35,7 +35,7 @@ void CBotVarInt::SetValInt(int val, const std::string& defnum)
m_defnum = defnum; m_defnum = defnum;
} }
std::string CBotVarInt::GetValString() std::string CBotVarInt::GetValString() const
{ {
if (!m_defnum.empty()) return m_defnum; if (!m_defnum.empty()) return m_defnum;
return CBotVarValue::GetValString(); return CBotVarValue::GetValString();

View File

@ -33,7 +33,7 @@ public:
CBotVarInt(const CBotToken &name) : CBotVarInteger(name) {} CBotVarInt(const CBotToken &name) : CBotVarInteger(name) {}
void SetValInt(int val, const std::string& s = "") override; void SetValInt(int val, const std::string& s = "") override;
std::string GetValString() override; std::string GetValString() const override;
void Copy(CBotVar* pSrc, bool bName = true) override; void Copy(CBotVar* pSrc, bool bName = true) override;

View File

@ -90,7 +90,7 @@ CBotVar* CBotVarPointer::GetItemList()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string CBotVarPointer::GetValString() std::string CBotVarPointer::GetValString() const
{ {
std::string s = "Pointer to "; std::string s = "Pointer to ";
if ( m_pVarClass == nullptr ) s = "Null pointer" ; if ( m_pVarClass == nullptr ) s = "Null pointer" ;

View File

@ -47,7 +47,7 @@ public:
CBotVar* GetItem(const std::string& name) override; CBotVar* GetItem(const std::string& name) override;
CBotVar* GetItemRef(int nIdent) override; CBotVar* GetItemRef(int nIdent) override;
CBotVar* GetItemList() override; CBotVar* GetItemList() override;
std::string GetValString() override; std::string GetValString() const override;
void SetPointer(CBotVar* p) override; void SetPointer(CBotVar* p) override;
CBotVarClass* GetPointer() override; CBotVarClass* GetPointer() override;

View File

@ -48,12 +48,12 @@ public:
SetValString(ToString(val)); SetValString(ToString(val));
} }
int GetValInt() override int GetValInt() const override
{ {
return FromString<int>(GetValString()); return FromString<int>(GetValString());
} }
float GetValFloat() override float GetValFloat() const override
{ {
return FromString<float>(GetValString()); return FromString<float>(GetValString());
} }

View File

@ -62,15 +62,13 @@ public:
m_binit = CBotVar::InitType::DEF; m_binit = CBotVar::InitType::DEF;
} }
std::string GetValString() override std::string GetValString() const override
{ {
if (m_binit == CBotVar::InitType::UNDEF) if (m_binit == CBotVar::InitType::UNDEF)
return LoadString(TX_UNDEF); return LoadString(TX_UNDEF);
if (m_binit == CBotVar::InitType::IS_NAN)
return LoadString(TX_NAN);
std::ostringstream s; std::ostringstream s;
s << m_val; s << std::boolalpha << m_val;
return s.str(); return s.str();
} }
@ -133,37 +131,37 @@ public:
this->SetValue(static_cast<T>(val)); this->SetValue(static_cast<T>(val));
} }
signed char GetValByte() override signed char GetValByte() const override
{ {
return static_cast<signed char>(this->m_val); return static_cast<signed char>(this->m_val);
} }
short GetValShort() override short GetValShort() const override
{ {
return static_cast<short>(this->m_val); return static_cast<short>(this->m_val);
} }
uint32_t GetValChar() override uint32_t GetValChar() const override
{ {
return static_cast<uint32_t>(this->m_val); return static_cast<uint32_t>(this->m_val);
} }
int GetValInt() override int GetValInt() const override
{ {
return static_cast<int>(this->m_val); return static_cast<int>(this->m_val);
} }
long GetValLong() override long GetValLong() const override
{ {
return static_cast<long>(this->m_val); return static_cast<long>(this->m_val);
} }
float GetValFloat() override float GetValFloat() const override
{ {
return static_cast<float>(this->m_val); return static_cast<float>(this->m_val);
} }
double GetValDouble() override double GetValDouble() const override
{ {
return static_cast<double>(this->m_val); return static_cast<double>(this->m_val);
} }

View File

@ -133,7 +133,7 @@ bool rfdestruct (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception
if (!pVar->IsDefined()) return true; // file not opened if (!pVar->IsDefined()) return true; // file not opened
g_files.erase(pVar->GetValInt()); g_files.erase(pVar->GetValInt());
pVar->SetInit(CBotVar::InitType::IS_NAN); pVar->SetInit(CBotVar::InitType::UNDEF);
return true; return true;
} }
@ -203,7 +203,7 @@ bool rfclose (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, v
g_files.erase(handleIter); g_files.erase(handleIter);
pVar->SetInit(CBotVar::InitType::IS_NAN); pVar->SetInit(CBotVar::InitType::UNDEF);
return true; return true;
} }

View File

@ -218,6 +218,37 @@ bool rTrunc(CBotVar* var, CBotVar* result, int& exception, void* user)
return true; return true;
} }
// Instruction "isnan()"
CBotTypResult cIsNAN(CBotVar*& var, void* user)
{
if (var == nullptr) return CBotTypResult(CBotErrLowParam);
if (var->GetType() > CBotTypDouble) return CBotTypResult(CBotErrBadNum);
var = var->GetNext();
if (var != nullptr) return CBotTypResult(CBotErrOverParam);
return CBotTypResult(CBotTypBoolean);
}
bool rIsNAN(CBotVar* var, CBotVar* result, int& exception, void* user)
{
bool isnan = false;
if (var->GetType() == CBotTypFloat)
{
if (std::isnan(var->GetValFloat())) isnan = true;
}
else if (var->GetType() == CBotTypDouble)
{
if (std::isnan(var->GetValDouble())) isnan = true;
}
result->SetValInt(isnan);
return true;
}
} // namespace } // namespace
void InitMathFunctions() void InitMathFunctions()
@ -237,6 +268,7 @@ void InitMathFunctions()
CBotProgram::AddFunction("ceil", rCeil, cOneFloat); CBotProgram::AddFunction("ceil", rCeil, cOneFloat);
CBotProgram::AddFunction("round", rRound, cOneFloat); CBotProgram::AddFunction("round", rRound, cOneFloat);
CBotProgram::AddFunction("trunc", rTrunc, cOneFloat); CBotProgram::AddFunction("trunc", rTrunc, cOneFloat);
CBotProgram::AddFunction("isnan", rIsNAN, cIsNAN);
} }
} // namespace CBot } // namespace CBot

View File

@ -233,7 +233,7 @@ bool rStrFind( CBotVar* pVar, CBotVar* pResult, int& ex, void* pUser )
} }
else else
{ {
pResult->SetInit(CBotVar::InitType::IS_NAN); pResult->SetValInt(-1);
} }
return true; return true;
} }

View File

@ -493,6 +493,20 @@ target_link_libraries(colobotbase PUBLIC
SndFile::sndfile SndFile::sndfile
) )
if(mpg123_FOUND)
target_link_libraries(colobotbase PUBLIC
MPG123::libmpg123
MPG123::libout123
MPG123::libsyn123
)
endif()
if(mp3lame_FOUND)
target_link_libraries(colobotbase PUBLIC
mp3lame::mp3lame
)
endif()
# Optional libraries # Optional libraries
if(OPENAL_SOUND) if(OPENAL_SOUND)
target_sources(colobotbase PRIVATE target_sources(colobotbase PRIVATE

View File

@ -56,11 +56,12 @@
#include <SDL_image.h> #include <SDL_image.h>
#include <stdlib.h> #include <stdlib.h>
#include <libintl.h>
#include <getopt.h> #include <getopt.h>
#include <localename.h> #include <localename.h>
#include <thread> #include <thread>
#include <libintl.h>
using TimeUtils::TimeStamp; using TimeUtils::TimeStamp;
using TimeUtils::TimeUnit; using TimeUtils::TimeUnit;

View File

@ -31,10 +31,11 @@
#include "object/object_type.h" #include "object/object_type.h"
#include <libintl.h>
#include <SDL_keyboard.h> #include <SDL_keyboard.h>
#include <boost/regex.hpp> #include <boost/regex.hpp>
#include <libintl.h>
const char* stringsText[RT_MAX] = { nullptr }; const char* stringsText[RT_MAX] = { nullptr };
const char* stringsEvent[EVENT_STD_MAX] = { nullptr }; const char* stringsEvent[EVENT_STD_MAX] = { nullptr };
const char* stringsObject[OBJECT_MAX] = { nullptr }; const char* stringsObject[OBJECT_MAX] = { nullptr };

View File

@ -112,6 +112,7 @@
#include <algorithm> #include <algorithm>
#include <iomanip> #include <iomanip>
#include <stdexcept> #include <stdexcept>
#include <cmath>
#include <ctime> #include <ctime>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
@ -4101,70 +4102,64 @@ float SearchNearestObject(CObjectManager* objMan, Math::Vector center, CObject*
} }
return min; return min;
} }
bool BlockedByObject(CObjectManager* objMan, Math::Vector center, float space, CObject* exclu)
{
for (CObject* obj : objMan->GetAllObjects())
{
if (!obj->GetDetectable()) continue; // inactive?
if (IsObjectBeingTransported(obj)) continue;
if (obj == exclu) continue;
for (const auto &crashSphere : obj->GetAllCrashSpheres())
{
const Math::Vector oPos = crashSphere.sphere.pos;
const float oRadius = crashSphere.sphere.radius;
const float minDist = oRadius + space;
if (Math::DistanceSquared(center, oPos) < minDist * minDist)
return true;
}
}
return false;
}
} }
//! Calculates a free space //! Calculates a free space
bool CRobotMain::FreeSpace(Math::Vector &center, float minRadius, float maxRadius, bool CRobotMain::FreeSpace(Math::Vector &center, float minRadius, float maxRadius,
float space, CObject *exclu) float space, CObject *exclu)
{ {
if (minRadius < maxRadius) // from internal to external? for (float radius = minRadius; radius <= maxRadius; radius += space)
{ {
for (float radius = minRadius; radius <= maxRadius; radius += space) float ia = space/radius;
for (float angle = 0.0f; angle < Math::PI*2.0f; angle += ia)
{ {
float ia = space/radius; Math::Point p;
for (float angle = 0.0f; angle < Math::PI*2.0f; angle += ia) p.x = center.x+radius;
p.y = center.z;
p = Math::RotatePoint(Math::Point(center.x, center.z), angle, p);
Math::Vector pos;
pos.x = p.x;
pos.z = p.y;
pos.y = 0.0f;
pos.y = m_terrain->GetFloorLevel(pos);
if (!BlockedByObject(m_objMan.get(), pos, space, exclu))
{ {
Math::Point p; float flat = m_terrain->GetFlatZoneRadius(pos, space);
p.x = center.x+radius; if (flat >= space)
p.y = center.z;
p = Math::RotatePoint(Math::Point(center.x, center.z), angle, p);
Math::Vector pos;
pos.x = p.x;
pos.z = p.y;
pos.y = 0.0f;
m_terrain->AdjustToFloor(pos, true);
float dist = SearchNearestObject(m_objMan.get(), pos, exclu);
if (dist >= space)
{ {
float flat = m_terrain->GetFlatZoneRadius(pos, dist/2.0f); center = pos;
if (flat >= dist/2.0f) return true;
{
center = pos;
return true;
}
}
}
}
}
else // from external to internal?
{
for (float radius=maxRadius; radius >= minRadius; radius -= space)
{
float ia = space/radius;
for (float angle=0.0f ; angle<Math::PI*2.0f ; angle+=ia )
{
Math::Point p;
p.x = center.x+radius;
p.y = center.z;
p = Math::RotatePoint(Math::Point(center.x, center.z), angle, p);
Math::Vector pos;
pos.x = p.x;
pos.z = p.y;
pos.y = 0.0f;
m_terrain->AdjustToFloor(pos, true);
float dist = SearchNearestObject(m_objMan.get(), pos, exclu);
if (dist >= space)
{
float flat = m_terrain->GetFlatZoneRadius(pos, dist/2.0f);
if (flat >= dist/2.0f)
{
center = pos;
return true;
}
} }
} }
} }
} }
float nan = nanf("");
center = Math::Vector{ nan, nan, nan };
return false; return false;
} }
@ -4930,6 +4925,7 @@ CObject* CRobotMain::IOReadScene(std::string filename, std::string filecbot)
assert(slotNum >= 0); assert(slotNum >= 0);
assert(slots.find(slotNum) == slots.end()); assert(slots.find(slotNum) == slots.end());
asSlotted->SetSlotContainedObject(slotNum, power); asSlotted->SetSlotContainedObject(slotNum, power);
dynamic_cast<CTransportableObject&>(*power).SetTransporter(obj);
} }
for (std::pair<const int, CObject*>& slot : slots) for (std::pair<const int, CObject*>& slot : slots)
@ -4949,14 +4945,6 @@ CObject* CRobotMain::IOReadScene(std::string filename, std::string filecbot)
assert(cargo == nullptr); assert(cargo == nullptr);
} }
if (power != nullptr)
{
dynamic_cast<CSlottedObject&>(*obj).SetSlotContainedObjectReq(CSlottedObject::Pseudoslot::POWER, power);
dynamic_cast<CTransportableObject&>(*power).SetTransporter(obj);
}
cargo = nullptr;
power = nullptr;
objCounter++; objCounter++;
} }
} }

View File

@ -100,7 +100,7 @@ float HaltToFloat(uint16_t value)
// NaN // NaN
else if ((exponent == 31) && (mantissa != 0)) else if ((exponent == 31) && (mantissa != 0))
{ {
result = std::nanf(""); result = nanf("");
} }
// Normal number // Normal number
else else

View File

@ -273,6 +273,14 @@ inline float Distance(const Math::Vector &a, const Math::Vector &b)
(a.z-b.z)*(a.z-b.z) ); (a.z-b.z)*(a.z-b.z) );
} }
//! Returns the squared distance between the ends of two vectors
inline float DistanceSquared(const Math::Vector &a, const Math::Vector &b)
{
return (a.x-b.x)*(a.x-b.x) +
(a.y-b.y)*(a.y-b.y) +
(a.z-b.z)*(a.z-b.z);
}
//! Clamps the vector \a vec to range between \a min and \a max //! Clamps the vector \a vec to range between \a min and \a max
inline Vector Clamp(const Vector &vec, const Vector &min, const Vector &max) inline Vector Clamp(const Vector &vec, const Vector &min, const Vector &max)
{ {
@ -285,4 +293,3 @@ inline Vector Clamp(const Vector &vec, const Vector &min, const Vector &max)
} // namespace Math } // namespace Math

View File

@ -301,6 +301,7 @@ std::string GetHelpFilename(const char *token)
if ( strcmp(token, "ceil" ) == 0 ) helpfile = "cbot/ceil"; if ( strcmp(token, "ceil" ) == 0 ) helpfile = "cbot/ceil";
if ( strcmp(token, "round" ) == 0 ) helpfile = "cbot/round"; if ( strcmp(token, "round" ) == 0 ) helpfile = "cbot/round";
if ( strcmp(token, "trunc" ) == 0 ) helpfile = "cbot/trunc"; if ( strcmp(token, "trunc" ) == 0 ) helpfile = "cbot/trunc";
if ( strcmp(token, "isnan" ) == 0 ) helpfile = "cbot/isnan";
if ( strcmp(token, "retobject" ) == 0 ) helpfile = "cbot/retobj"; if ( strcmp(token, "retobject" ) == 0 ) helpfile = "cbot/retobj";
if ( strcmp(token, "errmode" ) == 0 ) helpfile = "cbot/errmode"; if ( strcmp(token, "errmode" ) == 0 ) helpfile = "cbot/errmode";
if ( strcmp(token, "isbusy" ) == 0 ) helpfile = "cbot/isbusy"; if ( strcmp(token, "isbusy" ) == 0 ) helpfile = "cbot/isbusy";
@ -463,9 +464,10 @@ bool IsFunction(const char *token)
if ( strcmp(token, "ceil" ) == 0 ) return true; if ( strcmp(token, "ceil" ) == 0 ) return true;
if ( strcmp(token, "round" ) == 0 ) return true; if ( strcmp(token, "round" ) == 0 ) return true;
if ( strcmp(token, "trunc" ) == 0 ) return true; if ( strcmp(token, "trunc" ) == 0 ) return true;
if ( strcmp(token, "isnan" ) == 0 ) return true;
if ( strcmp(token, "retobjectbyid") == 0 ) return true; if ( strcmp(token, "retobjectbyid") == 0 ) return true;
if ( strcmp(token, "retobject" ) == 0 ) return true; if ( strcmp(token, "retobject" ) == 0 ) return true;
if ( strcmp(token, "isbusy" ) == 0 ) return true; if ( strcmp(token, "isbusy" ) == 0 ) return true;
if ( strcmp(token, "factory" ) == 0 ) return true; if ( strcmp(token, "factory" ) == 0 ) return true;
if ( strcmp(token, "research" ) == 0 ) return true; if ( strcmp(token, "research" ) == 0 ) return true;
if ( strcmp(token, "takeoff" ) == 0 ) return true; if ( strcmp(token, "takeoff" ) == 0 ) return true;
@ -571,6 +573,7 @@ const char* GetHelpText(const char *token)
if ( strcmp(token, "ceil" ) == 0 ) return "ceil ( value );"; if ( strcmp(token, "ceil" ) == 0 ) return "ceil ( value );";
if ( strcmp(token, "round" ) == 0 ) return "round ( value );"; if ( strcmp(token, "round" ) == 0 ) return "round ( value );";
if ( strcmp(token, "trunc" ) == 0 ) return "trunc ( value );"; if ( strcmp(token, "trunc" ) == 0 ) return "trunc ( value );";
if ( strcmp(token, "isnan" ) == 0 ) return "isnan ( value );";
if ( strcmp(token, "retobject" ) == 0 ) return "retobject ( rank );"; if ( strcmp(token, "retobject" ) == 0 ) return "retobject ( rank );";
if ( strcmp(token, "retobjectbyid") == 0 ) return "retobjectbyid ( rank );"; if ( strcmp(token, "retobjectbyid") == 0 ) return "retobjectbyid ( rank );";
if ( strcmp(token, "progfunc" ) == 0 ) return "progfunc ( funcname );"; if ( strcmp(token, "progfunc" ) == 0 ) return "progfunc ( funcname );";

View File

@ -67,6 +67,8 @@
#include "ui/displaytext.h" #include "ui/displaytext.h"
#include <cmath>
using namespace CBot; using namespace CBot;
CBotTypResult CScriptFunctions::cClassNull(CBotVar* thisclass, CBotVar* &var) CBotTypResult CScriptFunctions::cClassNull(CBotVar* thisclass, CBotVar* &var)
@ -1836,18 +1838,30 @@ bool CScriptFunctions::rSpace(CBotVar* var, CBotVar* result, int& exception, voi
} }
} }
} }
script->m_main->FreeSpace(center, rMin, rMax, dist, pThis);
bool success = script->m_main->FreeSpace(center, rMin, rMax, dist, pThis);
if ( result != nullptr ) if ( result != nullptr )
{ {
pSub = result->GetItemList(); pSub = result->GetItemList();
if ( pSub != nullptr ) if ( pSub != nullptr )
{ {
pSub->SetValFloat(center.x/g_unit); if (success)
pSub = pSub->GetNext(); // "y" {
pSub->SetValFloat(center.z/g_unit); pSub->SetValFloat(center.x / g_unit);
pSub = pSub->GetNext(); // "z" pSub = pSub->GetNext(); // "y"
pSub->SetValFloat(center.y/g_unit); pSub->SetValFloat(center.z / g_unit);
pSub = pSub->GetNext(); // "z"
pSub->SetValFloat(center.y / g_unit);
}
else
{
pSub->SetValFloat(center.x);
pSub = pSub->GetNext(); // "y"
pSub->SetValFloat(center.y);
pSub = pSub->GetNext(); // "z"
pSub->SetValFloat(center.z);
}
} }
} }
return true; return true;
@ -2313,7 +2327,7 @@ bool CScriptFunctions::rReceive(CBotVar* var, CBotVar* result, int& exception, v
if ( err != ERR_OK ) if ( err != ERR_OK )
{ {
script->m_taskExecutor->StopForegroundTask(); script->m_taskExecutor->StopForegroundTask();
result->SetInit(CBotVar::InitType::IS_NAN); result->SetValFloat(nanf(""));
return true; return true;
} }
@ -2324,7 +2338,7 @@ bool CScriptFunctions::rReceive(CBotVar* var, CBotVar* result, int& exception, v
if ( script->m_returnValue == boost::none ) if ( script->m_returnValue == boost::none )
{ {
result->SetInit(CBotVar::InitType::IS_NAN); result->SetValFloat(nanf(""));
} }
else else
{ {
@ -2859,6 +2873,7 @@ CBotTypResult CScriptFunctions::cMessage(CBotVar* &var, void* user)
{ {
if ( var == nullptr ) return CBotTypResult(CBotErrLowParam); if ( var == nullptr ) return CBotTypResult(CBotErrLowParam);
if ( var->GetType() != CBotTypString && if ( var->GetType() != CBotTypString &&
var->GetType() != CBotTypBoolean &&
var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum);
var = var->GetNext(); var = var->GetNext();
@ -3644,11 +3659,11 @@ void CScriptFunctions::uObject(CBotVar* botThis, void* user)
if (IsObjectBeingTransported(object)) if (IsObjectBeingTransported(object))
{ {
pSub = pVar->GetItemList(); // "x" pSub = pVar->GetItemList(); // "x"
pSub->SetInit(CBotVar::InitType::IS_NAN); pSub->SetValFloat(nanf(""));
pSub = pSub->GetNext(); // "y" pSub = pSub->GetNext(); // "y"
pSub->SetInit(CBotVar::InitType::IS_NAN); pSub->SetValFloat(nanf(""));
pSub = pSub->GetNext(); // "z" pSub = pSub->GetNext(); // "z"
pSub->SetInit(CBotVar::InitType::IS_NAN); pSub->SetValFloat(nanf(""));
} }
else else
{ {
@ -3749,11 +3764,11 @@ void CScriptFunctions::uObject(CBotVar* botThis, void* user)
if (IsObjectBeingTransported(object) || physics == nullptr) if (IsObjectBeingTransported(object) || physics == nullptr)
{ {
pSub = pVar->GetItemList(); // "x" pSub = pVar->GetItemList(); // "x"
pSub->SetInit(CBotVar::InitType::IS_NAN); pSub->SetValFloat(nanf(""));
pSub = pSub->GetNext(); // "y" pSub = pSub->GetNext(); // "y"
pSub->SetInit(CBotVar::InitType::IS_NAN); pSub->SetValFloat(nanf(""));
pSub = pSub->GetNext(); // "z" pSub = pSub->GetNext(); // "z"
pSub->SetInit(CBotVar::InitType::IS_NAN); pSub->SetValFloat(nanf(""));
} }
else else
{ {