CTaskExecutorObject interface; some general task and CBrain cleanup

master
krzys-h 2015-08-10 13:46:39 +02:00
parent 73e0abc510
commit 3a5f618f65
20 changed files with 638 additions and 590 deletions

View File

@ -70,6 +70,9 @@ const int MAXTRACERECORD = 1000;
CBrain::CBrain(COldObject* object)
{
m_object = object;
assert(object->Implements(ObjectInterfaceType::TaskExecutor));
m_taskExecutor = dynamic_cast<CTaskExecutorObject*>(m_object);
m_engine = Gfx::CEngine::GetInstancePointer();
m_water = m_engine->GetWater();
m_particle = m_engine->GetParticle();
@ -80,13 +83,10 @@ CBrain::CBrain(COldObject* object)
m_sound = CApplication::GetInstancePointer()->GetSound();
m_physics = nullptr;
m_motion = nullptr;
m_primaryTask = nullptr;
m_secondaryTask = nullptr;
m_studio = nullptr;
m_program.clear();
m_currentProgram = nullptr;
m_bActivity = true;
m_bBurn = false;
m_bActiveVirus = false;
m_time = 0.0f;
@ -114,12 +114,6 @@ CBrain::~CBrain()
{
m_program.clear();
delete m_primaryTask;
m_primaryTask = nullptr;
delete m_secondaryTask;
m_secondaryTask = nullptr;
delete m_studio;
m_studio = nullptr;
@ -165,7 +159,7 @@ bool CBrain::Write(CLevelParserLine* line)
if ( m_object->GetType() == OBJECT_MOBILErs )
{
line->AddParam("bShieldActive", MakeUnique<CLevelParserParam>(m_secondaryTask != nullptr));
line->AddParam("bShieldActive", MakeUnique<CLevelParserParam>(m_taskExecutor->IsBackgroundTask()));
}
return true;
@ -180,7 +174,7 @@ bool CBrain::Read(CLevelParserLine* line)
{
if( line->GetParam("bShieldActive")->AsBool(false) )
{
StartTaskShield(TSM_START);
m_taskExecutor->StartTaskShield(TSM_START);
}
}
return true;
@ -201,16 +195,6 @@ bool CBrain::EventProcess(const Event &event)
type = m_object->GetType();
if ( m_primaryTask != 0 ) // current task?
{
m_primaryTask->EventProcess(event);
}
if ( m_secondaryTask != 0 ) // current task?
{
m_secondaryTask->EventProcess(event);
}
action = EVENT_NULL;
bool isActionSlot = false;
@ -376,7 +360,7 @@ bool CBrain::EventProcess(const Event &event)
if ( !m_object->GetSelect() && // robot pas sélectionné ?
m_currentProgram == nullptr &&
m_primaryTask == 0 )
!m_taskExecutor->IsForegroundTask() )
{
axeX = 0.0f;
axeY = 0.0f;
@ -425,14 +409,14 @@ bool CBrain::EventProcess(const Event &event)
return true;
}
if ( m_secondaryTask != 0 ) // current task?
if ( m_taskExecutor->IsBackgroundTask() ) // current task?
{
if ( action == EVENT_OBJECT_ENDSHIELD )
{
m_secondaryTask->StartTaskShield(TSM_DOWN, 0.0f);
m_taskExecutor->StartTaskShield(TSM_DOWN, 0.0f);
}
}
if ( m_primaryTask != 0 || // current task?
if ( m_taskExecutor->IsForegroundTask() || // current task?
m_currentProgram != nullptr )
{
if ( action == EVENT_OBJECT_PROGRUN )
@ -447,7 +431,7 @@ bool CBrain::EventProcess(const Event &event)
}
}
if ( m_primaryTask == 0 || !m_primaryTask->IsPilot() ) return true;
if ( !m_taskExecutor->IsForegroundTask() || !m_taskExecutor->GetForegroundTask()->IsPilot() ) return true;
}
if ( m_currentProgram == nullptr )
@ -620,7 +604,7 @@ bool CBrain::EventProcess(const Event &event)
{
if ( action == EVENT_OBJECT_HTAKE )
{
err = StartTaskTake();
err = m_taskExecutor->StartTaskTake();
}
if ( action == EVENT_OBJECT_MFRONT ||
@ -635,11 +619,11 @@ bool CBrain::EventProcess(const Event &event)
{
if ( m_manipStyle == EVENT_OBJECT_MFRONT )
{
err = StartTaskManip(TMO_AUTO, TMA_FFRONT);
err = m_taskExecutor->StartTaskManip(TMO_AUTO, TMA_FFRONT);
}
if ( m_manipStyle == EVENT_OBJECT_MBACK )
{
err = StartTaskManip(TMO_AUTO, TMA_FBACK);
err = m_taskExecutor->StartTaskManip(TMO_AUTO, TMA_FBACK);
if ( err == ERR_OK )
{
m_manipStyle = EVENT_OBJECT_MFRONT;
@ -648,7 +632,7 @@ bool CBrain::EventProcess(const Event &event)
}
if ( m_manipStyle == EVENT_OBJECT_MPOWER )
{
err = StartTaskManip(TMO_AUTO, TMA_POWER);
err = m_taskExecutor->StartTaskManip(TMO_AUTO, TMA_POWER);
if ( err == ERR_OK )
{
m_manipStyle = EVENT_OBJECT_MFRONT;
@ -659,59 +643,59 @@ bool CBrain::EventProcess(const Event &event)
if ( action == EVENT_OBJECT_BDERRICK )
{
err = StartTaskBuild(OBJECT_DERRICK);
err = m_taskExecutor->StartTaskBuild(OBJECT_DERRICK);
}
if ( action == EVENT_OBJECT_BSTATION )
{
err = StartTaskBuild(OBJECT_STATION);
err = m_taskExecutor->StartTaskBuild(OBJECT_STATION);
}
if ( action == EVENT_OBJECT_BFACTORY )
{
err = StartTaskBuild(OBJECT_FACTORY);
err = m_taskExecutor->StartTaskBuild(OBJECT_FACTORY);
}
if ( action == EVENT_OBJECT_BREPAIR )
{
err = StartTaskBuild(OBJECT_REPAIR);
err = m_taskExecutor->StartTaskBuild(OBJECT_REPAIR);
}
if ( action == EVENT_OBJECT_BCONVERT )
{
err = StartTaskBuild(OBJECT_CONVERT);
err = m_taskExecutor->StartTaskBuild(OBJECT_CONVERT);
}
if ( action == EVENT_OBJECT_BTOWER )
{
err = StartTaskBuild(OBJECT_TOWER);
err = m_taskExecutor->StartTaskBuild(OBJECT_TOWER);
}
if ( action == EVENT_OBJECT_BRESEARCH )
{
err = StartTaskBuild(OBJECT_RESEARCH);
err = m_taskExecutor->StartTaskBuild(OBJECT_RESEARCH);
}
if ( action == EVENT_OBJECT_BRADAR )
{
err = StartTaskBuild(OBJECT_RADAR);
err = m_taskExecutor->StartTaskBuild(OBJECT_RADAR);
}
if ( action == EVENT_OBJECT_BENERGY )
{
err = StartTaskBuild(OBJECT_ENERGY);
err = m_taskExecutor->StartTaskBuild(OBJECT_ENERGY);
}
if ( action == EVENT_OBJECT_BLABO )
{
err = StartTaskBuild(OBJECT_LABO);
err = m_taskExecutor->StartTaskBuild(OBJECT_LABO);
}
if ( action == EVENT_OBJECT_BNUCLEAR )
{
err = StartTaskBuild(OBJECT_NUCLEAR);
err = m_taskExecutor->StartTaskBuild(OBJECT_NUCLEAR);
}
if ( action == EVENT_OBJECT_BPARA )
{
err = StartTaskBuild(OBJECT_PARA);
err = m_taskExecutor->StartTaskBuild(OBJECT_PARA);
}
if ( action == EVENT_OBJECT_BINFO )
{
err = StartTaskBuild(OBJECT_INFO);
err = m_taskExecutor->StartTaskBuild(OBJECT_INFO);
}
if ( action == EVENT_OBJECT_BDESTROYER )
{
err = StartTaskBuild(OBJECT_DESTROYER);
err = m_taskExecutor->StartTaskBuild(OBJECT_DESTROYER);
}
if ( action == EVENT_OBJECT_GFLAT )
@ -720,11 +704,11 @@ bool CBrain::EventProcess(const Event &event)
}
if ( action == EVENT_OBJECT_FCREATE )
{
err = StartTaskFlag(TFL_CREATE, m_flagColor);
err = m_taskExecutor->StartTaskFlag(TFL_CREATE, m_flagColor);
}
if ( action == EVENT_OBJECT_FDELETE )
{
err = StartTaskFlag(TFL_DELETE, m_flagColor);
err = m_taskExecutor->StartTaskFlag(TFL_DELETE, m_flagColor);
}
if ( action == EVENT_OBJECT_FCOLORb ||
action == EVENT_OBJECT_FCOLORr ||
@ -737,27 +721,27 @@ bool CBrain::EventProcess(const Event &event)
if ( action == EVENT_OBJECT_SEARCH )
{
err = StartTaskSearch();
err = m_taskExecutor->StartTaskSearch();
}
if ( action == EVENT_OBJECT_DELSEARCH )
{
err = StartTaskDeleteMark();
err = m_taskExecutor->StartTaskDeleteMark();
}
if ( action == EVENT_OBJECT_TERRAFORM )
{
err = StartTaskTerraform();
err = m_taskExecutor->StartTaskTerraform();
}
if ( action == EVENT_OBJECT_RECOVER )
{
err = StartTaskRecover();
err = m_taskExecutor->StartTaskRecover();
}
if ( action == EVENT_OBJECT_BEGSHIELD )
{
err = StartTaskShield(TSM_UP);
err = m_taskExecutor->StartTaskShield(TSM_UP);
}
if ( action == EVENT_OBJECT_DIMSHIELD )
@ -773,64 +757,64 @@ bool CBrain::EventProcess(const Event &event)
}
}
if ( action == EVENT_OBJECT_FIRE && m_primaryTask == 0 && !m_object->GetTrainer())
if ( action == EVENT_OBJECT_FIRE && !m_taskExecutor->IsForegroundTask() && !m_object->GetTrainer())
{
if ( m_camera->GetType() != Gfx::CAM_TYPE_ONBOARD )
{
m_camera->SetType(Gfx::CAM_TYPE_ONBOARD);
}
err = StartTaskFire(0.0f);
err = m_taskExecutor->StartTaskFire(0.0f);
}
if ( action == EVENT_OBJECT_TARGET && !m_object->GetTrainer() )
{
err = StartTaskGunGoal((event.mousePos.y-0.50f)*1.3f, (event.mousePos.x-0.50f)*2.0f);
err = m_taskExecutor->StartTaskGunGoal((event.mousePos.y-0.50f)*1.3f, (event.mousePos.x-0.50f)*2.0f);
}
if ( action == EVENT_OBJECT_FIREANT )
{
//? err = StartTaskFireAnt();
//? err = m_taskExecutor->StartTaskFireAnt();
}
if ( action == EVENT_OBJECT_SPIDEREXPLO && m_primaryTask == 0 )
if ( action == EVENT_OBJECT_SPIDEREXPLO && !m_taskExecutor->IsForegroundTask() )
{
err = StartTaskSpiderExplo();
err = m_taskExecutor->StartTaskSpiderExplo();
}
if ( action == EVENT_OBJECT_PEN0 ) // up
{
err = StartTaskPen(false);
err = m_taskExecutor->StartTaskPen(false);
}
if ( action == EVENT_OBJECT_PEN1 ) // black
{
err = StartTaskPen(true, TraceColor::Black);
err = m_taskExecutor->StartTaskPen(true, TraceColor::Black);
}
if ( action == EVENT_OBJECT_PEN2 ) // yellow
{
err = StartTaskPen(true, TraceColor::Yellow);
err = m_taskExecutor->StartTaskPen(true, TraceColor::Yellow);
}
if ( action == EVENT_OBJECT_PEN3 ) // orange
{
err = StartTaskPen(true, TraceColor::Orange);
err = m_taskExecutor->StartTaskPen(true, TraceColor::Orange);
}
if ( action == EVENT_OBJECT_PEN4 ) // red
{
err = StartTaskPen(true, TraceColor::Red);
err = m_taskExecutor->StartTaskPen(true, TraceColor::Red);
}
if ( action == EVENT_OBJECT_PEN5 ) // violet
{
err = StartTaskPen(true, TraceColor::Purple);
err = m_taskExecutor->StartTaskPen(true, TraceColor::Purple);
}
if ( action == EVENT_OBJECT_PEN6 ) // blue
{
err = StartTaskPen(true, TraceColor::Blue);
err = m_taskExecutor->StartTaskPen(true, TraceColor::Blue);
}
if ( action == EVENT_OBJECT_PEN7 ) // green
{
err = StartTaskPen(true, TraceColor::Green);
err = m_taskExecutor->StartTaskPen(true, TraceColor::Green);
}
if ( action == EVENT_OBJECT_PEN8 ) // brown
{
err = StartTaskPen(true, TraceColor::Brown);
err = m_taskExecutor->StartTaskPen(true, TraceColor::Brown);
}
if ( action == EVENT_OBJECT_REC ) // registered?
@ -932,12 +916,11 @@ bool CBrain::EventFrame(const Event &event)
UpdateInterface(event.rTime);
if ( m_engine->GetPause() ) return true;
if ( !m_bActivity ) return true; // expected if idle
if ( EndedTask() == ERR_CONTINUE ) return true; // expected if not finished ...
if ( !m_object->GetActivity() ) return true;
if ( m_currentProgram != nullptr ) // current program?
{
if ( m_currentProgram->script->Continue(event) )
if ( m_currentProgram->script->Continue() )
{
StopProgram();
}
@ -956,7 +939,7 @@ bool CBrain::EventFrame(const Event &event)
void CBrain::StopProgram()
{
StopTask();
m_taskExecutor->StopForegroundTask();
if ( m_object->GetType() == OBJECT_HUMAN ||
m_object->GetType() == OBJECT_TECH ) return;
@ -981,30 +964,6 @@ void CBrain::StopProgram()
m_object->CreateSelectParticle();
}
// Stops the current task.
void CBrain::StopTask()
{
if (m_primaryTask != nullptr)
{
m_primaryTask->Abort();
delete m_primaryTask; // stops the current task
m_primaryTask = nullptr;
}
}
// Stops the current secondary task.
void CBrain::StopSecondaryTask()
{
if (m_secondaryTask != nullptr)
{
m_secondaryTask->Abort();
delete m_secondaryTask; // stops the current secondary task
m_secondaryTask = nullptr;
}
}
// Introduces a virus into a program.
// Returns true if it was inserted.
@ -1046,7 +1005,6 @@ bool CBrain::GetActiveVirus()
return m_bActiveVirus;
}
// Start editing a program.
void CBrain::StartEditScript(Program* program, char* name)
@ -1072,221 +1030,6 @@ void CBrain::StopEditScript(bool bCancel)
}
// Move the manipulator arm.
Error CBrain::StartTaskTake()
{
StopTask();
m_primaryTask = new CTaskManager(m_object);
Error err = m_primaryTask->StartTaskTake();
UpdateInterface();
return err;
}
// Move the manipulator arm.
Error CBrain::StartTaskManip(TaskManipOrder order, TaskManipArm arm)
{
StopTask();
m_primaryTask = new CTaskManager(m_object);
Error err = m_primaryTask->StartTaskManip(order, arm);
UpdateInterface();
return err;
}
// Puts or removes a flag.
Error CBrain::StartTaskFlag(TaskFlagOrder order, int rank)
{
StopTask();
m_primaryTask = new CTaskManager(m_object);
Error err = m_primaryTask->StartTaskFlag(order, rank);
UpdateInterface();
return err;
}
// Built a building.
Error CBrain::StartTaskBuild(ObjectType type)
{
StopTask();
m_primaryTask = new CTaskManager(m_object);
Error err = m_primaryTask->StartTaskBuild(type);
UpdateInterface();
return err;
}
// Probe the ground.
Error CBrain::StartTaskSearch()
{
StopTask();
m_primaryTask = new CTaskManager(m_object);
Error err = m_primaryTask->StartTaskSearch();
UpdateInterface();
return err;
}
// Delete mark on ground
Error CBrain::StartTaskDeleteMark()
{
StopTask();
m_primaryTask = new CTaskManager(m_object);
Error err = m_primaryTask->StartTaskDeleteMark();
UpdateInterface();
return err;
}
// Terraformed the ground.
Error CBrain::StartTaskTerraform()
{
StopTask();
m_primaryTask = new CTaskManager(m_object);
Error err = m_primaryTask->StartTaskTerraform();
UpdateInterface();
return err;
}
// Change pencil.
Error CBrain::StartTaskPen(bool down, TraceColor color)
{
auto motionVehicle = dynamic_cast<CMotionVehicle*>(m_motion);
assert(motionVehicle != nullptr);
if (color == TraceColor::Default)
color = motionVehicle->GetTraceColor();
motionVehicle->SetTraceDown(down);
motionVehicle->SetTraceColor(color);
m_physics->SetMotorSpeedX(0.0f);
m_physics->SetMotorSpeedY(0.0f);
m_physics->SetMotorSpeedZ(0.0f);
StopTask();
m_primaryTask = new CTaskManager(m_object);
Error err = m_primaryTask->StartTaskPen(down, color);
UpdateInterface();
return err;
}
// Recovers a ruin.
Error CBrain::StartTaskRecover()
{
StopTask();
m_primaryTask = new CTaskManager(m_object);
Error err = m_primaryTask->StartTaskRecover();
UpdateInterface();
return err;
}
// Deploys the shield.
Error CBrain::StartTaskShield(TaskShieldMode mode)
{
StopSecondaryTask();
m_secondaryTask = new CTaskManager(m_object);
Error err = m_secondaryTask->StartTaskShield(mode, 1000.0f);
UpdateInterface();
return err;
}
// Shoots.
Error CBrain::StartTaskFire(float delay)
{
StopTask();
m_primaryTask = new CTaskManager(m_object);
Error err = m_primaryTask->StartTaskFire(delay);
UpdateInterface();
return err;
}
// Explodes spider.
Error CBrain::StartTaskSpiderExplo()
{
StopTask();
m_primaryTask = new CTaskManager(m_object);
Error err = m_primaryTask->StartTaskSpiderExplo();
UpdateInterface();
return err;
}
// Shoots to the ant.
Error CBrain::StartTaskFireAnt(Math::Vector impact)
{
StopTask();
m_primaryTask = new CTaskManager(m_object);
Error err = m_primaryTask->StartTaskFireAnt(impact);
UpdateInterface();
return err;
}
// Adjusts upward.
Error CBrain::StartTaskGunGoal(float dirV, float dirH)
{
StopSecondaryTask();
m_secondaryTask = new CTaskManager(m_object);
Error err = m_secondaryTask->StartTaskGunGoal(dirV, dirH);
UpdateInterface();
return err;
}
// Completes the task when the time came.
Error CBrain::EndedTask()
{
if (m_secondaryTask != nullptr) // current task?
{
Error err = m_secondaryTask->IsEnded();
if ( err != ERR_CONTINUE ) // job ended?
{
delete m_secondaryTask;
m_secondaryTask = nullptr;
UpdateInterface();
}
}
if (m_primaryTask != nullptr) // current task?
{
Error err = m_primaryTask->IsEnded();
if ( err != ERR_CONTINUE ) // job ended?
{
delete m_primaryTask;
m_primaryTask = nullptr;
UpdateInterface();
}
return err;
}
return ERR_STOP;
}
// Shows flat areas in the field.
void CBrain::GroundFlat()
@ -2281,9 +2024,9 @@ void CBrain::UpdateInterface()
type = m_object->GetType();
bEnable = ( m_primaryTask == 0 && m_currentProgram == nullptr ) && m_main->CanPlayerInteract();
bEnable = ( !m_taskExecutor->IsForegroundTask() && m_currentProgram == nullptr ) && m_main->CanPlayerInteract();
EnableInterface(pw, EVENT_OBJECT_PROGEDIT, (m_primaryTask == 0 && !m_bTraceRecord) && m_selScript < m_program.size() && m_main->CanPlayerInteract());
EnableInterface(pw, EVENT_OBJECT_PROGEDIT, (!m_taskExecutor->IsForegroundTask() && !m_bTraceRecord) && m_selScript < m_program.size() && m_main->CanPlayerInteract());
EnableInterface(pw, EVENT_OBJECT_PROGLIST, bEnable && !m_bTraceRecord);
EnableInterface(pw, EVENT_OBJECT_PROGADD, m_currentProgram == nullptr && m_main->CanPlayerInteract());
EnableInterface(pw, EVENT_OBJECT_PROGREMOVE, m_currentProgram == nullptr && m_selScript < m_program.size() && !m_program[m_selScript]->readOnly && m_main->CanPlayerInteract());
@ -2357,12 +2100,12 @@ void CBrain::UpdateInterface()
if ( type == OBJECT_MOBILErs ) // shield?
{
if ( (m_secondaryTask == 0 || !m_secondaryTask->IsBusy()) && m_currentProgram == nullptr )
if ( (!m_taskExecutor->IsBackgroundTask() || !m_taskExecutor->GetBackgroundTask()->IsBusy()) && m_currentProgram == nullptr )
{
EnableInterface(pw, EVENT_OBJECT_BEGSHIELD, (m_secondaryTask == 0) && m_main->CanPlayerInteract());
EnableInterface(pw, EVENT_OBJECT_ENDSHIELD, (m_secondaryTask != 0) && m_main->CanPlayerInteract());
DefaultEnter (pw, EVENT_OBJECT_BEGSHIELD, (m_secondaryTask == 0));
DefaultEnter (pw, EVENT_OBJECT_ENDSHIELD, (m_secondaryTask != 0));
EnableInterface(pw, EVENT_OBJECT_BEGSHIELD, !m_taskExecutor->IsBackgroundTask() && m_main->CanPlayerInteract());
EnableInterface(pw, EVENT_OBJECT_ENDSHIELD, m_taskExecutor->IsBackgroundTask() && m_main->CanPlayerInteract());
DefaultEnter (pw, EVENT_OBJECT_BEGSHIELD, !m_taskExecutor->IsBackgroundTask());
DefaultEnter (pw, EVENT_OBJECT_ENDSHIELD, m_taskExecutor->IsBackgroundTask());
}
else
{
@ -2724,26 +2467,6 @@ void CBrain::DefaultEnter(Ui::CWindow *pw, EventType event, bool bState)
}
}
// Indicates whether the object is busy with a task.
bool CBrain::IsBusy()
{
return (m_primaryTask != 0);
}
// Management of the activity of an object.
void CBrain::SetActivity(bool bMode)
{
m_bActivity = bMode;
}
bool CBrain::GetActivity()
{
return m_bActivity;
}
// Indicates whether a program is running.
bool CBrain::IsProgram()
@ -3094,7 +2817,7 @@ bool CBrain::TraceRecordPut(std::stringstream& buffer, TraceOper oper, float par
Program* CBrain::AddProgram()
{
auto program = MakeUnique<Program>();
program->script = MakeUnique<CScript>(m_object, &m_secondaryTask);
program->script = MakeUnique<CScript>(m_object);
program->readOnly = false;
program->runnable = true;

View File

@ -38,6 +38,7 @@
#include <memory>
class COldObject;
class CTaskExecutorObject;
class CPhysics;
class CMotion;
class CTaskManager;
@ -106,15 +107,10 @@ public:
bool Write(CLevelParserLine* line);
bool Read(CLevelParserLine* line);
bool IsBusy();
void SetActivity(bool bMode);
bool GetActivity();
bool IsProgram();
void RunProgram(Program* program);
int GetProgram();
void StopProgram();
void StopTask();
void StopSecondaryTask();
bool IntroduceVirus();
void SetActiveVirus(bool bActive);
@ -133,20 +129,6 @@ public:
bool WriteStack(FILE *file);
std::vector<std::unique_ptr<Program>>& GetPrograms();
Error StartTaskTake();
Error StartTaskManip(TaskManipOrder order, TaskManipArm arm);
Error StartTaskFlag(TaskFlagOrder order, int rank);
Error StartTaskBuild(ObjectType type);
Error StartTaskSearch();
Error StartTaskDeleteMark();
Error StartTaskTerraform();
Error StartTaskRecover();
Error StartTaskShield(TaskShieldMode mode);
Error StartTaskFire(float delay);
Error StartTaskFireAnt(Math::Vector impact);
Error StartTaskSpiderExplo();
Error StartTaskGunGoal(float dirV, float dirH);
void UpdateInterface(float rTime);
void UpdateInterface();
@ -160,15 +142,11 @@ public:
int GetProgramIndex(Program* program);
protected:
Error StartTaskPen(bool down, TraceColor color = TraceColor::Default);
bool EventFrame(const Event &event);
void StartEditScript(Program* program, char* name);
void StopEditScript(bool bCancel);
Error EndedTask();
void GroundFlat();
void ColorFlag(int color);
@ -200,6 +178,7 @@ protected:
Gfx::CCamera* m_camera;
Gfx::CParticle* m_particle;
COldObject* m_object;
CTaskExecutorObject* m_taskExecutor;
CPhysics* m_physics;
CMotion* m_motion;
Ui::CInterface* m_interface;
@ -207,15 +186,11 @@ protected:
Ui::CStudio* m_studio;
CSoundInterface* m_sound;
CTaskManager* m_primaryTask;
CTaskManager* m_secondaryTask;
std::vector<std::unique_ptr<Program>> m_program;
Program* m_currentProgram;
unsigned int m_selScript; // rank of the selected script
bool m_bActivity;
bool m_bBurn;
bool m_bActiveVirus;

View File

@ -22,8 +22,6 @@
#include "object/object.h"
#include "object/object_interface_type.h"
struct Event;
/**
* \class CCarrierObject
* \brief Interface for carrier objects

View File

@ -23,8 +23,6 @@
#include "object/object_interface_type.h"
struct Event;
/**
* \class CJostleableObject
* \brief Interface for objects that can be jostled

View File

@ -0,0 +1,90 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
#pragma once
#include "object/object.h"
#include "object/object_interface_type.h"
#include "object/trace_color.h"
#include "object/task/taskflag.h"
#include "object/task/taskgoto.h"
#include "object/task/taskmanip.h"
#include "object/task/taskshield.h"
class CTaskManager;
/**
* \class CTaskExecutorObject
* \brief Interface for objects that can execute tasks
*/
class CTaskExecutorObject
{
public:
explicit CTaskExecutorObject(ObjectInterfaceTypes& types)
{
types[static_cast<int>(ObjectInterfaceType::TaskExecutor)] = true;
}
virtual ~CTaskExecutorObject()
{}
//! Start a foreground task
//@{
virtual Error StartTaskTake() = 0;
virtual Error StartTaskManip(TaskManipOrder order, TaskManipArm arm) = 0;
virtual Error StartTaskFlag(TaskFlagOrder order, int rank) = 0;
virtual Error StartTaskBuild(ObjectType type) = 0;
virtual Error StartTaskSearch() = 0;
virtual Error StartTaskDeleteMark() = 0;
virtual Error StartTaskTerraform() = 0;
virtual Error StartTaskRecover() = 0;
virtual Error StartTaskFire(float delay) = 0;
virtual Error StartTaskFireAnt(Math::Vector impact) = 0;
virtual Error StartTaskSpiderExplo() = 0;
virtual Error StartTaskPen(bool down, TraceColor color = TraceColor::Default) = 0;
//@}
//! Start a foreground task (scriptable tasks, not in UI)
//@{
virtual Error StartTaskWait(float time) = 0;
virtual Error StartTaskAdvance(float length) = 0;
virtual Error StartTaskTurn(float angle) = 0;
virtual Error StartTaskGoto(Math::Vector pos, float altitude, TaskGotoGoal goalMode, TaskGotoCrash crashMode) = 0;
virtual Error StartTaskInfo(const char *name, float value, float power, bool bSend) = 0;
//@}
//! Starts a background task
//@{
virtual Error StartTaskShield(TaskShieldMode mode, float delay = 1000.0f) = 0;
virtual Error StartTaskGunGoal(float dirV, float dirH) = 0;
//@}
//! Is executing foreground task?
virtual bool IsForegroundTask() = 0;
//! Is executing background task?
virtual bool IsBackgroundTask() = 0;
//! Return the foreground task
virtual CTaskManager* GetForegroundTask() = 0;
//! Return the background task
virtual CTaskManager* GetBackgroundTask() = 0;
//! Stop foreground task
virtual void StopForegroundTask() = 0;
//! Stop background task
virtual void StopBackgroundTask() = 0;
};

View File

@ -22,8 +22,6 @@
#include "object/object.h"
#include "object/object_interface_type.h"
struct Event;
/**
* \class CTransportableObject
* \brief Interface for transportable objects

View File

@ -51,7 +51,6 @@ CMotion::CMotion(COldObject* object)
m_object = object;
m_physics = 0;
m_brain = 0;
m_actionType = -1;
m_actionTime = 0.0f;
@ -73,11 +72,6 @@ void CMotion::SetPhysics(CPhysics* physics)
m_physics = physics;
}
void CMotion::SetBrain(CBrain* brain)
{
m_brain = brain;
}
// Management of an event.
bool CMotion::EventProcess(const Event &event)
@ -219,4 +213,3 @@ Math::Vector CMotion::GetTilt()
{
return m_inclinaison;
}

View File

@ -53,7 +53,6 @@ public:
virtual ~CMotion();
void SetPhysics(CPhysics* physics);
void SetBrain(CBrain* brain);
virtual void DeleteObject(bool bAll=false) = 0;
virtual void Create(Math::Vector pos, float angle, ObjectType type, float power, Gfx::COldModelManager* modelManager) = 0;
@ -82,7 +81,6 @@ protected:
Gfx::CWater* m_water;
Gfx::CCamera* m_camera;
COldObject* m_object;
CBrain* m_brain;
CPhysics* m_physics;
CRobotMain* m_main;
CSoundInterface* m_sound;
@ -95,4 +93,3 @@ protected:
Math::Vector m_cirVibration; // circular vibration
Math::Vector m_inclinaison; // tilt
};

View File

@ -2651,9 +2651,7 @@ CObjectUPtr CObjectFactory::CreateVehicle(const ObjectCreateParams& params)
brain->SetMotion(motion.get());
brain->SetPhysics(physics.get());
motion->SetBrain(brain.get());
motion->SetPhysics(physics.get());
physics->SetBrain(brain.get());
physics->SetMotion(motion.get());
motion->Create(pos, angle, type, power, m_oldModelManager);
@ -2704,11 +2702,9 @@ CObjectUPtr CObjectFactory::CreateInsect(const ObjectCreateParams& params)
}
assert(motion != nullptr);
physics->SetBrain(brain.get());
physics->SetMotion(motion.get());
brain->SetMotion(motion.get());
brain->SetPhysics(physics.get());
motion->SetBrain(brain.get());
motion->SetPhysics(physics.get());
motion->Create(pos, angle, type, 0.0f, m_oldModelManager);

View File

@ -36,6 +36,7 @@ enum class ObjectInterfaceType
Interactive, //!< interactive objects can process events from event loop
Transportable, //!< objects that can be carried by robots or astronaut
Programmable, //!< objects that can be programmed in CBOT
TaskExecutor, //!< objects that can execute tasks (CTask classes)
Jostleable, //!< object that can be jostled
Carrier, //!< object that can carry other objects
Powered, //!< object powered with power cell

View File

@ -51,6 +51,8 @@
#include "object/motion/motion.h"
#include "object/motion/motionvehicle.h"
#include "object/task/taskmanager.h"
#include "physics/physics.h"
#include "script/cbottoken.h"
@ -86,6 +88,7 @@ COldObject::COldObject(int id)
: CObject(id, OBJECT_NULL)
, CInteractiveObject(m_implementedInterfaces)
, CTransportableObject(m_implementedInterfaces)
, CTaskExecutorObject(m_implementedInterfaces)
, CProgrammableObject(m_implementedInterfaces)
, CJostleableObject(m_implementedInterfaces)
, CCarrierObject(m_implementedInterfaces)
@ -184,6 +187,8 @@ COldObject::COldObject(int id)
m_cmdLine.clear();
m_activity = true;
DeleteAllCrashSpheres();
m_botVar = CScriptFunctions::CreateObjectVar(this);
@ -1819,6 +1824,16 @@ bool COldObject::EventProcess(const Event &event)
#endif
}
if ( m_foregroundTask != nullptr )
{
m_foregroundTask->EventProcess(event);
}
if ( m_backgroundTask != nullptr )
{
m_backgroundTask->EventProcess(event);
}
if ( m_physics != nullptr )
{
if ( !m_physics->EventProcess(event) ) // object destroyed?
@ -1835,6 +1850,11 @@ bool COldObject::EventProcess(const Event &event)
}
}
if ( m_brain.get() != nullptr )
{
m_brain->EventProcess(event);
}
if ( m_auto != nullptr )
{
m_auto->EventProcess(event);
@ -1871,7 +1891,7 @@ bool COldObject::EventFrame(const Event &event)
return true;
}
if ( m_type != OBJECT_SHOW && m_engine->GetPause() ) return true;
if ( m_engine->GetPause() && m_type != OBJECT_SHOW ) return true;
m_aTime += event.rTime;
m_shotTime += event.rTime;
@ -1897,6 +1917,9 @@ bool COldObject::EventFrame(const Event &event)
}
}
// NOTE: This MUST be called AFTER CScriptFunctions::Process, otherwise weird stuff may happen to scripts
EndedTask();
return true;
}
@ -2449,9 +2472,9 @@ void COldObject::SetSelect(bool bMode, bool bDisplayError)
m_bSelect = bMode;
if ( m_physics != nullptr )
if ( m_brain != nullptr )
{
m_physics->CreateInterface(m_bSelect);
m_brain->CreateInterface(m_bSelect);
}
if ( m_auto != nullptr )
@ -2506,26 +2529,6 @@ bool COldObject::GetSelectable()
}
// Management of the activities of an object.
void COldObject::SetActivity(bool bMode)
{
if ( m_brain != nullptr )
{
m_brain->SetActivity(bMode);
}
}
bool COldObject::GetActivity()
{
if ( m_brain != nullptr )
{
return m_brain->GetActivity();
}
return false;
}
// Indicates if necessary to check the tokens of the object.
void COldObject::SetCheckToken(bool bMode)
@ -3151,3 +3154,320 @@ void COldObject::SetScale(const Math::Vector& scale)
{
SetPartScale(0, scale);
}
// Move the manipulator arm.
Error COldObject::StartTaskTake()
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskTake();
m_brain->UpdateInterface();
return err;
}
// Move the manipulator arm.
Error COldObject::StartTaskManip(TaskManipOrder order, TaskManipArm arm)
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskManip(order, arm);
m_brain->UpdateInterface();
return err;
}
// Puts or removes a flag.
Error COldObject::StartTaskFlag(TaskFlagOrder order, int rank)
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskFlag(order, rank);
m_brain->UpdateInterface();
return err;
}
// Built a building.
Error COldObject::StartTaskBuild(ObjectType type)
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskBuild(type);
m_brain->UpdateInterface();
return err;
}
// Probe the ground.
Error COldObject::StartTaskSearch()
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskSearch();
m_brain->UpdateInterface();
return err;
}
// Delete mark on ground
Error COldObject::StartTaskDeleteMark()
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskDeleteMark();
m_brain->UpdateInterface();
return err;
}
// Terraformed the ground.
Error COldObject::StartTaskTerraform()
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskTerraform();
m_brain->UpdateInterface();
return err;
}
// Change pencil.
Error COldObject::StartTaskPen(bool down, TraceColor color)
{
auto motionVehicle = dynamic_cast<CMotionVehicle*>(m_motion.get());
assert(motionVehicle != nullptr);
if (color == TraceColor::Default)
color = motionVehicle->GetTraceColor();
motionVehicle->SetTraceDown(down);
motionVehicle->SetTraceColor(color);
m_physics->SetMotorSpeedX(0.0f);
m_physics->SetMotorSpeedY(0.0f);
m_physics->SetMotorSpeedZ(0.0f);
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskPen(down, color);
m_brain->UpdateInterface();
return err;
}
// Recovers a ruin.
Error COldObject::StartTaskRecover()
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskRecover();
m_brain->UpdateInterface();
return err;
}
// Shoots.
Error COldObject::StartTaskFire(float delay)
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskFire(delay);
m_brain->UpdateInterface();
return err;
}
// Explodes spider.
Error COldObject::StartTaskSpiderExplo()
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskSpiderExplo();
m_brain->UpdateInterface();
return err;
}
// Shoots to the ant.
Error COldObject::StartTaskFireAnt(Math::Vector impact)
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskFireAnt(impact);
m_brain->UpdateInterface();
return err;
}
Error COldObject::StartTaskWait(float time)
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskWait(time);
m_brain->UpdateInterface();
return err;
}
Error COldObject::StartTaskAdvance(float length)
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskAdvance(length);
m_brain->UpdateInterface();
return err;
}
Error COldObject::StartTaskTurn(float angle)
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskTurn(angle);
m_brain->UpdateInterface();
return err;
}
Error COldObject::StartTaskGoto(Math::Vector pos, float altitude, TaskGotoGoal goalMode, TaskGotoCrash crashMode)
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskGoto(pos, altitude, goalMode, crashMode);
m_brain->UpdateInterface();
return err;
}
Error COldObject::StartTaskInfo(const char *name, float value, float power, bool bSend)
{
StopForegroundTask();
m_foregroundTask = MakeUnique<CTaskManager>(this);
Error err = m_foregroundTask->StartTaskInfo(name, value, power, bSend);
m_brain->UpdateInterface();
return err;
}
// Deploys the shield.
Error COldObject::StartTaskShield(TaskShieldMode mode, float delay)
{
if (m_backgroundTask == nullptr)
{
m_backgroundTask = MakeUnique<CTaskManager>(this);
}
Error err = m_backgroundTask->StartTaskShield(mode, delay);
m_brain->UpdateInterface();
return err;
}
// Adjusts upward.
Error COldObject::StartTaskGunGoal(float dirV, float dirH)
{
StopBackgroundTask();
m_backgroundTask = MakeUnique<CTaskManager>(this);
Error err = m_backgroundTask->StartTaskGunGoal(dirV, dirH);
m_brain->UpdateInterface();
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();
m_brain->UpdateInterface();
}
}
if (m_foregroundTask.get() != nullptr) // current task?
{
Error err = m_foregroundTask->IsEnded();
if ( err != ERR_CONTINUE ) // job ended?
{
m_foregroundTask.reset();
m_brain->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;
}

View File

@ -31,6 +31,7 @@
#include "object/interface/jostleable_object.h"
#include "object/interface/powered_object.h"
#include "object/interface/programmable_object.h"
#include "object/interface/task_executor_object.h"
#include "object/interface/transportable_object.h"
// The father of all parts must always be the part number zero!
@ -58,6 +59,7 @@ struct ObjectPart
class COldObject : public CObject,
public CInteractiveObject,
public CTransportableObject,
public CTaskExecutorObject,
public CProgrammableObject,
public CJostleableObject,
public CCarrierObject,
@ -218,8 +220,11 @@ public:
void SetSelectable(bool bMode);
bool GetSelectable() override;
void SetActivity(bool bMode) override;
bool GetActivity() override;
//! Management of object "activity" (temporairly stops program execution, right now used only by Aliens in eggs)
//@{
void SetActivity(bool activity);
bool GetActivity();
//@}
void SetVisible(bool bVisible);
@ -295,6 +300,35 @@ public:
void SetScale(const Math::Vector& scale) override;
Math::Vector GetScale() const override;
Error StartTaskTake() override;
Error StartTaskManip(TaskManipOrder order, TaskManipArm arm) override;
Error StartTaskFlag(TaskFlagOrder order, int rank) override;
Error StartTaskBuild(ObjectType type) override;
Error StartTaskSearch() override;
Error StartTaskDeleteMark() override;
Error StartTaskTerraform() override;
Error StartTaskRecover() override;
Error StartTaskFire(float delay) override;
Error StartTaskFireAnt(Math::Vector impact) override;
Error StartTaskSpiderExplo() override;
Error StartTaskPen(bool down, TraceColor color = TraceColor::Default) override;
Error StartTaskWait(float time) override;
Error StartTaskAdvance(float length) override;
Error StartTaskTurn(float angle) override;
Error StartTaskGoto(Math::Vector pos, float altitude, TaskGotoGoal goalMode, TaskGotoCrash crashMode) override;
Error StartTaskInfo(const char *name, float value, float power, bool bSend) override;
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;
protected:
bool EventFrame(const Event &event);
void VirusFrame(float rTime);
@ -309,6 +343,8 @@ protected:
void TransformCrashSphere(Math::Sphere &crashSphere) override;
void TransformCameraCollisionSphere(Math::Sphere& collisionSphere) override;
Error EndedTask();
protected:
Gfx::CEngine* m_engine;
Gfx::CLightManager* m_lightMan;
@ -391,4 +427,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;
};

View File

@ -4944,10 +4944,9 @@ bool CRobotMain::IsBusy()
for (CObject* obj : m_objMan->GetAllObjects())
{
if (! obj->Implements(ObjectInterfaceType::Programmable)) continue;
if (! obj->Implements(ObjectInterfaceType::TaskExecutor)) continue;
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
if (brain->IsBusy()) return true;
if (dynamic_cast<CTaskExecutorObject*>(obj)->IsForegroundTask()) return true;
}
return false;
}

View File

@ -376,16 +376,16 @@ bool CTaskTerraform::Terraform()
if ( type == OBJECT_ANT )
{
if (pObj->Implements(ObjectInterfaceType::Programmable))
dynamic_cast<CProgrammableObject*>(pObj)->GetBrain()->StopTask();
assert(pObj->Implements(ObjectInterfaceType::TaskExecutor));
dynamic_cast<CTaskExecutorObject*>(pObj)->StopForegroundTask();
motion->SetAction(MAS_BACK1, 0.8f+Math::Rand()*0.3f);
pObj->SetFixed(true); // not moving
}
if ( type == OBJECT_SPIDER )
{
if (pObj->Implements(ObjectInterfaceType::Programmable))
dynamic_cast<CProgrammableObject*>(pObj)->GetBrain()->StopTask();
assert(pObj->Implements(ObjectInterfaceType::TaskExecutor));
dynamic_cast<CTaskExecutorObject*>(pObj)->StopForegroundTask();
motion->SetAction(MSS_BACK1, 0.8f+Math::Rand()*0.3f);
pObj->SetFixed(true); // not moving
@ -395,4 +395,3 @@ bool CTaskTerraform::Terraform()
return true;
}

View File

@ -75,7 +75,6 @@ CPhysics::CPhysics(COldObject* object)
m_terrain = CRobotMain::GetInstancePointer()->GetTerrain();
m_camera = CRobotMain::GetInstancePointer()->GetCamera();
m_sound = CApplication::GetInstancePointer()->GetSound();
m_brain = nullptr;
m_motion = nullptr;
m_type = TYPE_ROLLING;
@ -150,10 +149,6 @@ void CPhysics::DeleteObject(bool bAll)
void CPhysics::SetBrain(CBrain* brain)
{
m_brain = brain;
}
void CPhysics::SetMotion(CMotion* motion)
{
@ -767,11 +762,6 @@ bool CPhysics::EventProcess(const Event &event)
{
if ( !m_object->GetEnable() ) return true;
if ( m_brain != 0 )
{
m_brain->EventProcess(event);
}
if ( event.type == EVENT_FRAME )
{
return EventFrame(event);
@ -3822,17 +3812,6 @@ void CPhysics::WheelParticle(TraceColor color, float width)
}
// Creates the interface.
void CPhysics::CreateInterface(bool bSelect)
{
if ( m_brain != 0 )
{
m_brain->CreateInterface(bSelect);
}
}
// Returns an error related to the general state.
Error CPhysics::GetError()
@ -3848,9 +3827,12 @@ Error CPhysics::GetError()
type == OBJECT_APOLLO2 ||
type == OBJECT_MOBILEdr ) return ERR_OK;
if ( m_brain != 0 && m_brain->GetActiveVirus() )
if (m_object->Implements(ObjectInterfaceType::Programmable))
{
return ERR_VEH_VIRUS;
if ( dynamic_cast<CProgrammableObject*>(m_object)->GetBrain()->GetActiveVirus() )
{
return ERR_VEH_VIRUS;
}
}
if (m_object->Implements(ObjectInterfaceType::Powered))

View File

@ -171,7 +171,6 @@ public:
float GetMotorSpeedY();
float GetMotorSpeedZ();
void CreateInterface(bool bSelect);
Error GetError();
float GetFallingHeight();

View File

@ -35,11 +35,10 @@
#include "object/old_object.h"
#include "object/robotmain.h"
#include "object/task/taskmanager.h"
#include "script/cbottoken.h"
#include "ui/displaytext.h"
#include "ui/controls/edit.h"
#include "ui/controls/interface.h"
#include "ui/controls/list.h"
@ -51,19 +50,20 @@ const int CBOT_IPF = 100; // CBOT: default number of instructions / frame
// Object's constructor.
CScript::CScript(COldObject* object, CTaskManager** secondaryTask)
CScript::CScript(COldObject* object)
{
m_object = object;
assert(m_object->Implements(ObjectInterfaceType::TaskExecutor));
m_taskExecutor = dynamic_cast<CTaskExecutorObject*>(m_object);
m_engine = Gfx::CEngine::GetInstancePointer();
m_main = CRobotMain::GetInstancePointer();
m_terrain = m_main->GetTerrain();
m_water = m_engine->GetWater();
m_botProg = nullptr;
m_object = object;
m_primaryTask = nullptr;
m_secondaryTask = secondaryTask;
m_interface = m_main->GetInterface();
m_pause = CPauseManager::GetInstancePointer();
m_interface = m_main->GetInterface();
m_pause = CPauseManager::GetInstancePointer();
m_botProg = nullptr;
m_ipf = CBOT_IPF;
m_errMode = ERM_STOP;
@ -86,9 +86,6 @@ CScript::~CScript()
delete m_botProg;
m_botProg = nullptr;
delete m_primaryTask;
m_primaryTask = nullptr;
delete[] m_script;
m_script = nullptr;
@ -358,8 +355,7 @@ bool CScript::Run()
if ( m_bStepMode ) // step by step mode?
{
Event newEvent;
Step(newEvent);
Step();
}
return true;
@ -368,13 +364,11 @@ bool CScript::Run()
// Continues the execution of current program.
// Returns true when execution is finished.
bool CScript::Continue(const Event &event)
bool CScript::Continue()
{
if( m_botProg == 0 ) return true;
if ( !m_bRun ) return true;
m_event = event.Clone();
if ( m_bStepMode ) // step by step mode?
{
if ( m_bContinue ) // instuction "move", "goto", etc. ?
@ -442,7 +436,7 @@ bool CScript::Continue(const Event &event)
// Continues the execution of current program.
// Returns true when execution is finished.
bool CScript::Step(const Event &event)
bool CScript::Step()
{
if( m_botProg == 0 ) return true;
if ( !m_bRun ) return true;
@ -452,8 +446,6 @@ bool CScript::Step(const Event &event)
// TODO: m_app StepSimulation??? m_engine->StepSimulation(0.01f); // advance of 10ms
// ??? m_engine->SetPause(true);
m_event = event.Clone();
if ( m_botProg->Run(m_object, 0) ) // step mode
{
m_botProg->GetError(m_error, m_cursor1, m_cursor2);
@ -499,13 +491,6 @@ void CScript::Stop()
m_botProg->Stop();
}
if ( m_primaryTask != 0 )
{
m_primaryTask->Abort();
delete m_primaryTask;
m_primaryTask = 0;
}
m_bRun = false;
}

View File

@ -32,7 +32,7 @@
class COldObject;
class CTaskManager;
class CTaskExecutorObject;
class CRobotMain;
class CPauseManager;
class CScriptFunctions;
@ -60,7 +60,7 @@ class CScript
{
friend class CScriptFunctions;
public:
CScript(COldObject* object, CTaskManager** secondaryTask);
CScript(COldObject* object);
~CScript();
void PutScript(Ui::CEdit* edit, const char* name);
@ -71,8 +71,8 @@ public:
void SetStepMode(bool bStep);
bool Run();
bool Continue(const Event &event);
bool Step(const Event &event);
bool Continue();
bool Step();
void Stop();
bool IsRunning();
bool IsContinue();
@ -101,15 +101,15 @@ protected:
bool Compile();
protected:
COldObject* m_object;
CTaskExecutorObject* m_taskExecutor;
Gfx::CEngine* m_engine;
Ui::CInterface* m_interface;
Ui::CInterface* m_interface;
CBotProgram* m_botProg;
CRobotMain* m_main;
Gfx::CTerrain* m_terrain;
Gfx::CWater* m_water;
CTaskManager* m_primaryTask;
CTaskManager** m_secondaryTask;
COldObject* m_object;
CPauseManager* m_pause;
int m_ipf; // number of instructions/second
@ -130,4 +130,3 @@ protected:
Event m_event;
float m_returnValue;
};

View File

@ -45,6 +45,8 @@
#include "object/auto/autobase.h"
#include "object/auto/autofactory.h"
#include "object/interface/task_executor_object.h"
#include "object/level/parser.h"
#include "object/motion/motionvehicle.h"
@ -1201,11 +1203,10 @@ bool CScriptFunctions::Process(CScript* script, CBotVar* result, int &exception)
{
Error err;
err = script->m_primaryTask->IsEnded();
err = script->m_taskExecutor->GetForegroundTask()->IsEnded();
if ( err != ERR_CONTINUE ) // task terminated?
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
script->m_bContinue = false;
@ -1219,7 +1220,6 @@ bool CScriptFunctions::Process(CScript* script, CBotVar* result, int &exception)
return true; // it's all over
}
script->m_primaryTask->EventProcess(script->m_event);
script->m_bContinue = true;
return false; // not done
}
@ -1265,7 +1265,7 @@ bool CScriptFunctions::rDetect(CBotVar* var, CBotVar* result, int& exception, vo
exception = 0;
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
type = OBJECT_NULL;
array = 0;
@ -1314,12 +1314,10 @@ bool CScriptFunctions::rDetect(CBotVar* var, CBotVar* result, int& exception, vo
script->m_returnValue = 1.0f;
}
script->m_primaryTask = new CTaskManager(script->m_object);
err = script->m_primaryTask->StartTaskWait(0.3f);
err = script->m_taskExecutor->StartTaskWait(0.3f);
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
if ( script->m_errMode == ERM_STOP )
{
@ -1441,20 +1439,15 @@ bool CScriptFunctions::rBuild(CBotVar* var, CBotVar* result, int& exception, voi
if (pThis->GetIgnoreBuildCheck())
err = ERR_OK;
if (err == ERR_OK && script->m_primaryTask == 0) // if we can build and no task is present
if (err == ERR_OK && !script->m_taskExecutor->IsForegroundTask()) // if we can build
{
script->m_primaryTask = new CTaskManager(script->m_object);
err = script->m_primaryTask->StartTaskBuild(category);
err = script->m_taskExecutor->StartTaskBuild(category);
if (err != ERR_OK)
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
}
}
// When script is waiting for finishing this task, it sets ERR_OK, and continues executing Process
// without creating new task. I think, there was a problem with previous version in release configuration
// It did not init error variable in this situation, and code tried to use variable with trash inside
}
if ( err != ERR_OK )
@ -1893,15 +1886,13 @@ bool CScriptFunctions::rWait(CBotVar* var, CBotVar* result, int& exception, void
exception = 0;
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
script->m_primaryTask = new CTaskManager(script->m_object);
value = var->GetValFloat();
err = script->m_primaryTask->StartTaskWait(value);
err = script->m_taskExecutor->StartTaskWait(value);
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
if ( script->m_errMode == ERM_STOP )
{
@ -1924,15 +1915,13 @@ bool CScriptFunctions::rMove(CBotVar* var, CBotVar* result, int& exception, void
exception = 0;
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
script->m_primaryTask = new CTaskManager(script->m_object);
value = var->GetValFloat();
err = script->m_primaryTask->StartTaskAdvance(value*g_unit);
err = script->m_taskExecutor->StartTaskAdvance(value*g_unit);
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
if ( script->m_errMode == ERM_STOP )
{
@ -1955,15 +1944,13 @@ bool CScriptFunctions::rTurn(CBotVar* var, CBotVar* result, int& exception, void
exception = 0;
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
script->m_primaryTask = new CTaskManager(script->m_object);
value = var->GetValFloat();
err = script->m_primaryTask->StartTaskTurn(-value*Math::PI/180.0f);
err = script->m_taskExecutor->StartTaskTurn(-value*Math::PI/180.0f);
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
if ( script->m_errMode == ERM_STOP )
{
@ -2015,9 +2002,8 @@ bool CScriptFunctions::rGoto(CBotVar* var, CBotVar* result, int& exception, void
exception = 0;
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
script->m_primaryTask = new CTaskManager(script->m_object);
if ( !GetPoint(var, exception, pos) ) return true;
goal = TGG_DEFAULT;
@ -2041,11 +2027,10 @@ bool CScriptFunctions::rGoto(CBotVar* var, CBotVar* result, int& exception, void
}
}
err = script->m_primaryTask->StartTaskGoto(pos, altitude, goal, crash);
err = script->m_taskExecutor->StartTaskGoto(pos, altitude, goal, crash);
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
if ( script->m_errMode == ERM_STOP )
{
@ -2081,9 +2066,8 @@ bool CScriptFunctions::rGrab(CBotVar* var, CBotVar* result, int& exception, void
exception = 0;
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
script->m_primaryTask = new CTaskManager(script->m_object);
if ( var == 0 )
{
type = TMA_FFRONT;
@ -2097,17 +2081,16 @@ bool CScriptFunctions::rGrab(CBotVar* var, CBotVar* result, int& exception, void
if ( oType == OBJECT_HUMAN ||
oType == OBJECT_TECH )
{
err = script->m_primaryTask->StartTaskTake();
err = script->m_taskExecutor->StartTaskTake();
}
else
{
err = script->m_primaryTask->StartTaskManip(TMO_GRAB, type);
err = script->m_taskExecutor->StartTaskManip(TMO_GRAB, type);
}
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
if ( script->m_errMode == ERM_STOP )
{
@ -2132,9 +2115,8 @@ bool CScriptFunctions::rDrop(CBotVar* var, CBotVar* result, int& exception, void
exception = 0;
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
script->m_primaryTask = new CTaskManager(script->m_object);
if ( var == 0 ) type = TMA_FFRONT;
else type = static_cast<TaskManipArm>(var->GetValInt());
@ -2142,17 +2124,16 @@ bool CScriptFunctions::rDrop(CBotVar* var, CBotVar* result, int& exception, void
if ( oType == OBJECT_HUMAN ||
oType == OBJECT_TECH )
{
err = script->m_primaryTask->StartTaskTake();
err = script->m_taskExecutor->StartTaskTake();
}
else
{
err = script->m_primaryTask->StartTaskManip(TMO_DROP, type);
err = script->m_taskExecutor->StartTaskManip(TMO_DROP, type);
}
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
if ( script->m_errMode == ERM_STOP )
{
@ -2174,14 +2155,12 @@ bool CScriptFunctions::rSniff(CBotVar* var, CBotVar* result, int& exception, voi
exception = 0;
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
script->m_primaryTask = new CTaskManager(script->m_object);
err = script->m_primaryTask->StartTaskSearch();
err = script->m_taskExecutor->StartTaskSearch();
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
if ( script->m_errMode == ERM_STOP )
{
@ -2223,10 +2202,8 @@ bool CScriptFunctions::rReceive(CBotVar* var, CBotVar* result, int& exception, v
exception = 0;
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
script->m_primaryTask = new CTaskManager(script->m_object);
cbs = var->GetValString();
p = cbs;
var = var->GetNext();
@ -2238,11 +2215,10 @@ bool CScriptFunctions::rReceive(CBotVar* var, CBotVar* result, int& exception, v
var = var->GetNext();
}
err = script->m_primaryTask->StartTaskInfo(static_cast<const char*>(p), 0.0f, power, false);
err = script->m_taskExecutor->StartTaskInfo(static_cast<const char*>(p), 0.0f, power, false);
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetInit(CBotVar::InitType::IS_NAN);
return true;
}
@ -2293,10 +2269,8 @@ bool CScriptFunctions::rSend(CBotVar* var, CBotVar* result, int& exception, void
exception = 0;
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
script->m_primaryTask = new CTaskManager(script->m_object);
cbs = var->GetValString();
p = cbs;
var = var->GetNext();
@ -2311,11 +2285,10 @@ bool CScriptFunctions::rSend(CBotVar* var, CBotVar* result, int& exception, void
var = var->GetNext();
}
err = script->m_primaryTask->StartTaskInfo(static_cast<const char*>(p), value, power, true);
err = script->m_taskExecutor->StartTaskInfo(static_cast<const char*>(p), value, power, true);
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
if ( script->m_errMode == ERM_STOP )
{
@ -2440,14 +2413,12 @@ bool CScriptFunctions::rThump(CBotVar* var, CBotVar* result, int& exception, voi
exception = 0;
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
script->m_primaryTask = new CTaskManager(script->m_object);
err = script->m_primaryTask->StartTaskTerraform();
err = script->m_taskExecutor->StartTaskTerraform();
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
if ( script->m_errMode == ERM_STOP )
{
@ -2469,14 +2440,12 @@ bool CScriptFunctions::rRecycle(CBotVar* var, CBotVar* result, int& exception, v
exception = 0;
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
script->m_primaryTask = new CTaskManager(script->m_object);
err = script->m_primaryTask->StartTaskRecover();
err = script->m_taskExecutor->StartTaskRecover();
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
if ( script->m_errMode == ERM_STOP )
{
@ -2535,7 +2504,7 @@ bool CScriptFunctions::rShield(CBotVar* var, CBotVar* result, int& exception, vo
if ( radius > 25.0f ) radius = 25.0f;
radius = (radius-10.0f)/15.0f;
if ( *script->m_secondaryTask == 0 ) // shield folds?
if ( !script->m_taskExecutor->IsBackgroundTask() ) // shield folds?
{
if ( oper == 0.0f ) // down?
{
@ -2544,12 +2513,10 @@ bool CScriptFunctions::rShield(CBotVar* var, CBotVar* result, int& exception, vo
else // up ?
{
pThis->SetParam(radius);
*script->m_secondaryTask = new CTaskManager(script->m_object);
err = (*script->m_secondaryTask)->StartTaskShield(TSM_UP, 1000.0f);
err = script->m_taskExecutor->StartTaskShield(TSM_UP, 1000.0f);
if ( err != ERR_OK )
{
delete *script->m_secondaryTask;
*script->m_secondaryTask = 0;
script->m_taskExecutor->StopBackgroundTask();
result->SetValInt(err); // shows the error
}
}
@ -2558,13 +2525,13 @@ bool CScriptFunctions::rShield(CBotVar* var, CBotVar* result, int& exception, vo
{
if ( oper == 0.0f ) // down?
{
(*script->m_secondaryTask)->StartTaskShield(TSM_DOWN, 0.0f);
script->m_taskExecutor->StartTaskShield(TSM_DOWN, 0.0f);
}
else // up?
{
//? result->SetValInt(1); // shows the error
pThis->SetParam(radius);
(*script->m_secondaryTask)->StartTaskShield(TSM_UPDATE, 0.0f);
script->m_taskExecutor->StartTaskShield(TSM_UPDATE, 0.0f);
}
}
@ -2616,10 +2583,8 @@ bool CScriptFunctions::rFire(CBotVar* var, CBotVar* result, int& exception, void
exception = 0;
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
script->m_primaryTask = new CTaskManager(script->m_object);
type = pThis->GetType();
if ( type == OBJECT_ANT )
@ -2627,24 +2592,23 @@ bool CScriptFunctions::rFire(CBotVar* var, CBotVar* result, int& exception, void
if ( !GetPoint(var, exception, impact) ) return true;
float waterLevel = Gfx::CEngine::GetInstancePointer()->GetWater()->GetLevel();
impact.y += waterLevel;
err = script->m_primaryTask->StartTaskFireAnt(impact);
err = script->m_taskExecutor->StartTaskFireAnt(impact);
}
else if ( type == OBJECT_SPIDER )
{
err = script->m_primaryTask->StartTaskSpiderExplo();
err = script->m_taskExecutor->StartTaskSpiderExplo();
}
else
{
if ( var == 0 ) delay = 0.0f;
else delay = var->GetValFloat();
if ( delay < 0.0f ) delay = -delay;
err = script->m_primaryTask->StartTaskFire(delay);
err = script->m_taskExecutor->StartTaskFire(delay);
}
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
return true;
}
@ -2679,21 +2643,19 @@ bool CScriptFunctions::rAim(CBotVar* var, CBotVar* result, int& exception, void*
exception = 0;
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
script->m_primaryTask = new CTaskManager(script->m_object);
x = var->GetValFloat();
var = var->GetNext();
var == 0 ? y=0.0f : y=var->GetValFloat();
err = script->m_primaryTask->StartTaskGunGoal(x*Math::PI/180.0f, y*Math::PI/180.0f);
err = script->m_taskExecutor->StartTaskGunGoal(x*Math::PI/180.0f, y*Math::PI/180.0f);
if ( err == ERR_AIM_IMPOSSIBLE )
{
result->SetValInt(err); // shows the error
}
else if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
return true;
}
@ -2959,14 +2921,12 @@ bool CScriptFunctions::rPenDown(CBotVar* var, CBotVar* result, int& exception, v
if ( pThis->GetType() == OBJECT_MOBILEdr )
{
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
script->m_primaryTask = new CTaskManager(script->m_object);
err = script->m_primaryTask->StartTaskPen(motionVehicle->GetTraceDown(), motionVehicle->GetTraceColor());
err = script->m_taskExecutor->StartTaskPen(motionVehicle->GetTraceDown(), motionVehicle->GetTraceColor());
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
if ( script->m_errMode == ERM_STOP )
{
@ -3001,16 +2961,14 @@ bool CScriptFunctions::rPenUp(CBotVar* var, CBotVar* result, int& exception, voi
if ( pThis->GetType() == OBJECT_MOBILEdr )
{
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
motionVehicle->SetTraceDown(false);
script->m_primaryTask = new CTaskManager(script->m_object);
err = script->m_primaryTask->StartTaskPen(motionVehicle->GetTraceDown(), motionVehicle->GetTraceColor());
err = script->m_taskExecutor->StartTaskPen(motionVehicle->GetTraceDown(), motionVehicle->GetTraceColor());
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
if ( script->m_errMode == ERM_STOP )
{
@ -3049,14 +3007,12 @@ bool CScriptFunctions::rPenColor(CBotVar* var, CBotVar* result, int& exception,
if ( pThis->GetType() == OBJECT_MOBILEdr )
{
if ( script->m_primaryTask == 0 ) // no task in progress?
if ( !script->m_taskExecutor->IsForegroundTask() ) // no task in progress?
{
script->m_primaryTask = new CTaskManager(script->m_object);
err = script->m_primaryTask->StartTaskPen(motionVehicle->GetTraceDown(), motionVehicle->GetTraceColor());
err = script->m_taskExecutor->StartTaskPen(motionVehicle->GetTraceDown(), motionVehicle->GetTraceColor());
if ( err != ERR_OK )
{
delete script->m_primaryTask;
script->m_primaryTask = 0;
script->m_taskExecutor->StopForegroundTask();
result->SetValInt(err); // shows the error
if ( script->m_errMode == ERM_STOP )
{

View File

@ -236,7 +236,7 @@ bool CStudio::EventProcess(const Event &event)
if ( event.type == EVENT_STUDIO_STEP ) // step?
{
m_script->Step(event);
m_script->Step();
}
if ( event.type == EVENT_WINDOW3 ) // window is moved?