Moved common interface implementations to separate classes
Additionaly, merged all "inappropariate bot" errors into one and renamed ERR_GENERIC -> ERR_UNKNOWNmaster
parent
63d83185b5
commit
f7d2f501bb
|
@ -1400,9 +1400,6 @@ msgstr ""
|
||||||
msgid "Unknown command"
|
msgid "Unknown command"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Inappropriate bot"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Impossible when flying"
|
msgid "Impossible when flying"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1597,6 +1594,9 @@ msgstr ""
|
||||||
msgid "Do not use in this exercise"
|
msgid "Do not use in this exercise"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Inappropriate bot"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Building completed"
|
msgid "Building completed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -150,6 +150,9 @@ set(BASE_SOURCES
|
||||||
object/auto/autopowerstation.cpp
|
object/auto/autopowerstation.cpp
|
||||||
object/auto/autotower.cpp
|
object/auto/autotower.cpp
|
||||||
object/drive_type.cpp
|
object/drive_type.cpp
|
||||||
|
object/implementation/power_container_impl.cpp
|
||||||
|
object/implementation/programmable_impl.cpp
|
||||||
|
object/implementation/task_executor_impl.cpp
|
||||||
object/level/parser.cpp
|
object/level/parser.cpp
|
||||||
object/level/parserexceptions.cpp
|
object/level/parserexceptions.cpp
|
||||||
object/level/parserline.cpp
|
object/level/parserline.cpp
|
||||||
|
|
|
@ -32,11 +32,10 @@
|
||||||
enum Error
|
enum Error
|
||||||
{
|
{
|
||||||
ERR_OK = 0, //! < ok
|
ERR_OK = 0, //! < ok
|
||||||
ERR_GENERIC = 1, //! < any error
|
ERR_UNKNOWN = 1, //! < any error
|
||||||
ERR_CONTINUE = 2, //! < continues
|
ERR_CONTINUE = 2, //! < continues
|
||||||
ERR_STOP = 3, //! < stops
|
ERR_STOP = 3, //! < stops
|
||||||
ERR_CMD = 4, //! < unknown command
|
ERR_CMD = 4, //! < unknown command
|
||||||
ERR_MANIP_VEH = 100, //! < inappropriate vehicle
|
|
||||||
ERR_MANIP_FLY = 101, //! < impossible in flight
|
ERR_MANIP_FLY = 101, //! < impossible in flight
|
||||||
ERR_MANIP_BUSY = 102, //! < taking: hands already occupied
|
ERR_MANIP_BUSY = 102, //! < taking: hands already occupied
|
||||||
ERR_MANIP_NIL = 103, //! < taking: nothing has to take
|
ERR_MANIP_NIL = 103, //! < taking: nothing has to take
|
||||||
|
@ -61,21 +60,16 @@ enum Error
|
||||||
ERR_BUILD_DISABLED = 132, //! < built: can not produce this object in this mission
|
ERR_BUILD_DISABLED = 132, //! < built: can not produce this object in this mission
|
||||||
ERR_BUILD_RESEARCH = 133, //! < built: can not produce not researched object
|
ERR_BUILD_RESEARCH = 133, //! < built: can not produce not researched object
|
||||||
ERR_SEARCH_FLY = 140, //! < not possible in flight
|
ERR_SEARCH_FLY = 140, //! < not possible in flight
|
||||||
ERR_SEARCH_VEH = 141, //! < inappropriate vehicle
|
|
||||||
ERR_SEARCH_MOTOR = 142, //! < impossible in movement
|
ERR_SEARCH_MOTOR = 142, //! < impossible in movement
|
||||||
ERR_TERRA_VEH = 150, //! < inappropriate vehicle
|
|
||||||
ERR_TERRA_ENERGY = 151, //! < not enough energy
|
ERR_TERRA_ENERGY = 151, //! < not enough energy
|
||||||
ERR_TERRA_FLOOR = 152, //! < inappropriate ground
|
ERR_TERRA_FLOOR = 152, //! < inappropriate ground
|
||||||
ERR_TERRA_BUILDING = 153, //! < building too close
|
ERR_TERRA_BUILDING = 153, //! < building too close
|
||||||
ERR_TERRA_OBJECT = 154, //! < object too close
|
ERR_TERRA_OBJECT = 154, //! < object too close
|
||||||
ERR_FIRE_VEH = 160, //! < inappropriate vehicle
|
|
||||||
ERR_FIRE_ENERGY = 161, //! < not enough energy
|
ERR_FIRE_ENERGY = 161, //! < not enough energy
|
||||||
ERR_FIRE_FLY = 162, //! < not possible in flight
|
ERR_FIRE_FLY = 162, //! < not possible in flight
|
||||||
ERR_RECOVER_VEH = 170, //! < inappropriate vehicle
|
|
||||||
ERR_RECOVER_ENERGY = 171, //! < not enough energy
|
ERR_RECOVER_ENERGY = 171, //! < not enough energy
|
||||||
ERR_RECOVER_NULL = 172, //! < lack of ruin
|
ERR_RECOVER_NULL = 172, //! < lack of ruin
|
||||||
ERR_CONVERT_EMPTY = 180, //! < no stone was transformed
|
ERR_CONVERT_EMPTY = 180, //! < no stone was transformed
|
||||||
ERR_SHIELD_VEH = 190, //! < inappropriate vehicle
|
|
||||||
ERR_SHIELD_ENERGY = 191, //! < not enough energy
|
ERR_SHIELD_ENERGY = 191, //! < not enough energy
|
||||||
ERR_MOVE_IMPOSSIBLE = 200, //! < move impossible
|
ERR_MOVE_IMPOSSIBLE = 200, //! < move impossible
|
||||||
ERR_FIND_IMPOSSIBLE = 201, //! < find impossible
|
ERR_FIND_IMPOSSIBLE = 201, //! < find impossible
|
||||||
|
@ -128,6 +122,7 @@ enum Error
|
||||||
ERR_OBLIGATORYTOKEN = 800, //! < compulsory instruction missing
|
ERR_OBLIGATORYTOKEN = 800, //! < compulsory instruction missing
|
||||||
ERR_PROHIBITEDTOKEN = 801, //! < instruction prohibited
|
ERR_PROHIBITEDTOKEN = 801, //! < instruction prohibited
|
||||||
ERR_AIM_IMPOSSIBLE = 900, //! < cannot aim at specified angle(s)
|
ERR_AIM_IMPOSSIBLE = 900, //! < cannot aim at specified angle(s)
|
||||||
|
ERR_WRONG_BOT = 910, //! < inappropriate bot
|
||||||
|
|
||||||
INFO_FIRST = 10000, //! < first information
|
INFO_FIRST = 10000, //! < first information
|
||||||
INFO_BUILD = 10001, //! < construction builded
|
INFO_BUILD = 10001, //! < construction builded
|
||||||
|
|
|
@ -581,9 +581,8 @@ void InitializeRestext()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
stringsErr[ERR_GENERIC] = TR("Internal error - tell the developers");
|
stringsErr[ERR_UNKNOWN] = TR("Internal error - tell the developers");
|
||||||
stringsErr[ERR_CMD] = TR("Unknown command");
|
stringsErr[ERR_CMD] = TR("Unknown command");
|
||||||
stringsErr[ERR_MANIP_VEH] = TR("Inappropriate bot");
|
|
||||||
stringsErr[ERR_MANIP_FLY] = TR("Impossible when flying");
|
stringsErr[ERR_MANIP_FLY] = TR("Impossible when flying");
|
||||||
stringsErr[ERR_MANIP_BUSY] = TR("Already carrying something");
|
stringsErr[ERR_MANIP_BUSY] = TR("Already carrying something");
|
||||||
stringsErr[ERR_MANIP_NIL] = TR("Nothing to grab");
|
stringsErr[ERR_MANIP_NIL] = TR("Nothing to grab");
|
||||||
|
@ -608,24 +607,19 @@ void InitializeRestext()
|
||||||
stringsErr[ERR_SEARCH_FLY] = TR("Impossible when flying");
|
stringsErr[ERR_SEARCH_FLY] = TR("Impossible when flying");
|
||||||
stringsErr[ERR_BUILD_DISABLED] = TR("Can not produce this object in this mission");
|
stringsErr[ERR_BUILD_DISABLED] = TR("Can not produce this object in this mission");
|
||||||
stringsErr[ERR_BUILD_RESEARCH] = TR("Can not produce not researched object");
|
stringsErr[ERR_BUILD_RESEARCH] = TR("Can not produce not researched object");
|
||||||
stringsErr[ERR_SEARCH_VEH] = TR("Inappropriate bot");
|
|
||||||
stringsErr[ERR_SEARCH_MOTOR] = TR("Impossible when moving");
|
stringsErr[ERR_SEARCH_MOTOR] = TR("Impossible when moving");
|
||||||
stringsErr[ERR_TERRA_VEH] = TR("Inappropriate bot");
|
|
||||||
stringsErr[ERR_TERRA_ENERGY] = TR("Not enough energy");
|
stringsErr[ERR_TERRA_ENERGY] = TR("Not enough energy");
|
||||||
stringsErr[ERR_TERRA_FLOOR] = TR("Ground inappropriate");
|
stringsErr[ERR_TERRA_FLOOR] = TR("Ground inappropriate");
|
||||||
stringsErr[ERR_TERRA_BUILDING] = TR("Building too close");
|
stringsErr[ERR_TERRA_BUILDING] = TR("Building too close");
|
||||||
stringsErr[ERR_TERRA_OBJECT] = TR("Object too close");
|
stringsErr[ERR_TERRA_OBJECT] = TR("Object too close");
|
||||||
stringsErr[ERR_RECOVER_VEH] = TR("Inappropriate bot");
|
|
||||||
stringsErr[ERR_RECOVER_ENERGY] = TR("Not enough energy");
|
stringsErr[ERR_RECOVER_ENERGY] = TR("Not enough energy");
|
||||||
stringsErr[ERR_RECOVER_NULL] = TR("Nothing to recycle");
|
stringsErr[ERR_RECOVER_NULL] = TR("Nothing to recycle");
|
||||||
stringsErr[ERR_SHIELD_VEH] = TR("Inappropriate bot");
|
|
||||||
stringsErr[ERR_SHIELD_ENERGY] = TR("No more energy");
|
stringsErr[ERR_SHIELD_ENERGY] = TR("No more energy");
|
||||||
stringsErr[ERR_MOVE_IMPOSSIBLE] = TR("Error in instruction move");
|
stringsErr[ERR_MOVE_IMPOSSIBLE] = TR("Error in instruction move");
|
||||||
stringsErr[ERR_FIND_IMPOSSIBLE] = TR("Object not found");
|
stringsErr[ERR_FIND_IMPOSSIBLE] = TR("Object not found");
|
||||||
stringsErr[ERR_GOTO_IMPOSSIBLE] = TR("Goto: inaccessible destination");
|
stringsErr[ERR_GOTO_IMPOSSIBLE] = TR("Goto: inaccessible destination");
|
||||||
stringsErr[ERR_GOTO_ITER] = TR("Goto: inaccessible destination");
|
stringsErr[ERR_GOTO_ITER] = TR("Goto: inaccessible destination");
|
||||||
stringsErr[ERR_GOTO_BUSY] = TR("Goto: destination occupied");
|
stringsErr[ERR_GOTO_BUSY] = TR("Goto: destination occupied");
|
||||||
stringsErr[ERR_FIRE_VEH] = TR("Inappropriate bot");
|
|
||||||
stringsErr[ERR_FIRE_ENERGY] = TR("Not enough energy");
|
stringsErr[ERR_FIRE_ENERGY] = TR("Not enough energy");
|
||||||
stringsErr[ERR_FIRE_FLY] = TR("Impossible when flying");
|
stringsErr[ERR_FIRE_FLY] = TR("Impossible when flying");
|
||||||
stringsErr[ERR_CONVERT_EMPTY] = TR("No titanium ore to convert");
|
stringsErr[ERR_CONVERT_EMPTY] = TR("No titanium ore to convert");
|
||||||
|
@ -674,6 +668,7 @@ void InitializeRestext()
|
||||||
stringsErr[ERR_ENEMY_OBJECT] = TR("Unable to control enemy objects");
|
stringsErr[ERR_ENEMY_OBJECT] = TR("Unable to control enemy objects");
|
||||||
stringsErr[ERR_OBLIGATORYTOKEN] = TR("\"%s\" missing in this exercise");
|
stringsErr[ERR_OBLIGATORYTOKEN] = TR("\"%s\" missing in this exercise");
|
||||||
stringsErr[ERR_PROHIBITEDTOKEN] = TR("Do not use in this exercise");
|
stringsErr[ERR_PROHIBITEDTOKEN] = TR("Do not use in this exercise");
|
||||||
|
stringsErr[ERR_WRONG_BOT] = TR("Inappropriate bot");
|
||||||
|
|
||||||
stringsErr[INFO_BUILD] = TR("Building completed");
|
stringsErr[INFO_BUILD] = TR("Building completed");
|
||||||
stringsErr[INFO_CONVERT] = TR("Titanium available");
|
stringsErr[INFO_CONVERT] = TR("Titanium available");
|
||||||
|
|
|
@ -107,7 +107,7 @@ void CAuto::Start(int param)
|
||||||
|
|
||||||
Error CAuto::StartAction(int param)
|
Error CAuto::StartAction(int param)
|
||||||
{
|
{
|
||||||
return ERR_GENERIC;
|
return ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gete a type.
|
// Gete a type.
|
||||||
|
|
|
@ -103,7 +103,7 @@ Error CAutoDestroyer::StartAction(int param)
|
||||||
m_bExplo = false;
|
m_bExplo = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return ERR_GENERIC;
|
return ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,7 @@ Error CAutoFactory::StartAction(int param)
|
||||||
m_speed = 1.0f/3.0f;
|
m_speed = 1.0f/3.0f;
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
return ERR_GENERIC;
|
return ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -219,10 +219,10 @@ bool CAutoFactory::EventProcess(const Event &event)
|
||||||
type = ObjectTypeFromFactoryButton(event.type);
|
type = ObjectTypeFromFactoryButton(event.type);
|
||||||
|
|
||||||
Error err = StartAction(type);
|
Error err = StartAction(type);
|
||||||
if( err != ERR_OK && err != ERR_GENERIC )
|
if( err != ERR_OK && err != ERR_UNKNOWN )
|
||||||
m_main->DisplayError(err, m_object);
|
m_main->DisplayError(err, m_object);
|
||||||
|
|
||||||
if( err != ERR_GENERIC )
|
if( err != ERR_UNKNOWN )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ Error CAutoLabo::StartAction(int param)
|
||||||
{
|
{
|
||||||
if ( m_phase != ALAP_WAIT )
|
if ( m_phase != ALAP_WAIT )
|
||||||
{
|
{
|
||||||
return ERR_GENERIC;
|
return ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_research = static_cast<ResearchType>(param);
|
m_research = static_cast<ResearchType>(param);
|
||||||
|
@ -175,14 +175,14 @@ bool CAutoLabo::EventProcess(const Event &event)
|
||||||
|
|
||||||
if ( m_object->GetSelect() ) // center selected?
|
if ( m_object->GetSelect() ) // center selected?
|
||||||
{
|
{
|
||||||
Error err = ERR_GENERIC;
|
Error err = ERR_UNKNOWN;
|
||||||
if ( event.type == EVENT_OBJECT_RiPAW ) err = StartAction(RESEARCH_iPAW);
|
if ( event.type == EVENT_OBJECT_RiPAW ) err = StartAction(RESEARCH_iPAW);
|
||||||
if ( event.type == EVENT_OBJECT_RiGUN ) err = StartAction(RESEARCH_iGUN);
|
if ( event.type == EVENT_OBJECT_RiGUN ) err = StartAction(RESEARCH_iGUN);
|
||||||
|
|
||||||
if( err != ERR_OK && err != ERR_GENERIC )
|
if( err != ERR_OK && err != ERR_UNKNOWN )
|
||||||
m_main->DisplayError(err, m_object);
|
m_main->DisplayError(err, m_object);
|
||||||
|
|
||||||
if( err != ERR_GENERIC )
|
if( err != ERR_UNKNOWN )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ Error CAutoResearch::StartAction(int param)
|
||||||
{
|
{
|
||||||
if ( m_phase != ALP_WAIT )
|
if ( m_phase != ALP_WAIT )
|
||||||
{
|
{
|
||||||
return ERR_GENERIC;
|
return ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_research = static_cast<ResearchType>(param);
|
m_research = static_cast<ResearchType>(param);
|
||||||
|
@ -167,7 +167,7 @@ bool CAutoResearch::EventProcess(const Event &event)
|
||||||
|
|
||||||
if ( m_object->GetSelect() ) // center selected?
|
if ( m_object->GetSelect() ) // center selected?
|
||||||
{
|
{
|
||||||
Error err = ERR_GENERIC;
|
Error err = ERR_UNKNOWN;
|
||||||
if ( event.type == EVENT_OBJECT_RTANK ) err = StartAction(RESEARCH_TANK);
|
if ( event.type == EVENT_OBJECT_RTANK ) err = StartAction(RESEARCH_TANK);
|
||||||
if ( event.type == EVENT_OBJECT_RFLY ) err = StartAction(RESEARCH_FLY);
|
if ( event.type == EVENT_OBJECT_RFLY ) err = StartAction(RESEARCH_FLY);
|
||||||
if ( event.type == EVENT_OBJECT_RTHUMP ) err = StartAction(RESEARCH_THUMP);
|
if ( event.type == EVENT_OBJECT_RTHUMP ) err = StartAction(RESEARCH_THUMP);
|
||||||
|
@ -177,10 +177,10 @@ bool CAutoResearch::EventProcess(const Event &event)
|
||||||
if ( event.type == EVENT_OBJECT_RSHIELD ) err = StartAction(RESEARCH_SHIELD);
|
if ( event.type == EVENT_OBJECT_RSHIELD ) err = StartAction(RESEARCH_SHIELD);
|
||||||
if ( event.type == EVENT_OBJECT_RATOMIC ) err = StartAction(RESEARCH_ATOMIC);
|
if ( event.type == EVENT_OBJECT_RATOMIC ) err = StartAction(RESEARCH_ATOMIC);
|
||||||
|
|
||||||
if( err != ERR_OK && err != ERR_GENERIC )
|
if( err != ERR_OK && err != ERR_UNKNOWN )
|
||||||
m_main->DisplayError(err, m_object);
|
m_main->DisplayError(err, m_object);
|
||||||
|
|
||||||
if( err != ERR_GENERIC )
|
if( err != ERR_UNKNOWN )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "object/implementation/power_container_impl.h"
|
||||||
|
|
||||||
|
CPowerContainerObjectImpl::CPowerContainerObjectImpl(ObjectInterfaceTypes& types, CObject* object)
|
||||||
|
: CPowerContainerObject(types)
|
||||||
|
, m_energyLevel(1.0f)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CPowerContainerObjectImpl::~CPowerContainerObjectImpl()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CPowerContainerObjectImpl::SetEnergyLevel(float level)
|
||||||
|
{
|
||||||
|
m_energyLevel = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
float CPowerContainerObjectImpl::GetEnergyLevel()
|
||||||
|
{
|
||||||
|
return m_energyLevel;
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* 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/interface/power_container_object.h"
|
||||||
|
|
||||||
|
class CObject;
|
||||||
|
|
||||||
|
class CPowerContainerObjectImpl : public CPowerContainerObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit CPowerContainerObjectImpl(ObjectInterfaceTypes& types, CObject* object);
|
||||||
|
virtual ~CPowerContainerObjectImpl();
|
||||||
|
|
||||||
|
void SetEnergyLevel(float level) override;
|
||||||
|
float GetEnergyLevel() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
float m_energyLevel;
|
||||||
|
};
|
|
@ -0,0 +1,622 @@
|
||||||
|
/*
|
||||||
|
* 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/implementation/programmable_impl.h"
|
||||||
|
|
||||||
|
#include "math/all.h"
|
||||||
|
|
||||||
|
#include "object/object.h"
|
||||||
|
#include "object/old_object.h"
|
||||||
|
#include "object/robotmain.h"
|
||||||
|
|
||||||
|
#include "object/interface/controllable_object.h"
|
||||||
|
#include "object/interface/task_executor_object.h"
|
||||||
|
|
||||||
|
#include "object/motion/motion.h"
|
||||||
|
#include "object/motion/motionvehicle.h"
|
||||||
|
|
||||||
|
#include "physics/physics.h"
|
||||||
|
|
||||||
|
#include "script/script.h"
|
||||||
|
|
||||||
|
#include "ui/controls/edit.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
CProgrammableObjectImpl::CProgrammableObjectImpl(ObjectInterfaceTypes& types, CObject* object)
|
||||||
|
: CProgrammableObject(types)
|
||||||
|
, m_object(object)
|
||||||
|
, m_activity(true)
|
||||||
|
, m_cmdLine()
|
||||||
|
, m_program()
|
||||||
|
, m_currentProgram(nullptr)
|
||||||
|
, m_activeVirus(false)
|
||||||
|
, m_scriptRun(nullptr)
|
||||||
|
, m_soluceName("")
|
||||||
|
, m_traceRecord(false)
|
||||||
|
{
|
||||||
|
assert(m_object != nullptr);
|
||||||
|
assert(m_object->Implements(ObjectInterfaceType::TaskExecutor));
|
||||||
|
}
|
||||||
|
|
||||||
|
CProgrammableObjectImpl::~CProgrammableObjectImpl()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool CProgrammableObjectImpl::EventProcess(const Event &event)
|
||||||
|
{
|
||||||
|
if (event.type == EVENT_FRAME)
|
||||||
|
{
|
||||||
|
if ( m_object->GetRuin() && IsProgram() )
|
||||||
|
{
|
||||||
|
StopProgram();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( GetActivity() )
|
||||||
|
{
|
||||||
|
if ( IsProgram() ) // current program?
|
||||||
|
{
|
||||||
|
if ( m_currentProgram->script->Continue() )
|
||||||
|
{
|
||||||
|
StopProgram();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_traceRecord ) // registration of the design in progress?
|
||||||
|
{
|
||||||
|
TraceRecordFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CProgrammableObjectImpl::SetActivity(bool activity)
|
||||||
|
{
|
||||||
|
m_activity = activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CProgrammableObjectImpl::GetActivity()
|
||||||
|
{
|
||||||
|
return m_activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CProgrammableObjectImpl::RunProgram(Program* program)
|
||||||
|
{
|
||||||
|
if ( program->script->Run() )
|
||||||
|
{
|
||||||
|
m_currentProgram = program; // start new program
|
||||||
|
m_object->UpdateInterface();
|
||||||
|
if (m_object->Implements(ObjectInterfaceType::Controllable) && dynamic_cast<CControllableObject*>(m_object)->GetTrainer())
|
||||||
|
CRobotMain::GetInstancePointer()->StartMissionTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CProgrammableObjectImpl::StopProgram()
|
||||||
|
{
|
||||||
|
if ( m_currentProgram != nullptr )
|
||||||
|
{
|
||||||
|
m_currentProgram->script->Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentProgram = nullptr;
|
||||||
|
|
||||||
|
m_object->UpdateInterface();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CProgrammableObjectImpl::IsProgram()
|
||||||
|
{
|
||||||
|
return m_currentProgram != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Introduces a virus into a program.
|
||||||
|
// Returns true if it was inserted.
|
||||||
|
|
||||||
|
bool CProgrammableObjectImpl::IntroduceVirus()
|
||||||
|
{
|
||||||
|
if(m_program.size() == 0) return false;
|
||||||
|
|
||||||
|
for ( int i=0 ; i<50 ; i++ )
|
||||||
|
{
|
||||||
|
int programIndex = rand() % m_program.size();
|
||||||
|
if ( m_program[programIndex]->script->IntroduceVirus() ) // tries to introduce
|
||||||
|
{
|
||||||
|
m_activeVirus = true; // active virus
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Active Virus indicates that the object is contaminated. Unlike ch'tites (??? - Programerus)
|
||||||
|
// letters which automatically disappear after a while,
|
||||||
|
// ActiveVirus does not disappear after you edit the program
|
||||||
|
// (Even if the virus is not fixed).
|
||||||
|
|
||||||
|
void CProgrammableObjectImpl::SetActiveVirus(bool bActive)
|
||||||
|
{
|
||||||
|
m_activeVirus = bActive;
|
||||||
|
|
||||||
|
if ( !m_activeVirus ) // virus disabled?
|
||||||
|
{
|
||||||
|
m_object->SetVirusMode(false); // chtites (??? - Programerus) letters also
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CProgrammableObjectImpl::GetActiveVirus()
|
||||||
|
{
|
||||||
|
return m_activeVirus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Program* CProgrammableObjectImpl::AddProgram()
|
||||||
|
{
|
||||||
|
assert(m_object->Implements(ObjectInterfaceType::Old)); //TODO
|
||||||
|
auto program = MakeUnique<Program>();
|
||||||
|
program->script = MakeUnique<CScript>(dynamic_cast<COldObject*>(this));
|
||||||
|
program->readOnly = false;
|
||||||
|
program->runnable = true;
|
||||||
|
|
||||||
|
Program* prog = program.get();
|
||||||
|
AddProgram(std::move(program));
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CProgrammableObjectImpl::AddProgram(std::unique_ptr<Program> program)
|
||||||
|
{
|
||||||
|
m_program.push_back(std::move(program));
|
||||||
|
m_object->UpdateInterface();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CProgrammableObjectImpl::RemoveProgram(Program* program)
|
||||||
|
{
|
||||||
|
if(m_currentProgram == program)
|
||||||
|
{
|
||||||
|
StopProgram();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_program.erase(
|
||||||
|
std::remove_if(m_program.begin(), m_program.end(),
|
||||||
|
[program](std::unique_ptr<Program>& prog) { return prog.get() == program; }),
|
||||||
|
m_program.end());
|
||||||
|
|
||||||
|
m_object->UpdateInterface();
|
||||||
|
}
|
||||||
|
|
||||||
|
Program* CProgrammableObjectImpl::CloneProgram(Program* program)
|
||||||
|
{
|
||||||
|
Program* newprog = AddProgram();
|
||||||
|
|
||||||
|
// TODO: Is there any reason CScript doesn't have a function to get the program code directly?
|
||||||
|
Ui::CEdit* edit = new Ui::CEdit();
|
||||||
|
edit->SetMaxChar(Ui::EDITSTUDIOMAX);
|
||||||
|
program->script->PutScript(edit, "");
|
||||||
|
newprog->script->GetScript(edit);
|
||||||
|
delete edit;
|
||||||
|
|
||||||
|
return newprog;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<Program>>& CProgrammableObjectImpl::GetPrograms()
|
||||||
|
{
|
||||||
|
return m_program;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CProgrammableObjectImpl::GetProgramCount()
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_program.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
int CProgrammableObjectImpl::GetProgramIndex(Program* program)
|
||||||
|
{
|
||||||
|
for(unsigned int i = 0; i < m_program.size(); i++)
|
||||||
|
{
|
||||||
|
if(m_program[i].get() == program)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CProgrammableObjectImpl::GetProgram()
|
||||||
|
{
|
||||||
|
if(m_currentProgram == nullptr)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < m_program.size(); i++)
|
||||||
|
{
|
||||||
|
if(m_program[i].get() == m_currentProgram)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Program* CProgrammableObjectImpl::GetProgram(int index)
|
||||||
|
{
|
||||||
|
if(index < 0 || index >= static_cast<int>(m_program.size()))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return m_program[index].get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Program* CProgrammableObjectImpl::GetOrAddProgram(int index)
|
||||||
|
{
|
||||||
|
if(index < 0)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if(index < static_cast<int>(m_program.size()))
|
||||||
|
return m_program[index].get();
|
||||||
|
|
||||||
|
for(int i = m_program.size(); i < index; i++)
|
||||||
|
{
|
||||||
|
AddProgram();
|
||||||
|
}
|
||||||
|
return AddProgram();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name management scripts to load.
|
||||||
|
|
||||||
|
void CProgrammableObjectImpl::SetScriptRun(Program* program)
|
||||||
|
{
|
||||||
|
m_scriptRun = program;
|
||||||
|
}
|
||||||
|
|
||||||
|
Program* CProgrammableObjectImpl::GetScriptRun()
|
||||||
|
{
|
||||||
|
return m_scriptRun;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CProgrammableObjectImpl::SetSoluceName(const std::string& name)
|
||||||
|
{
|
||||||
|
m_soluceName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& CProgrammableObjectImpl::GetSoluceName()
|
||||||
|
{
|
||||||
|
return m_soluceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Load a script solution, in the first free script.
|
||||||
|
// If there is already an identical script, nothing is loaded.
|
||||||
|
|
||||||
|
bool CProgrammableObjectImpl::ReadSoluce(const std::string& filename)
|
||||||
|
{
|
||||||
|
Program* prog = AddProgram();
|
||||||
|
|
||||||
|
if ( !ReadProgram(prog, filename) ) return false; // load solution
|
||||||
|
prog->readOnly = true;
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < m_program.size(); i++)
|
||||||
|
{
|
||||||
|
if(m_program[i].get() == prog) continue;
|
||||||
|
|
||||||
|
//TODO: This is bad. It's very sensitive to things like \n vs \r\n etc.
|
||||||
|
if ( m_program[i]->script->Compare(prog->script.get()) ) // the same already?
|
||||||
|
{
|
||||||
|
m_program[i]->readOnly = true; // Mark is as read-only
|
||||||
|
RemoveProgram(prog);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load a script with a text file.
|
||||||
|
|
||||||
|
bool CProgrammableObjectImpl::ReadProgram(Program* program, const std::string& filename)
|
||||||
|
{
|
||||||
|
if ( program->script->ReadScript(filename.c_str()) ) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Indicates whether a program is compiled correctly.
|
||||||
|
|
||||||
|
bool CProgrammableObjectImpl::GetCompile(Program* program)
|
||||||
|
{
|
||||||
|
return program->script->GetCompile();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Saves a script in a text file.
|
||||||
|
|
||||||
|
bool CProgrammableObjectImpl::WriteProgram(Program* program, const std::string& filename)
|
||||||
|
{
|
||||||
|
if ( program->script->WriteScript(filename.c_str()) ) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Load a stack of script implementation from a file.
|
||||||
|
|
||||||
|
bool CProgrammableObjectImpl::ReadStack(FILE *file)
|
||||||
|
{
|
||||||
|
short op;
|
||||||
|
|
||||||
|
fRead(&op, sizeof(short), 1, file);
|
||||||
|
if ( op == 1 ) // run ?
|
||||||
|
{
|
||||||
|
fRead(&op, sizeof(short), 1, file); // program rank
|
||||||
|
if ( op >= 0 )
|
||||||
|
{
|
||||||
|
assert(op < static_cast<int>(m_program.size()));
|
||||||
|
|
||||||
|
//TODO: m_selScript = op;
|
||||||
|
|
||||||
|
if ( !m_program[op]->script->ReadStack(file) ) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the script implementation stack of a file.
|
||||||
|
|
||||||
|
bool CProgrammableObjectImpl::WriteStack(FILE *file)
|
||||||
|
{
|
||||||
|
short op;
|
||||||
|
|
||||||
|
if ( m_currentProgram != nullptr && // current program?
|
||||||
|
m_currentProgram->script->IsRunning() )
|
||||||
|
{
|
||||||
|
op = 1; // run
|
||||||
|
fWrite(&op, sizeof(short), 1, file);
|
||||||
|
|
||||||
|
op = GetProgram();
|
||||||
|
fWrite(&op, sizeof(short), 1, file);
|
||||||
|
|
||||||
|
return m_currentProgram->script->WriteStack(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
op = 0; // stop
|
||||||
|
fWrite(&op, sizeof(short), 1, file);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const int MAXTRACERECORD = 1000;
|
||||||
|
|
||||||
|
// Start of registration of the design.
|
||||||
|
|
||||||
|
void CProgrammableObjectImpl::TraceRecordStart()
|
||||||
|
{
|
||||||
|
if (m_traceRecord)
|
||||||
|
{
|
||||||
|
TraceRecordStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(m_object->Implements(ObjectInterfaceType::Old)); // TODO
|
||||||
|
CMotionVehicle* motionVehicle = dynamic_cast<CMotionVehicle*>(dynamic_cast<COldObjectInterface*>(m_object)->GetMotion());
|
||||||
|
assert(motionVehicle != nullptr);
|
||||||
|
|
||||||
|
m_traceRecord = true;
|
||||||
|
|
||||||
|
m_traceOper = TO_STOP;
|
||||||
|
|
||||||
|
m_tracePos = m_object->GetPosition();
|
||||||
|
m_traceAngle = m_object->GetRotationY();
|
||||||
|
|
||||||
|
if ( motionVehicle->GetTraceDown() ) // pencil down?
|
||||||
|
{
|
||||||
|
m_traceColor = motionVehicle->GetTraceColor();
|
||||||
|
}
|
||||||
|
else // pen up?
|
||||||
|
{
|
||||||
|
m_traceColor = TraceColor::Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_traceRecordBuffer = MakeUniqueArray<TraceRecord>(MAXTRACERECORD);
|
||||||
|
m_traceRecordIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Saving the current drawing.
|
||||||
|
|
||||||
|
void CProgrammableObjectImpl::TraceRecordFrame()
|
||||||
|
{
|
||||||
|
TraceOper oper = TO_STOP;
|
||||||
|
Math::Vector pos;
|
||||||
|
float angle, len, speed;
|
||||||
|
|
||||||
|
assert(m_object->Implements(ObjectInterfaceType::Old)); // TODO
|
||||||
|
CMotionVehicle* motionVehicle = dynamic_cast<CMotionVehicle*>(dynamic_cast<COldObjectInterface*>(m_object)->GetMotion());
|
||||||
|
assert(motionVehicle != nullptr);
|
||||||
|
|
||||||
|
CPhysics* physics = dynamic_cast<COldObjectInterface*>(m_object)->GetPhysics();
|
||||||
|
|
||||||
|
speed = physics->GetLinMotionX(MO_REASPEED);
|
||||||
|
if ( speed > 0.0f ) oper = TO_ADVANCE;
|
||||||
|
if ( speed < 0.0f ) oper = TO_RECEDE;
|
||||||
|
|
||||||
|
speed = physics->GetCirMotionY(MO_REASPEED);
|
||||||
|
if ( speed != 0.0f ) oper = TO_TURN;
|
||||||
|
|
||||||
|
TraceColor color = TraceColor::Default;
|
||||||
|
if ( motionVehicle->GetTraceDown() ) // pencil down?
|
||||||
|
{
|
||||||
|
color = motionVehicle->GetTraceColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( oper != m_traceOper ||
|
||||||
|
color != m_traceColor )
|
||||||
|
{
|
||||||
|
if ( m_traceOper == TO_ADVANCE ||
|
||||||
|
m_traceOper == TO_RECEDE )
|
||||||
|
{
|
||||||
|
pos = m_object->GetPosition();
|
||||||
|
len = Math::DistanceProjected(pos, m_tracePos);
|
||||||
|
TraceRecordOper(m_traceOper, len);
|
||||||
|
}
|
||||||
|
if ( m_traceOper == TO_TURN )
|
||||||
|
{
|
||||||
|
angle = m_object->GetRotationY()-m_traceAngle;
|
||||||
|
TraceRecordOper(m_traceOper, angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( color != m_traceColor )
|
||||||
|
{
|
||||||
|
TraceRecordOper(TO_PEN, static_cast<float>(color));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_traceOper = oper;
|
||||||
|
m_tracePos = m_object->GetPosition();
|
||||||
|
m_traceAngle = m_object->GetRotationY();
|
||||||
|
m_traceColor = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// End of the registration of the design. Program generates the CBOT.
|
||||||
|
|
||||||
|
void CProgrammableObjectImpl::TraceRecordStop()
|
||||||
|
{
|
||||||
|
TraceOper lastOper, curOper;
|
||||||
|
float lastParam, curParam;
|
||||||
|
|
||||||
|
m_traceRecord = false;
|
||||||
|
|
||||||
|
std::stringstream buffer;
|
||||||
|
buffer << "extern void object::AutoDraw()\n{\n";
|
||||||
|
|
||||||
|
lastOper = TO_STOP;
|
||||||
|
lastParam = 0.0f;
|
||||||
|
for ( int i=0 ; i<m_traceRecordIndex ; i++ )
|
||||||
|
{
|
||||||
|
curOper = m_traceRecordBuffer[i].oper;
|
||||||
|
curParam = m_traceRecordBuffer[i].param;
|
||||||
|
|
||||||
|
if ( curOper == lastOper )
|
||||||
|
{
|
||||||
|
if ( curOper == TO_PEN )
|
||||||
|
{
|
||||||
|
lastParam = curParam;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastParam += curParam;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TraceRecordPut(buffer, lastOper, lastParam);
|
||||||
|
lastOper = curOper;
|
||||||
|
lastParam = curParam;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TraceRecordPut(buffer, lastOper, lastParam);
|
||||||
|
|
||||||
|
m_traceRecordBuffer.reset();
|
||||||
|
|
||||||
|
buffer << "}\n";
|
||||||
|
|
||||||
|
Program* prog = AddProgram();
|
||||||
|
prog->script->SendScript(buffer.str().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Saves an instruction CBOT.
|
||||||
|
|
||||||
|
bool CProgrammableObjectImpl::TraceRecordOper(TraceOper oper, float param)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = m_traceRecordIndex;
|
||||||
|
if ( i >= MAXTRACERECORD ) return false;
|
||||||
|
|
||||||
|
m_traceRecordBuffer[i].oper = oper;
|
||||||
|
m_traceRecordBuffer[i].param = param;
|
||||||
|
|
||||||
|
m_traceRecordIndex = i+1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates an instruction CBOT.
|
||||||
|
|
||||||
|
bool CProgrammableObjectImpl::TraceRecordPut(std::stringstream& buffer, TraceOper oper, float param)
|
||||||
|
{
|
||||||
|
if ( oper == TO_ADVANCE )
|
||||||
|
{
|
||||||
|
param /= g_unit;
|
||||||
|
buffer << "\tmove(" << std::fixed << std::setprecision(1) << param << ");\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( oper == TO_RECEDE )
|
||||||
|
{
|
||||||
|
param /= g_unit;
|
||||||
|
buffer << "\tmove(-" << std::fixed << std::setprecision(1) << param << ");\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( oper == TO_TURN )
|
||||||
|
{
|
||||||
|
param = -param*180.0f/Math::PI;
|
||||||
|
buffer << "\tturn(" << static_cast<int>(param) << ");\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( oper == TO_PEN )
|
||||||
|
{
|
||||||
|
TraceColor color = static_cast<TraceColor>(static_cast<int>(param));
|
||||||
|
if ( color == TraceColor::Default )
|
||||||
|
buffer << "\tpenup();\n";
|
||||||
|
else
|
||||||
|
buffer << "\tpendown(" << TraceColorName(color) << ");\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CProgrammableObjectImpl::IsTraceRecord()
|
||||||
|
{
|
||||||
|
return m_traceRecord;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CProgrammableObjectImpl::SetCmdLine(unsigned int rank, float value)
|
||||||
|
{
|
||||||
|
if (rank == m_cmdLine.size())
|
||||||
|
{
|
||||||
|
m_cmdLine.push_back(value);
|
||||||
|
}
|
||||||
|
else if (rank < m_cmdLine.size())
|
||||||
|
{
|
||||||
|
m_cmdLine[rank] = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// should never happen
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float CProgrammableObjectImpl::GetCmdLine(unsigned int rank)
|
||||||
|
{
|
||||||
|
if ( rank >= m_cmdLine.size() ) return 0.0f;
|
||||||
|
return m_cmdLine[rank];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float>& CProgrammableObjectImpl::GetCmdLine()
|
||||||
|
{
|
||||||
|
return m_cmdLine;
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
* 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/interface/interactive_object.h"
|
||||||
|
#include "object/interface/programmable_object.h"
|
||||||
|
|
||||||
|
#include "object/trace_color.h"
|
||||||
|
|
||||||
|
#include "math/vector.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
class CObject;
|
||||||
|
|
||||||
|
enum TraceOper
|
||||||
|
{
|
||||||
|
TO_STOP = 0, // stop
|
||||||
|
TO_ADVANCE = 1, // advance
|
||||||
|
TO_RECEDE = 2, // back
|
||||||
|
TO_TURN = 3, // rotate
|
||||||
|
TO_PEN = 4, // color change
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TraceRecord
|
||||||
|
{
|
||||||
|
TraceOper oper;
|
||||||
|
float param;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CProgrammableObjectImpl : public CProgrammableObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit CProgrammableObjectImpl(ObjectInterfaceTypes& types, CObject* object);
|
||||||
|
virtual ~CProgrammableObjectImpl();
|
||||||
|
|
||||||
|
bool EventProcess(const Event& event);
|
||||||
|
|
||||||
|
bool IsProgram() override;
|
||||||
|
void RunProgram(Program* program) override;
|
||||||
|
int GetProgram() override;
|
||||||
|
void StopProgram() override;
|
||||||
|
|
||||||
|
bool IntroduceVirus() override;
|
||||||
|
void SetActiveVirus(bool bActive) override;
|
||||||
|
bool GetActiveVirus() override;
|
||||||
|
|
||||||
|
void SetScriptRun(Program* rank) override;
|
||||||
|
Program* GetScriptRun() override;
|
||||||
|
void SetSoluceName(const std::string& name) override;
|
||||||
|
const std::string& GetSoluceName() override;
|
||||||
|
|
||||||
|
bool ReadSoluce(const std::string& filename) override;
|
||||||
|
bool ReadProgram(Program* program, const std::string& filename) override;
|
||||||
|
bool GetCompile(Program* program) override;
|
||||||
|
bool WriteProgram(Program* program, const std::string& filename) override;
|
||||||
|
bool ReadStack(FILE *file) override;
|
||||||
|
bool WriteStack(FILE *file) override;
|
||||||
|
|
||||||
|
Program* AddProgram() override;
|
||||||
|
void AddProgram(std::unique_ptr<Program> program) override;
|
||||||
|
void RemoveProgram(Program* program) override;
|
||||||
|
Program* CloneProgram(Program* program) override;
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<Program>>& GetPrograms() override;
|
||||||
|
int GetProgramCount() override;
|
||||||
|
Program* GetProgram(int index) override;
|
||||||
|
Program* GetOrAddProgram(int index) override;
|
||||||
|
int GetProgramIndex(Program* program) override;
|
||||||
|
|
||||||
|
void TraceRecordStart() override;
|
||||||
|
void TraceRecordStop() override;
|
||||||
|
bool IsTraceRecord() override;
|
||||||
|
|
||||||
|
void SetActivity(bool bMode) override;
|
||||||
|
bool GetActivity() override;
|
||||||
|
|
||||||
|
void SetCmdLine(unsigned int rank, float value);
|
||||||
|
float GetCmdLine(unsigned int rank) override;
|
||||||
|
std::vector<float>& GetCmdLine();
|
||||||
|
|
||||||
|
private:
|
||||||
|
//! Save current status to recording buffer
|
||||||
|
void TraceRecordFrame();
|
||||||
|
//! Save this operation to recording buffer
|
||||||
|
bool TraceRecordOper(TraceOper oper, float param);
|
||||||
|
//! Convert this recording operation to CBot instruction
|
||||||
|
bool TraceRecordPut(std::stringstream& buffer, TraceOper oper, float param);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CObject* m_object;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_activity;
|
||||||
|
|
||||||
|
std::vector<float> m_cmdLine;
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<Program>> m_program;
|
||||||
|
Program* m_currentProgram;
|
||||||
|
|
||||||
|
bool m_activeVirus;
|
||||||
|
|
||||||
|
Program* m_scriptRun;
|
||||||
|
std::string m_soluceName;
|
||||||
|
|
||||||
|
bool m_traceRecord;
|
||||||
|
TraceOper m_traceOper;
|
||||||
|
Math::Vector m_tracePos;
|
||||||
|
float m_traceAngle;
|
||||||
|
TraceColor m_traceColor;
|
||||||
|
int m_traceRecordIndex;
|
||||||
|
std::unique_ptr<TraceRecord[]> m_traceRecordBuffer;
|
||||||
|
};
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
* 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/implementation/task_executor_impl.h"
|
||||||
|
|
||||||
|
#include "object/object.h"
|
||||||
|
|
||||||
|
#include "object/task/taskmanager.h"
|
||||||
|
|
||||||
|
CTaskExecutorObjectImpl::CTaskExecutorObjectImpl(ObjectInterfaceTypes& types, CObject* object)
|
||||||
|
: CTaskExecutorObject(types)
|
||||||
|
, m_object(object)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CTaskExecutorObjectImpl::~CTaskExecutorObjectImpl()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool CTaskExecutorObjectImpl::EventProcess(const Event &event)
|
||||||
|
{
|
||||||
|
// NOTE: This function CAN'T BE CALLED BETWEEN CTaskManager::EventProcess AND CScriptFunctions::Process, otherwise weird stuff may happen to scripts (they'll be stuck executing the same task over and over again)
|
||||||
|
EndedTask();
|
||||||
|
|
||||||
|
if ( m_foregroundTask != nullptr )
|
||||||
|
{
|
||||||
|
m_foregroundTask->EventProcess(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_backgroundTask != nullptr )
|
||||||
|
{
|
||||||
|
m_backgroundTask->EventProcess(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTaskExecutorObjectImpl::IsForegroundTask()
|
||||||
|
{
|
||||||
|
return m_foregroundTask != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTaskExecutorObjectImpl::IsBackgroundTask()
|
||||||
|
{
|
||||||
|
return m_backgroundTask != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
CTaskManager* CTaskExecutorObjectImpl::GetForegroundTask()
|
||||||
|
{
|
||||||
|
return m_foregroundTask.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
CTaskManager* CTaskExecutorObjectImpl::GetBackgroundTask()
|
||||||
|
{
|
||||||
|
return m_backgroundTask.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stops the current task.
|
||||||
|
|
||||||
|
void CTaskExecutorObjectImpl::StopForegroundTask()
|
||||||
|
{
|
||||||
|
if (m_foregroundTask != nullptr)
|
||||||
|
{
|
||||||
|
m_foregroundTask->Abort();
|
||||||
|
m_foregroundTask.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stops the current secondary task.
|
||||||
|
|
||||||
|
void CTaskExecutorObjectImpl::StopBackgroundTask()
|
||||||
|
{
|
||||||
|
if (m_backgroundTask != nullptr)
|
||||||
|
{
|
||||||
|
m_backgroundTask->Abort();
|
||||||
|
m_backgroundTask.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Completes the task when the time came.
|
||||||
|
|
||||||
|
Error CTaskExecutorObjectImpl::EndedTask()
|
||||||
|
{
|
||||||
|
if (m_backgroundTask != nullptr) // current task?
|
||||||
|
{
|
||||||
|
Error err = m_backgroundTask->IsEnded();
|
||||||
|
if ( err != ERR_CONTINUE ) // job ended?
|
||||||
|
{
|
||||||
|
m_backgroundTask.reset();
|
||||||
|
m_object->UpdateInterface();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_foregroundTask != nullptr) // current task?
|
||||||
|
{
|
||||||
|
Error err = m_foregroundTask->IsEnded();
|
||||||
|
if ( err != ERR_CONTINUE ) // job ended?
|
||||||
|
{
|
||||||
|
m_foregroundTask.reset();
|
||||||
|
m_object->UpdateInterface();
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_STOP;
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* 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/interface/task_executor_object.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class CObject;
|
||||||
|
class CTaskManager;
|
||||||
|
|
||||||
|
class CTaskExecutorObjectImpl : public CTaskExecutorObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit CTaskExecutorObjectImpl(ObjectInterfaceTypes& types, CObject* object);
|
||||||
|
virtual ~CTaskExecutorObjectImpl();
|
||||||
|
|
||||||
|
bool EventProcess(const Event& event);
|
||||||
|
|
||||||
|
bool IsForegroundTask() override;
|
||||||
|
bool IsBackgroundTask() override;
|
||||||
|
|
||||||
|
CTaskManager* GetForegroundTask() override;
|
||||||
|
CTaskManager* GetBackgroundTask() override;
|
||||||
|
|
||||||
|
void StopForegroundTask() override;
|
||||||
|
void StopBackgroundTask() override;
|
||||||
|
|
||||||
|
Error StartTaskTake() { return ERR_WRONG_BOT; }
|
||||||
|
Error StartTaskManip(TaskManipOrder order, TaskManipArm arm) { return ERR_WRONG_BOT; }
|
||||||
|
Error StartTaskFlag(TaskFlagOrder order, int rank) { return ERR_WRONG_BOT; }
|
||||||
|
Error StartTaskBuild(ObjectType type) { return ERR_WRONG_BOT; }
|
||||||
|
Error StartTaskSearch() { return ERR_WRONG_BOT; }
|
||||||
|
Error StartTaskDeleteMark() { return ERR_WRONG_BOT; }
|
||||||
|
Error StartTaskTerraform() { return ERR_WRONG_BOT; }
|
||||||
|
Error StartTaskRecover() { return ERR_WRONG_BOT; }
|
||||||
|
Error StartTaskFire(float delay) { return ERR_WRONG_BOT; }
|
||||||
|
Error StartTaskFireAnt(Math::Vector impact) { return ERR_WRONG_BOT; }
|
||||||
|
Error StartTaskSpiderExplo() { return ERR_WRONG_BOT; }
|
||||||
|
Error StartTaskPen(bool down, TraceColor color = TraceColor::Default) { return ERR_WRONG_BOT; }
|
||||||
|
|
||||||
|
Error StartTaskWait(float time) { return ERR_UNKNOWN; }
|
||||||
|
Error StartTaskAdvance(float length) { return ERR_UNKNOWN; }
|
||||||
|
Error StartTaskTurn(float angle) { return ERR_UNKNOWN; }
|
||||||
|
Error StartTaskGoto(Math::Vector pos, float altitude, TaskGotoGoal goalMode, TaskGotoCrash crashMode) { return ERR_UNKNOWN; }
|
||||||
|
Error StartTaskInfo(const char *name, float value, float power, bool bSend) { return ERR_UNKNOWN; }
|
||||||
|
|
||||||
|
Error StartTaskShield(TaskShieldMode mode, float delay = 1000.0f) { return ERR_WRONG_BOT; }
|
||||||
|
Error StartTaskGunGoal(float dirV, float dirH) { return ERR_WRONG_BOT; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Error EndedTask();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<CTaskManager> m_foregroundTask;
|
||||||
|
std::unique_ptr<CTaskManager> m_backgroundTask;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CObject* m_object;
|
||||||
|
};
|
|
@ -61,13 +61,13 @@ public:
|
||||||
|
|
||||||
virtual void SetScriptRun(Program* rank) = 0;
|
virtual void SetScriptRun(Program* rank) = 0;
|
||||||
virtual Program* GetScriptRun() = 0;
|
virtual Program* GetScriptRun() = 0;
|
||||||
virtual void SetSoluceName(char *name) = 0;
|
virtual void SetSoluceName(const std::string& name) = 0;
|
||||||
virtual char* GetSoluceName() = 0;
|
virtual const std::string& GetSoluceName() = 0;
|
||||||
|
|
||||||
virtual bool ReadSoluce(char* filename) = 0;
|
virtual bool ReadSoluce(const std::string& filename) = 0;
|
||||||
virtual bool ReadProgram(Program* program, const char* filename) = 0;
|
virtual bool ReadProgram(Program* program, const std::string& filename) = 0;
|
||||||
virtual bool GetCompile(Program* program) = 0;
|
virtual bool GetCompile(Program* program) = 0;
|
||||||
virtual bool WriteProgram(Program* program, const char* filename) = 0;
|
virtual bool WriteProgram(Program* program, const std::string& filename) = 0;
|
||||||
virtual bool ReadStack(FILE *file) = 0;
|
virtual bool ReadStack(FILE *file) = 0;
|
||||||
virtual bool WriteStack(FILE *file) = 0;
|
virtual bool WriteStack(FILE *file) = 0;
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,9 @@ public:
|
||||||
//! Reads object properties from line in level file
|
//! Reads object properties from line in level file
|
||||||
virtual void Read(CLevelParserLine* line) = 0;
|
virtual void Read(CLevelParserLine* line) = 0;
|
||||||
|
|
||||||
|
//! Updates all interface controls
|
||||||
|
virtual void UpdateInterface() {};
|
||||||
|
|
||||||
//! Check if object implements the given type of interface
|
//! Check if object implements the given type of interface
|
||||||
inline bool Implements(ObjectInterfaceType type) const
|
inline bool Implements(ObjectInterfaceType type) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -86,8 +86,6 @@ static float debug_arm2 = 0.0f;
|
||||||
static float debug_arm3 = 0.0f;
|
static float debug_arm3 = 0.0f;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const int MAXTRACERECORD = 1000;
|
|
||||||
|
|
||||||
|
|
||||||
// Object's constructor.
|
// Object's constructor.
|
||||||
|
|
||||||
|
@ -95,14 +93,14 @@ COldObject::COldObject(int id)
|
||||||
: CObject(id, OBJECT_NULL)
|
: CObject(id, OBJECT_NULL)
|
||||||
, CInteractiveObject(m_implementedInterfaces)
|
, CInteractiveObject(m_implementedInterfaces)
|
||||||
, CTransportableObject(m_implementedInterfaces)
|
, CTransportableObject(m_implementedInterfaces)
|
||||||
, CTaskExecutorObject(m_implementedInterfaces)
|
, CTaskExecutorObjectImpl(m_implementedInterfaces, this)
|
||||||
, CProgrammableObject(m_implementedInterfaces)
|
, CProgrammableObjectImpl(m_implementedInterfaces, this)
|
||||||
, CJostleableObject(m_implementedInterfaces)
|
, CJostleableObject(m_implementedInterfaces)
|
||||||
, CCarrierObject(m_implementedInterfaces)
|
, CCarrierObject(m_implementedInterfaces)
|
||||||
, CPoweredObject(m_implementedInterfaces)
|
, CPoweredObject(m_implementedInterfaces)
|
||||||
, CMovableObject(m_implementedInterfaces)
|
, CMovableObject(m_implementedInterfaces)
|
||||||
, CControllableObject(m_implementedInterfaces)
|
, CControllableObject(m_implementedInterfaces)
|
||||||
, CPowerContainerObject(m_implementedInterfaces)
|
, CPowerContainerObjectImpl(m_implementedInterfaces, this)
|
||||||
{
|
{
|
||||||
// A bit of a hack since we don't have subclasses yet, set externally in SetProgrammable()
|
// A bit of a hack since we don't have subclasses yet, set externally in SetProgrammable()
|
||||||
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = false;
|
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = false;
|
||||||
|
@ -132,7 +130,6 @@ COldObject::COldObject(int id)
|
||||||
m_cargo = 0;
|
m_cargo = 0;
|
||||||
m_transporter = 0;
|
m_transporter = 0;
|
||||||
m_transporterLink = 0;
|
m_transporterLink = 0;
|
||||||
m_energy = 1.0f;
|
|
||||||
m_shield = 1.0f;
|
m_shield = 1.0f;
|
||||||
m_range = 0.0f;
|
m_range = 0.0f;
|
||||||
m_transparency = 0.0f;
|
m_transparency = 0.0f;
|
||||||
|
@ -185,22 +182,11 @@ COldObject::COldObject(int id)
|
||||||
m_partiSel[i] = -1;
|
m_partiSel[i] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cmdLine.clear();
|
|
||||||
|
|
||||||
m_activity = true;
|
|
||||||
|
|
||||||
m_currentProgram = nullptr;
|
|
||||||
m_bActiveVirus = false;
|
|
||||||
m_time = 0.0f;
|
m_time = 0.0f;
|
||||||
m_burnTime = 0.0f;
|
m_burnTime = 0.0f;
|
||||||
|
|
||||||
m_buttonAxe = EVENT_NULL;
|
m_buttonAxe = EVENT_NULL;
|
||||||
|
|
||||||
m_scriptRun = nullptr;
|
|
||||||
m_soluceName[0] = 0;
|
|
||||||
|
|
||||||
m_traceRecord = false;
|
|
||||||
|
|
||||||
DeleteAllCrashSpheres();
|
DeleteAllCrashSpheres();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -806,7 +792,7 @@ void COldObject::Write(CLevelParserLine* line)
|
||||||
|
|
||||||
// Sets the parameters of the command line.
|
// Sets the parameters of the command line.
|
||||||
CLevelParserParamVec cmdline;
|
CLevelParserParamVec cmdline;
|
||||||
for(float value : m_cmdLine)
|
for(float value : GetCmdLine())
|
||||||
{
|
{
|
||||||
cmdline.push_back(MakeUnique<CLevelParserParam>(value));
|
cmdline.push_back(MakeUnique<CLevelParserParam>(value));
|
||||||
}
|
}
|
||||||
|
@ -820,7 +806,7 @@ void COldObject::Write(CLevelParserLine* line)
|
||||||
|
|
||||||
if ( Implements(ObjectInterfaceType::Programmable) )
|
if ( Implements(ObjectInterfaceType::Programmable) )
|
||||||
{
|
{
|
||||||
line->AddParam("bVirusActive", MakeUnique<CLevelParserParam>(m_bActiveVirus));
|
line->AddParam("bVirusActive", MakeUnique<CLevelParserParam>(GetActiveVirus()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( Implements(ObjectInterfaceType::TaskExecutor) )
|
if ( Implements(ObjectInterfaceType::TaskExecutor) )
|
||||||
|
@ -891,7 +877,7 @@ void COldObject::Read(CLevelParserLine* line)
|
||||||
|
|
||||||
if (Implements(ObjectInterfaceType::Programmable))
|
if (Implements(ObjectInterfaceType::Programmable))
|
||||||
{
|
{
|
||||||
m_bActiveVirus = line->GetParam("bVirusActive")->AsBool(false);
|
SetActiveVirus(line->GetParam("bVirusActive")->AsBool(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Implements(ObjectInterfaceType::TaskExecutor))
|
if (Implements(ObjectInterfaceType::TaskExecutor))
|
||||||
|
@ -1382,29 +1368,6 @@ float COldObject::GetInfoReturn()
|
||||||
return m_infoReturn;
|
return m_infoReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void COldObject::SetCmdLine(unsigned int rank, float value)
|
|
||||||
{
|
|
||||||
if (rank == m_cmdLine.size())
|
|
||||||
{
|
|
||||||
m_cmdLine.push_back(value);
|
|
||||||
}
|
|
||||||
else if (rank < m_cmdLine.size())
|
|
||||||
{
|
|
||||||
m_cmdLine[rank] = value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// should never happen
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float COldObject::GetCmdLine(unsigned int rank)
|
|
||||||
{
|
|
||||||
if ( rank >= m_cmdLine.size() ) return 0.0f;
|
|
||||||
return m_cmdLine[rank];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Returns matrices of an object portion.
|
// Returns matrices of an object portion.
|
||||||
|
|
||||||
|
@ -1735,10 +1698,10 @@ void COldObject::FlatParent()
|
||||||
|
|
||||||
void COldObject::UpdateEnergyMapping()
|
void COldObject::UpdateEnergyMapping()
|
||||||
{
|
{
|
||||||
if (Math::IsEqual(m_energy, m_lastEnergy, 0.01f))
|
if (Math::IsEqual(GetEnergyLevel(), m_lastEnergy, 0.01f))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_lastEnergy = m_energy;
|
m_lastEnergy = GetEnergyLevel();
|
||||||
|
|
||||||
Gfx::Material mat;
|
Gfx::Material mat;
|
||||||
mat.diffuse = Gfx::Color(1.0f, 1.0f, 1.0f); // white
|
mat.diffuse = Gfx::Color(1.0f, 1.0f, 1.0f); // white
|
||||||
|
@ -1763,7 +1726,7 @@ void COldObject::UpdateEnergyMapping()
|
||||||
b = 3.0f; // dimensions of the battery (according to y)
|
b = 3.0f; // dimensions of the battery (according to y)
|
||||||
}
|
}
|
||||||
|
|
||||||
float i = 0.50f+0.25f*m_energy; // origin
|
float i = 0.50f+0.25f*GetEnergyLevel(); // origin
|
||||||
float s = i+0.25f; // width
|
float s = i+0.25f; // width
|
||||||
|
|
||||||
float au = (s-i)/(b-a);
|
float au = (s-i)/(b-a);
|
||||||
|
@ -1822,15 +1785,8 @@ bool COldObject::EventProcess(const Event &event)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_foregroundTask != nullptr )
|
// NOTE: This should be called befoce CProgrammableObjectImpl::EventProcess, see the other note inside this function
|
||||||
{
|
if (!CTaskExecutorObjectImpl::EventProcess(event)) return true;
|
||||||
m_foregroundTask->EventProcess(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( m_backgroundTask != nullptr )
|
|
||||||
{
|
|
||||||
m_backgroundTask->EventProcess(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( m_physics != nullptr )
|
if ( m_physics != nullptr )
|
||||||
{
|
{
|
||||||
|
@ -1848,14 +1804,6 @@ bool COldObject::EventProcess(const Event &event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Implements(ObjectInterfaceType::Programmable))
|
|
||||||
{
|
|
||||||
if ( GetRuin() && m_currentProgram != nullptr )
|
|
||||||
{
|
|
||||||
StopProgram();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Implements(ObjectInterfaceType::Movable) && m_physics != nullptr)
|
if (Implements(ObjectInterfaceType::Movable) && m_physics != nullptr)
|
||||||
{
|
{
|
||||||
bool deselectedStop = !GetSelect();
|
bool deselectedStop = !GetSelect();
|
||||||
|
@ -1990,6 +1938,8 @@ bool COldObject::EventProcess(const Event &event)
|
||||||
if (!m_motion->EventProcess(event)) return false;
|
if (!m_motion->EventProcess(event)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!CProgrammableObjectImpl::EventProcess(event)) return true;
|
||||||
|
|
||||||
if ( event.type == EVENT_FRAME )
|
if ( event.type == EVENT_FRAME )
|
||||||
{
|
{
|
||||||
return EventFrame(event);
|
return EventFrame(event);
|
||||||
|
@ -2025,28 +1975,6 @@ bool COldObject::EventFrame(const Event &event)
|
||||||
UpdateTransformObject();
|
UpdateTransformObject();
|
||||||
UpdateSelectParticle();
|
UpdateSelectParticle();
|
||||||
|
|
||||||
if (Implements(ObjectInterfaceType::Programmable))
|
|
||||||
{
|
|
||||||
if ( GetActivity() )
|
|
||||||
{
|
|
||||||
if ( m_currentProgram != nullptr ) // current program?
|
|
||||||
{
|
|
||||||
if ( m_currentProgram->script->Continue() )
|
|
||||||
{
|
|
||||||
StopProgram();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( m_traceRecord ) // registration of the design in progress?
|
|
||||||
{
|
|
||||||
TraceRecordFrame();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: This MUST be called AFTER CScriptFunctions::Process, otherwise weird stuff may happen to scripts
|
|
||||||
EndedTask();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2292,25 +2220,6 @@ float COldObject::GetAbsTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Management of energy contained in a battery.
|
|
||||||
// Single subject possesses the battery energy, but not the vehicle that carries the battery!
|
|
||||||
|
|
||||||
void COldObject::SetEnergyLevel(float level)
|
|
||||||
{
|
|
||||||
if ( level < 0.0f ) level = 0.0f;
|
|
||||||
if ( level > 1.0f ) level = 1.0f;
|
|
||||||
m_energy = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
float COldObject::GetEnergyLevel()
|
|
||||||
{
|
|
||||||
if ( m_type != OBJECT_POWER &&
|
|
||||||
m_type != OBJECT_ATOMIC &&
|
|
||||||
m_type != OBJECT_STATION &&
|
|
||||||
m_type != OBJECT_ENERGY ) return 0.0f;
|
|
||||||
return m_energy;
|
|
||||||
}
|
|
||||||
|
|
||||||
float COldObject::GetCapacity()
|
float COldObject::GetCapacity()
|
||||||
{
|
{
|
||||||
return m_type == OBJECT_ATOMIC ? 10.0f : 1.0f;
|
return m_type == OBJECT_ATOMIC ? 10.0f : 1.0f;
|
||||||
|
@ -3310,603 +3219,25 @@ Error COldObject::StartTaskGunGoal(float dirV, float dirH)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indicates whether the object is busy with a task.
|
|
||||||
|
|
||||||
bool COldObject::IsForegroundTask()
|
|
||||||
{
|
|
||||||
return (m_foregroundTask.get() != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool COldObject::IsBackgroundTask()
|
|
||||||
{
|
|
||||||
return (m_backgroundTask.get() != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
CTaskManager* COldObject::GetForegroundTask()
|
|
||||||
{
|
|
||||||
return m_foregroundTask.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
CTaskManager* COldObject::GetBackgroundTask()
|
|
||||||
{
|
|
||||||
return m_backgroundTask.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stops the current task.
|
|
||||||
|
|
||||||
void COldObject::StopForegroundTask()
|
|
||||||
{
|
|
||||||
if (m_foregroundTask != nullptr)
|
|
||||||
{
|
|
||||||
m_foregroundTask->Abort();
|
|
||||||
m_foregroundTask.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stops the current secondary task.
|
|
||||||
|
|
||||||
void COldObject::StopBackgroundTask()
|
|
||||||
{
|
|
||||||
if (m_backgroundTask != nullptr)
|
|
||||||
{
|
|
||||||
m_backgroundTask->Abort();
|
|
||||||
m_backgroundTask.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Completes the task when the time came.
|
|
||||||
|
|
||||||
Error COldObject::EndedTask()
|
|
||||||
{
|
|
||||||
if (m_backgroundTask.get() != nullptr) // current task?
|
|
||||||
{
|
|
||||||
Error err = m_backgroundTask->IsEnded();
|
|
||||||
if ( err != ERR_CONTINUE ) // job ended?
|
|
||||||
{
|
|
||||||
m_backgroundTask.reset();
|
|
||||||
UpdateInterface();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_foregroundTask.get() != nullptr) // current task?
|
|
||||||
{
|
|
||||||
Error err = m_foregroundTask->IsEnded();
|
|
||||||
if ( err != ERR_CONTINUE ) // job ended?
|
|
||||||
{
|
|
||||||
m_foregroundTask.reset();
|
|
||||||
UpdateInterface();
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ERR_STOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Management of the activity of an object.
|
|
||||||
|
|
||||||
void COldObject::SetActivity(bool activity)
|
|
||||||
{
|
|
||||||
m_activity = activity;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool COldObject::GetActivity()
|
|
||||||
{
|
|
||||||
return m_activity;
|
|
||||||
}
|
|
||||||
|
|
||||||
void COldObject::UpdateInterface()
|
void COldObject::UpdateInterface()
|
||||||
{
|
{
|
||||||
if (m_objectInterface != nullptr && GetSelect())
|
if (m_objectInterface != nullptr && GetSelect())
|
||||||
{
|
{
|
||||||
m_objectInterface->UpdateInterface();
|
m_objectInterface->UpdateInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CreateSelectParticle();
|
||||||
|
m_main->UpdateShortcuts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Stops the running program.
|
|
||||||
|
|
||||||
void COldObject::StopProgram()
|
void COldObject::StopProgram()
|
||||||
{
|
{
|
||||||
StopForegroundTask();
|
CProgrammableObjectImpl::StopProgram();
|
||||||
|
|
||||||
if ( m_type == OBJECT_HUMAN ||
|
|
||||||
m_type == OBJECT_TECH ) return;
|
|
||||||
|
|
||||||
if ( m_currentProgram != nullptr )
|
|
||||||
{
|
|
||||||
m_currentProgram->script->Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_currentProgram = nullptr;
|
|
||||||
|
|
||||||
|
//TODO: I don't want CProgrammableObjectImpl to depend on motion and physics, refactor this somehow
|
||||||
m_physics->SetMotorSpeedX(0.0f);
|
m_physics->SetMotorSpeedX(0.0f);
|
||||||
m_physics->SetMotorSpeedY(0.0f);
|
m_physics->SetMotorSpeedY(0.0f);
|
||||||
m_physics->SetMotorSpeedZ(0.0f);
|
m_physics->SetMotorSpeedZ(0.0f);
|
||||||
|
|
||||||
m_motion->SetAction(-1);
|
m_motion->SetAction(-1);
|
||||||
|
|
||||||
UpdateInterface();
|
|
||||||
m_main->UpdateShortcuts();
|
|
||||||
CreateSelectParticle();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Introduces a virus into a program.
|
|
||||||
// Returns true if it was inserted.
|
|
||||||
|
|
||||||
bool COldObject::IntroduceVirus()
|
|
||||||
{
|
|
||||||
if(m_program.size() == 0) return false;
|
|
||||||
|
|
||||||
for ( int i=0 ; i<50 ; i++ )
|
|
||||||
{
|
|
||||||
int j = rand()%m_program.size();
|
|
||||||
if ( m_program[j]->script->IntroduceVirus() ) // tries to introduce
|
|
||||||
{
|
|
||||||
m_bActiveVirus = true; // active virus
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Active Virus indicates that the object is contaminated. Unlike ch'tites (??? - Programerus)
|
|
||||||
// letters which automatically disappear after a while,
|
|
||||||
// ActiveVirus does not disappear after you edit the program
|
|
||||||
// (Even if the virus is not fixed).
|
|
||||||
|
|
||||||
|
|
||||||
void COldObject::SetActiveVirus(bool bActive)
|
|
||||||
{
|
|
||||||
m_bActiveVirus = bActive;
|
|
||||||
|
|
||||||
if ( !m_bActiveVirus ) // virus disabled?
|
|
||||||
{
|
|
||||||
SetVirusMode(false); // chtites (??? - Programerus) letters also
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool COldObject::GetActiveVirus()
|
|
||||||
{
|
|
||||||
return m_bActiveVirus;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Indicates whether a program is running.
|
|
||||||
|
|
||||||
bool COldObject::IsProgram()
|
|
||||||
{
|
|
||||||
return m_currentProgram != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Starts a program.
|
|
||||||
|
|
||||||
void COldObject::RunProgram(Program* program)
|
|
||||||
{
|
|
||||||
if ( program->script->Run() )
|
|
||||||
{
|
|
||||||
m_currentProgram = program; // start new program
|
|
||||||
UpdateInterface();
|
|
||||||
CreateSelectParticle();
|
|
||||||
m_main->UpdateShortcuts();
|
|
||||||
if(GetTrainer())
|
|
||||||
m_main->StartMissionTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Returns the current program.
|
|
||||||
|
|
||||||
int COldObject::GetProgram()
|
|
||||||
{
|
|
||||||
if(m_currentProgram == nullptr)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < m_program.size(); i++)
|
|
||||||
{
|
|
||||||
if(m_program[i].get() == m_currentProgram)
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Name management scripts to load.
|
|
||||||
|
|
||||||
void COldObject::SetScriptRun(Program* program)
|
|
||||||
{
|
|
||||||
m_scriptRun = program;
|
|
||||||
}
|
|
||||||
|
|
||||||
Program* COldObject::GetScriptRun()
|
|
||||||
{
|
|
||||||
return m_scriptRun;
|
|
||||||
}
|
|
||||||
|
|
||||||
void COldObject::SetSoluceName(char *name)
|
|
||||||
{
|
|
||||||
strcpy(m_soluceName, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* COldObject::GetSoluceName()
|
|
||||||
{
|
|
||||||
return m_soluceName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Load a script solution, in the first free script.
|
|
||||||
// If there is already an identical script, nothing is loaded.
|
|
||||||
|
|
||||||
bool COldObject::ReadSoluce(char* filename)
|
|
||||||
{
|
|
||||||
Program* prog = AddProgram();
|
|
||||||
|
|
||||||
if ( !ReadProgram(prog, filename) ) return false; // load solution
|
|
||||||
prog->readOnly = true;
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < m_program.size(); i++)
|
|
||||||
{
|
|
||||||
if(m_program[i].get() == prog) continue;
|
|
||||||
|
|
||||||
//TODO: This is bad. It's very sensitive to things like \n vs \r\n etc.
|
|
||||||
if ( m_program[i]->script->Compare(prog->script.get()) ) // the same already?
|
|
||||||
{
|
|
||||||
m_program[i]->readOnly = true; // Mark is as read-only
|
|
||||||
RemoveProgram(prog);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load a script with a text file.
|
|
||||||
|
|
||||||
bool COldObject::ReadProgram(Program* program, const char* filename)
|
|
||||||
{
|
|
||||||
if ( program->script->ReadScript(filename) ) return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Indicates whether a program is compiled correctly.
|
|
||||||
|
|
||||||
bool COldObject::GetCompile(Program* program)
|
|
||||||
{
|
|
||||||
return program->script->GetCompile();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Saves a script in a text file.
|
|
||||||
|
|
||||||
bool COldObject::WriteProgram(Program* program, const char* filename)
|
|
||||||
{
|
|
||||||
if ( program->script->WriteScript(filename) ) return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Load a stack of script implementation from a file.
|
|
||||||
|
|
||||||
bool COldObject::ReadStack(FILE *file)
|
|
||||||
{
|
|
||||||
short op;
|
|
||||||
|
|
||||||
fRead(&op, sizeof(short), 1, file);
|
|
||||||
if ( op == 1 ) // run ?
|
|
||||||
{
|
|
||||||
fRead(&op, sizeof(short), 1, file); // program rank
|
|
||||||
if ( op >= 0 )
|
|
||||||
{
|
|
||||||
assert(op < static_cast<int>(m_program.size())); //TODO: is it good?
|
|
||||||
|
|
||||||
//TODO: m_selScript = op;
|
|
||||||
|
|
||||||
if ( !m_program[op]->script->ReadStack(file) ) return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the script implementation stack of a file.
|
|
||||||
|
|
||||||
bool COldObject::WriteStack(FILE *file)
|
|
||||||
{
|
|
||||||
short op;
|
|
||||||
|
|
||||||
if ( m_currentProgram != nullptr && // current program?
|
|
||||||
m_currentProgram->script->IsRunning() )
|
|
||||||
{
|
|
||||||
op = 1; // run
|
|
||||||
fWrite(&op, sizeof(short), 1, file);
|
|
||||||
|
|
||||||
op = GetProgram();
|
|
||||||
fWrite(&op, sizeof(short), 1, file);
|
|
||||||
|
|
||||||
return m_currentProgram->script->WriteStack(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
op = 0; // stop
|
|
||||||
fWrite(&op, sizeof(short), 1, file);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Start of registration of the design.
|
|
||||||
|
|
||||||
void COldObject::TraceRecordStart()
|
|
||||||
{
|
|
||||||
if (m_traceRecord)
|
|
||||||
{
|
|
||||||
TraceRecordStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
CMotionVehicle* motionVehicle = dynamic_cast<CMotionVehicle*>(m_motion.get());
|
|
||||||
assert(motionVehicle != nullptr);
|
|
||||||
|
|
||||||
m_traceRecord = true;
|
|
||||||
|
|
||||||
m_traceOper = TO_STOP;
|
|
||||||
|
|
||||||
m_tracePos = GetPosition();
|
|
||||||
m_traceAngle = GetRotationY();
|
|
||||||
|
|
||||||
if ( motionVehicle->GetTraceDown() ) // pencil down?
|
|
||||||
{
|
|
||||||
m_traceColor = motionVehicle->GetTraceColor();
|
|
||||||
}
|
|
||||||
else // pen up?
|
|
||||||
{
|
|
||||||
m_traceColor = TraceColor::Default;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_traceRecordBuffer = MakeUniqueArray<TraceRecord>(MAXTRACERECORD);
|
|
||||||
m_traceRecordIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Saving the current drawing.
|
|
||||||
|
|
||||||
void COldObject::TraceRecordFrame()
|
|
||||||
{
|
|
||||||
TraceOper oper = TO_STOP;
|
|
||||||
Math::Vector pos;
|
|
||||||
float angle, len, speed;
|
|
||||||
|
|
||||||
CMotionVehicle* motionVehicle = dynamic_cast<CMotionVehicle*>(m_motion.get());
|
|
||||||
assert(motionVehicle != nullptr);
|
|
||||||
|
|
||||||
speed = m_physics->GetLinMotionX(MO_REASPEED);
|
|
||||||
if ( speed > 0.0f ) oper = TO_ADVANCE;
|
|
||||||
if ( speed < 0.0f ) oper = TO_RECEDE;
|
|
||||||
|
|
||||||
speed = m_physics->GetCirMotionY(MO_REASPEED);
|
|
||||||
if ( speed != 0.0f ) oper = TO_TURN;
|
|
||||||
|
|
||||||
TraceColor color = TraceColor::Default;
|
|
||||||
if ( motionVehicle->GetTraceDown() ) // pencil down?
|
|
||||||
{
|
|
||||||
color = motionVehicle->GetTraceColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( oper != m_traceOper ||
|
|
||||||
color != m_traceColor )
|
|
||||||
{
|
|
||||||
if ( m_traceOper == TO_ADVANCE ||
|
|
||||||
m_traceOper == TO_RECEDE )
|
|
||||||
{
|
|
||||||
pos = GetPosition();
|
|
||||||
len = Math::DistanceProjected(pos, m_tracePos);
|
|
||||||
TraceRecordOper(m_traceOper, len);
|
|
||||||
}
|
|
||||||
if ( m_traceOper == TO_TURN )
|
|
||||||
{
|
|
||||||
angle = GetRotationY()-m_traceAngle;
|
|
||||||
TraceRecordOper(m_traceOper, angle);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( color != m_traceColor )
|
|
||||||
{
|
|
||||||
TraceRecordOper(TO_PEN, static_cast<float>(color));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_traceOper = oper;
|
|
||||||
m_tracePos = GetPosition();
|
|
||||||
m_traceAngle = GetRotationY();
|
|
||||||
m_traceColor = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// End of the registration of the design. Program generates the CBOT.
|
|
||||||
|
|
||||||
void COldObject::TraceRecordStop()
|
|
||||||
{
|
|
||||||
TraceOper lastOper, curOper;
|
|
||||||
float lastParam, curParam;
|
|
||||||
|
|
||||||
m_traceRecord = false;
|
|
||||||
|
|
||||||
std::stringstream buffer;
|
|
||||||
buffer << "extern void object::AutoDraw()\n{\n";
|
|
||||||
|
|
||||||
lastOper = TO_STOP;
|
|
||||||
lastParam = 0.0f;
|
|
||||||
for ( int i=0 ; i<m_traceRecordIndex ; i++ )
|
|
||||||
{
|
|
||||||
curOper = m_traceRecordBuffer[i].oper;
|
|
||||||
curParam = m_traceRecordBuffer[i].param;
|
|
||||||
|
|
||||||
if ( curOper == lastOper )
|
|
||||||
{
|
|
||||||
if ( curOper == TO_PEN )
|
|
||||||
{
|
|
||||||
lastParam = curParam;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lastParam += curParam;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TraceRecordPut(buffer, lastOper, lastParam);
|
|
||||||
lastOper = curOper;
|
|
||||||
lastParam = curParam;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TraceRecordPut(buffer, lastOper, lastParam);
|
|
||||||
|
|
||||||
m_traceRecordBuffer.reset();
|
|
||||||
|
|
||||||
buffer << "}\n";
|
|
||||||
|
|
||||||
Program* prog = AddProgram();
|
|
||||||
prog->script->SendScript(buffer.str().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Saves an instruction CBOT.
|
|
||||||
|
|
||||||
bool COldObject::TraceRecordOper(TraceOper oper, float param)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
i = m_traceRecordIndex;
|
|
||||||
if ( i >= MAXTRACERECORD ) return false;
|
|
||||||
|
|
||||||
m_traceRecordBuffer[i].oper = oper;
|
|
||||||
m_traceRecordBuffer[i].param = param;
|
|
||||||
|
|
||||||
m_traceRecordIndex = i+1;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates an instruction CBOT.
|
|
||||||
|
|
||||||
bool COldObject::TraceRecordPut(std::stringstream& buffer, TraceOper oper, float param)
|
|
||||||
{
|
|
||||||
if ( oper == TO_ADVANCE )
|
|
||||||
{
|
|
||||||
param /= g_unit;
|
|
||||||
buffer << "\tmove(" << std::fixed << std::setprecision(1) << param << ");\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( oper == TO_RECEDE )
|
|
||||||
{
|
|
||||||
param /= g_unit;
|
|
||||||
buffer << "\tmove(-" << std::fixed << std::setprecision(1) << param << ");\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( oper == TO_TURN )
|
|
||||||
{
|
|
||||||
param = -param*180.0f/Math::PI;
|
|
||||||
buffer << "\tturn(" << static_cast<int>(param) << ");\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( oper == TO_PEN )
|
|
||||||
{
|
|
||||||
TraceColor color = static_cast<TraceColor>(static_cast<int>(param));
|
|
||||||
if ( color == TraceColor::Default )
|
|
||||||
buffer << "\tpenup();\n";
|
|
||||||
else
|
|
||||||
buffer << "\tpendown(" << TraceColorName(color) << ");\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool COldObject::IsTraceRecord()
|
|
||||||
{
|
|
||||||
return m_traceRecord;
|
|
||||||
}
|
|
||||||
|
|
||||||
Program* COldObject::AddProgram()
|
|
||||||
{
|
|
||||||
auto program = MakeUnique<Program>();
|
|
||||||
program->script = MakeUnique<CScript>(this);
|
|
||||||
program->readOnly = false;
|
|
||||||
program->runnable = true;
|
|
||||||
|
|
||||||
Program* prog = program.get();
|
|
||||||
AddProgram(std::move(program));
|
|
||||||
return prog;
|
|
||||||
}
|
|
||||||
|
|
||||||
void COldObject::AddProgram(std::unique_ptr<Program> program)
|
|
||||||
{
|
|
||||||
m_program.push_back(std::move(program));
|
|
||||||
UpdateInterface();
|
|
||||||
}
|
|
||||||
|
|
||||||
void COldObject::RemoveProgram(Program* program)
|
|
||||||
{
|
|
||||||
if(m_currentProgram == program)
|
|
||||||
{
|
|
||||||
StopProgram();
|
|
||||||
}
|
|
||||||
m_program.erase(
|
|
||||||
std::remove_if(m_program.begin(), m_program.end(),
|
|
||||||
[program](std::unique_ptr<Program>& prog) { return prog.get() == program; }),
|
|
||||||
m_program.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
Program* COldObject::CloneProgram(Program* program)
|
|
||||||
{
|
|
||||||
Program* newprog = AddProgram();
|
|
||||||
|
|
||||||
// TODO: Is there any reason CScript doesn't have a function to get the program code directly?
|
|
||||||
Ui::CEdit* edit = new Ui::CEdit();
|
|
||||||
edit->SetMaxChar(Ui::EDITSTUDIOMAX);
|
|
||||||
program->script->PutScript(edit, "");
|
|
||||||
newprog->script->GetScript(edit);
|
|
||||||
delete edit;
|
|
||||||
|
|
||||||
return newprog;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Program>>& COldObject::GetPrograms()
|
|
||||||
{
|
|
||||||
return m_program;
|
|
||||||
}
|
|
||||||
|
|
||||||
int COldObject::GetProgramCount()
|
|
||||||
{
|
|
||||||
return static_cast<int>(m_program.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
int COldObject::GetProgramIndex(Program* program)
|
|
||||||
{
|
|
||||||
for(unsigned int i = 0; i < m_program.size(); i++)
|
|
||||||
{
|
|
||||||
if(m_program[i].get() == program)
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Program* COldObject::GetProgram(int index)
|
|
||||||
{
|
|
||||||
if(index < 0 || index >= static_cast<int>(m_program.size()))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return m_program[index].get();
|
|
||||||
}
|
|
||||||
|
|
||||||
Program* COldObject::GetOrAddProgram(int index)
|
|
||||||
{
|
|
||||||
if(index < 0)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if(index < static_cast<int>(m_program.size()))
|
|
||||||
return m_program[index].get();
|
|
||||||
|
|
||||||
for(int i = m_program.size(); i < index; i++)
|
|
||||||
{
|
|
||||||
AddProgram();
|
|
||||||
}
|
|
||||||
return AddProgram();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,10 @@
|
||||||
#include "object/interface/task_executor_object.h"
|
#include "object/interface/task_executor_object.h"
|
||||||
#include "object/interface/transportable_object.h"
|
#include "object/interface/transportable_object.h"
|
||||||
|
|
||||||
|
#include "object/implementation/power_container_impl.h"
|
||||||
|
#include "object/implementation/programmable_impl.h"
|
||||||
|
#include "object/implementation/task_executor_impl.h"
|
||||||
|
|
||||||
// The father of all parts must always be the part number zero!
|
// The father of all parts must always be the part number zero!
|
||||||
const int OBJECTMAXPART = 40;
|
const int OBJECTMAXPART = 40;
|
||||||
|
|
||||||
|
@ -58,21 +62,6 @@ struct ObjectPart
|
||||||
Math::Matrix matWorld;
|
Math::Matrix matWorld;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TraceOper
|
|
||||||
{
|
|
||||||
TO_STOP = 0, // stop
|
|
||||||
TO_ADVANCE = 1, // advance
|
|
||||||
TO_RECEDE = 2, // back
|
|
||||||
TO_TURN = 3, // rotate
|
|
||||||
TO_PEN = 4, // color change
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TraceRecord
|
|
||||||
{
|
|
||||||
TraceOper oper;
|
|
||||||
float param;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
class CObjectInterface;
|
class CObjectInterface;
|
||||||
|
@ -82,14 +71,14 @@ class CObjectInterface;
|
||||||
class COldObject : public CObject,
|
class COldObject : public CObject,
|
||||||
public CInteractiveObject,
|
public CInteractiveObject,
|
||||||
public CTransportableObject,
|
public CTransportableObject,
|
||||||
public CTaskExecutorObject,
|
public CTaskExecutorObjectImpl,
|
||||||
public CProgrammableObject,
|
public CProgrammableObjectImpl,
|
||||||
public CJostleableObject,
|
public CJostleableObject,
|
||||||
public CCarrierObject,
|
public CCarrierObject,
|
||||||
public CPoweredObject,
|
public CPoweredObject,
|
||||||
public CMovableObject,
|
public CMovableObject,
|
||||||
public CControllableObject,
|
public CControllableObject,
|
||||||
public CPowerContainerObject
|
public CPowerContainerObjectImpl
|
||||||
{
|
{
|
||||||
friend class CObjectFactory;
|
friend class CObjectFactory;
|
||||||
friend class CObjectManager;
|
friend class CObjectManager;
|
||||||
|
@ -185,9 +174,6 @@ public:
|
||||||
CObject* GetTransporter() override;
|
CObject* GetTransporter() override;
|
||||||
void SetTransporterPart(int part) override;
|
void SetTransporterPart(int part) override;
|
||||||
|
|
||||||
void SetCmdLine(unsigned int rank, float value);
|
|
||||||
float GetCmdLine(unsigned int rank) override;
|
|
||||||
|
|
||||||
Math::Matrix* GetRotateMatrix(int part);
|
Math::Matrix* GetRotateMatrix(int part);
|
||||||
Math::Matrix* GetWorldMatrix(int part) override;
|
Math::Matrix* GetWorldMatrix(int part) override;
|
||||||
|
|
||||||
|
@ -199,9 +185,6 @@ public:
|
||||||
|
|
||||||
float GetAbsTime();
|
float GetAbsTime();
|
||||||
|
|
||||||
void SetEnergyLevel(float level) override;
|
|
||||||
float GetEnergyLevel() override;
|
|
||||||
|
|
||||||
float GetCapacity() override;
|
float GetCapacity() override;
|
||||||
|
|
||||||
bool IsRechargeable() override;
|
bool IsRechargeable() override;
|
||||||
|
@ -238,9 +221,6 @@ public:
|
||||||
void SetSelectable(bool bMode);
|
void SetSelectable(bool bMode);
|
||||||
bool GetSelectable() override;
|
bool GetSelectable() override;
|
||||||
|
|
||||||
void SetActivity(bool activity) override;
|
|
||||||
bool GetActivity() override;
|
|
||||||
|
|
||||||
void SetVisible(bool bVisible);
|
void SetVisible(bool bVisible);
|
||||||
|
|
||||||
void SetCheckToken(bool bMode);
|
void SetCheckToken(bool bMode);
|
||||||
|
@ -318,54 +298,10 @@ public:
|
||||||
Error StartTaskShield(TaskShieldMode mode, float delay = 1000.0f) override;
|
Error StartTaskShield(TaskShieldMode mode, float delay = 1000.0f) override;
|
||||||
Error StartTaskGunGoal(float dirV, float dirH) override;
|
Error StartTaskGunGoal(float dirV, float dirH) override;
|
||||||
|
|
||||||
bool IsForegroundTask() override;
|
void UpdateInterface() override;
|
||||||
bool IsBackgroundTask() override;
|
|
||||||
CTaskManager* GetForegroundTask() override;
|
|
||||||
CTaskManager* GetBackgroundTask() override;
|
|
||||||
void StopForegroundTask() override;
|
|
||||||
void StopBackgroundTask() override;
|
|
||||||
|
|
||||||
void UpdateInterface();
|
|
||||||
|
|
||||||
bool IsProgram() override;
|
|
||||||
void RunProgram(Program* program) override;
|
|
||||||
int GetProgram() override;
|
|
||||||
void StopProgram() override;
|
void StopProgram() override;
|
||||||
|
|
||||||
bool IntroduceVirus() override;
|
|
||||||
void SetActiveVirus(bool bActive) override;
|
|
||||||
bool GetActiveVirus() override;
|
|
||||||
|
|
||||||
void SetScriptRun(Program* rank) override;
|
|
||||||
Program* GetScriptRun() override;
|
|
||||||
void SetSoluceName(char *name) override;
|
|
||||||
char* GetSoluceName() override;
|
|
||||||
|
|
||||||
bool ReadSoluce(char* filename) override;
|
|
||||||
bool ReadProgram(Program* program, const char* filename) override;
|
|
||||||
bool GetCompile(Program* program) override;
|
|
||||||
bool WriteProgram(Program* program, const char* filename) override;
|
|
||||||
bool ReadStack(FILE *file) override;
|
|
||||||
bool WriteStack(FILE *file) override;
|
|
||||||
|
|
||||||
Program* AddProgram() override;
|
|
||||||
void AddProgram(std::unique_ptr<Program> program) override;
|
|
||||||
void RemoveProgram(Program* program) override;
|
|
||||||
Program* CloneProgram(Program* program) override;
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Program>>& GetPrograms() override;
|
|
||||||
int GetProgramCount() override;
|
|
||||||
Program* GetProgram(int index) override;
|
|
||||||
Program* GetOrAddProgram(int index) override;
|
|
||||||
int GetProgramIndex(Program* program) override;
|
|
||||||
|
|
||||||
//! Start recording trace
|
|
||||||
void TraceRecordStart() override;
|
|
||||||
//! Stop recording trace and generate CBot program
|
|
||||||
void TraceRecordStop() override;
|
|
||||||
//! Returns true if trace recording is in progress
|
|
||||||
bool IsTraceRecord() override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool EventFrame(const Event &event);
|
bool EventFrame(const Event &event);
|
||||||
void VirusFrame(float rTime);
|
void VirusFrame(float rTime);
|
||||||
|
@ -382,13 +318,6 @@ protected:
|
||||||
|
|
||||||
Error EndedTask();
|
Error EndedTask();
|
||||||
|
|
||||||
//! Save current status to recording buffer
|
|
||||||
void TraceRecordFrame();
|
|
||||||
//! Save this operation to recording buffer
|
|
||||||
bool TraceRecordOper(TraceOper oper, float param);
|
|
||||||
//! Convert this recording operation to CBot instruction
|
|
||||||
bool TraceRecordPut(std::stringstream& buffer, TraceOper oper, float param);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Gfx::CEngine* m_engine;
|
Gfx::CEngine* m_engine;
|
||||||
Gfx::CLightManager* m_lightMan;
|
Gfx::CLightManager* m_lightMan;
|
||||||
|
@ -417,7 +346,6 @@ protected:
|
||||||
CObject* m_cargo; // object transported
|
CObject* m_cargo; // object transported
|
||||||
CObject* m_transporter; // object with the latter
|
CObject* m_transporter; // object with the latter
|
||||||
int m_transporterLink; // part
|
int m_transporterLink; // part
|
||||||
float m_energy; // energy contained (if battery)
|
|
||||||
float m_lastEnergy;
|
float m_lastEnergy;
|
||||||
float m_shield; // shield
|
float m_shield; // shield
|
||||||
float m_range; // flight range
|
float m_range; // flight range
|
||||||
|
@ -462,30 +390,8 @@ protected:
|
||||||
|
|
||||||
float m_infoReturn;
|
float m_infoReturn;
|
||||||
|
|
||||||
std::vector<float> m_cmdLine;
|
|
||||||
|
|
||||||
bool m_activity;
|
|
||||||
std::unique_ptr<CTaskManager> m_foregroundTask;
|
|
||||||
std::unique_ptr<CTaskManager> m_backgroundTask;
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Program>> m_program;
|
|
||||||
Program* m_currentProgram;
|
|
||||||
|
|
||||||
bool m_bActiveVirus;
|
|
||||||
|
|
||||||
Program* m_scriptRun;
|
|
||||||
char m_soluceName[50];
|
|
||||||
|
|
||||||
EventType m_buttonAxe;
|
EventType m_buttonAxe;
|
||||||
|
|
||||||
float m_time;
|
float m_time;
|
||||||
float m_burnTime;
|
float m_burnTime;
|
||||||
|
|
||||||
bool m_traceRecord;
|
|
||||||
TraceOper m_traceOper;
|
|
||||||
Math::Vector m_tracePos;
|
|
||||||
float m_traceAngle;
|
|
||||||
TraceColor m_traceColor;
|
|
||||||
int m_traceRecordIndex;
|
|
||||||
std::unique_ptr<TraceRecord[]> m_traceRecordBuffer;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -3710,7 +3710,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
|
||||||
|
|
||||||
if (soluce && oldObj->Implements(ObjectInterfaceType::Programmable) && line->GetParam("soluce")->IsDefined())
|
if (soluce && oldObj->Implements(ObjectInterfaceType::Programmable) && line->GetParam("soluce")->IsDefined())
|
||||||
dynamic_cast<CProgrammableObject*>(oldObj)
|
dynamic_cast<CProgrammableObject*>(oldObj)
|
||||||
->SetSoluceName(const_cast<char*>(line->GetParam("soluce")->AsPath("ai").c_str()));
|
->SetSoluceName(line->GetParam("soluce")->AsPath("ai"));
|
||||||
|
|
||||||
if (line->GetParam("reset")->AsBool(false))
|
if (line->GetParam("reset")->AsBool(false))
|
||||||
oldObj->SetAnimateOnReset(true);
|
oldObj->SetAnimateOnReset(true);
|
||||||
|
@ -4717,8 +4717,8 @@ void CRobotMain::CompileScript(bool soluce)
|
||||||
|
|
||||||
if (soluce)
|
if (soluce)
|
||||||
{
|
{
|
||||||
char* name = programmable->GetSoluceName();
|
std::string name = programmable->GetSoluceName();
|
||||||
if (name[0] != 0)
|
if (!name.empty())
|
||||||
{
|
{
|
||||||
programmable->ReadSoluce(name); // load solution
|
programmable->ReadSoluce(name); // load solution
|
||||||
}
|
}
|
||||||
|
|
|
@ -646,7 +646,7 @@ Error CTaskBuild::FlatFloor()
|
||||||
if ( m_type == OBJECT_PARA ) radius = 20.0f;
|
if ( m_type == OBJECT_PARA ) radius = 20.0f;
|
||||||
if ( m_type == OBJECT_INFO ) radius = 5.0f;
|
if ( m_type == OBJECT_INFO ) radius = 5.0f;
|
||||||
if ( m_type == OBJECT_DESTROYER) radius = 20.0f;
|
if ( m_type == OBJECT_DESTROYER) radius = 20.0f;
|
||||||
//if ( radius == 0.0f ) return ERR_GENERIC;
|
//if ( radius == 0.0f ) return ERR_UNKNOWN;
|
||||||
|
|
||||||
center = m_metal->GetPosition();
|
center = m_metal->GetPosition();
|
||||||
angle = m_terrain->GetFineSlope(center);
|
angle = m_terrain->GetFineSlope(center);
|
||||||
|
|
|
@ -287,7 +287,7 @@ Error CTaskFire::Start(float delay)
|
||||||
type != OBJECT_MOBILEti &&
|
type != OBJECT_MOBILEti &&
|
||||||
type != OBJECT_MOBILEwi &&
|
type != OBJECT_MOBILEwi &&
|
||||||
type != OBJECT_MOBILEii &&
|
type != OBJECT_MOBILEii &&
|
||||||
type != OBJECT_MOBILErc ) return ERR_FIRE_VEH;
|
type != OBJECT_MOBILErc ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
//? if ( !m_physics->GetLand() ) return ERR_FIRE_FLY;
|
//? if ( !m_physics->GetLand() ) return ERR_FIRE_FLY;
|
||||||
|
|
||||||
|
|
|
@ -92,13 +92,13 @@ Error CTaskFireAnt::Start(Math::Vector impact)
|
||||||
m_impact = impact;
|
m_impact = impact;
|
||||||
|
|
||||||
m_bError = true; // operation impossible
|
m_bError = true; // operation impossible
|
||||||
if ( !m_physics->GetLand() ) return ERR_FIRE_VEH;
|
if ( !m_physics->GetLand() ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
type = m_object->GetType();
|
type = m_object->GetType();
|
||||||
if ( type != OBJECT_ANT ) return ERR_FIRE_VEH;
|
if ( type != OBJECT_ANT ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
// Insect on its back?
|
// Insect on its back?
|
||||||
if ( m_object->GetFixed() ) return ERR_FIRE_VEH;
|
if ( m_object->GetFixed() ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
m_physics->SetMotorSpeed(Math::Vector(0.0f, 0.0f, 0.0f));
|
m_physics->SetMotorSpeed(Math::Vector(0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
|
|
|
@ -936,7 +936,7 @@ Error CTaskGoto::IsEnded()
|
||||||
{
|
{
|
||||||
m_physics->SetMotorSpeedX(0.0f); // stops the advance
|
m_physics->SetMotorSpeedX(0.0f); // stops the advance
|
||||||
m_physics->SetMotorSpeedZ(0.0f); // stops the rotation
|
m_physics->SetMotorSpeedZ(0.0f); // stops the rotation
|
||||||
m_error = ERR_GENERIC;
|
m_error = ERR_UNKNOWN;
|
||||||
return m_error;
|
return m_error;
|
||||||
}
|
}
|
||||||
if ( m_time >= 1.0f )
|
if ( m_time >= 1.0f )
|
||||||
|
|
|
@ -183,7 +183,7 @@ Error CTaskManager::StartTaskShield(TaskShieldMode mode, float delay)
|
||||||
{
|
{
|
||||||
return (static_cast<CTaskShield*>(m_task))->Start(mode, delay);
|
return (static_cast<CTaskShield*>(m_task))->Start(mode, delay);
|
||||||
}
|
}
|
||||||
return ERR_GENERIC;
|
return ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shoots.
|
// Shoots.
|
||||||
|
@ -233,7 +233,7 @@ bool CTaskManager::EventProcess(const Event &event)
|
||||||
|
|
||||||
Error CTaskManager::IsEnded()
|
Error CTaskManager::IsEnded()
|
||||||
{
|
{
|
||||||
if ( m_task == 0 ) return ERR_GENERIC;
|
if ( m_task == 0 ) return ERR_UNKNOWN;
|
||||||
return m_task->IsEnded();
|
return m_task->IsEnded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -308,7 +308,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm)
|
||||||
if ( m_arm != TMA_FFRONT &&
|
if ( m_arm != TMA_FFRONT &&
|
||||||
m_arm != TMA_FBACK &&
|
m_arm != TMA_FBACK &&
|
||||||
m_arm != TMA_POWER &&
|
m_arm != TMA_POWER &&
|
||||||
m_arm != TMA_GRAB ) return ERR_MANIP_VEH;
|
m_arm != TMA_GRAB ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
m_physics->SetMotorSpeed(Math::Vector(0.0f, 0.0f, 0.0f));
|
m_physics->SetMotorSpeed(Math::Vector(0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
|
@ -374,7 +374,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm)
|
||||||
type != OBJECT_MOBILEta &&
|
type != OBJECT_MOBILEta &&
|
||||||
type != OBJECT_MOBILEwa &&
|
type != OBJECT_MOBILEwa &&
|
||||||
type != OBJECT_MOBILEia &&
|
type != OBJECT_MOBILEia &&
|
||||||
type != OBJECT_MOBILEsa ) return ERR_MANIP_VEH;
|
type != OBJECT_MOBILEsa ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
if ( m_bSubm ) // submarine?
|
if ( m_bSubm ) // submarine?
|
||||||
{
|
{
|
||||||
|
|
|
@ -139,7 +139,7 @@ Error CTaskPen::Start(bool bDown, TraceColor color)
|
||||||
m_bError = true; // operation impossible
|
m_bError = true; // operation impossible
|
||||||
|
|
||||||
type = m_object->GetType();
|
type = m_object->GetType();
|
||||||
if ( type != OBJECT_MOBILEdr ) return ERR_FIRE_VEH;
|
if ( type != OBJECT_MOBILEdr ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
m_bError = false; // ok
|
m_bError = false; // ok
|
||||||
|
|
||||||
|
|
|
@ -180,10 +180,10 @@ bool CTaskRecover::EventProcess(const Event &event)
|
||||||
Error CTaskRecover::Start()
|
Error CTaskRecover::Start()
|
||||||
{
|
{
|
||||||
m_bError = true; // operation impossible
|
m_bError = true; // operation impossible
|
||||||
if ( !m_physics->GetLand() ) return ERR_RECOVER_VEH;
|
if ( !m_physics->GetLand() ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
ObjectType type = m_object->GetType();
|
ObjectType type = m_object->GetType();
|
||||||
if ( type != OBJECT_MOBILErr ) return ERR_RECOVER_VEH;
|
if ( type != OBJECT_MOBILErr ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
||||||
CObject* power = dynamic_cast<CPoweredObject*>(m_object)->GetPower();
|
CObject* power = dynamic_cast<CPoweredObject*>(m_object)->GetPower();
|
||||||
|
|
|
@ -140,7 +140,7 @@ Error CTaskSearch::Start()
|
||||||
if ( type != OBJECT_MOBILEfs &&
|
if ( type != OBJECT_MOBILEfs &&
|
||||||
type != OBJECT_MOBILEts &&
|
type != OBJECT_MOBILEts &&
|
||||||
type != OBJECT_MOBILEws &&
|
type != OBJECT_MOBILEws &&
|
||||||
type != OBJECT_MOBILEis ) return ERR_SEARCH_VEH;
|
type != OBJECT_MOBILEis ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
m_hand = TSH_DOWN;
|
m_hand = TSH_DOWN;
|
||||||
m_phase = TSP_DOWN;
|
m_phase = TSP_DOWN;
|
||||||
|
|
|
@ -287,10 +287,10 @@ Error CTaskShield::Start(TaskShieldMode mode, float delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectType type = m_object->GetType();
|
ObjectType type = m_object->GetType();
|
||||||
if ( type != OBJECT_MOBILErs ) return ERR_SHIELD_VEH;
|
if ( type != OBJECT_MOBILErs ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
m_bError = true; // operation impossible
|
m_bError = true; // operation impossible
|
||||||
if ( !m_physics->GetLand() ) return ERR_SHIELD_VEH;
|
if ( !m_physics->GetLand() ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
CObject* power = m_object->GetPower();
|
CObject* power = m_object->GetPower();
|
||||||
if (power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer)) return ERR_SHIELD_ENERGY;
|
if (power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer)) return ERR_SHIELD_ENERGY;
|
||||||
|
|
|
@ -110,7 +110,7 @@ Error CTaskTake::Start()
|
||||||
|
|
||||||
ObjectType type = m_object->GetType();
|
ObjectType type = m_object->GetType();
|
||||||
if ( type != OBJECT_HUMAN &&
|
if ( type != OBJECT_HUMAN &&
|
||||||
type != OBJECT_TECH ) return ERR_MANIP_VEH;
|
type != OBJECT_TECH ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
m_physics->SetMotorSpeed(Math::Vector(0.0f, 0.0f, 0.0f));
|
m_physics->SetMotorSpeed(Math::Vector(0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
|
|
|
@ -203,10 +203,10 @@ Error CTaskTerraform::Start()
|
||||||
ObjectType type;
|
ObjectType type;
|
||||||
|
|
||||||
m_bError = true; // operation impossible
|
m_bError = true; // operation impossible
|
||||||
if ( !m_physics->GetLand() ) return ERR_TERRA_VEH;
|
if ( !m_physics->GetLand() ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
type = m_object->GetType();
|
type = m_object->GetType();
|
||||||
if ( type != OBJECT_MOBILErt ) return ERR_TERRA_VEH;
|
if ( type != OBJECT_MOBILErt ) return ERR_WRONG_BOT;
|
||||||
|
|
||||||
power = m_object->GetPower();
|
power = m_object->GetPower();
|
||||||
if ( power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer) ) return ERR_TERRA_ENERGY;
|
if ( power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer) ) return ERR_TERRA_ENERGY;
|
||||||
|
|
|
@ -487,6 +487,8 @@ void CScript::Stop()
|
||||||
{
|
{
|
||||||
if ( !m_bRun ) return;
|
if ( !m_bRun ) return;
|
||||||
|
|
||||||
|
m_taskExecutor->StopForegroundTask();
|
||||||
|
|
||||||
if( m_botProg != 0 )
|
if( m_botProg != 0 )
|
||||||
{
|
{
|
||||||
m_botProg->Stop();
|
m_botProg->Stop();
|
||||||
|
|
|
@ -718,8 +718,8 @@ bool CScriptFunctions::rFactory(CBotVar* thisclass, CBotVar* var, CBotVar* resul
|
||||||
CObject* factory = static_cast<CObject*>(thisclass->GetUserPtr());
|
CObject* factory = static_cast<CObject*>(thisclass->GetUserPtr());
|
||||||
if (factory == nullptr)
|
if (factory == nullptr)
|
||||||
{
|
{
|
||||||
exception = ERR_GENERIC;
|
exception = ERR_UNKNOWN;
|
||||||
result->SetValInt(ERR_GENERIC);
|
result->SetValInt(ERR_UNKNOWN);
|
||||||
GetLogger()->Error("in object.factory() - factory is nullptr");
|
GetLogger()->Error("in object.factory() - factory is nullptr");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -736,8 +736,8 @@ bool CScriptFunctions::rFactory(CBotVar* thisclass, CBotVar* var, CBotVar* resul
|
||||||
CAutoFactory* automat = static_cast<CAutoFactory*>(factory->GetAuto());
|
CAutoFactory* automat = static_cast<CAutoFactory*>(factory->GetAuto());
|
||||||
if (automat == nullptr)
|
if (automat == nullptr)
|
||||||
{
|
{
|
||||||
exception = ERR_GENERIC;
|
exception = ERR_UNKNOWN;
|
||||||
result->SetValInt(ERR_GENERIC);
|
result->SetValInt(ERR_UNKNOWN);
|
||||||
GetLogger()->Error("in object.factory() - automat is nullptr");
|
GetLogger()->Error("in object.factory() - automat is nullptr");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -752,7 +752,7 @@ bool CScriptFunctions::rFactory(CBotVar* thisclass, CBotVar* var, CBotVar* resul
|
||||||
if ( err == ERR_OK ) automat->SetProgram(program);
|
if ( err == ERR_OK ) automat->SetProgram(program);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
err = ERR_GENERIC;
|
err = ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -824,7 +824,7 @@ bool CScriptFunctions::rResearch(CBotVar* thisclass, CBotVar* var, CBotVar* resu
|
||||||
err = automat->StartAction(type);
|
err = automat->StartAction(type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
err = ERR_GENERIC;
|
err = ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
err = ERR_BUILD_DISABLED;
|
err = ERR_BUILD_DISABLED;
|
||||||
|
@ -1417,7 +1417,7 @@ bool CScriptFunctions::rBuild(CBotVar* var, CBotVar* result, int& exception, voi
|
||||||
oType != OBJECT_HUMAN &&
|
oType != OBJECT_HUMAN &&
|
||||||
oType != OBJECT_TECH )
|
oType != OBJECT_TECH )
|
||||||
{
|
{
|
||||||
err = ERR_MANIP_VEH; // Wrong object
|
err = ERR_WRONG_BOT; // Wrong object
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2475,10 +2475,10 @@ bool CScriptFunctions::rShield(CBotVar* var, CBotVar* result, int& exception, vo
|
||||||
// only shielder can use shield()
|
// only shielder can use shield()
|
||||||
if (pThis->GetType() != OBJECT_MOBILErs)
|
if (pThis->GetType() != OBJECT_MOBILErs)
|
||||||
{
|
{
|
||||||
result->SetValInt(ERR_MANIP_VEH); // return error
|
result->SetValInt(ERR_WRONG_BOT); // return error
|
||||||
if (script->m_errMode == ERM_STOP)
|
if (script->m_errMode == ERM_STOP)
|
||||||
{
|
{
|
||||||
exception = ERR_MANIP_VEH;
|
exception = ERR_WRONG_BOT;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue