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"
|
||||
msgstr ""
|
||||
|
||||
msgid "Inappropriate bot"
|
||||
msgstr ""
|
||||
|
||||
msgid "Impossible when flying"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1597,6 +1594,9 @@ msgstr ""
|
|||
msgid "Do not use in this exercise"
|
||||
msgstr ""
|
||||
|
||||
msgid "Inappropriate bot"
|
||||
msgstr ""
|
||||
|
||||
msgid "Building completed"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -150,6 +150,9 @@ set(BASE_SOURCES
|
|||
object/auto/autopowerstation.cpp
|
||||
object/auto/autotower.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/parserexceptions.cpp
|
||||
object/level/parserline.cpp
|
||||
|
|
|
@ -32,11 +32,10 @@
|
|||
enum Error
|
||||
{
|
||||
ERR_OK = 0, //! < ok
|
||||
ERR_GENERIC = 1, //! < any error
|
||||
ERR_UNKNOWN = 1, //! < any error
|
||||
ERR_CONTINUE = 2, //! < continues
|
||||
ERR_STOP = 3, //! < stops
|
||||
ERR_CMD = 4, //! < unknown command
|
||||
ERR_MANIP_VEH = 100, //! < inappropriate vehicle
|
||||
ERR_MANIP_FLY = 101, //! < impossible in flight
|
||||
ERR_MANIP_BUSY = 102, //! < taking: hands already occupied
|
||||
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_RESEARCH = 133, //! < built: can not produce not researched object
|
||||
ERR_SEARCH_FLY = 140, //! < not possible in flight
|
||||
ERR_SEARCH_VEH = 141, //! < inappropriate vehicle
|
||||
ERR_SEARCH_MOTOR = 142, //! < impossible in movement
|
||||
ERR_TERRA_VEH = 150, //! < inappropriate vehicle
|
||||
ERR_TERRA_ENERGY = 151, //! < not enough energy
|
||||
ERR_TERRA_FLOOR = 152, //! < inappropriate ground
|
||||
ERR_TERRA_BUILDING = 153, //! < building too close
|
||||
ERR_TERRA_OBJECT = 154, //! < object too close
|
||||
ERR_FIRE_VEH = 160, //! < inappropriate vehicle
|
||||
ERR_FIRE_ENERGY = 161, //! < not enough energy
|
||||
ERR_FIRE_FLY = 162, //! < not possible in flight
|
||||
ERR_RECOVER_VEH = 170, //! < inappropriate vehicle
|
||||
ERR_RECOVER_ENERGY = 171, //! < not enough energy
|
||||
ERR_RECOVER_NULL = 172, //! < lack of ruin
|
||||
ERR_CONVERT_EMPTY = 180, //! < no stone was transformed
|
||||
ERR_SHIELD_VEH = 190, //! < inappropriate vehicle
|
||||
ERR_SHIELD_ENERGY = 191, //! < not enough energy
|
||||
ERR_MOVE_IMPOSSIBLE = 200, //! < move impossible
|
||||
ERR_FIND_IMPOSSIBLE = 201, //! < find impossible
|
||||
|
@ -128,6 +122,7 @@ enum Error
|
|||
ERR_OBLIGATORYTOKEN = 800, //! < compulsory instruction missing
|
||||
ERR_PROHIBITEDTOKEN = 801, //! < instruction prohibited
|
||||
ERR_AIM_IMPOSSIBLE = 900, //! < cannot aim at specified angle(s)
|
||||
ERR_WRONG_BOT = 910, //! < inappropriate bot
|
||||
|
||||
INFO_FIRST = 10000, //! < first information
|
||||
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_MANIP_VEH] = TR("Inappropriate bot");
|
||||
stringsErr[ERR_MANIP_FLY] = TR("Impossible when flying");
|
||||
stringsErr[ERR_MANIP_BUSY] = TR("Already carrying something");
|
||||
stringsErr[ERR_MANIP_NIL] = TR("Nothing to grab");
|
||||
|
@ -608,24 +607,19 @@ void InitializeRestext()
|
|||
stringsErr[ERR_SEARCH_FLY] = TR("Impossible when flying");
|
||||
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_SEARCH_VEH] = TR("Inappropriate bot");
|
||||
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_FLOOR] = TR("Ground inappropriate");
|
||||
stringsErr[ERR_TERRA_BUILDING] = TR("Building 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_NULL] = TR("Nothing to recycle");
|
||||
stringsErr[ERR_SHIELD_VEH] = TR("Inappropriate bot");
|
||||
stringsErr[ERR_SHIELD_ENERGY] = TR("No more energy");
|
||||
stringsErr[ERR_MOVE_IMPOSSIBLE] = TR("Error in instruction move");
|
||||
stringsErr[ERR_FIND_IMPOSSIBLE] = TR("Object not found");
|
||||
stringsErr[ERR_GOTO_IMPOSSIBLE] = TR("Goto: inaccessible destination");
|
||||
stringsErr[ERR_GOTO_ITER] = TR("Goto: inaccessible destination");
|
||||
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_FLY] = TR("Impossible when flying");
|
||||
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_OBLIGATORYTOKEN] = TR("\"%s\" missing 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_CONVERT] = TR("Titanium available");
|
||||
|
|
|
@ -107,7 +107,7 @@ void CAuto::Start(int param)
|
|||
|
||||
Error CAuto::StartAction(int param)
|
||||
{
|
||||
return ERR_GENERIC;
|
||||
return ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
// Gete a type.
|
||||
|
|
|
@ -103,7 +103,7 @@ Error CAutoDestroyer::StartAction(int param)
|
|||
m_bExplo = false;
|
||||
}
|
||||
else
|
||||
return ERR_GENERIC;
|
||||
return ERR_UNKNOWN;
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ Error CAutoFactory::StartAction(int param)
|
|||
m_speed = 1.0f/3.0f;
|
||||
return ERR_OK;
|
||||
}
|
||||
return ERR_GENERIC;
|
||||
return ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
|
@ -219,10 +219,10 @@ bool CAutoFactory::EventProcess(const Event &event)
|
|||
type = ObjectTypeFromFactoryButton(event.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);
|
||||
|
||||
if( err != ERR_GENERIC )
|
||||
if( err != ERR_UNKNOWN )
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ Error CAutoLabo::StartAction(int param)
|
|||
{
|
||||
if ( m_phase != ALAP_WAIT )
|
||||
{
|
||||
return ERR_GENERIC;
|
||||
return ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
m_research = static_cast<ResearchType>(param);
|
||||
|
@ -175,14 +175,14 @@ bool CAutoLabo::EventProcess(const Event &event)
|
|||
|
||||
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_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);
|
||||
|
||||
if( err != ERR_GENERIC )
|
||||
if( err != ERR_UNKNOWN )
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ Error CAutoResearch::StartAction(int param)
|
|||
{
|
||||
if ( m_phase != ALP_WAIT )
|
||||
{
|
||||
return ERR_GENERIC;
|
||||
return ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
m_research = static_cast<ResearchType>(param);
|
||||
|
@ -167,7 +167,7 @@ bool CAutoResearch::EventProcess(const Event &event)
|
|||
|
||||
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_RFLY ) err = StartAction(RESEARCH_FLY);
|
||||
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_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);
|
||||
|
||||
if( err != ERR_GENERIC )
|
||||
if( err != ERR_UNKNOWN )
|
||||
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 Program* GetScriptRun() = 0;
|
||||
virtual void SetSoluceName(char *name) = 0;
|
||||
virtual char* GetSoluceName() = 0;
|
||||
virtual void SetSoluceName(const std::string& name) = 0;
|
||||
virtual const std::string& GetSoluceName() = 0;
|
||||
|
||||
virtual bool ReadSoluce(char* filename) = 0;
|
||||
virtual bool ReadProgram(Program* program, const char* filename) = 0;
|
||||
virtual bool ReadSoluce(const std::string& filename) = 0;
|
||||
virtual bool ReadProgram(Program* program, const std::string& filename) = 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 WriteStack(FILE *file) = 0;
|
||||
|
||||
|
|
|
@ -83,6 +83,9 @@ public:
|
|||
//! Reads object properties from line in level file
|
||||
virtual void Read(CLevelParserLine* line) = 0;
|
||||
|
||||
//! Updates all interface controls
|
||||
virtual void UpdateInterface() {};
|
||||
|
||||
//! Check if object implements the given type of interface
|
||||
inline bool Implements(ObjectInterfaceType type) const
|
||||
{
|
||||
|
|
|
@ -86,8 +86,6 @@ static float debug_arm2 = 0.0f;
|
|||
static float debug_arm3 = 0.0f;
|
||||
#endif
|
||||
|
||||
const int MAXTRACERECORD = 1000;
|
||||
|
||||
|
||||
// Object's constructor.
|
||||
|
||||
|
@ -95,14 +93,14 @@ COldObject::COldObject(int id)
|
|||
: CObject(id, OBJECT_NULL)
|
||||
, CInteractiveObject(m_implementedInterfaces)
|
||||
, CTransportableObject(m_implementedInterfaces)
|
||||
, CTaskExecutorObject(m_implementedInterfaces)
|
||||
, CProgrammableObject(m_implementedInterfaces)
|
||||
, CTaskExecutorObjectImpl(m_implementedInterfaces, this)
|
||||
, CProgrammableObjectImpl(m_implementedInterfaces, this)
|
||||
, CJostleableObject(m_implementedInterfaces)
|
||||
, CCarrierObject(m_implementedInterfaces)
|
||||
, CPoweredObject(m_implementedInterfaces)
|
||||
, CMovableObject(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()
|
||||
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = false;
|
||||
|
@ -132,7 +130,6 @@ COldObject::COldObject(int id)
|
|||
m_cargo = 0;
|
||||
m_transporter = 0;
|
||||
m_transporterLink = 0;
|
||||
m_energy = 1.0f;
|
||||
m_shield = 1.0f;
|
||||
m_range = 0.0f;
|
||||
m_transparency = 0.0f;
|
||||
|
@ -185,22 +182,11 @@ COldObject::COldObject(int id)
|
|||
m_partiSel[i] = -1;
|
||||
}
|
||||
|
||||
m_cmdLine.clear();
|
||||
|
||||
m_activity = true;
|
||||
|
||||
m_currentProgram = nullptr;
|
||||
m_bActiveVirus = false;
|
||||
m_time = 0.0f;
|
||||
m_burnTime = 0.0f;
|
||||
|
||||
m_buttonAxe = EVENT_NULL;
|
||||
|
||||
m_scriptRun = nullptr;
|
||||
m_soluceName[0] = 0;
|
||||
|
||||
m_traceRecord = false;
|
||||
|
||||
DeleteAllCrashSpheres();
|
||||
}
|
||||
|
||||
|
@ -806,7 +792,7 @@ void COldObject::Write(CLevelParserLine* line)
|
|||
|
||||
// Sets the parameters of the command line.
|
||||
CLevelParserParamVec cmdline;
|
||||
for(float value : m_cmdLine)
|
||||
for(float value : GetCmdLine())
|
||||
{
|
||||
cmdline.push_back(MakeUnique<CLevelParserParam>(value));
|
||||
}
|
||||
|
@ -820,7 +806,7 @@ void COldObject::Write(CLevelParserLine* line)
|
|||
|
||||
if ( Implements(ObjectInterfaceType::Programmable) )
|
||||
{
|
||||
line->AddParam("bVirusActive", MakeUnique<CLevelParserParam>(m_bActiveVirus));
|
||||
line->AddParam("bVirusActive", MakeUnique<CLevelParserParam>(GetActiveVirus()));
|
||||
}
|
||||
|
||||
if ( Implements(ObjectInterfaceType::TaskExecutor) )
|
||||
|
@ -891,7 +877,7 @@ void COldObject::Read(CLevelParserLine* line)
|
|||
|
||||
if (Implements(ObjectInterfaceType::Programmable))
|
||||
{
|
||||
m_bActiveVirus = line->GetParam("bVirusActive")->AsBool(false);
|
||||
SetActiveVirus(line->GetParam("bVirusActive")->AsBool(false));
|
||||
}
|
||||
|
||||
if (Implements(ObjectInterfaceType::TaskExecutor))
|
||||
|
@ -1382,29 +1368,6 @@ float COldObject::GetInfoReturn()
|
|||
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.
|
||||
|
||||
|
@ -1735,10 +1698,10 @@ void COldObject::FlatParent()
|
|||
|
||||
void COldObject::UpdateEnergyMapping()
|
||||
{
|
||||
if (Math::IsEqual(m_energy, m_lastEnergy, 0.01f))
|
||||
if (Math::IsEqual(GetEnergyLevel(), m_lastEnergy, 0.01f))
|
||||
return;
|
||||
|
||||
m_lastEnergy = m_energy;
|
||||
m_lastEnergy = GetEnergyLevel();
|
||||
|
||||
Gfx::Material mat;
|
||||
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)
|
||||
}
|
||||
|
||||
float i = 0.50f+0.25f*m_energy; // origin
|
||||
float i = 0.50f+0.25f*GetEnergyLevel(); // origin
|
||||
float s = i+0.25f; // width
|
||||
|
||||
float au = (s-i)/(b-a);
|
||||
|
@ -1822,15 +1785,8 @@ bool COldObject::EventProcess(const Event &event)
|
|||
#endif
|
||||
}
|
||||
|
||||
if ( m_foregroundTask != nullptr )
|
||||
{
|
||||
m_foregroundTask->EventProcess(event);
|
||||
}
|
||||
|
||||
if ( m_backgroundTask != nullptr )
|
||||
{
|
||||
m_backgroundTask->EventProcess(event);
|
||||
}
|
||||
// NOTE: This should be called befoce CProgrammableObjectImpl::EventProcess, see the other note inside this function
|
||||
if (!CTaskExecutorObjectImpl::EventProcess(event)) return true;
|
||||
|
||||
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)
|
||||
{
|
||||
bool deselectedStop = !GetSelect();
|
||||
|
@ -1990,6 +1938,8 @@ bool COldObject::EventProcess(const Event &event)
|
|||
if (!m_motion->EventProcess(event)) return false;
|
||||
}
|
||||
|
||||
if (!CProgrammableObjectImpl::EventProcess(event)) return true;
|
||||
|
||||
if ( event.type == EVENT_FRAME )
|
||||
{
|
||||
return EventFrame(event);
|
||||
|
@ -2025,28 +1975,6 @@ bool COldObject::EventFrame(const Event &event)
|
|||
UpdateTransformObject();
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
{
|
||||
return m_type == OBJECT_ATOMIC ? 10.0f : 1.0f;
|
||||
|
@ -3310,603 +3219,25 @@ Error COldObject::StartTaskGunGoal(float dirV, float dirH)
|
|||
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()
|
||||
{
|
||||
if (m_objectInterface != nullptr && GetSelect())
|
||||
{
|
||||
m_objectInterface->UpdateInterface();
|
||||
}
|
||||
|
||||
CreateSelectParticle();
|
||||
m_main->UpdateShortcuts();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Stops the running program.
|
||||
|
||||
void COldObject::StopProgram()
|
||||
{
|
||||
StopForegroundTask();
|
||||
|
||||
if ( m_type == OBJECT_HUMAN ||
|
||||
m_type == OBJECT_TECH ) return;
|
||||
|
||||
if ( m_currentProgram != nullptr )
|
||||
{
|
||||
m_currentProgram->script->Stop();
|
||||
}
|
||||
|
||||
m_currentProgram = nullptr;
|
||||
CProgrammableObjectImpl::StopProgram();
|
||||
|
||||
//TODO: I don't want CProgrammableObjectImpl to depend on motion and physics, refactor this somehow
|
||||
m_physics->SetMotorSpeedX(0.0f);
|
||||
m_physics->SetMotorSpeedY(0.0f);
|
||||
m_physics->SetMotorSpeedZ(0.0f);
|
||||
|
||||
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/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!
|
||||
const int OBJECTMAXPART = 40;
|
||||
|
||||
|
@ -58,21 +62,6 @@ struct ObjectPart
|
|||
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
|
||||
{
|
||||
class CObjectInterface;
|
||||
|
@ -82,14 +71,14 @@ class CObjectInterface;
|
|||
class COldObject : public CObject,
|
||||
public CInteractiveObject,
|
||||
public CTransportableObject,
|
||||
public CTaskExecutorObject,
|
||||
public CProgrammableObject,
|
||||
public CTaskExecutorObjectImpl,
|
||||
public CProgrammableObjectImpl,
|
||||
public CJostleableObject,
|
||||
public CCarrierObject,
|
||||
public CPoweredObject,
|
||||
public CMovableObject,
|
||||
public CControllableObject,
|
||||
public CPowerContainerObject
|
||||
public CPowerContainerObjectImpl
|
||||
{
|
||||
friend class CObjectFactory;
|
||||
friend class CObjectManager;
|
||||
|
@ -185,9 +174,6 @@ public:
|
|||
CObject* GetTransporter() 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* GetWorldMatrix(int part) override;
|
||||
|
||||
|
@ -199,9 +185,6 @@ public:
|
|||
|
||||
float GetAbsTime();
|
||||
|
||||
void SetEnergyLevel(float level) override;
|
||||
float GetEnergyLevel() override;
|
||||
|
||||
float GetCapacity() override;
|
||||
|
||||
bool IsRechargeable() override;
|
||||
|
@ -238,9 +221,6 @@ public:
|
|||
void SetSelectable(bool bMode);
|
||||
bool GetSelectable() override;
|
||||
|
||||
void SetActivity(bool activity) override;
|
||||
bool GetActivity() override;
|
||||
|
||||
void SetVisible(bool bVisible);
|
||||
|
||||
void SetCheckToken(bool bMode);
|
||||
|
@ -318,54 +298,10 @@ public:
|
|||
Error StartTaskShield(TaskShieldMode mode, float delay = 1000.0f) override;
|
||||
Error StartTaskGunGoal(float dirV, float dirH) override;
|
||||
|
||||
bool IsForegroundTask() override;
|
||||
bool IsBackgroundTask() override;
|
||||
CTaskManager* GetForegroundTask() override;
|
||||
CTaskManager* GetBackgroundTask() override;
|
||||
void StopForegroundTask() override;
|
||||
void StopBackgroundTask() override;
|
||||
void UpdateInterface() override;
|
||||
|
||||
void UpdateInterface();
|
||||
|
||||
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(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:
|
||||
bool EventFrame(const Event &event);
|
||||
void VirusFrame(float rTime);
|
||||
|
@ -382,13 +318,6 @@ protected:
|
|||
|
||||
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:
|
||||
Gfx::CEngine* m_engine;
|
||||
Gfx::CLightManager* m_lightMan;
|
||||
|
@ -417,7 +346,6 @@ protected:
|
|||
CObject* m_cargo; // object transported
|
||||
CObject* m_transporter; // object with the latter
|
||||
int m_transporterLink; // part
|
||||
float m_energy; // energy contained (if battery)
|
||||
float m_lastEnergy;
|
||||
float m_shield; // shield
|
||||
float m_range; // flight range
|
||||
|
@ -462,30 +390,8 @@ protected:
|
|||
|
||||
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;
|
||||
|
||||
float m_time;
|
||||
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())
|
||||
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))
|
||||
oldObj->SetAnimateOnReset(true);
|
||||
|
@ -4717,8 +4717,8 @@ void CRobotMain::CompileScript(bool soluce)
|
|||
|
||||
if (soluce)
|
||||
{
|
||||
char* name = programmable->GetSoluceName();
|
||||
if (name[0] != 0)
|
||||
std::string name = programmable->GetSoluceName();
|
||||
if (!name.empty())
|
||||
{
|
||||
programmable->ReadSoluce(name); // load solution
|
||||
}
|
||||
|
|
|
@ -646,7 +646,7 @@ Error CTaskBuild::FlatFloor()
|
|||
if ( m_type == OBJECT_PARA ) radius = 20.0f;
|
||||
if ( m_type == OBJECT_INFO ) radius = 5.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();
|
||||
angle = m_terrain->GetFineSlope(center);
|
||||
|
|
|
@ -287,7 +287,7 @@ Error CTaskFire::Start(float delay)
|
|||
type != OBJECT_MOBILEti &&
|
||||
type != OBJECT_MOBILEwi &&
|
||||
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;
|
||||
|
||||
|
|
|
@ -92,13 +92,13 @@ Error CTaskFireAnt::Start(Math::Vector impact)
|
|||
m_impact = impact;
|
||||
|
||||
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();
|
||||
if ( type != OBJECT_ANT ) return ERR_FIRE_VEH;
|
||||
if ( type != OBJECT_ANT ) return ERR_WRONG_BOT;
|
||||
|
||||
// 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));
|
||||
|
||||
|
|
|
@ -936,7 +936,7 @@ Error CTaskGoto::IsEnded()
|
|||
{
|
||||
m_physics->SetMotorSpeedX(0.0f); // stops the advance
|
||||
m_physics->SetMotorSpeedZ(0.0f); // stops the rotation
|
||||
m_error = ERR_GENERIC;
|
||||
m_error = ERR_UNKNOWN;
|
||||
return m_error;
|
||||
}
|
||||
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 ERR_GENERIC;
|
||||
return ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
// Shoots.
|
||||
|
@ -233,7 +233,7 @@ bool CTaskManager::EventProcess(const Event &event)
|
|||
|
||||
Error CTaskManager::IsEnded()
|
||||
{
|
||||
if ( m_task == 0 ) return ERR_GENERIC;
|
||||
if ( m_task == 0 ) return ERR_UNKNOWN;
|
||||
return m_task->IsEnded();
|
||||
}
|
||||
|
||||
|
|
|
@ -308,7 +308,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm)
|
|||
if ( m_arm != TMA_FFRONT &&
|
||||
m_arm != TMA_FBACK &&
|
||||
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));
|
||||
|
||||
|
@ -374,7 +374,7 @@ Error CTaskManip::Start(TaskManipOrder order, TaskManipArm arm)
|
|||
type != OBJECT_MOBILEta &&
|
||||
type != OBJECT_MOBILEwa &&
|
||||
type != OBJECT_MOBILEia &&
|
||||
type != OBJECT_MOBILEsa ) return ERR_MANIP_VEH;
|
||||
type != OBJECT_MOBILEsa ) return ERR_WRONG_BOT;
|
||||
|
||||
if ( m_bSubm ) // submarine?
|
||||
{
|
||||
|
|
|
@ -139,7 +139,7 @@ Error CTaskPen::Start(bool bDown, TraceColor color)
|
|||
m_bError = true; // operation impossible
|
||||
|
||||
type = m_object->GetType();
|
||||
if ( type != OBJECT_MOBILEdr ) return ERR_FIRE_VEH;
|
||||
if ( type != OBJECT_MOBILEdr ) return ERR_WRONG_BOT;
|
||||
|
||||
m_bError = false; // ok
|
||||
|
||||
|
|
|
@ -180,10 +180,10 @@ bool CTaskRecover::EventProcess(const Event &event)
|
|||
Error CTaskRecover::Start()
|
||||
{
|
||||
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();
|
||||
if ( type != OBJECT_MOBILErr ) return ERR_RECOVER_VEH;
|
||||
if ( type != OBJECT_MOBILErr ) return ERR_WRONG_BOT;
|
||||
|
||||
assert(m_object->Implements(ObjectInterfaceType::Powered));
|
||||
CObject* power = dynamic_cast<CPoweredObject*>(m_object)->GetPower();
|
||||
|
|
|
@ -140,7 +140,7 @@ Error CTaskSearch::Start()
|
|||
if ( type != OBJECT_MOBILEfs &&
|
||||
type != OBJECT_MOBILEts &&
|
||||
type != OBJECT_MOBILEws &&
|
||||
type != OBJECT_MOBILEis ) return ERR_SEARCH_VEH;
|
||||
type != OBJECT_MOBILEis ) return ERR_WRONG_BOT;
|
||||
|
||||
m_hand = TSH_DOWN;
|
||||
m_phase = TSP_DOWN;
|
||||
|
|
|
@ -287,10 +287,10 @@ Error CTaskShield::Start(TaskShieldMode mode, float delay)
|
|||
}
|
||||
|
||||
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
|
||||
if ( !m_physics->GetLand() ) return ERR_SHIELD_VEH;
|
||||
if ( !m_physics->GetLand() ) return ERR_WRONG_BOT;
|
||||
|
||||
CObject* power = m_object->GetPower();
|
||||
if (power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer)) return ERR_SHIELD_ENERGY;
|
||||
|
|
|
@ -110,7 +110,7 @@ Error CTaskTake::Start()
|
|||
|
||||
ObjectType type = m_object->GetType();
|
||||
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));
|
||||
|
||||
|
|
|
@ -203,10 +203,10 @@ Error CTaskTerraform::Start()
|
|||
ObjectType type;
|
||||
|
||||
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();
|
||||
if ( type != OBJECT_MOBILErt ) return ERR_TERRA_VEH;
|
||||
if ( type != OBJECT_MOBILErt ) return ERR_WRONG_BOT;
|
||||
|
||||
power = m_object->GetPower();
|
||||
if ( power == nullptr || !power->Implements(ObjectInterfaceType::PowerContainer) ) return ERR_TERRA_ENERGY;
|
||||
|
|
|
@ -487,6 +487,8 @@ void CScript::Stop()
|
|||
{
|
||||
if ( !m_bRun ) return;
|
||||
|
||||
m_taskExecutor->StopForegroundTask();
|
||||
|
||||
if( m_botProg != 0 )
|
||||
{
|
||||
m_botProg->Stop();
|
||||
|
|
|
@ -718,8 +718,8 @@ bool CScriptFunctions::rFactory(CBotVar* thisclass, CBotVar* var, CBotVar* resul
|
|||
CObject* factory = static_cast<CObject*>(thisclass->GetUserPtr());
|
||||
if (factory == nullptr)
|
||||
{
|
||||
exception = ERR_GENERIC;
|
||||
result->SetValInt(ERR_GENERIC);
|
||||
exception = ERR_UNKNOWN;
|
||||
result->SetValInt(ERR_UNKNOWN);
|
||||
GetLogger()->Error("in object.factory() - factory is nullptr");
|
||||
return false;
|
||||
}
|
||||
|
@ -736,8 +736,8 @@ bool CScriptFunctions::rFactory(CBotVar* thisclass, CBotVar* var, CBotVar* resul
|
|||
CAutoFactory* automat = static_cast<CAutoFactory*>(factory->GetAuto());
|
||||
if (automat == nullptr)
|
||||
{
|
||||
exception = ERR_GENERIC;
|
||||
result->SetValInt(ERR_GENERIC);
|
||||
exception = ERR_UNKNOWN;
|
||||
result->SetValInt(ERR_UNKNOWN);
|
||||
GetLogger()->Error("in object.factory() - automat is nullptr");
|
||||
return false;
|
||||
}
|
||||
|
@ -752,7 +752,7 @@ bool CScriptFunctions::rFactory(CBotVar* thisclass, CBotVar* var, CBotVar* resul
|
|||
if ( err == ERR_OK ) automat->SetProgram(program);
|
||||
}
|
||||
else
|
||||
err = ERR_GENERIC;
|
||||
err = ERR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -824,7 +824,7 @@ bool CScriptFunctions::rResearch(CBotVar* thisclass, CBotVar* var, CBotVar* resu
|
|||
err = automat->StartAction(type);
|
||||
}
|
||||
else
|
||||
err = ERR_GENERIC;
|
||||
err = ERR_UNKNOWN;
|
||||
}
|
||||
else
|
||||
err = ERR_BUILD_DISABLED;
|
||||
|
@ -1417,7 +1417,7 @@ bool CScriptFunctions::rBuild(CBotVar* var, CBotVar* result, int& exception, voi
|
|||
oType != OBJECT_HUMAN &&
|
||||
oType != OBJECT_TECH )
|
||||
{
|
||||
err = ERR_MANIP_VEH; // Wrong object
|
||||
err = ERR_WRONG_BOT; // Wrong object
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2475,10 +2475,10 @@ bool CScriptFunctions::rShield(CBotVar* var, CBotVar* result, int& exception, vo
|
|||
// only shielder can use shield()
|
||||
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)
|
||||
{
|
||||
exception = ERR_MANIP_VEH;
|
||||
exception = ERR_WRONG_BOT;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue