Merge pull request #1529 from colobot/dev-fix-space

undefined
fix-squashed-planets
tomangelo 2022-09-15 02:13:19 +02:00 committed by GitHub
commit 0df78e7fa6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 132 additions and 93 deletions

View File

@ -23,6 +23,8 @@
#include "CBot/CBotVar/CBotVar.h"
#include <cmath>
namespace CBot
{
@ -41,9 +43,9 @@ bool CBotExprLitNan::Execute(CBotStack* &pj)
CBotStack* pile = pj->AddStack(this);
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
return pj->Return(pile); // forward below
}

View File

@ -206,12 +206,6 @@ bool CBotExpression::Execute(CBotStack* &pj)
if (m_token.GetType() != ID_ASS)
{
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));
}

View File

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

View File

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

View File

@ -55,12 +55,6 @@ bool CBotPreIncExpr::Execute(CBotStack* &pj)
// pile2 is modified on return
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())
{
pile->SetError(CBotErrNotInit, &m_token);

View File

@ -31,6 +31,7 @@
#include "CBot/CBotVar/CBotVar.h"
#include <cassert>
#include <cmath>
#include <algorithm>
namespace CBot
@ -305,7 +306,13 @@ CBotInstr* CBotTwoOpExpr::Compile(CBotToken* &p, CBotCStack* pStack, int* pOpera
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)
@ -475,13 +482,13 @@ bool CBotTwoOpExpr::Execute(CBotStack* &pStack)
break;
case ID_EQ:
if ( IsNan(left, right) )
result->SetValInt(left->GetInit() == right->GetInit()) ;
result->SetValInt(VarIsNAN(left) == VarIsNAN(right));
else
result->SetValInt(temp->Eq(left , right)); // equal
break;
case ID_NE:
if ( IsNan(left, right) )
result->SetValInt(left ->GetInit() != right->GetInit()) ;
result->SetValInt(VarIsNAN(left) != VarIsNAN(right));
else
result->SetValInt(temp->Ne(left , right)); // different
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) )
return CBotTypPointer;
@ -584,43 +584,43 @@ CBotVarClass* CBotVar::GetPointer()
// All these functions must be defined in the subclasses
// derived from class CBotVar
signed char CBotVar::GetValByte()
signed char CBotVar::GetValByte() const
{
assert(0);
return 0;
}
short CBotVar::GetValShort()
short CBotVar::GetValShort() const
{
assert(0);
return 0;
}
uint32_t CBotVar::GetValChar()
uint32_t CBotVar::GetValChar() const
{
assert(0);
return 0;
}
int CBotVar::GetValInt()
int CBotVar::GetValInt() const
{
assert(0);
return 0;
}
long CBotVar::GetValLong()
long CBotVar::GetValLong() const
{
assert(0);
return 0;
}
float CBotVar::GetValFloat()
float CBotVar::GetValFloat() const
{
assert(0);
return 0;
}
double CBotVar::GetValDouble()
double CBotVar::GetValDouble() const
{
assert(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);
return std::string();

View File

@ -199,7 +199,7 @@ public:
* \brief GetType Returns the base type of the variable (::CBotType)
* \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)
@ -243,7 +243,6 @@ public:
UNDEF = 0, //!< the variable value is currently not defined
DEF = 1, //!< the variable value is defined
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; }
/**
* \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 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
* \return Current value
*/
virtual int GetValInt();
virtual int GetValInt() const;
virtual long GetValLong();
virtual long GetValLong() const;
/**
* \brief Get value as float
* \return Current value
*/
virtual float GetValFloat();
virtual float GetValFloat() const;
virtual double GetValDouble();
virtual double GetValDouble() const;
/**
* \brief Get value as string
@ -539,7 +532,7 @@ public:
*
* \return Current value
*/
virtual std::string GetValString();
virtual std::string GetValString() const;
/**
* \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" ) ) ;
return m_pInstance->GetValString();

View File

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

View File

@ -32,12 +32,10 @@ class CBotVarChar : public CBotVarInteger<uint32_t, CBotTypChar>
public:
CBotVarChar(const CBotToken &name) : CBotVarInteger(name) {}
std::string GetValString() override
std::string GetValString() const override
{
if (m_binit == CBotVar::InitType::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))
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;

View File

@ -52,7 +52,7 @@ public:
CBotVar* GetItemRef(int nIdent) override;
CBotVar* GetItem(int n, bool bExtend) override;
CBotVar* GetItemList() override;
std::string GetValString() override;
std::string GetValString() const 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;
}
std::string CBotVarInt::GetValString()
std::string CBotVarInt::GetValString() const
{
if (!m_defnum.empty()) return m_defnum;
return CBotVarValue::GetValString();

View File

@ -33,7 +33,7 @@ public:
CBotVarInt(const CBotToken &name) : CBotVarInteger(name) {}
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;

View File

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

View File

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

View File

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

View File

@ -62,15 +62,13 @@ public:
m_binit = CBotVar::InitType::DEF;
}
std::string GetValString() override
std::string GetValString() const override
{
if (m_binit == CBotVar::InitType::UNDEF)
return LoadString(TX_UNDEF);
if (m_binit == CBotVar::InitType::IS_NAN)
return LoadString(TX_NAN);
std::ostringstream s;
s << m_val;
s << std::boolalpha << m_val;
return s.str();
}
@ -133,37 +131,37 @@ public:
this->SetValue(static_cast<T>(val));
}
signed char GetValByte() override
signed char GetValByte() const override
{
return static_cast<signed char>(this->m_val);
}
short GetValShort() override
short GetValShort() const override
{
return static_cast<short>(this->m_val);
}
uint32_t GetValChar() override
uint32_t GetValChar() const override
{
return static_cast<uint32_t>(this->m_val);
}
int GetValInt() override
int GetValInt() const override
{
return static_cast<int>(this->m_val);
}
long GetValLong() override
long GetValLong() const override
{
return static_cast<long>(this->m_val);
}
float GetValFloat() override
float GetValFloat() const override
{
return static_cast<float>(this->m_val);
}
double GetValDouble() override
double GetValDouble() const override
{
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
g_files.erase(pVar->GetValInt());
pVar->SetInit(CBotVar::InitType::IS_NAN);
pVar->SetInit(CBotVar::InitType::UNDEF);
return true;
}
@ -203,7 +203,7 @@ bool rfclose (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception, v
g_files.erase(handleIter);
pVar->SetInit(CBotVar::InitType::IS_NAN);
pVar->SetInit(CBotVar::InitType::UNDEF);
return true;
}

View File

@ -218,6 +218,37 @@ bool rTrunc(CBotVar* var, CBotVar* result, int& exception, void* user)
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
void InitMathFunctions()
@ -237,6 +268,7 @@ void InitMathFunctions()
CBotProgram::AddFunction("ceil", rCeil, cOneFloat);
CBotProgram::AddFunction("round", rRound, cOneFloat);
CBotProgram::AddFunction("trunc", rTrunc, cOneFloat);
CBotProgram::AddFunction("isnan", rIsNAN, cIsNAN);
}
} // namespace CBot

View File

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

View File

@ -112,6 +112,7 @@
#include <algorithm>
#include <iomanip>
#include <stdexcept>
#include <cmath>
#include <ctime>
#include <boost/lexical_cast.hpp>
@ -4142,7 +4143,7 @@ bool CRobotMain::FreeSpace(Math::Vector &center, float minRadius, float maxRadiu
pos.x = p.x;
pos.z = p.y;
pos.y = 0.0f;
m_terrain->AdjustToFloor(pos, true);
pos.y = m_terrain->GetFloorLevel(pos);
if (!BlockedByObject(m_objMan.get(), pos, space, exclu))
{
float flat = m_terrain->GetFlatZoneRadius(pos, space);
@ -4154,6 +4155,11 @@ bool CRobotMain::FreeSpace(Math::Vector &center, float minRadius, float maxRadiu
}
}
}
float nan = nanf("");
center = Math::Vector{ nan, nan, nan };
return false;
}

View File

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

View File

@ -301,6 +301,7 @@ std::string GetHelpFilename(const char *token)
if ( strcmp(token, "ceil" ) == 0 ) helpfile = "cbot/ceil";
if ( strcmp(token, "round" ) == 0 ) helpfile = "cbot/round";
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, "errmode" ) == 0 ) helpfile = "cbot/errmode";
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, "round" ) == 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, "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, "research" ) == 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, "round" ) == 0 ) return "round ( 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, "retobjectbyid") == 0 ) return "retobjectbyid ( rank );";
if ( strcmp(token, "progfunc" ) == 0 ) return "progfunc ( funcname );";

View File

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