Merged CBrain into CProgrammableObject
parent
726cfbda77
commit
abb272600e
|
@ -149,7 +149,6 @@ set(BASE_SOURCES
|
|||
object/auto/autovault.cpp
|
||||
object/auto/autopowerstation.cpp
|
||||
object/auto/autotower.cpp
|
||||
object/brain.cpp
|
||||
object/drive_type.cpp
|
||||
object/level/parser.cpp
|
||||
object/level/parserexceptions.cpp
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include "math/geometry.h"
|
||||
|
||||
#include "object/brain.h"
|
||||
#include "object/object_manager.h"
|
||||
#include "object/old_object.h"
|
||||
|
||||
|
@ -185,11 +184,11 @@ bool CAutoEgg::EventProcess(const Event &event)
|
|||
|
||||
if (alien->Implements(ObjectInterfaceType::Programmable))
|
||||
{
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(alien)->GetBrain();
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(alien);
|
||||
|
||||
Program* program = brain->AddProgram();
|
||||
brain->ReadProgram(program, m_alienProgramName.c_str());
|
||||
brain->RunProgram(program);
|
||||
Program* program = programmable->AddProgram();
|
||||
programmable->ReadProgram(program, m_alienProgramName.c_str());
|
||||
programmable->RunProgram(program);
|
||||
}
|
||||
Init();
|
||||
}
|
||||
|
@ -332,4 +331,3 @@ bool CAutoEgg::Read(CLevelParserLine* line)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#include "math/geometry.h"
|
||||
|
||||
#include "object/brain.h"
|
||||
#include "object/object_create_params.h"
|
||||
#include "object/object_manager.h"
|
||||
#include "object/old_object.h"
|
||||
|
@ -408,7 +407,6 @@ bool CAutoFactory::EventProcess(const Event &event)
|
|||
}
|
||||
|
||||
vehicle->SetLock(false); // vehicle useable
|
||||
//? vehicle->GetPhysics()->GetBrain()->StartTaskAdvance(16.0f);
|
||||
vehicle->SetRotationY(m_object->GetRotationY()+Math::PI);
|
||||
vehicle->SetScale(1.0f);
|
||||
|
||||
|
@ -416,8 +414,8 @@ bool CAutoFactory::EventProcess(const Event &event)
|
|||
{
|
||||
if (vehicle->Implements(ObjectInterfaceType::Programmable))
|
||||
{
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(vehicle)->GetBrain();
|
||||
Program* program = brain->AddProgram();
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(vehicle);
|
||||
Program* program = programmable->AddProgram();
|
||||
|
||||
if (boost::regex_search(m_program, boost::regex("^[A-Za-z0-9_]+$"))) // Public function name?
|
||||
{
|
||||
|
@ -433,7 +431,7 @@ bool CAutoFactory::EventProcess(const Event &event)
|
|||
program->script->SendScript(m_program.c_str());
|
||||
}
|
||||
|
||||
brain->RunProgram(program);
|
||||
programmable->RunProgram(program);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -680,13 +678,13 @@ bool CAutoFactory::CreateVehicle()
|
|||
|
||||
if (vehicle->Implements(ObjectInterfaceType::Programmable))
|
||||
{
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(vehicle)->GetBrain();
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(vehicle);
|
||||
for ( int i=0 ; ; i++ )
|
||||
{
|
||||
char* name = m_main->GetNewScriptName(m_type, i);
|
||||
if ( name == nullptr ) break;
|
||||
Program* prog = brain->GetOrAddProgram(i);
|
||||
brain->ReadProgram(prog, name);
|
||||
Program* prog = programmable->GetOrAddProgram(i);
|
||||
programmable->ReadProgram(prog, name);
|
||||
prog->readOnly = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,785 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
||||
#include "object/brain.h"
|
||||
|
||||
#include "common/make_unique.h"
|
||||
|
||||
#include "math/geometry.h"
|
||||
|
||||
#include "object/old_object.h"
|
||||
#include "object/robotmain.h"
|
||||
|
||||
#include "object/interface/task_executor_object.h"
|
||||
|
||||
#include "object/level/parserline.h"
|
||||
#include "object/level/parserparam.h"
|
||||
|
||||
#include "object/motion/motion.h"
|
||||
#include "object/motion/motionvehicle.h"
|
||||
|
||||
#include "object/task/taskmanager.h"
|
||||
|
||||
#include "physics/physics.h"
|
||||
|
||||
#include "script/script.h"
|
||||
|
||||
#include "ui/studio.h"
|
||||
|
||||
#include "ui/controls/edit.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
|
||||
const int MAXTRACERECORD = 1000;
|
||||
|
||||
// Object's constructor.
|
||||
|
||||
CBrain::CBrain(COldObject* object)
|
||||
{
|
||||
m_object = object;
|
||||
assert(object->Implements(ObjectInterfaceType::TaskExecutor));
|
||||
m_taskExecutor = dynamic_cast<CTaskExecutorObject*>(m_object);
|
||||
|
||||
m_physics = nullptr;
|
||||
m_motion = nullptr;
|
||||
|
||||
m_engine = Gfx::CEngine::GetInstancePointer();
|
||||
m_main = CRobotMain::GetInstancePointer();
|
||||
m_camera = m_main->GetCamera();
|
||||
|
||||
m_program.clear();
|
||||
m_currentProgram = nullptr;
|
||||
m_bBurn = false;
|
||||
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;
|
||||
}
|
||||
|
||||
// Object's destructor.
|
||||
|
||||
CBrain::~CBrain()
|
||||
{
|
||||
}
|
||||
|
||||
void CBrain::SetPhysics(CPhysics* physics)
|
||||
{
|
||||
m_physics = physics;
|
||||
}
|
||||
|
||||
void CBrain::SetMotion(CMotion* motion)
|
||||
{
|
||||
m_motion = motion;
|
||||
}
|
||||
|
||||
|
||||
// Saves all parameters of the object.
|
||||
|
||||
bool CBrain::Write(CLevelParserLine* line)
|
||||
{
|
||||
line->AddParam("bVirusActive", MakeUnique<CLevelParserParam>(m_bActiveVirus));
|
||||
|
||||
if ( m_object->GetType() == OBJECT_MOBILErs )
|
||||
{
|
||||
line->AddParam("bShieldActive", MakeUnique<CLevelParserParam>(m_taskExecutor->IsBackgroundTask()));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Restores all parameters of the object.
|
||||
|
||||
bool CBrain::Read(CLevelParserLine* line)
|
||||
{
|
||||
m_bActiveVirus = line->GetParam("bVirusActive")->AsBool(false);
|
||||
if ( m_object->GetType() == OBJECT_MOBILErs )
|
||||
{
|
||||
if( line->GetParam("bShieldActive")->AsBool(false) )
|
||||
{
|
||||
m_taskExecutor->StartTaskShield(TSM_START);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Management of an event.
|
||||
|
||||
bool CBrain::EventProcess(const Event &event)
|
||||
{
|
||||
if ( event.type == EVENT_FRAME )
|
||||
{
|
||||
EventFrame(event);
|
||||
}
|
||||
|
||||
if ( !m_object->GetSelect() && // robot pas sélectionné ?
|
||||
m_currentProgram == nullptr &&
|
||||
!m_taskExecutor->IsForegroundTask() )
|
||||
{
|
||||
float axeX = 0.0f;
|
||||
float axeY = 0.0f;
|
||||
float axeZ = 0.0f;
|
||||
if ( m_object->GetBurn() ) // Gifted?
|
||||
{
|
||||
if ( !m_bBurn ) // beginning?
|
||||
{
|
||||
m_bBurn = true;
|
||||
m_burnTime = 0.0f;
|
||||
}
|
||||
|
||||
axeZ = -1.0f; // tomb
|
||||
|
||||
if ( !m_object->GetFixed() &&
|
||||
(m_object->GetType() == OBJECT_ANT ||
|
||||
m_object->GetType() == OBJECT_SPIDER ||
|
||||
m_object->GetType() == OBJECT_WORM ) )
|
||||
{
|
||||
axeY = 2.0f; // zigzag disorganized fast
|
||||
if ( m_object->GetType() == OBJECT_WORM ) axeY = 5.0f;
|
||||
axeX = 0.5f+sinf(m_time* 1.0f)*0.5f+
|
||||
sinf(m_time* 6.0f)*2.0f+
|
||||
sinf(m_time*21.0f)*0.2f;
|
||||
float factor = 1.0f-m_burnTime/15.0f; // slow motion
|
||||
if ( factor < 0.0f ) factor = 0.0f;
|
||||
axeY *= factor;
|
||||
axeX *= factor;
|
||||
}
|
||||
}
|
||||
m_physics->SetMotorSpeedX(axeY); // move forward/move back
|
||||
m_physics->SetMotorSpeedY(axeZ); // up / down
|
||||
m_physics->SetMotorSpeedZ(axeX); // rotate
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( m_currentProgram != nullptr &&
|
||||
m_object->GetRuin() )
|
||||
{
|
||||
StopProgram();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( !m_object->GetSelect() ) return true; // robot not selected?
|
||||
|
||||
if ( m_taskExecutor->IsForegroundTask() || // current task?
|
||||
m_currentProgram != nullptr )
|
||||
{
|
||||
if ( !m_taskExecutor->IsForegroundTask() || !m_taskExecutor->GetForegroundTask()->IsPilot() ) return true;
|
||||
}
|
||||
|
||||
if ( event.type == EVENT_OBJECT_LEFT ||
|
||||
event.type == EVENT_OBJECT_RIGHT ||
|
||||
event.type == EVENT_OBJECT_UP ||
|
||||
event.type == EVENT_OBJECT_DOWN ||
|
||||
event.type == EVENT_OBJECT_GASUP ||
|
||||
event.type == EVENT_OBJECT_GASDOWN )
|
||||
{
|
||||
m_buttonAxe = event.type;
|
||||
}
|
||||
if ( event.type == EVENT_MOUSE_BUTTON_UP )
|
||||
{
|
||||
m_buttonAxe = EVENT_NULL;
|
||||
}
|
||||
|
||||
float axeX = event.motionInput.x;
|
||||
float axeY = event.motionInput.y;
|
||||
float axeZ = event.motionInput.z;
|
||||
|
||||
if ( (!m_main->GetTrainerPilot() &&
|
||||
m_object->GetTrainer()) ||
|
||||
!m_main->CanPlayerInteract() ) // drive vehicle?
|
||||
{
|
||||
axeX = 0.0f;
|
||||
axeY = 0.0f;
|
||||
axeZ = 0.0f; // Remote control impossible!
|
||||
}
|
||||
|
||||
if ( m_buttonAxe == EVENT_OBJECT_LEFT ) axeX = -1.0f;
|
||||
if ( m_buttonAxe == EVENT_OBJECT_RIGHT ) axeX = 1.0f;
|
||||
if ( m_buttonAxe == EVENT_OBJECT_UP ) axeY = 1.0f;
|
||||
if ( m_buttonAxe == EVENT_OBJECT_DOWN ) axeY = -1.0f;
|
||||
if ( m_buttonAxe == EVENT_OBJECT_GASUP ) axeZ = 1.0f;
|
||||
if ( m_buttonAxe == EVENT_OBJECT_GASDOWN ) axeZ = -1.0f;
|
||||
|
||||
if ( m_object->GetType() == OBJECT_MOBILEdr && m_object->GetManual() ) // scribbler in manual mode?
|
||||
{
|
||||
if ( axeX != 0.0f ) axeY = 0.0f; // if running -> not moving!
|
||||
axeX *= 0.5f;
|
||||
axeY *= 0.5f;
|
||||
}
|
||||
|
||||
if ( !m_main->IsResearchDone(RESEARCH_FLY, m_object->GetTeam()) )
|
||||
{
|
||||
axeZ = -1.0f; // tomb
|
||||
}
|
||||
|
||||
axeX += m_camera->GetMotorTurn(); // additional power according to camera
|
||||
if ( axeX > 1.0f ) axeX = 1.0f;
|
||||
if ( axeX < -1.0f ) axeX = -1.0f;
|
||||
|
||||
m_physics->SetMotorSpeedX(axeY); // move forward/move back
|
||||
m_physics->SetMotorSpeedY(axeZ); // up/down
|
||||
m_physics->SetMotorSpeedZ(axeX); // rotate
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// The brain is changing by time.
|
||||
|
||||
bool CBrain::EventFrame(const Event &event)
|
||||
{
|
||||
m_time += event.rTime;
|
||||
if ( m_bBurn ) m_burnTime += event.rTime;
|
||||
|
||||
if ( m_engine->GetPause() ) return true;
|
||||
if ( !m_object->GetActivity() ) return true;
|
||||
|
||||
if ( m_currentProgram != nullptr ) // current program?
|
||||
{
|
||||
if ( m_currentProgram->script->Continue() )
|
||||
{
|
||||
StopProgram();
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_traceRecord ) // registration of the design in progress?
|
||||
{
|
||||
TraceRecordFrame();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Stops the running program.
|
||||
|
||||
void CBrain::StopProgram()
|
||||
{
|
||||
m_taskExecutor->StopForegroundTask();
|
||||
|
||||
if ( m_object->GetType() == OBJECT_HUMAN ||
|
||||
m_object->GetType() == OBJECT_TECH ) return;
|
||||
|
||||
if ( m_currentProgram != nullptr )
|
||||
{
|
||||
m_currentProgram->script->Stop();
|
||||
}
|
||||
|
||||
m_currentProgram = nullptr;
|
||||
|
||||
m_physics->SetMotorSpeedX(0.0f);
|
||||
m_physics->SetMotorSpeedY(0.0f);
|
||||
m_physics->SetMotorSpeedZ(0.0f);
|
||||
|
||||
m_motion->SetAction(-1);
|
||||
|
||||
m_object->UpdateInterface();
|
||||
m_main->UpdateShortcuts();
|
||||
m_object->CreateSelectParticle();
|
||||
}
|
||||
|
||||
|
||||
// Introduces a virus into a program.
|
||||
// Returns true if it was inserted.
|
||||
|
||||
bool CBrain::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 CBrain::SetActiveVirus(bool bActive)
|
||||
{
|
||||
m_bActiveVirus = bActive;
|
||||
|
||||
if ( !m_bActiveVirus ) // virus disabled?
|
||||
{
|
||||
m_object->SetVirusMode(false); // chtites (??? - Programerus) letters also
|
||||
}
|
||||
}
|
||||
|
||||
bool CBrain::GetActiveVirus()
|
||||
{
|
||||
return m_bActiveVirus;
|
||||
}
|
||||
|
||||
// Indicates whether a program is running.
|
||||
|
||||
bool CBrain::IsProgram()
|
||||
{
|
||||
return m_currentProgram != nullptr;
|
||||
}
|
||||
|
||||
// Starts a program.
|
||||
|
||||
void CBrain::RunProgram(Program* program)
|
||||
{
|
||||
if ( program->script->Run() )
|
||||
{
|
||||
m_currentProgram = program; // start new program
|
||||
m_object->UpdateInterface();
|
||||
m_object->CreateSelectParticle();
|
||||
m_main->UpdateShortcuts();
|
||||
if(m_object->GetTrainer())
|
||||
m_main->StartMissionTimer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Returns the current program.
|
||||
|
||||
int CBrain::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 CBrain::SetScriptRun(Program* program)
|
||||
{
|
||||
m_scriptRun = program;
|
||||
}
|
||||
|
||||
Program* CBrain::GetScriptRun()
|
||||
{
|
||||
return m_scriptRun;
|
||||
}
|
||||
|
||||
void CBrain::SetSoluceName(char *name)
|
||||
{
|
||||
strcpy(m_soluceName, name);
|
||||
}
|
||||
|
||||
char* CBrain::GetSoluceName()
|
||||
{
|
||||
return m_soluceName;
|
||||
}
|
||||
|
||||
|
||||
// Load a script solution, in the first free script.
|
||||
// If there is already an identical script, nothing is loaded.
|
||||
|
||||
bool CBrain::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 CBrain::ReadProgram(Program* program, const char* filename)
|
||||
{
|
||||
if ( program->script->ReadScript(filename) ) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Indicates whether a program is compiled correctly.
|
||||
|
||||
bool CBrain::GetCompile(Program* program)
|
||||
{
|
||||
return program->script->GetCompile();
|
||||
}
|
||||
|
||||
// Saves a script in a text file.
|
||||
|
||||
bool CBrain::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 CBrain::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 CBrain::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 CBrain::TraceRecordStart()
|
||||
{
|
||||
if (m_traceRecord)
|
||||
{
|
||||
TraceRecordStop();
|
||||
}
|
||||
|
||||
CMotionVehicle* motionVehicle = dynamic_cast<CMotionVehicle*>(m_motion);
|
||||
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 CBrain::TraceRecordFrame()
|
||||
{
|
||||
TraceOper oper = TO_STOP;
|
||||
Math::Vector pos;
|
||||
float angle, len, speed;
|
||||
|
||||
CMotionVehicle* motionVehicle = dynamic_cast<CMotionVehicle*>(m_motion);
|
||||
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 = 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 CBrain::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 CBrain::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 CBrain::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 CBrain::IsTraceRecord()
|
||||
{
|
||||
return m_traceRecord;
|
||||
}
|
||||
|
||||
Program* CBrain::AddProgram()
|
||||
{
|
||||
auto program = MakeUnique<Program>();
|
||||
program->script = MakeUnique<CScript>(m_object);
|
||||
program->readOnly = false;
|
||||
program->runnable = true;
|
||||
|
||||
Program* prog = program.get();
|
||||
AddProgram(std::move(program));
|
||||
return prog;
|
||||
}
|
||||
|
||||
void CBrain::AddProgram(std::unique_ptr<Program> program)
|
||||
{
|
||||
m_program.push_back(std::move(program));
|
||||
m_object->UpdateInterface();
|
||||
}
|
||||
|
||||
void CBrain::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* CBrain::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>>& CBrain::GetPrograms()
|
||||
{
|
||||
return m_program;
|
||||
}
|
||||
|
||||
int CBrain::GetProgramCount()
|
||||
{
|
||||
return static_cast<int>(m_program.size());
|
||||
}
|
||||
|
||||
int CBrain::GetProgramIndex(Program* program)
|
||||
{
|
||||
for(unsigned int i = 0; i < m_program.size(); i++)
|
||||
{
|
||||
if(m_program[i].get() == program)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Program* CBrain::GetProgram(int index)
|
||||
{
|
||||
if(index < 0 || index >= static_cast<int>(m_program.size()))
|
||||
return nullptr;
|
||||
|
||||
return m_program[index].get();
|
||||
}
|
||||
|
||||
Program* CBrain::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();
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file object/brain.h
|
||||
* \brief CBrain - dispatches commands to objects
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/event.h"
|
||||
|
||||
#include "object/trace_color.h"
|
||||
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
|
||||
class COldObject;
|
||||
class CTaskExecutorObject;
|
||||
class CPhysics;
|
||||
class CMotion;
|
||||
class CScript;
|
||||
class CRobotMain;
|
||||
class CLevelParserLine;
|
||||
|
||||
namespace Gfx
|
||||
{
|
||||
class CEngine;
|
||||
class CCamera;
|
||||
} /* Gfx */
|
||||
|
||||
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
struct Program
|
||||
{
|
||||
std::unique_ptr<CScript> script;
|
||||
std::string filename;
|
||||
bool readOnly;
|
||||
bool runnable;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class CBrain
|
||||
{
|
||||
public:
|
||||
CBrain(COldObject* object);
|
||||
~CBrain();
|
||||
|
||||
void SetPhysics(CPhysics* physics);
|
||||
void SetMotion(CMotion* motion);
|
||||
|
||||
bool EventProcess(const Event &event);
|
||||
|
||||
bool Write(CLevelParserLine* line);
|
||||
bool Read(CLevelParserLine* line);
|
||||
|
||||
bool IsProgram();
|
||||
void RunProgram(Program* program);
|
||||
int GetProgram();
|
||||
void StopProgram();
|
||||
|
||||
bool IntroduceVirus();
|
||||
void SetActiveVirus(bool bActive);
|
||||
bool GetActiveVirus();
|
||||
|
||||
void SetScriptRun(Program* rank);
|
||||
Program* GetScriptRun();
|
||||
void SetSoluceName(char *name);
|
||||
char* GetSoluceName();
|
||||
|
||||
bool ReadSoluce(char* filename);
|
||||
bool ReadProgram(Program* program, const char* filename);
|
||||
bool GetCompile(Program* program);
|
||||
bool WriteProgram(Program* program, const char* filename);
|
||||
bool ReadStack(FILE *file);
|
||||
bool WriteStack(FILE *file);
|
||||
|
||||
Program* AddProgram();
|
||||
void AddProgram(std::unique_ptr<Program> program);
|
||||
void RemoveProgram(Program* program);
|
||||
Program* CloneProgram(Program* program);
|
||||
|
||||
std::vector<std::unique_ptr<Program>>& GetPrograms();
|
||||
int GetProgramCount();
|
||||
Program* GetProgram(int index);
|
||||
Program* GetOrAddProgram(int index);
|
||||
int GetProgramIndex(Program* program);
|
||||
|
||||
//! Start recording trace
|
||||
void TraceRecordStart();
|
||||
//! Stop recording trace and generate CBot program
|
||||
void TraceRecordStop();
|
||||
//! Returns true if trace recording is in progress
|
||||
bool IsTraceRecord();
|
||||
|
||||
protected:
|
||||
bool EventFrame(const Event &event);
|
||||
|
||||
//! 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:
|
||||
CRobotMain* m_main;
|
||||
Gfx::CEngine* m_engine;
|
||||
Gfx::CCamera* m_camera;
|
||||
|
||||
COldObject* m_object;
|
||||
CTaskExecutorObject* m_taskExecutor;
|
||||
CPhysics* m_physics;
|
||||
CMotion* m_motion;
|
||||
|
||||
std::vector<std::unique_ptr<Program>> m_program;
|
||||
Program* m_currentProgram;
|
||||
|
||||
bool m_bBurn;
|
||||
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;
|
||||
};
|
|
@ -21,7 +21,15 @@
|
|||
|
||||
#include "object/object_interface_type.h"
|
||||
|
||||
class CBrain;
|
||||
class CScript;
|
||||
|
||||
struct Program
|
||||
{
|
||||
std::unique_ptr<CScript> script;
|
||||
std::string filename;
|
||||
bool readOnly;
|
||||
bool runnable;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class CProgrammableObject
|
||||
|
@ -39,11 +47,42 @@ public:
|
|||
virtual ~CProgrammableObject()
|
||||
{}
|
||||
|
||||
//! Returns CBrain
|
||||
/** If only the object implements ObjectInterfaceType::Programmable,
|
||||
* returned object will always be non-null*/
|
||||
virtual CBrain* GetBrain() = 0;
|
||||
virtual bool IsProgram() = 0;
|
||||
virtual void RunProgram(Program* program) = 0;
|
||||
virtual int GetProgram() = 0;
|
||||
virtual void StopProgram() = 0;
|
||||
|
||||
virtual bool IntroduceVirus() = 0;
|
||||
virtual void SetActiveVirus(bool bActive) = 0;
|
||||
virtual bool GetActiveVirus() = 0;
|
||||
|
||||
// TODO: CBrain interface can actually be moved here
|
||||
virtual void SetScriptRun(Program* rank) = 0;
|
||||
virtual Program* GetScriptRun() = 0;
|
||||
virtual void SetSoluceName(char *name) = 0;
|
||||
virtual char* GetSoluceName() = 0;
|
||||
|
||||
virtual bool ReadSoluce(char* filename) = 0;
|
||||
virtual bool ReadProgram(Program* program, const char* filename) = 0;
|
||||
virtual bool GetCompile(Program* program) = 0;
|
||||
virtual bool WriteProgram(Program* program, const char* filename) = 0;
|
||||
virtual bool ReadStack(FILE *file) = 0;
|
||||
virtual bool WriteStack(FILE *file) = 0;
|
||||
|
||||
virtual Program* AddProgram() = 0;
|
||||
virtual void AddProgram(std::unique_ptr<Program> program) = 0;
|
||||
virtual void RemoveProgram(Program* program) = 0;
|
||||
virtual Program* CloneProgram(Program* program) = 0;
|
||||
|
||||
virtual std::vector<std::unique_ptr<Program>>& GetPrograms() = 0;
|
||||
virtual int GetProgramCount() = 0;
|
||||
virtual Program* GetProgram(int index) = 0;
|
||||
virtual Program* GetOrAddProgram(int index) = 0;
|
||||
virtual int GetProgramIndex(Program* program) = 0;
|
||||
|
||||
//! Start recording trace
|
||||
virtual void TraceRecordStart() = 0;
|
||||
//! Stop recording trace and generate CBot program
|
||||
virtual void TraceRecordStop() = 0;
|
||||
//! Returns true if trace recording is in progress
|
||||
virtual bool IsTraceRecord() = 0;
|
||||
};
|
||||
|
|
|
@ -38,7 +38,6 @@ class COldModelManager;
|
|||
}
|
||||
|
||||
class CApplication;
|
||||
class CBrain;
|
||||
class CPhysics;
|
||||
class COldObject;
|
||||
class CRobotMain;
|
||||
|
|
|
@ -30,11 +30,11 @@
|
|||
|
||||
#include "math/geometry.h"
|
||||
|
||||
#include "object/brain.h"
|
||||
#include "object/object_manager.h"
|
||||
#include "object/old_object.h"
|
||||
|
||||
#include "object/interface/powered_object.h"
|
||||
#include "object/interface/programmable_object.h"
|
||||
#include "object/interface/transportable_object.h"
|
||||
|
||||
#include "physics/physics.h"
|
||||
|
|
|
@ -35,6 +35,8 @@ namespace Gfx
|
|||
struct ModelCrashSphere;
|
||||
} // namespace Gfx
|
||||
|
||||
class CLevelParserLine;
|
||||
|
||||
/**
|
||||
* \class CObject
|
||||
* \brief Base class for all 3D in-game objects
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
#include "math/geometry.h"
|
||||
|
||||
#include "object/brain.h"
|
||||
#include "object/object_create_params.h"
|
||||
#include "object/old_object.h"
|
||||
#include "object/robotmain.h"
|
||||
|
@ -2632,7 +2631,6 @@ CObjectUPtr CObjectFactory::CreateVehicle(const ObjectCreateParams& params)
|
|||
obj->SetShowLimitRadius(showLimitRadius);
|
||||
|
||||
auto physics = MakeUnique<CPhysics>(obj.get());
|
||||
auto brain = MakeUnique<CBrain>(obj.get());
|
||||
|
||||
std::unique_ptr<CMotion> motion;
|
||||
if ( type == OBJECT_HUMAN ||
|
||||
|
@ -2649,14 +2647,12 @@ CObjectUPtr CObjectFactory::CreateVehicle(const ObjectCreateParams& params)
|
|||
motion = MakeUnique<CMotionVehicle>(obj.get());
|
||||
}
|
||||
|
||||
brain->SetMotion(motion.get());
|
||||
brain->SetPhysics(physics.get());
|
||||
motion->SetPhysics(physics.get());
|
||||
physics->SetMotion(motion.get());
|
||||
|
||||
motion->Create(pos, angle, type, power, m_oldModelManager);
|
||||
|
||||
obj->SetBrain(std::move(brain));
|
||||
obj->SetProgrammable(true);
|
||||
obj->SetMotion(std::move(motion));
|
||||
obj->SetPhysics(std::move(physics));
|
||||
|
||||
|
@ -2677,7 +2673,6 @@ CObjectUPtr CObjectFactory::CreateInsect(const ObjectCreateParams& params)
|
|||
obj->SetTeam(params.team);
|
||||
|
||||
auto physics = MakeUnique<CPhysics>(obj.get());
|
||||
auto brain = MakeUnique<CBrain>(obj.get());
|
||||
|
||||
std::unique_ptr<CMotion> motion;
|
||||
if ( type == OBJECT_MOTHER )
|
||||
|
@ -2703,15 +2698,13 @@ CObjectUPtr CObjectFactory::CreateInsect(const ObjectCreateParams& params)
|
|||
assert(motion != nullptr);
|
||||
|
||||
physics->SetMotion(motion.get());
|
||||
brain->SetMotion(motion.get());
|
||||
brain->SetPhysics(physics.get());
|
||||
motion->SetPhysics(physics.get());
|
||||
|
||||
motion->Create(pos, angle, type, 0.0f, m_oldModelManager);
|
||||
|
||||
obj->SetMotion(std::move(motion));
|
||||
obj->SetPhysics(std::move(physics));
|
||||
obj->SetBrain(std::move(brain));
|
||||
obj->SetProgrammable(true);
|
||||
|
||||
return std::move(obj);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
|
||||
#include "math/geometry.h"
|
||||
|
||||
#include "object/brain.h"
|
||||
#include "object/object_manager.h"
|
||||
#include "object/robotmain.h"
|
||||
|
||||
|
@ -56,11 +55,16 @@
|
|||
#include "physics/physics.h"
|
||||
|
||||
#include "script/cbottoken.h"
|
||||
#include "script/script.h"
|
||||
#include "script/scriptfunc.h"
|
||||
|
||||
#include "ui/object_interface.h"
|
||||
#include "ui/studio.h"
|
||||
|
||||
#include "ui/controls/edit.h"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
|
||||
|
@ -83,6 +87,8 @@ static float debug_arm2 = 0.0f;
|
|||
static float debug_arm3 = 0.0f;
|
||||
#endif
|
||||
|
||||
const int MAXTRACERECORD = 1000;
|
||||
|
||||
|
||||
// Object's constructor.
|
||||
|
||||
|
@ -96,7 +102,7 @@ COldObject::COldObject(int id)
|
|||
, CCarrierObject(m_implementedInterfaces)
|
||||
, CPoweredObject(m_implementedInterfaces)
|
||||
{
|
||||
// A bit of a hack since CBrain is set externally in SetBrain()
|
||||
// A bit of a hack since we don't have subclasses yet, set externally in SetProgrammable()
|
||||
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = false;
|
||||
// Another hack
|
||||
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Jostleable)] = false;
|
||||
|
@ -191,6 +197,18 @@ COldObject::COldObject(int id)
|
|||
|
||||
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();
|
||||
|
||||
m_botVar = CScriptFunctions::CreateObjectVar(this);
|
||||
|
@ -331,18 +349,18 @@ void COldObject::DeleteObject(bool bAll)
|
|||
if ( !bAll ) m_main->CreateShortcuts();
|
||||
}
|
||||
|
||||
// Simplifies a object (he was the brain, among others).
|
||||
// Simplifies a object (he was the programmable, among others).
|
||||
|
||||
void COldObject::Simplify()
|
||||
{
|
||||
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = false;
|
||||
|
||||
if ( m_brain != nullptr )
|
||||
if ( Implements(ObjectInterfaceType::Programmable) )
|
||||
{
|
||||
m_brain->StopProgram();
|
||||
StopProgram();
|
||||
}
|
||||
m_main->SaveOneScript(this);
|
||||
|
||||
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = false;
|
||||
|
||||
if ( m_physics != nullptr )
|
||||
{
|
||||
m_physics->DeleteObject();
|
||||
|
@ -355,11 +373,6 @@ void COldObject::Simplify()
|
|||
m_objectInterface.reset();
|
||||
}
|
||||
|
||||
if ( m_brain != nullptr )
|
||||
{
|
||||
m_brain.reset();
|
||||
}
|
||||
|
||||
if ( m_motion != nullptr )
|
||||
{
|
||||
m_motion->DeleteObject();
|
||||
|
@ -568,9 +581,9 @@ bool COldObject::ExplodeObject(ExplosionType type, float force, float decay)
|
|||
|
||||
if ( shield == 0.0f ) // dead?
|
||||
{
|
||||
if ( m_brain != nullptr )
|
||||
if ( Implements(ObjectInterfaceType::Programmable) )
|
||||
{
|
||||
m_brain->StopProgram();
|
||||
StopProgram();
|
||||
}
|
||||
m_main->SaveOneScript(this);
|
||||
}
|
||||
|
@ -839,9 +852,14 @@ void COldObject::Write(CLevelParserLine* line)
|
|||
m_motion->Write(line);
|
||||
}
|
||||
|
||||
if ( m_brain != nullptr )
|
||||
if ( Implements(ObjectInterfaceType::Programmable) )
|
||||
{
|
||||
m_brain->Write(line);
|
||||
line->AddParam("bVirusActive", MakeUnique<CLevelParserParam>(m_bActiveVirus));
|
||||
|
||||
if ( m_type == OBJECT_MOBILErs )
|
||||
{
|
||||
line->AddParam("bShieldActive", MakeUnique<CLevelParserParam>(IsBackgroundTask()));
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_physics != nullptr )
|
||||
|
@ -905,9 +923,16 @@ void COldObject::Read(CLevelParserLine* line)
|
|||
m_motion->Read(line);
|
||||
}
|
||||
|
||||
if ( m_brain != nullptr )
|
||||
if ( Implements(ObjectInterfaceType::Programmable) )
|
||||
{
|
||||
m_brain->Read(line);
|
||||
m_bActiveVirus = line->GetParam("bVirusActive")->AsBool(false);
|
||||
if ( m_type == OBJECT_MOBILErs )
|
||||
{
|
||||
if( line->GetParam("bShieldActive")->AsBool(false) )
|
||||
{
|
||||
StartTaskShield(TSM_START);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( m_physics != nullptr )
|
||||
{
|
||||
|
@ -1857,9 +1882,103 @@ bool COldObject::EventProcess(const Event &event)
|
|||
}
|
||||
}
|
||||
|
||||
if ( m_brain != nullptr )
|
||||
if ( Implements(ObjectInterfaceType::Programmable) )
|
||||
{
|
||||
m_brain->EventProcess(event);
|
||||
if ( GetRuin() && m_currentProgram != nullptr )
|
||||
{
|
||||
StopProgram();
|
||||
}
|
||||
|
||||
if ( !GetSelect() && // robot pas sélectionné ?
|
||||
m_currentProgram == nullptr &&
|
||||
!IsForegroundTask() )
|
||||
{
|
||||
float axeX = 0.0f;
|
||||
float axeY = 0.0f;
|
||||
float axeZ = 0.0f;
|
||||
if ( m_bBurn ) // Gifted?
|
||||
{
|
||||
axeZ = -1.0f; // tomb
|
||||
|
||||
if ( !GetFixed() &&
|
||||
(m_type == OBJECT_ANT ||
|
||||
m_type == OBJECT_SPIDER ||
|
||||
m_type == OBJECT_WORM ) )
|
||||
{
|
||||
axeY = 2.0f; // zigzag disorganized fast
|
||||
if ( m_type == OBJECT_WORM ) axeY = 5.0f;
|
||||
axeX = 0.5f+sinf(m_time* 1.0f)*0.5f+
|
||||
sinf(m_time* 6.0f)*2.0f+
|
||||
sinf(m_time*21.0f)*0.2f;
|
||||
float factor = 1.0f-m_burnTime/15.0f; // slow motion
|
||||
if ( factor < 0.0f ) factor = 0.0f;
|
||||
axeY *= factor;
|
||||
axeX *= factor;
|
||||
}
|
||||
}
|
||||
m_physics->SetMotorSpeedX(axeY); // move forward/move back
|
||||
m_physics->SetMotorSpeedY(axeZ); // up / down
|
||||
m_physics->SetMotorSpeedZ(axeX); // rotate
|
||||
}
|
||||
else if (GetSelect())
|
||||
{
|
||||
if ( (IsForegroundTask() && GetForegroundTask()->IsPilot()) || m_currentProgram == nullptr )
|
||||
{
|
||||
if ( event.type == EVENT_OBJECT_LEFT ||
|
||||
event.type == EVENT_OBJECT_RIGHT ||
|
||||
event.type == EVENT_OBJECT_UP ||
|
||||
event.type == EVENT_OBJECT_DOWN ||
|
||||
event.type == EVENT_OBJECT_GASUP ||
|
||||
event.type == EVENT_OBJECT_GASDOWN )
|
||||
{
|
||||
m_buttonAxe = event.type;
|
||||
}
|
||||
if ( event.type == EVENT_MOUSE_BUTTON_UP )
|
||||
{
|
||||
m_buttonAxe = EVENT_NULL;
|
||||
}
|
||||
|
||||
float axeX = event.motionInput.x;
|
||||
float axeY = event.motionInput.y;
|
||||
float axeZ = event.motionInput.z;
|
||||
|
||||
if ( (!m_main->GetTrainerPilot() &&
|
||||
GetTrainer()) ||
|
||||
!m_main->CanPlayerInteract() ) // drive vehicle?
|
||||
{
|
||||
axeX = 0.0f;
|
||||
axeY = 0.0f;
|
||||
axeZ = 0.0f; // Remote control impossible!
|
||||
}
|
||||
|
||||
if ( m_buttonAxe == EVENT_OBJECT_LEFT ) axeX = -1.0f;
|
||||
if ( m_buttonAxe == EVENT_OBJECT_RIGHT ) axeX = 1.0f;
|
||||
if ( m_buttonAxe == EVENT_OBJECT_UP ) axeY = 1.0f;
|
||||
if ( m_buttonAxe == EVENT_OBJECT_DOWN ) axeY = -1.0f;
|
||||
if ( m_buttonAxe == EVENT_OBJECT_GASUP ) axeZ = 1.0f;
|
||||
if ( m_buttonAxe == EVENT_OBJECT_GASDOWN ) axeZ = -1.0f;
|
||||
|
||||
if ( m_type == OBJECT_MOBILEdr && GetManual() ) // scribbler in manual mode?
|
||||
{
|
||||
if ( axeX != 0.0f ) axeY = 0.0f; // if running -> not moving!
|
||||
axeX *= 0.5f;
|
||||
axeY *= 0.5f;
|
||||
}
|
||||
|
||||
if ( !m_main->IsResearchDone(RESEARCH_FLY, GetTeam()) )
|
||||
{
|
||||
axeZ = -1.0f; // tomb
|
||||
}
|
||||
|
||||
axeX += m_camera->GetMotorTurn(); // additional power according to camera
|
||||
if ( axeX > 1.0f ) axeX = 1.0f;
|
||||
if ( axeX < -1.0f ) axeX = -1.0f;
|
||||
|
||||
m_physics->SetMotorSpeedX(axeY); // move forward/move back
|
||||
m_physics->SetMotorSpeedY(axeZ); // up/down
|
||||
m_physics->SetMotorSpeedZ(axeX); // rotate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_objectInterface != nullptr )
|
||||
|
@ -1903,8 +2022,12 @@ bool COldObject::EventFrame(const Event &event)
|
|||
return true;
|
||||
}
|
||||
|
||||
m_time += event.rTime;
|
||||
|
||||
if ( m_engine->GetPause() && m_type != OBJECT_SHOW ) return true;
|
||||
|
||||
if ( m_bBurn ) m_burnTime += event.rTime;
|
||||
|
||||
m_aTime += event.rTime;
|
||||
m_shotTime += event.rTime;
|
||||
|
||||
|
@ -1929,6 +2052,25 @@ bool COldObject::EventFrame(const Event &event)
|
|||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
|
@ -2404,9 +2546,9 @@ void COldObject::SetVirusMode(bool bEnable)
|
|||
m_bVirusMode = bEnable;
|
||||
m_virusTime = 0.0f;
|
||||
|
||||
if ( m_bVirusMode && m_brain != nullptr )
|
||||
if ( m_bVirusMode && Implements(ObjectInterfaceType::Programmable) )
|
||||
{
|
||||
if ( !m_brain->IntroduceVirus() ) // tries to infect
|
||||
if ( !IntroduceVirus() ) // tries to infect
|
||||
{
|
||||
m_bVirusMode = false; // program was not contaminated!
|
||||
}
|
||||
|
@ -2679,6 +2821,7 @@ bool COldObject::IsExploding()
|
|||
void COldObject::SetBurn(bool bBurn)
|
||||
{
|
||||
m_bBurn = bBurn;
|
||||
m_burnTime = 0.0f;
|
||||
|
||||
//? if ( m_botVar != 0 )
|
||||
//? {
|
||||
|
@ -2696,9 +2839,9 @@ void COldObject::SetDead(bool bDead)
|
|||
{
|
||||
m_bDead = bDead;
|
||||
|
||||
if ( bDead && m_brain != nullptr )
|
||||
if ( bDead && Implements(ObjectInterfaceType::Programmable) )
|
||||
{
|
||||
m_brain->StopProgram(); // stops the current task
|
||||
StopProgram(); // stops the current task
|
||||
}
|
||||
|
||||
//? if ( m_botVar != 0 )
|
||||
|
@ -2827,14 +2970,6 @@ void COldObject::SetShowLimitRadius(float radius)
|
|||
m_showLimitRadius = radius;
|
||||
}
|
||||
|
||||
// Indicates whether a program is under execution.
|
||||
|
||||
bool COldObject::IsProgram()
|
||||
{
|
||||
if ( m_brain == nullptr ) return false;
|
||||
return m_brain->IsProgram();
|
||||
}
|
||||
|
||||
|
||||
// Creates or removes particles associated to the object.
|
||||
|
||||
|
@ -3082,17 +3217,10 @@ void COldObject::SetPhysics(std::unique_ptr<CPhysics> physics)
|
|||
m_physics = std::move(physics);
|
||||
}
|
||||
|
||||
// Returns the brain associated to the object.
|
||||
|
||||
CBrain* COldObject::GetBrain()
|
||||
// TODO: Temporary hack until we'll have subclasses for objects
|
||||
void COldObject::SetProgrammable(bool programmable)
|
||||
{
|
||||
return m_brain.get();
|
||||
}
|
||||
|
||||
void COldObject::SetBrain(std::unique_ptr<CBrain> brain)
|
||||
{
|
||||
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = true;
|
||||
m_brain = std::move(brain);
|
||||
m_implementedInterfaces[static_cast<int>(ObjectInterfaceType::Programmable)] = programmable;
|
||||
}
|
||||
|
||||
// Returns the movement associated to the object.
|
||||
|
@ -3497,3 +3625,512 @@ void COldObject::UpdateInterface()
|
|||
m_objectInterface->UpdateInterface();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -55,6 +55,21 @@ 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;
|
||||
|
@ -76,7 +91,7 @@ class COldObject : public CObject,
|
|||
protected:
|
||||
void DeleteObject(bool bAll=false);
|
||||
void SetPhysics(std::unique_ptr<CPhysics> physics);
|
||||
void SetBrain(std::unique_ptr<CBrain> brain);
|
||||
void SetProgrammable(bool programmable);
|
||||
void SetMotion(std::unique_ptr<CMotion> motion);
|
||||
void SetAuto(std::unique_ptr<CAuto> automat);
|
||||
void SetShowLimitRadius(float radius);
|
||||
|
@ -227,8 +242,8 @@ public:
|
|||
|
||||
//! Management of object "activity" (temporairly stops program execution, right now used only by Aliens in eggs)
|
||||
//@{
|
||||
void SetActivity(bool activity);
|
||||
bool GetActivity();
|
||||
void SetActivity(bool activity) override;
|
||||
bool GetActivity() override;
|
||||
//@}
|
||||
|
||||
void SetVisible(bool bVisible);
|
||||
|
@ -270,14 +285,12 @@ public:
|
|||
bool StartShowLimit() override;
|
||||
void StopShowLimit() override;
|
||||
|
||||
bool IsProgram() override;
|
||||
void CreateSelectParticle();
|
||||
|
||||
void SetRunScript(CScript* script);
|
||||
CScript* GetRunScript() override;
|
||||
CBotVar* GetBotVar() override;
|
||||
CPhysics* GetPhysics() override;
|
||||
CBrain* GetBrain() override;
|
||||
CMotion* GetMotion() override;
|
||||
CAuto* GetAuto() override;
|
||||
|
||||
|
@ -336,6 +349,45 @@ public:
|
|||
|
||||
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);
|
||||
|
@ -352,6 +404,13 @@ 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;
|
||||
|
@ -362,7 +421,6 @@ protected:
|
|||
CSoundInterface* m_sound;
|
||||
|
||||
std::unique_ptr<CPhysics> m_physics;
|
||||
std::unique_ptr<CBrain> m_brain;
|
||||
std::unique_ptr<CMotion> m_motion;
|
||||
std::unique_ptr<CAuto> m_auto;
|
||||
std::unique_ptr<Ui::CObjectInterface> m_objectInterface;
|
||||
|
@ -441,4 +499,25 @@ protected:
|
|||
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;
|
||||
};
|
||||
|
|
|
@ -397,11 +397,6 @@ void COldObjectInterface::StopShowLimit()
|
|||
}
|
||||
|
||||
|
||||
bool COldObjectInterface::IsProgram()
|
||||
{
|
||||
throw std::logic_error("IsProgram: not implemented!");
|
||||
}
|
||||
|
||||
CScript* COldObjectInterface::GetRunScript()
|
||||
{
|
||||
throw std::logic_error("GetRunScript: not implemented!");
|
||||
|
|
|
@ -33,17 +33,11 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
class CApplication;
|
||||
class CPhysics;
|
||||
class CBrain;
|
||||
class CMotion;
|
||||
class CAuto;
|
||||
class CDisplayText;
|
||||
class CRobotMain;
|
||||
class CBotVar;
|
||||
class CScript;
|
||||
class CLevelParserLine;
|
||||
struct Program;
|
||||
|
||||
|
||||
struct Character
|
||||
|
@ -175,8 +169,6 @@ public:
|
|||
virtual bool StartShowLimit();
|
||||
virtual void StopShowLimit();
|
||||
|
||||
virtual bool IsProgram();
|
||||
|
||||
virtual CScript* GetRunScript();
|
||||
virtual CBotVar* GetBotVar();
|
||||
virtual CPhysics* GetPhysics();
|
||||
|
@ -192,4 +184,3 @@ public:
|
|||
|
||||
virtual float GetInfoReturn();
|
||||
};
|
||||
|
||||
|
|
|
@ -56,7 +56,6 @@
|
|||
#include "math/const.h"
|
||||
#include "math/geometry.h"
|
||||
|
||||
#include "object/brain.h"
|
||||
#include "object/mainmovie.h"
|
||||
#include "object/object.h"
|
||||
#include "object/object_create_exception.h"
|
||||
|
@ -3468,13 +3467,13 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
|
|||
m_controller->SetIgnoreBuildCheck(true);
|
||||
if (m_controller->Implements(ObjectInterfaceType::Programmable))
|
||||
{
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(m_controller)->GetBrain();
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(m_controller);
|
||||
if (line->GetParam("script")->IsDefined())
|
||||
{
|
||||
Program* program = brain->AddProgram();
|
||||
Program* program = programmable->AddProgram();
|
||||
program->filename = "../" + line->GetParam("script")->AsPath("ai");
|
||||
program->readOnly = true;
|
||||
brain->SetScriptRun(program);
|
||||
programmable->SetScriptRun(program);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
@ -3637,7 +3636,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
|
|||
std::map<int, Program*> loadedPrograms;
|
||||
if (oldObj->Implements(ObjectInterfaceType::Programmable))
|
||||
{
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(oldObj)->GetBrain();
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(oldObj);
|
||||
|
||||
bool allFilled = true;
|
||||
for (int i = 0; i < 10 || allFilled; i++)
|
||||
|
@ -3647,7 +3646,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
|
|||
std::string opRunnable = "scriptRunnable" + boost::lexical_cast<std::string>(i+1); // scriptRunnable1..scriptRunnable10
|
||||
if (line->GetParam(op)->IsDefined())
|
||||
{
|
||||
Program* program = brain->AddProgram();
|
||||
Program* program = programmable->AddProgram();
|
||||
program->filename = "../" + line->GetParam(op)->AsPath("ai");
|
||||
program->readOnly = line->GetParam(opReadOnly)->AsBool(true);
|
||||
program->runnable = line->GetParam(opRunnable)->AsBool(true);
|
||||
|
@ -3663,7 +3662,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
|
|||
if (i != 0)
|
||||
{
|
||||
run = i-1;
|
||||
brain->SetScriptRun(loadedPrograms[run]);
|
||||
programmable->SetScriptRun(loadedPrograms[run]);
|
||||
}
|
||||
}
|
||||
CAuto* automat = oldObj->GetAuto();
|
||||
|
@ -3688,7 +3687,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
|
|||
}
|
||||
|
||||
if (soluce && oldObj->Implements(ObjectInterfaceType::Programmable) && line->GetParam("soluce")->IsDefined())
|
||||
dynamic_cast<CProgrammableObject*>(oldObj)->GetBrain()
|
||||
dynamic_cast<CProgrammableObject*>(oldObj)
|
||||
->SetSoluceName(const_cast<char*>(line->GetParam("soluce")->AsPath("ai").c_str()));
|
||||
|
||||
if (line->GetParam("reset")->AsBool(false))
|
||||
|
@ -4684,27 +4683,27 @@ void CRobotMain::CompileScript(bool soluce)
|
|||
m_ui->GetLoadingScreen()->SetProgress(0.75f+objectProgress*0.25f, RT_LOADING_PROGRAMS, "for object "+StrUtils::ToString<int>(objCounter+1)+" / "+StrUtils::ToString<int>(numObjects));
|
||||
objCounter++;
|
||||
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
|
||||
for (auto& prog : brain->GetPrograms())
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(obj);
|
||||
for (auto& prog : programmable->GetPrograms())
|
||||
{
|
||||
Program* program = prog.get();
|
||||
|
||||
if (program->filename.empty()) continue;
|
||||
|
||||
std::string name = "ai/" + program->filename;
|
||||
if (! brain->ReadProgram(program, const_cast<char*>(name.c_str())))
|
||||
if (! programmable->ReadProgram(program, const_cast<char*>(name.c_str())))
|
||||
{
|
||||
GetLogger()->Error("Unable to read script from file \"%s\"\n", name.c_str());
|
||||
}
|
||||
//? if (!brain->GetCompile(program)) nbError++;
|
||||
//? if (!programmable->GetCompile(program)) nbError++;
|
||||
}
|
||||
|
||||
if (soluce)
|
||||
{
|
||||
char* name = brain->GetSoluceName();
|
||||
char* name = programmable->GetSoluceName();
|
||||
if (name[0] != 0)
|
||||
{
|
||||
brain->ReadSoluce(name); // load solution
|
||||
programmable->ReadSoluce(name); // load solution
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4716,11 +4715,11 @@ void CRobotMain::CompileScript(bool soluce)
|
|||
{
|
||||
if (! obj->Implements(ObjectInterfaceType::Programmable)) continue;
|
||||
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
|
||||
Program* program = brain->GetScriptRun();
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(obj);
|
||||
Program* program = programmable->GetScriptRun();
|
||||
if (program != nullptr)
|
||||
{
|
||||
brain->RunProgram(program); // starts the program
|
||||
programmable->RunProgram(program); // starts the program
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4730,7 +4729,7 @@ void CRobotMain::LoadOneScript(CObject *obj)
|
|||
{
|
||||
if (! obj->Implements(ObjectInterfaceType::Programmable)) return;
|
||||
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(obj);
|
||||
|
||||
if (!IsSelectable(obj)) return;
|
||||
|
||||
|
@ -4749,10 +4748,10 @@ void CRobotMain::LoadOneScript(CObject *obj)
|
|||
|
||||
if (CResourceManager::Exists(filename))
|
||||
{
|
||||
Program* program = brain->GetOrAddProgram(i);
|
||||
if(brain->GetCompile(program)) continue; // If already loaded (e.g. from level file), skip
|
||||
brain->ReadProgram(program, filename.c_str());
|
||||
//? if (!brain->GetCompile(program)) nbError++;
|
||||
Program* program = programmable->GetOrAddProgram(i);
|
||||
if(programmable->GetCompile(program)) continue; // If already loaded (e.g. from level file), skip
|
||||
programmable->ReadProgram(program, filename.c_str());
|
||||
//? if (!programmable->GetCompile(program)) nbError++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4764,7 +4763,7 @@ void CRobotMain::LoadFileScript(CObject *obj, const char* filename, int objRank)
|
|||
|
||||
if (! obj->Implements(ObjectInterfaceType::Programmable)) return;
|
||||
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(obj);
|
||||
|
||||
ObjectType type = obj->GetType();
|
||||
if (type == OBJECT_HUMAN) return;
|
||||
|
@ -4778,9 +4777,9 @@ void CRobotMain::LoadFileScript(CObject *obj, const char* filename, int objRank)
|
|||
sprintf(fn, "%s/prog%.3d%.3d.txt", dirname.c_str(), objRank, i);
|
||||
if (CResourceManager::Exists(fn))
|
||||
{
|
||||
Program* program = brain->GetOrAddProgram(i);
|
||||
brain->ReadProgram(program, fn);
|
||||
//? if (!brain->GetCompile(program)) nbError++;
|
||||
Program* program = programmable->GetOrAddProgram(i);
|
||||
programmable->ReadProgram(program, fn);
|
||||
//? if (!programmable->GetCompile(program)) nbError++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4800,7 +4799,7 @@ void CRobotMain::SaveOneScript(CObject *obj)
|
|||
{
|
||||
if (! obj->Implements(ObjectInterfaceType::Programmable)) return;
|
||||
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(obj);
|
||||
|
||||
if (!IsSelectable(obj)) return;
|
||||
|
||||
|
@ -4811,7 +4810,7 @@ void CRobotMain::SaveOneScript(CObject *obj)
|
|||
if (objRank == -1) return;
|
||||
|
||||
char categoryChar = GetLevelCategoryDir(m_levelCategory)[0];
|
||||
auto& programs = brain->GetPrograms();
|
||||
auto& programs = programmable->GetPrograms();
|
||||
// TODO: Find a better way to do that
|
||||
for (unsigned int i = 0; i <= 999; i++)
|
||||
{
|
||||
|
@ -4821,7 +4820,7 @@ void CRobotMain::SaveOneScript(CObject *obj)
|
|||
|
||||
if (i < programs.size())
|
||||
{
|
||||
brain->WriteProgram(programs[i].get(), filename.c_str());
|
||||
programmable->WriteProgram(programs[i].get(), filename.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4838,7 +4837,7 @@ void CRobotMain::SaveFileScript(CObject *obj, const char* filename, int objRank)
|
|||
|
||||
if (! obj->Implements(ObjectInterfaceType::Programmable)) return;
|
||||
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(obj);
|
||||
|
||||
ObjectType type = obj->GetType();
|
||||
if (type == OBJECT_HUMAN) return;
|
||||
|
@ -4847,14 +4846,14 @@ void CRobotMain::SaveFileScript(CObject *obj, const char* filename, int objRank)
|
|||
dirname = dirname.substr(0, dirname.find_last_of("/"));
|
||||
|
||||
char fn[MAX_FNAME]; //TODO: Refactor to std::string
|
||||
auto& programs = brain->GetPrograms();
|
||||
auto& programs = programmable->GetPrograms();
|
||||
// TODO: Find a better way to do that
|
||||
for (unsigned int i = 0; i <= 999; i++)
|
||||
{
|
||||
sprintf(fn, "%s/prog%.3d%.3d.txt", dirname.c_str(), objRank, i);
|
||||
if (i < programs.size())
|
||||
{
|
||||
brain->WriteProgram(programs[i].get(), fn);
|
||||
programmable->WriteProgram(programs[i].get(), fn);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4870,12 +4869,12 @@ bool CRobotMain::SaveFileStack(CObject *obj, FILE *file, int objRank)
|
|||
|
||||
if (! obj->Implements(ObjectInterfaceType::Programmable)) return true;
|
||||
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(obj);
|
||||
|
||||
ObjectType type = obj->GetType();
|
||||
if (type == OBJECT_HUMAN) return true;
|
||||
|
||||
return brain->WriteStack(file);
|
||||
return programmable->WriteStack(file);
|
||||
}
|
||||
|
||||
//! Resumes the execution stack of the program in a robot
|
||||
|
@ -4885,12 +4884,12 @@ bool CRobotMain::ReadFileStack(CObject *obj, FILE *file, int objRank)
|
|||
|
||||
if (! obj->Implements(ObjectInterfaceType::Programmable)) return true;
|
||||
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(obj);
|
||||
|
||||
ObjectType type = obj->GetType();
|
||||
if (type == OBJECT_HUMAN) return true;
|
||||
|
||||
return brain->ReadStack(file);
|
||||
return programmable->ReadStack(file);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5005,15 +5004,15 @@ void CRobotMain::IOWriteObject(CLevelParserLine* line, CObject* obj)
|
|||
|
||||
if (obj->Implements(ObjectInterfaceType::Programmable))
|
||||
{
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(obj);
|
||||
|
||||
int run = brain->GetProgram();
|
||||
int run = programmable->GetProgram();
|
||||
if (run != -1)
|
||||
{
|
||||
line->AddParam("run", MakeUnique<CLevelParserParam>(run+1));
|
||||
}
|
||||
|
||||
auto& programs = brain->GetPrograms();
|
||||
auto& programs = programmable->GetPrograms();
|
||||
for (unsigned int i = 0; i < programs.size(); i++)
|
||||
{
|
||||
if (programs[i]->readOnly)
|
||||
|
@ -5249,19 +5248,19 @@ CObject* CRobotMain::IOReadObject(CLevelParserLine *line, const char* filename,
|
|||
|
||||
if (obj->Implements(ObjectInterfaceType::Programmable))
|
||||
{
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(obj);
|
||||
|
||||
if (run != -1)
|
||||
{
|
||||
Program* program = brain->GetOrAddProgram(run-1);
|
||||
brain->SetScriptRun(program); // marks the program to be started
|
||||
Program* program = programmable->GetOrAddProgram(run-1);
|
||||
programmable->SetScriptRun(program); // marks the program to be started
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i <= 999; i++)
|
||||
{
|
||||
if (line->GetParam("scriptReadOnly" + boost::lexical_cast<std::string>(i+1))->AsBool(false))
|
||||
{
|
||||
Program* prog = brain->GetOrAddProgram(i);
|
||||
Program* prog = programmable->GetOrAddProgram(i);
|
||||
prog->readOnly = true;
|
||||
}
|
||||
}
|
||||
|
@ -5371,12 +5370,12 @@ CObject* CRobotMain::IOReadScene(std::string filename, std::string filecbot)
|
|||
if (! obj->Implements(ObjectInterfaceType::Programmable)) continue;
|
||||
if (obj->GetDefRank() == -1) continue;
|
||||
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(obj)->GetBrain();
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(obj);
|
||||
|
||||
Program* program = brain->GetScriptRun();
|
||||
Program* program = programmable->GetScriptRun();
|
||||
if (program != nullptr)
|
||||
{
|
||||
brain->RunProgram(program); // starts the program
|
||||
programmable->RunProgram(program); // starts the program
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,10 +43,10 @@ CTask::CTask(COldObject* object)
|
|||
|
||||
m_object = object;
|
||||
m_physics = m_object->GetPhysics();
|
||||
m_brain = nullptr;
|
||||
m_programmable = nullptr;
|
||||
if (object->Implements(ObjectInterfaceType::Programmable))
|
||||
{
|
||||
m_brain = dynamic_cast<CProgrammableObject*>(m_object)->GetBrain();
|
||||
m_programmable = dynamic_cast<CProgrammableObject*>(m_object);
|
||||
}
|
||||
m_motion = m_object->GetMotion();
|
||||
}
|
||||
|
@ -88,4 +88,3 @@ bool CTask::Abort()
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
#include "math/const.h"
|
||||
|
||||
|
||||
class CBrain;
|
||||
class CPhysics;
|
||||
class CMotion;
|
||||
class COldObject;
|
||||
class CProgrammableObject;
|
||||
class CRobotMain;
|
||||
class CSoundInterface;
|
||||
|
||||
|
@ -80,11 +80,11 @@ protected:
|
|||
Gfx::CTerrain* m_terrain;
|
||||
Gfx::CWater* m_water;
|
||||
Gfx::CCamera* m_camera;
|
||||
CMotion* m_motion;
|
||||
CBrain* m_brain;
|
||||
CPhysics* m_physics;
|
||||
COldObject* m_object;
|
||||
CRobotMain* m_main;
|
||||
CSoundInterface* m_sound;
|
||||
};
|
||||
|
||||
COldObject* m_object;
|
||||
CProgrammableObject* m_programmable;
|
||||
CMotion* m_motion;
|
||||
CPhysics* m_physics;
|
||||
};
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
#include "math/geometry.h"
|
||||
|
||||
#include "object/brain.h"
|
||||
#include "object/object_manager.h"
|
||||
#include "object/old_object.h"
|
||||
#include "object/robotmain.h"
|
||||
|
@ -578,4 +577,3 @@ float CTaskShield::GetRadius()
|
|||
{
|
||||
return RADIUS_SHIELD_MIN + (RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)*m_object->GetParam();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,13 +25,11 @@
|
|||
|
||||
#include "math/geometry.h"
|
||||
|
||||
#include "object/brain.h"
|
||||
#include "object/object_manager.h"
|
||||
#include "object/old_object.h"
|
||||
#include "object/robotmain.h"
|
||||
|
||||
#include "object/interface/powered_object.h"
|
||||
#include "object/interface/programmable_object.h"
|
||||
|
||||
#include "object/motion/motionant.h"
|
||||
#include "object/motion/motionspider.h"
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
|
||||
#include "math/geometry.h"
|
||||
|
||||
#include "object/brain.h"
|
||||
#include "object/object_manager.h"
|
||||
#include "object/old_object.h"
|
||||
#include "object/robotmain.h"
|
||||
|
@ -3829,7 +3828,7 @@ Error CPhysics::GetError()
|
|||
|
||||
if (m_object->Implements(ObjectInterfaceType::Programmable))
|
||||
{
|
||||
if ( dynamic_cast<CProgrammableObject*>(m_object)->GetBrain()->GetActiveVirus() )
|
||||
if ( dynamic_cast<CProgrammableObject*>(m_object)->GetActiveVirus() )
|
||||
{
|
||||
return ERR_VEH_VIRUS;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
|
||||
class CObject;
|
||||
class COldObject;
|
||||
class CBrain;
|
||||
class CMotion;
|
||||
class CSoundInterface;
|
||||
class CLevelParserLine;
|
||||
|
@ -111,7 +110,6 @@ public:
|
|||
|
||||
bool EventProcess(const Event &event);
|
||||
|
||||
void SetBrain(CBrain* brain);
|
||||
void SetMotion(CMotion* motion);
|
||||
|
||||
void SetType(PhysicsType type);
|
||||
|
@ -216,11 +214,11 @@ protected:
|
|||
Gfx::CTerrain* m_terrain;
|
||||
Gfx::CWater* m_water;
|
||||
Gfx::CCamera* m_camera;
|
||||
COldObject* m_object;
|
||||
CBrain* m_brain;
|
||||
CMotion* m_motion;
|
||||
CSoundInterface* m_sound;
|
||||
|
||||
COldObject* m_object;
|
||||
CMotion* m_motion;
|
||||
|
||||
PhysicsType m_type; // TYPE_*
|
||||
float m_gravity; // force of gravity
|
||||
float m_time; // absolute time
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
|
||||
#include "math/all.h"
|
||||
|
||||
#include "object/brain.h"
|
||||
#include "object/object.h"
|
||||
#include "object/object_manager.h"
|
||||
#include "object/robotmain.h"
|
||||
|
@ -45,6 +44,7 @@
|
|||
#include "object/auto/autobase.h"
|
||||
#include "object/auto/autofactory.h"
|
||||
|
||||
#include "object/interface/programmable_object.h"
|
||||
#include "object/interface/task_executor_object.h"
|
||||
|
||||
#include "object/level/parser.h"
|
||||
|
@ -1611,10 +1611,10 @@ bool CScriptFunctions::rProduce(CBotVar* var, CBotVar* result, int& exception, v
|
|||
std::string name2 = InjectLevelPathsForCurrentLevel(name, "ai");
|
||||
if (object->Implements(ObjectInterfaceType::Programmable))
|
||||
{
|
||||
CBrain* brain = dynamic_cast<CProgrammableObject*>(object)->GetBrain();
|
||||
Program* program = brain->AddProgram();
|
||||
brain->ReadProgram(program, name2.c_str());
|
||||
brain->RunProgram(program);
|
||||
CProgrammableObject* programmable = dynamic_cast<CProgrammableObject*>(object);
|
||||
Program* program = programmable->AddProgram();
|
||||
programmable->ReadProgram(program, name2.c_str());
|
||||
programmable->RunProgram(program);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include "object/object.h"
|
||||
#include "object/object_manager.h"
|
||||
|
||||
#include "object/interface/programmable_object.h"
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
|
@ -233,7 +235,7 @@ bool CMainShort::UpdateShortcuts()
|
|||
if ( pc != nullptr )
|
||||
{
|
||||
pc->SetState(STATE_CHECK, m_shortcuts[i]->GetSelect());
|
||||
pc->SetState(STATE_RUN, m_shortcuts[i]->IsProgram());
|
||||
pc->SetState(STATE_RUN, m_shortcuts[i]->Implements(ObjectInterfaceType::Programmable) && dynamic_cast<CProgrammableObject*>(m_shortcuts[i])->IsProgram());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
#include "math/geometry.h"
|
||||
|
||||
#include "object/brain.h"
|
||||
#include "object/old_object.h"
|
||||
|
||||
#include "object/interface/carrier_object.h"
|
||||
|
@ -63,7 +62,7 @@ CObjectInterface::CObjectInterface(COldObject* object)
|
|||
assert(object->Implements(ObjectInterfaceType::TaskExecutor));
|
||||
m_taskExecutor = dynamic_cast<CTaskExecutorObject*>(m_object);
|
||||
assert(object->Implements(ObjectInterfaceType::Programmable));
|
||||
m_brain = dynamic_cast<CProgrammableObject*>(m_object)->GetBrain();
|
||||
m_programmable = dynamic_cast<CProgrammableObject*>(m_object);
|
||||
|
||||
m_physics = m_object->GetPhysics();
|
||||
m_motion = m_object->GetMotion();
|
||||
|
@ -194,8 +193,8 @@ bool CObjectInterface::EventProcess(const Event &event)
|
|||
index = data->key-KEY(1);
|
||||
else if(data->key == KEY(0))
|
||||
index = 9;
|
||||
if(index < 0) index = m_brain->GetProgramCount()-1;
|
||||
if(index > static_cast<int>(m_brain->GetProgramCount())-1) index = 0;
|
||||
if(index < 0) index = m_programmable->GetProgramCount()-1;
|
||||
if(index > static_cast<int>(m_programmable->GetProgramCount())-1) index = 0;
|
||||
|
||||
if(GetSelScript() != index)
|
||||
{
|
||||
|
@ -226,29 +225,29 @@ bool CObjectInterface::EventProcess(const Event &event)
|
|||
|
||||
if ( action == EVENT_OBJECT_PROGRUN )
|
||||
{
|
||||
if ( !m_brain->IsProgram() )
|
||||
if ( !m_programmable->IsProgram() )
|
||||
{
|
||||
if(m_selScript < m_brain->GetProgramCount())
|
||||
if(m_selScript < m_programmable->GetProgramCount())
|
||||
{
|
||||
m_brain->RunProgram(m_brain->GetProgram(m_selScript));
|
||||
m_programmable->RunProgram(m_programmable->GetProgram(m_selScript));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_brain->StopProgram();
|
||||
m_programmable->StopProgram();
|
||||
}
|
||||
}
|
||||
if ( action == EVENT_OBJECT_PROGSTART )
|
||||
{
|
||||
m_main->SaveOneScript(m_object);
|
||||
if(m_selScript < m_brain->GetProgramCount())
|
||||
if(m_selScript < m_programmable->GetProgramCount())
|
||||
{
|
||||
m_brain->RunProgram(m_brain->GetProgram(m_selScript));
|
||||
m_programmable->RunProgram(m_programmable->GetProgram(m_selScript));
|
||||
}
|
||||
}
|
||||
if ( action == EVENT_OBJECT_PROGSTOP )
|
||||
{
|
||||
m_brain->StopProgram();
|
||||
m_programmable->StopProgram();
|
||||
}
|
||||
if ( action == EVENT_STUDIO_OK )
|
||||
{
|
||||
|
@ -263,8 +262,8 @@ bool CObjectInterface::EventProcess(const Event &event)
|
|||
if( action == EVENT_STUDIO_CLONE )
|
||||
{
|
||||
StopEditScript(false);
|
||||
Program* newProgram = m_brain->CloneProgram(m_brain->GetProgram(m_selScript));
|
||||
m_selScript = m_brain->GetProgramIndex(newProgram);
|
||||
Program* newProgram = m_programmable->CloneProgram(m_programmable->GetProgram(m_selScript));
|
||||
m_selScript = m_programmable->GetProgramIndex(newProgram);
|
||||
m_main->SaveOneScript(m_object);
|
||||
|
||||
UpdateInterface();
|
||||
|
@ -296,29 +295,29 @@ bool CObjectInterface::EventProcess(const Event &event)
|
|||
}
|
||||
}
|
||||
if ( m_taskExecutor->IsForegroundTask() || // current task?
|
||||
m_brain->IsProgram() )
|
||||
m_programmable->IsProgram() )
|
||||
{
|
||||
if ( action == EVENT_OBJECT_PROGRUN )
|
||||
{
|
||||
m_brain->StopProgram();
|
||||
m_programmable->StopProgram();
|
||||
}
|
||||
if ( action == EVENT_OBJECT_PROGEDIT )
|
||||
{
|
||||
if(m_selScript < m_brain->GetProgramCount())
|
||||
if(m_selScript < m_programmable->GetProgramCount())
|
||||
{
|
||||
StartEditScript(m_brain->GetProgram(m_selScript), m_main->GetScriptName());
|
||||
StartEditScript(m_programmable->GetProgram(m_selScript), m_main->GetScriptName());
|
||||
}
|
||||
}
|
||||
|
||||
if ( !m_taskExecutor->IsForegroundTask() || !m_taskExecutor->GetForegroundTask()->IsPilot() ) return true;
|
||||
}
|
||||
|
||||
if ( !m_brain->IsProgram() )
|
||||
if ( !m_programmable->IsProgram() )
|
||||
{
|
||||
if( action == EVENT_OBJECT_PROGADD )
|
||||
{
|
||||
Program* program = m_brain->AddProgram();
|
||||
m_selScript = m_brain->GetProgramIndex(program);
|
||||
Program* program = m_programmable->AddProgram();
|
||||
m_selScript = m_programmable->GetProgramIndex(program);
|
||||
m_main->SaveOneScript(m_object);
|
||||
|
||||
UpdateInterface();
|
||||
|
@ -332,11 +331,11 @@ bool CObjectInterface::EventProcess(const Event &event)
|
|||
|
||||
if( action == EVENT_OBJECT_PROGREMOVE )
|
||||
{
|
||||
if(m_selScript < m_brain->GetProgramCount())
|
||||
if(m_selScript < m_programmable->GetProgramCount())
|
||||
{
|
||||
m_brain->RemoveProgram(m_brain->GetProgram(m_selScript));
|
||||
if(m_selScript >= m_brain->GetProgramCount())
|
||||
m_selScript = m_brain->GetProgramCount()-1;
|
||||
m_programmable->RemoveProgram(m_programmable->GetProgram(m_selScript));
|
||||
if(m_selScript >= m_programmable->GetProgramCount())
|
||||
m_selScript = m_programmable->GetProgramCount()-1;
|
||||
m_main->SaveOneScript(m_object);
|
||||
|
||||
UpdateInterface();
|
||||
|
@ -351,10 +350,10 @@ bool CObjectInterface::EventProcess(const Event &event)
|
|||
|
||||
if( action == EVENT_OBJECT_PROGCLONE )
|
||||
{
|
||||
if(m_selScript < m_brain->GetProgramCount())
|
||||
if(m_selScript < m_programmable->GetProgramCount())
|
||||
{
|
||||
m_brain->CloneProgram(m_brain->GetProgram(m_selScript));
|
||||
m_selScript = m_brain->GetProgramCount()-1;
|
||||
m_programmable->CloneProgram(m_programmable->GetProgram(m_selScript));
|
||||
m_selScript = m_programmable->GetProgramCount()-1;
|
||||
m_main->SaveOneScript(m_object);
|
||||
|
||||
UpdateInterface();
|
||||
|
@ -370,7 +369,7 @@ bool CObjectInterface::EventProcess(const Event &event)
|
|||
|
||||
if( action == EVENT_OBJECT_PROGMOVEUP )
|
||||
{
|
||||
std::iter_swap(m_brain->GetPrograms().begin() + m_selScript, m_brain->GetPrograms().begin() + m_selScript - 1);
|
||||
std::iter_swap(m_programmable->GetPrograms().begin() + m_selScript, m_programmable->GetPrograms().begin() + m_selScript - 1);
|
||||
m_selScript--;
|
||||
m_main->SaveOneScript(m_object);
|
||||
|
||||
|
@ -385,7 +384,7 @@ bool CObjectInterface::EventProcess(const Event &event)
|
|||
|
||||
if( action == EVENT_OBJECT_PROGMOVEDOWN )
|
||||
{
|
||||
std::iter_swap(m_brain->GetPrograms().begin() + m_selScript, m_brain->GetPrograms().begin() + m_selScript + 1);
|
||||
std::iter_swap(m_programmable->GetPrograms().begin() + m_selScript, m_programmable->GetPrograms().begin() + m_selScript + 1);
|
||||
m_selScript++;
|
||||
m_main->SaveOneScript(m_object);
|
||||
|
||||
|
@ -407,25 +406,25 @@ bool CObjectInterface::EventProcess(const Event &event)
|
|||
|
||||
if ( action == EVENT_OBJECT_PROGEDIT )
|
||||
{
|
||||
if(m_selScript < m_brain->GetProgramCount())
|
||||
if(m_selScript < m_programmable->GetProgramCount())
|
||||
{
|
||||
StartEditScript(m_brain->GetProgram(m_selScript), m_main->GetScriptName());
|
||||
StartEditScript(m_programmable->GetProgram(m_selScript), m_main->GetScriptName());
|
||||
}
|
||||
}
|
||||
|
||||
if ( action == EVENT_OBJECT_PROGRUN )
|
||||
{
|
||||
m_brain->StopProgram(); // stops the current program
|
||||
if(m_selScript < m_brain->GetProgramCount())
|
||||
m_programmable->StopProgram(); // stops the current program
|
||||
if(m_selScript < m_programmable->GetProgramCount())
|
||||
{
|
||||
m_brain->RunProgram(m_brain->GetProgram(m_selScript));
|
||||
m_programmable->RunProgram(m_programmable->GetProgram(m_selScript));
|
||||
}
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
err = ERR_OK;
|
||||
|
||||
if ( !m_brain->IsProgram() )
|
||||
if ( !m_programmable->IsProgram() )
|
||||
{
|
||||
if ( action == EVENT_OBJECT_HTAKE )
|
||||
{
|
||||
|
@ -644,13 +643,13 @@ bool CObjectInterface::EventProcess(const Event &event)
|
|||
|
||||
if ( action == EVENT_OBJECT_REC ) // registered?
|
||||
{
|
||||
if ( m_brain->IsTraceRecord() )
|
||||
if ( m_programmable->IsTraceRecord() )
|
||||
{
|
||||
m_brain->TraceRecordStop();
|
||||
m_programmable->TraceRecordStop();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_brain->TraceRecordStart();
|
||||
m_programmable->TraceRecordStart();
|
||||
}
|
||||
UpdateInterface();
|
||||
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0));
|
||||
|
@ -661,9 +660,9 @@ bool CObjectInterface::EventProcess(const Event &event)
|
|||
}
|
||||
if ( action == EVENT_OBJECT_STOP ) // stops?
|
||||
{
|
||||
if ( m_brain->IsTraceRecord() )
|
||||
if ( m_programmable->IsTraceRecord() )
|
||||
{
|
||||
m_brain->TraceRecordStop();
|
||||
m_programmable->TraceRecordStop();
|
||||
}
|
||||
UpdateInterface();
|
||||
pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0));
|
||||
|
@ -756,7 +755,7 @@ void CObjectInterface::StopEditScript(bool bCancel)
|
|||
if ( !m_studio->StopEditScript(bCancel) ) return;
|
||||
m_studio.reset();
|
||||
|
||||
if ( !bCancel ) m_brain->SetActiveVirus(false);
|
||||
if ( !bCancel ) m_programmable->SetActiveVirus(false);
|
||||
|
||||
CreateInterface(true); // puts the control buttons
|
||||
}
|
||||
|
@ -1657,7 +1656,7 @@ void CObjectInterface::UpdateInterface(float rTime)
|
|||
pb = static_cast<CButton*>(pw->SearchControl(EVENT_OBJECT_REC));
|
||||
if ( pb != 0 )
|
||||
{
|
||||
if ( m_brain->IsTraceRecord() && Math::Mod(m_time, 0.4f) >= 0.2f )
|
||||
if ( m_programmable->IsTraceRecord() && Math::Mod(m_time, 0.4f) >= 0.2f )
|
||||
{
|
||||
pb->SetState(STATE_CHECK);
|
||||
}
|
||||
|
@ -1756,15 +1755,15 @@ void CObjectInterface::UpdateInterface()
|
|||
|
||||
type = m_object->GetType();
|
||||
|
||||
bEnable = ( !m_taskExecutor->IsForegroundTask() && !m_brain->IsProgram() ) && m_main->CanPlayerInteract();
|
||||
bEnable = ( !m_taskExecutor->IsForegroundTask() && !m_programmable->IsProgram() ) && m_main->CanPlayerInteract();
|
||||
|
||||
EnableInterface(pw, EVENT_OBJECT_PROGEDIT, !m_brain->IsTraceRecord() && m_selScript < m_brain->GetProgramCount() && m_main->CanPlayerInteract());
|
||||
EnableInterface(pw, EVENT_OBJECT_PROGLIST, bEnable && !m_brain->IsTraceRecord());
|
||||
EnableInterface(pw, EVENT_OBJECT_PROGADD, !m_brain->IsProgram() && m_main->CanPlayerInteract());
|
||||
EnableInterface(pw, EVENT_OBJECT_PROGREMOVE, !m_brain->IsProgram() && m_selScript < m_brain->GetProgramCount() && !m_brain->GetProgram(m_selScript)->readOnly && m_main->CanPlayerInteract());
|
||||
EnableInterface(pw, EVENT_OBJECT_PROGCLONE, !m_brain->IsProgram() && m_selScript < m_brain->GetProgramCount() && m_brain->GetProgram(m_selScript)->runnable && m_main->CanPlayerInteract());
|
||||
EnableInterface(pw, EVENT_OBJECT_PROGMOVEUP, !m_brain->IsProgram() && m_brain->GetProgramCount() >= 2 && m_selScript > 0 && m_main->CanPlayerInteract());
|
||||
EnableInterface(pw, EVENT_OBJECT_PROGMOVEDOWN,!m_brain->IsProgram() && m_brain->GetProgramCount() >= 2 && m_selScript < m_brain->GetProgramCount()-1 && m_main->CanPlayerInteract());
|
||||
EnableInterface(pw, EVENT_OBJECT_PROGEDIT, !m_programmable->IsTraceRecord() && m_selScript < m_programmable->GetProgramCount() && m_main->CanPlayerInteract());
|
||||
EnableInterface(pw, EVENT_OBJECT_PROGLIST, bEnable && !m_programmable->IsTraceRecord());
|
||||
EnableInterface(pw, EVENT_OBJECT_PROGADD, !m_programmable->IsProgram() && m_main->CanPlayerInteract());
|
||||
EnableInterface(pw, EVENT_OBJECT_PROGREMOVE, !m_programmable->IsProgram() && m_selScript < m_programmable->GetProgramCount() && !m_programmable->GetProgram(m_selScript)->readOnly && m_main->CanPlayerInteract());
|
||||
EnableInterface(pw, EVENT_OBJECT_PROGCLONE, !m_programmable->IsProgram() && m_selScript < m_programmable->GetProgramCount() && m_programmable->GetProgram(m_selScript)->runnable && m_main->CanPlayerInteract());
|
||||
EnableInterface(pw, EVENT_OBJECT_PROGMOVEUP, !m_programmable->IsProgram() && m_programmable->GetProgramCount() >= 2 && m_selScript > 0 && m_main->CanPlayerInteract());
|
||||
EnableInterface(pw, EVENT_OBJECT_PROGMOVEDOWN,!m_programmable->IsProgram() && m_programmable->GetProgramCount() >= 2 && m_selScript < m_programmable->GetProgramCount()-1 && m_main->CanPlayerInteract());
|
||||
EnableInterface(pw, EVENT_OBJECT_LEFT, bEnable);
|
||||
EnableInterface(pw, EVENT_OBJECT_RIGHT, bEnable);
|
||||
EnableInterface(pw, EVENT_OBJECT_UP, bEnable);
|
||||
|
@ -1832,7 +1831,7 @@ void CObjectInterface::UpdateInterface()
|
|||
|
||||
if ( type == OBJECT_MOBILErs ) // shield?
|
||||
{
|
||||
if ( (!m_taskExecutor->IsBackgroundTask() || !m_taskExecutor->GetBackgroundTask()->IsBusy()) && !m_brain->IsProgram() )
|
||||
if ( (!m_taskExecutor->IsBackgroundTask() || !m_taskExecutor->GetBackgroundTask()->IsBusy()) && !m_programmable->IsProgram() )
|
||||
{
|
||||
EnableInterface(pw, EVENT_OBJECT_BEGSHIELD, !m_taskExecutor->IsBackgroundTask() && m_main->CanPlayerInteract());
|
||||
EnableInterface(pw, EVENT_OBJECT_ENDSHIELD, m_taskExecutor->IsBackgroundTask() && m_main->CanPlayerInteract());
|
||||
|
@ -1910,11 +1909,11 @@ void CObjectInterface::UpdateInterface()
|
|||
type == OBJECT_CONTROLLER) // vehicle?
|
||||
{
|
||||
bRun = false;
|
||||
if ( m_selScript < m_brain->GetProgramCount() )
|
||||
if ( m_selScript < m_programmable->GetProgramCount() )
|
||||
{
|
||||
if(m_brain->GetProgram(m_selScript)->runnable)
|
||||
if(m_programmable->GetProgram(m_selScript)->runnable)
|
||||
{
|
||||
m_brain->GetProgram(m_selScript)->script->GetTitle(title);
|
||||
m_programmable->GetProgram(m_selScript)->script->GetTitle(title);
|
||||
if ( title[0] != 0 )
|
||||
{
|
||||
bRun = true;
|
||||
|
@ -1925,23 +1924,23 @@ void CObjectInterface::UpdateInterface()
|
|||
bRun = false;
|
||||
}
|
||||
}
|
||||
if ( !bEnable && !m_brain->IsProgram() ) bRun = false;
|
||||
if ( m_brain->IsTraceRecord() ) bRun = false;
|
||||
if ( !bEnable && !m_programmable->IsProgram() ) bRun = false;
|
||||
if ( m_programmable->IsTraceRecord() ) bRun = false;
|
||||
EnableInterface(pw, EVENT_OBJECT_PROGRUN, bRun && m_main->CanPlayerInteract());
|
||||
|
||||
pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_PROGRUN));
|
||||
if ( pb != 0 )
|
||||
{
|
||||
pb->SetIcon(!m_brain->IsProgram() ? 21 : 8); // run/stop
|
||||
pb->SetIcon(!m_programmable->IsProgram() ? 21 : 8); // run/stop
|
||||
}
|
||||
|
||||
//? pb = (CButton*)pw->SearchControl(EVENT_OBJECT_PROGEDIT);
|
||||
//? if ( pb != 0 )
|
||||
//? {
|
||||
//? pb->SetIcon(!m_brain->IsProgram() ? 22 : 40); // edit/debug
|
||||
//? pb->SetIcon(!m_programmable->IsProgram() ? 22 : 40); // edit/debug
|
||||
//? }
|
||||
|
||||
BlinkScript(m_brain->IsProgram()); // blinks if script execution
|
||||
BlinkScript(m_programmable->IsProgram()); // blinks if script execution
|
||||
}
|
||||
|
||||
if ( type == OBJECT_MOBILEfa ||
|
||||
|
@ -2068,14 +2067,14 @@ void CObjectInterface::UpdateScript(CWindow *pw)
|
|||
if ( pl == 0 ) return;
|
||||
|
||||
pl->Flush();
|
||||
for ( int i = 0 ; i < m_brain->GetProgramCount() ; i++ )
|
||||
for ( int i = 0 ; i < m_programmable->GetProgramCount() ; i++ )
|
||||
{
|
||||
sprintf(name, "%d", i+1);
|
||||
|
||||
m_brain->GetProgram(i)->script->GetTitle(title);
|
||||
m_programmable->GetProgram(i)->script->GetTitle(title);
|
||||
if ( title[0] != 0 )
|
||||
{
|
||||
if(!m_brain->GetProgram(i)->readOnly)
|
||||
if(!m_programmable->GetProgram(i)->readOnly)
|
||||
{
|
||||
sprintf(name, "%d: %s", i+1, title);
|
||||
}
|
||||
|
|
|
@ -23,12 +23,12 @@
|
|||
|
||||
class COldObject;
|
||||
class CTaskExecutorObject;
|
||||
class CProgrammableObject;
|
||||
class CPhysics;
|
||||
class CMotion;
|
||||
class CRobotMain;
|
||||
class CSoundInterface;
|
||||
class CLevelParserLine;
|
||||
class CBrain;
|
||||
struct Program;
|
||||
|
||||
namespace Gfx
|
||||
|
@ -87,12 +87,12 @@ protected:
|
|||
Gfx::CCamera* m_camera;
|
||||
Gfx::CParticle* m_particle;
|
||||
CRobotMain* m_main;
|
||||
Ui::CInterface* m_interface;
|
||||
CInterface* m_interface;
|
||||
CSoundInterface* m_sound;
|
||||
|
||||
COldObject* m_object;
|
||||
CTaskExecutorObject* m_taskExecutor;
|
||||
CBrain* m_brain;
|
||||
CProgrammableObject* m_programmable;
|
||||
CPhysics* m_physics;
|
||||
CMotion* m_motion;
|
||||
|
||||
|
|
|
@ -34,10 +34,11 @@
|
|||
#include "graphics/engine/camera.h"
|
||||
#include "graphics/engine/engine.h"
|
||||
|
||||
#include "object/brain.h"
|
||||
#include "object/object.h"
|
||||
#include "object/player_profile.h"
|
||||
|
||||
#include "object/interface/programmable_object.h"
|
||||
|
||||
#include "script/cbottoken.h"
|
||||
#include "script/script.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue