3012 lines
81 KiB
C++
3012 lines
81 KiB
C++
// * This file is part of the COLOBOT source code
|
|
// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
|
|
// *
|
|
// * 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://www.gnu.org/licenses/.
|
|
|
|
|
|
#include "object/brain.h"
|
|
|
|
#include "app/app.h"
|
|
|
|
#include "common/iman.h"
|
|
#include "common/misc.h"
|
|
|
|
#include "graphics/core/color.h"
|
|
#include "graphics/engine/terrain.h"
|
|
|
|
#include "object/motion/motion.h"
|
|
#include "object/task/taskmanager.h"
|
|
|
|
#include "physics/physics.h"
|
|
|
|
#include "script/cmdtoken.h"
|
|
#include "script/script.h"
|
|
|
|
#include "sound/sound.h"
|
|
|
|
#include "ui/interface.h"
|
|
#include "ui/slider.h"
|
|
#include "ui/studio.h"
|
|
#include "ui/window.h"
|
|
|
|
|
|
|
|
const int MAXTRACERECORD = 1000;
|
|
|
|
|
|
|
|
// Object's constructor.
|
|
|
|
CBrain::CBrain(CObject* object)
|
|
{
|
|
CInstanceManager::GetInstancePointer()->AddInstance(CLASS_BRAIN, this, 100);
|
|
|
|
m_object = object;
|
|
m_engine = Gfx::CEngine::GetInstancePointer();
|
|
m_water = m_engine->GetWater();
|
|
m_particle = m_engine->GetParticle();
|
|
m_main = CRobotMain::GetInstancePointer();
|
|
m_terrain = m_main->GetTerrain();
|
|
m_camera = m_main->GetCamera();
|
|
m_interface = m_main->GetInterface();
|
|
m_sound = CApplication::GetInstancePointer()->GetSound();
|
|
m_physics = nullptr;
|
|
m_motion = nullptr;
|
|
m_primaryTask = nullptr;
|
|
m_secondaryTask = nullptr;
|
|
m_studio = nullptr;
|
|
|
|
m_program = -1;
|
|
m_bActivity = true;
|
|
m_bBurn = false;
|
|
m_bActiveVirus = false;
|
|
m_time = 0.0f;
|
|
m_burnTime = 0.0f;
|
|
m_lastUpdateTime = 0.0f;
|
|
m_lastHumanTime = 0.0f;
|
|
m_lastWormTime = 0.0f;
|
|
m_antTarget = 0;
|
|
m_beeBullet = 0;
|
|
m_lastAlarmTime = 0.0f;
|
|
m_soundChannelAlarm = -1;
|
|
m_flagColor = 0;
|
|
|
|
m_buttonAxe = EVENT_NULL;
|
|
m_defaultEnter = EVENT_NULL;
|
|
m_manipStyle = EVENT_OBJECT_MFRONT;
|
|
|
|
for (int i=0 ; i<BRAINMAXSCRIPT ; i++ )
|
|
{
|
|
m_script[i] = 0;
|
|
m_scriptName[i][0] = 0;
|
|
}
|
|
m_scriptRun = -1;
|
|
m_soluceName[0] = 0;
|
|
m_selScript = 0;
|
|
|
|
m_bTraceRecord = false;
|
|
m_traceRecordBuffer = nullptr;
|
|
}
|
|
|
|
// Object's destructor.
|
|
|
|
CBrain::~CBrain()
|
|
{
|
|
for (int i=0 ; i<BRAINMAXSCRIPT ; i++ )
|
|
{
|
|
delete m_script[i];
|
|
m_script[i] = nullptr;
|
|
}
|
|
|
|
delete m_primaryTask;
|
|
m_primaryTask = nullptr;
|
|
|
|
delete m_secondaryTask;
|
|
m_secondaryTask = nullptr;
|
|
|
|
delete m_studio;
|
|
m_studio = nullptr;
|
|
|
|
delete[] m_traceRecordBuffer;
|
|
m_traceRecordBuffer = nullptr;
|
|
|
|
CInstanceManager::GetInstancePointer()->DeleteInstance(CLASS_BRAIN, this);
|
|
}
|
|
|
|
|
|
// Destroys the object.
|
|
|
|
void CBrain::DeleteObject(bool bAll)
|
|
{
|
|
if ( m_soundChannelAlarm != -1 )
|
|
{
|
|
m_sound->FlushEnvelope(m_soundChannelAlarm);
|
|
m_sound->AddEnvelope(m_soundChannelAlarm, 0.0f, 0.5f, 0.5f, SOPER_STOP);
|
|
m_soundChannelAlarm = -1;
|
|
}
|
|
|
|
if ( !bAll )
|
|
{
|
|
if ( m_beeBullet != 0 )
|
|
{
|
|
m_beeBullet->DeleteObject();
|
|
delete m_beeBullet;
|
|
m_beeBullet = 0;
|
|
}
|
|
}
|
|
|
|
if ( m_studio != 0 ) // current edition?
|
|
{
|
|
StopEditScript(true);
|
|
}
|
|
}
|
|
|
|
|
|
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(char *line)
|
|
{
|
|
char name[100];
|
|
|
|
sprintf(name, " bVirusActive=%d", m_bActiveVirus);
|
|
strcat(line, name);
|
|
|
|
return true;
|
|
}
|
|
|
|
// Restores all parameters of the object.
|
|
|
|
bool CBrain::Read(char *line)
|
|
{
|
|
m_bActiveVirus = OpInt(line, "bVirusActive", 0);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
// Management of an event.
|
|
|
|
bool CBrain::EventProcess(const Event &event)
|
|
{
|
|
Ui::CWindow* pw;
|
|
Ui::CControl* pc;
|
|
Ui::CSlider* ps;
|
|
EventType action;
|
|
ObjectType type;
|
|
Error err;
|
|
float axeX, axeY, axeZ, factor;
|
|
|
|
type = m_object->GetType();
|
|
|
|
if ( m_primaryTask != 0 ) // current task?
|
|
{
|
|
m_primaryTask->EventProcess(event);
|
|
}
|
|
|
|
if ( m_secondaryTask != 0 ) // current task?
|
|
{
|
|
m_secondaryTask->EventProcess(event);
|
|
}
|
|
|
|
action = EVENT_NULL;
|
|
|
|
if ( event.type == EVENT_KEY_DOWN &&
|
|
(event.key.key == m_main->GetInputBinding(INPUT_SLOT_ACTION).primary ||
|
|
event.key.key == m_main->GetInputBinding(INPUT_SLOT_ACTION).secondary ) &&
|
|
!m_main->GetEditLock() )
|
|
{
|
|
pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0));
|
|
if ( pw != 0 )
|
|
{
|
|
pc = pw->SearchControl(m_defaultEnter);
|
|
if ( pc != 0 )
|
|
{
|
|
if ( pc->TestState(Ui::STATE_ENABLE) )
|
|
{
|
|
action = m_defaultEnter;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
action = event.type;
|
|
}
|
|
|
|
if ( action == EVENT_NULL ) return true;
|
|
|
|
if ( action == EVENT_UPDINTERFACE )
|
|
{
|
|
if ( m_object->GetSelect() ) CreateInterface(true);
|
|
}
|
|
|
|
if ( action == EVENT_FRAME )
|
|
{
|
|
EventFrame(event);
|
|
}
|
|
|
|
if ( m_object->GetSelect() && // robot selected?
|
|
m_studio != 0 ) // current issue?
|
|
{
|
|
m_studio->EventProcess(event);
|
|
|
|
if ( action == EVENT_OBJECT_PROGRUN )
|
|
{
|
|
if ( m_program == -1 )
|
|
{
|
|
RunProgram(m_selScript);
|
|
}
|
|
else
|
|
{
|
|
StopProgram();
|
|
}
|
|
}
|
|
if ( action == EVENT_OBJECT_PROGSTART )
|
|
{
|
|
m_main->SaveOneScript(m_object);
|
|
RunProgram(m_selScript);
|
|
}
|
|
if ( action == EVENT_OBJECT_PROGSTOP )
|
|
{
|
|
StopProgram();
|
|
}
|
|
if ( action == EVENT_STUDIO_OK )
|
|
{
|
|
StopEditScript(false);
|
|
m_main->SaveOneScript(m_object);
|
|
}
|
|
if ( action == EVENT_STUDIO_CANCEL )
|
|
{
|
|
StopEditScript(true);
|
|
m_main->SaveOneScript(m_object);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if ( !m_object->GetSelect() && // robot pas sélectionné ?
|
|
m_program == -1 &&
|
|
m_primaryTask == 0 )
|
|
{
|
|
axeX = 0.0f;
|
|
axeY = 0.0f;
|
|
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() &&
|
|
(type == OBJECT_ANT ||
|
|
type == OBJECT_SPIDER ||
|
|
type == OBJECT_WORM ) )
|
|
{
|
|
axeY = 2.0f; // zigzag disorganized fast
|
|
if ( 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;
|
|
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_program != -1 &&
|
|
m_object->GetRuin() )
|
|
{
|
|
StopProgram();
|
|
return true;
|
|
}
|
|
|
|
if ( !m_object->GetSelect() ) // robot not selected?
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if ( m_secondaryTask != 0 ) // current task?
|
|
{
|
|
if ( action == EVENT_OBJECT_ENDSHIELD )
|
|
{
|
|
m_secondaryTask->StartTaskShield(TSM_DOWN, 0.0f);
|
|
}
|
|
}
|
|
if ( m_primaryTask != 0 || // current task?
|
|
m_program != -1 )
|
|
{
|
|
if ( action == EVENT_OBJECT_PROGRUN )
|
|
{
|
|
StopProgram();
|
|
}
|
|
if ( action == EVENT_OBJECT_PROGEDIT )
|
|
{
|
|
StartEditScript(m_selScript, m_main->GetScriptName());
|
|
}
|
|
if ( m_primaryTask == 0 || !m_primaryTask->IsPilot() ) return true;
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_LEFT ||
|
|
action == EVENT_OBJECT_RIGHT ||
|
|
action == EVENT_OBJECT_UP ||
|
|
action == EVENT_OBJECT_DOWN ||
|
|
action == EVENT_OBJECT_GASUP ||
|
|
action == EVENT_OBJECT_GASDOWN )
|
|
{
|
|
m_buttonAxe = action;
|
|
}
|
|
if ( action == EVENT_MOUSE_BUTTON_UP )
|
|
{
|
|
m_buttonAxe = EVENT_NULL;
|
|
}
|
|
|
|
axeX = event.motionInput.x;
|
|
axeY = event.motionInput.y;
|
|
axeZ = event.motionInput.z;
|
|
|
|
if ( !m_main->GetTrainerPilot() &&
|
|
m_object->GetTrainer() ) // 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->GetManual() ) // scribbler in manual mode?
|
|
{
|
|
if ( axeX != 0.0f ) axeY = 0.0f; // if running -> not moving!
|
|
axeX *= 0.5f;
|
|
axeY *= 0.5f;
|
|
}
|
|
|
|
if ( (g_researchDone&RESEARCH_FLY) == 0 )
|
|
{
|
|
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 ( action == EVENT_OBJECT_PROGLIST )
|
|
{
|
|
m_selScript = GetSelScript();
|
|
UpdateInterface();
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_PROGEDIT )
|
|
{
|
|
StartEditScript(m_selScript, m_main->GetScriptName());
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_PROGRUN )
|
|
{
|
|
StopProgram(); // stops the current program
|
|
RunProgram(m_selScript);
|
|
UpdateInterface();
|
|
}
|
|
|
|
err = ERR_OK;
|
|
|
|
if ( m_program == -1 )
|
|
{
|
|
if ( action == EVENT_OBJECT_HTAKE )
|
|
{
|
|
err = StartTaskTake();
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_MFRONT ||
|
|
action == EVENT_OBJECT_MBACK ||
|
|
action == EVENT_OBJECT_MPOWER )
|
|
{
|
|
m_manipStyle = action;
|
|
UpdateInterface();
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_MTAKE )
|
|
{
|
|
if ( m_manipStyle == EVENT_OBJECT_MFRONT )
|
|
{
|
|
err = StartTaskManip(TMO_AUTO, TMA_FFRONT);
|
|
}
|
|
if ( m_manipStyle == EVENT_OBJECT_MBACK )
|
|
{
|
|
err = StartTaskManip(TMO_AUTO, TMA_FBACK);
|
|
if ( err == ERR_OK )
|
|
{
|
|
m_manipStyle = EVENT_OBJECT_MFRONT;
|
|
UpdateInterface();
|
|
}
|
|
}
|
|
if ( m_manipStyle == EVENT_OBJECT_MPOWER )
|
|
{
|
|
err = StartTaskManip(TMO_AUTO, TMA_POWER);
|
|
if ( err == ERR_OK )
|
|
{
|
|
m_manipStyle = EVENT_OBJECT_MFRONT;
|
|
UpdateInterface();
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_BDERRICK )
|
|
{
|
|
err = StartTaskBuild(OBJECT_DERRICK);
|
|
}
|
|
if ( action == EVENT_OBJECT_BSTATION )
|
|
{
|
|
err = StartTaskBuild(OBJECT_STATION);
|
|
}
|
|
if ( action == EVENT_OBJECT_BFACTORY )
|
|
{
|
|
err = StartTaskBuild(OBJECT_FACTORY);
|
|
}
|
|
if ( action == EVENT_OBJECT_BREPAIR )
|
|
{
|
|
err = StartTaskBuild(OBJECT_REPAIR);
|
|
}
|
|
if ( action == EVENT_OBJECT_BCONVERT )
|
|
{
|
|
err = StartTaskBuild(OBJECT_CONVERT);
|
|
}
|
|
if ( action == EVENT_OBJECT_BTOWER )
|
|
{
|
|
err = StartTaskBuild(OBJECT_TOWER);
|
|
}
|
|
if ( action == EVENT_OBJECT_BRESEARCH )
|
|
{
|
|
err = StartTaskBuild(OBJECT_RESEARCH);
|
|
}
|
|
if ( action == EVENT_OBJECT_BRADAR )
|
|
{
|
|
err = StartTaskBuild(OBJECT_RADAR);
|
|
}
|
|
if ( action == EVENT_OBJECT_BENERGY )
|
|
{
|
|
err = StartTaskBuild(OBJECT_ENERGY);
|
|
}
|
|
if ( action == EVENT_OBJECT_BLABO )
|
|
{
|
|
err = StartTaskBuild(OBJECT_LABO);
|
|
}
|
|
if ( action == EVENT_OBJECT_BNUCLEAR )
|
|
{
|
|
err = StartTaskBuild(OBJECT_NUCLEAR);
|
|
}
|
|
if ( action == EVENT_OBJECT_BPARA )
|
|
{
|
|
err = StartTaskBuild(OBJECT_PARA);
|
|
}
|
|
if ( action == EVENT_OBJECT_BINFO )
|
|
{
|
|
err = StartTaskBuild(OBJECT_INFO);
|
|
}
|
|
if ( action == EVENT_OBJECT_BDESTROYER )
|
|
{
|
|
err = StartTaskBuild(OBJECT_DESTROYER);
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_GFLAT )
|
|
{
|
|
GroundFlat();
|
|
}
|
|
if ( action == EVENT_OBJECT_FCREATE )
|
|
{
|
|
err = StartTaskFlag(TFL_CREATE, m_flagColor);
|
|
}
|
|
if ( action == EVENT_OBJECT_FDELETE )
|
|
{
|
|
err = StartTaskFlag(TFL_DELETE, m_flagColor);
|
|
}
|
|
if ( action == EVENT_OBJECT_FCOLORb ||
|
|
action == EVENT_OBJECT_FCOLORr ||
|
|
action == EVENT_OBJECT_FCOLORg ||
|
|
action == EVENT_OBJECT_FCOLORy ||
|
|
action == EVENT_OBJECT_FCOLORv )
|
|
{
|
|
ColorFlag(action - EVENT_OBJECT_FCOLORb);
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_SEARCH )
|
|
{
|
|
err = StartTaskSearch();
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_TERRAFORM )
|
|
{
|
|
err = StartTaskTerraform();
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_RECOVER )
|
|
{
|
|
err = StartTaskRecover();
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_BEGSHIELD )
|
|
{
|
|
err = StartTaskShield(TSM_UP);
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_DIMSHIELD )
|
|
{
|
|
pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0));
|
|
if ( pw != 0 )
|
|
{
|
|
ps = static_cast< Ui::CSlider* >(pw->SearchControl(EVENT_OBJECT_DIMSHIELD));
|
|
if ( ps != 0 )
|
|
{
|
|
m_object->SetParam((ps->GetVisibleValue()-(RADIUS_SHIELD_MIN/g_unit))/((RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)/g_unit));
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_FIRE && m_primaryTask == 0 && !m_object->GetTrainer())
|
|
{
|
|
if ( m_camera->GetType() != Gfx::CAM_TYPE_ONBOARD )
|
|
{
|
|
m_camera->SetType(Gfx::CAM_TYPE_ONBOARD);
|
|
}
|
|
err = StartTaskFire(0.0f);
|
|
}
|
|
if ( action == EVENT_OBJECT_TARGET && !m_object->GetTrainer() )
|
|
{
|
|
err = StartTaskGunGoal((event.mousePos.y-0.50f)*1.3f, (event.mousePos.x-0.50f)*2.0f);
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_FIREANT )
|
|
{
|
|
//? err = StartTaskFireAnt();
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_SPIDEREXPLO && m_primaryTask == 0 )
|
|
{
|
|
err = StartTaskSpiderExplo();
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_PEN0 ) // up
|
|
{
|
|
err = StartTaskPen(false, m_object->GetTraceColor());
|
|
m_object->SetTraceDown(false);
|
|
}
|
|
if ( action == EVENT_OBJECT_PEN1 ) // black
|
|
{
|
|
err = StartTaskPen(true, 1);
|
|
m_object->SetTraceDown(true);
|
|
m_object->SetTraceColor(1);
|
|
}
|
|
if ( action == EVENT_OBJECT_PEN2 ) // yellow
|
|
{
|
|
err = StartTaskPen(true, 8);
|
|
m_object->SetTraceDown(true);
|
|
m_object->SetTraceColor(8);
|
|
}
|
|
if ( action == EVENT_OBJECT_PEN3 ) // orange
|
|
{
|
|
err = StartTaskPen(true, 7);
|
|
m_object->SetTraceDown(true);
|
|
m_object->SetTraceColor(7);
|
|
}
|
|
if ( action == EVENT_OBJECT_PEN4 ) // red
|
|
{
|
|
err = StartTaskPen(true, 4);
|
|
m_object->SetTraceDown(true);
|
|
m_object->SetTraceColor(4);
|
|
}
|
|
if ( action == EVENT_OBJECT_PEN5 ) // violet
|
|
{
|
|
err = StartTaskPen(true, 6);
|
|
m_object->SetTraceDown(true);
|
|
m_object->SetTraceColor(6);
|
|
}
|
|
if ( action == EVENT_OBJECT_PEN6 ) // blue
|
|
{
|
|
err = StartTaskPen(true, 14);
|
|
m_object->SetTraceDown(true);
|
|
m_object->SetTraceColor(14);
|
|
}
|
|
if ( action == EVENT_OBJECT_PEN7 ) // green
|
|
{
|
|
err = StartTaskPen(true, 12);
|
|
m_object->SetTraceDown(true);
|
|
m_object->SetTraceColor(12);
|
|
}
|
|
if ( action == EVENT_OBJECT_PEN8 ) // brown
|
|
{
|
|
err = StartTaskPen(true, 10);
|
|
m_object->SetTraceDown(true);
|
|
m_object->SetTraceColor(10);
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_REC ) // registered?
|
|
{
|
|
if ( m_bTraceRecord )
|
|
{
|
|
m_bTraceRecord = false;
|
|
TraceRecordStop();
|
|
}
|
|
else
|
|
{
|
|
m_bTraceRecord = true;
|
|
TraceRecordStart();
|
|
}
|
|
UpdateInterface();
|
|
pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0));
|
|
if ( pw != 0 )
|
|
{
|
|
UpdateScript(pw);
|
|
}
|
|
}
|
|
if ( action == EVENT_OBJECT_STOP ) // stops?
|
|
{
|
|
if ( m_bTraceRecord )
|
|
{
|
|
m_bTraceRecord = false;
|
|
TraceRecordStop();
|
|
}
|
|
UpdateInterface();
|
|
pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0));
|
|
if ( pw != 0 )
|
|
{
|
|
UpdateScript(pw);
|
|
}
|
|
}
|
|
|
|
if ( action == EVENT_OBJECT_RESET )
|
|
{
|
|
m_main->ResetObject(); // reset all objects
|
|
UpdateInterface();
|
|
}
|
|
|
|
#if 0
|
|
if ( event.param == 'T' )
|
|
{
|
|
Math::Vector p1, p2;
|
|
float h;
|
|
p1 = m_object->GetPosition(0);
|
|
h = m_terrain->GetFloorLevel(p1);
|
|
p2 = p1;
|
|
p1.x -= 20.0f;
|
|
p1.z -= 20.0f;
|
|
p2.x += 20.0f;
|
|
p2.z += 20.0f;
|
|
m_terrain->Terraform(p1, p2, h+1.0f);
|
|
}
|
|
if ( event.param == 'R' )
|
|
{
|
|
Math::Vector p1, p2;
|
|
float h;
|
|
p1 = m_object->GetPosition(0);
|
|
h = m_terrain->GetFloorLevel(p1);
|
|
p2 = p1;
|
|
p1.x -= 20.0f;
|
|
p1.z -= 20.0f;
|
|
p2.x += 20.0f;
|
|
p2.z += 20.0f;
|
|
m_terrain->Terraform(p1, p2, h-1.0f);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if ( err != ERR_OK )
|
|
{
|
|
m_main->DisplayError(err, m_object);
|
|
}
|
|
|
|
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_soundChannelAlarm != -1 )
|
|
{
|
|
m_sound->Position(m_soundChannelAlarm, m_object->GetPosition(0));
|
|
}
|
|
|
|
if ( m_studio != 0 ) // current edition?
|
|
{
|
|
m_studio->EventProcess(event);
|
|
}
|
|
|
|
UpdateInterface(event.rTime);
|
|
|
|
if ( m_engine->GetPause() ) return true;
|
|
if ( !m_bActivity ) return true; // expected if idle
|
|
if ( EndedTask() == ERR_CONTINUE ) return true; // expected if not finished ...
|
|
|
|
if ( m_program != -1 ) // current program?
|
|
{
|
|
if ( m_script[m_program]->Continue(event) )
|
|
{
|
|
StopProgram();
|
|
}
|
|
}
|
|
|
|
if ( m_bTraceRecord ) // registration of the design in progress?
|
|
{
|
|
TraceRecordFrame();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
// Stops the running program.
|
|
|
|
void CBrain::StopProgram()
|
|
{
|
|
StopTask();
|
|
|
|
if ( m_object->GetType() == OBJECT_HUMAN ||
|
|
m_object->GetType() == OBJECT_TECH ) return;
|
|
|
|
if ( m_program != -1 &&
|
|
m_script[m_program] != 0 )
|
|
{
|
|
m_script[m_program]->Stop();
|
|
}
|
|
|
|
BlinkScript(false); // stops flashing
|
|
|
|
m_program = -1;
|
|
|
|
m_physics->SetMotorSpeedX(0.0f);
|
|
m_physics->SetMotorSpeedY(0.0f);
|
|
m_physics->SetMotorSpeedZ(0.0f);
|
|
|
|
m_motion->SetAction(-1);
|
|
|
|
UpdateInterface();
|
|
m_main->UpdateShortcuts();
|
|
m_object->CreateSelectParticle();
|
|
}
|
|
|
|
// Stops the current task.
|
|
|
|
void CBrain::StopTask()
|
|
{
|
|
if ( m_primaryTask != 0 )
|
|
{
|
|
m_primaryTask->Abort();
|
|
delete m_primaryTask; // stops the current task
|
|
m_primaryTask = 0;
|
|
}
|
|
}
|
|
|
|
|
|
// Introduces a virus into a program.
|
|
// Returns true if it was inserted.
|
|
|
|
bool CBrain::IntroduceVirus()
|
|
{
|
|
int i, j;
|
|
|
|
for ( i=0 ; i<50 ; i++ )
|
|
{
|
|
j = rand()%BRAINMAXSCRIPT;
|
|
if ( m_script[j] != 0 )
|
|
{
|
|
if ( m_script[j]->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;
|
|
}
|
|
|
|
|
|
// Start editing a program.
|
|
|
|
void CBrain::StartEditScript(int rank, char* name)
|
|
{
|
|
CreateInterface(false); // removes the control buttons
|
|
|
|
if ( m_script[rank] == 0 )
|
|
{
|
|
m_script[rank] = new CScript(m_object, &m_secondaryTask);
|
|
}
|
|
|
|
m_studio = new Ui::CStudio();
|
|
m_studio->StartEditScript(m_script[rank], name, rank);
|
|
}
|
|
|
|
// End of editing a program.
|
|
|
|
void CBrain::StopEditScript(bool bCancel)
|
|
{
|
|
if ( !bCancel ) SetActiveVirus(false);
|
|
|
|
if ( !m_studio->StopEditScript(bCancel) ) return;
|
|
|
|
delete m_studio;
|
|
m_studio = 0;
|
|
|
|
CreateInterface(true); // puts the control buttons
|
|
}
|
|
|
|
|
|
|
|
// Move the manipulator arm.
|
|
|
|
Error CBrain::StartTaskTake()
|
|
{
|
|
Error err;
|
|
|
|
if ( m_primaryTask != 0 )
|
|
{
|
|
delete m_primaryTask; // stops the current task
|
|
m_primaryTask = 0;
|
|
}
|
|
|
|
m_primaryTask = new CTaskManager(m_object);
|
|
err = m_primaryTask->StartTaskTake();
|
|
UpdateInterface();
|
|
return err;
|
|
}
|
|
|
|
// Move the manipulator arm.
|
|
|
|
Error CBrain::StartTaskManip(TaskManipOrder order, TaskManipArm arm)
|
|
{
|
|
Error err;
|
|
|
|
if ( m_primaryTask != 0 )
|
|
{
|
|
delete m_primaryTask; // stops the current task
|
|
m_primaryTask = 0;
|
|
}
|
|
|
|
m_primaryTask = new CTaskManager(m_object);
|
|
err = m_primaryTask->StartTaskManip(order, arm);
|
|
UpdateInterface();
|
|
return err;
|
|
}
|
|
|
|
// Puts or removes a flag.
|
|
|
|
Error CBrain::StartTaskFlag(TaskFlagOrder order, int rank)
|
|
{
|
|
Error err;
|
|
|
|
if ( m_primaryTask != 0 )
|
|
{
|
|
delete m_primaryTask; // stops the current task
|
|
m_primaryTask = 0;
|
|
}
|
|
|
|
m_primaryTask = new CTaskManager(m_object);
|
|
err = m_primaryTask->StartTaskFlag(order, rank);
|
|
UpdateInterface();
|
|
return err;
|
|
}
|
|
|
|
// Built a building.
|
|
|
|
Error CBrain::StartTaskBuild(ObjectType type)
|
|
{
|
|
Error err;
|
|
|
|
if ( m_primaryTask != 0 )
|
|
{
|
|
delete m_primaryTask; // stops the current task
|
|
m_primaryTask = 0;
|
|
}
|
|
|
|
m_primaryTask = new CTaskManager(m_object);
|
|
err = m_primaryTask->StartTaskBuild(type);
|
|
UpdateInterface();
|
|
return err;
|
|
}
|
|
|
|
// Probe the ground.
|
|
|
|
Error CBrain::StartTaskSearch()
|
|
{
|
|
Error err;
|
|
|
|
if ( m_primaryTask != 0 )
|
|
{
|
|
delete m_primaryTask; // stops the current task
|
|
m_primaryTask = 0;
|
|
}
|
|
|
|
m_primaryTask = new CTaskManager(m_object);
|
|
err = m_primaryTask->StartTaskSearch();
|
|
UpdateInterface();
|
|
return err;
|
|
}
|
|
|
|
// Terraformed the ground.
|
|
|
|
Error CBrain::StartTaskTerraform()
|
|
{
|
|
Error err;
|
|
|
|
if ( m_primaryTask != 0 )
|
|
{
|
|
delete m_primaryTask; // stops the current task
|
|
m_primaryTask = 0;
|
|
}
|
|
|
|
m_primaryTask = new CTaskManager(m_object);
|
|
err = m_primaryTask->StartTaskTerraform();
|
|
UpdateInterface();
|
|
return err;
|
|
}
|
|
|
|
// Change pencil.
|
|
|
|
Error CBrain::StartTaskPen(bool bDown, int color)
|
|
{
|
|
Error err;
|
|
|
|
m_physics->SetMotorSpeedX(0.0f);
|
|
m_physics->SetMotorSpeedY(0.0f);
|
|
m_physics->SetMotorSpeedZ(0.0f);
|
|
|
|
if ( m_primaryTask != 0 )
|
|
{
|
|
delete m_primaryTask; // stops the current task
|
|
m_primaryTask = 0;
|
|
}
|
|
|
|
m_primaryTask = new CTaskManager(m_object);
|
|
err = m_primaryTask->StartTaskPen(bDown, color);
|
|
UpdateInterface();
|
|
return err;
|
|
}
|
|
|
|
// Recovers a ruin.
|
|
|
|
Error CBrain::StartTaskRecover()
|
|
{
|
|
Error err;
|
|
|
|
if ( m_primaryTask != 0 )
|
|
{
|
|
delete m_primaryTask; // stops the current task
|
|
m_primaryTask = 0;
|
|
}
|
|
|
|
m_primaryTask = new CTaskManager(m_object);
|
|
err = m_primaryTask->StartTaskRecover();
|
|
UpdateInterface();
|
|
return err;
|
|
}
|
|
|
|
// Deploys the shield.
|
|
|
|
Error CBrain::StartTaskShield(TaskShieldMode mode)
|
|
{
|
|
Error err;
|
|
|
|
if ( m_secondaryTask != 0 )
|
|
{
|
|
delete m_secondaryTask; // stops the current task
|
|
m_secondaryTask = 0;
|
|
}
|
|
|
|
m_secondaryTask = new CTaskManager(m_object);
|
|
err = m_secondaryTask->StartTaskShield(mode, 1000.0f);
|
|
UpdateInterface();
|
|
return err;
|
|
}
|
|
|
|
// Shoots.
|
|
|
|
Error CBrain::StartTaskFire(float delay)
|
|
{
|
|
Error err;
|
|
|
|
if ( m_primaryTask != 0 )
|
|
{
|
|
delete m_primaryTask; // stops the current task
|
|
m_primaryTask = 0;
|
|
}
|
|
|
|
m_primaryTask = new CTaskManager(m_object);
|
|
err = m_primaryTask->StartTaskFire(delay);
|
|
UpdateInterface();
|
|
return err;
|
|
}
|
|
|
|
// Explodes spider.
|
|
|
|
Error CBrain::StartTaskSpiderExplo()
|
|
{
|
|
Error err;
|
|
|
|
if ( m_primaryTask != 0 )
|
|
{
|
|
delete m_primaryTask; // stops the current task
|
|
m_primaryTask = 0;
|
|
}
|
|
|
|
m_primaryTask = new CTaskManager(m_object);
|
|
err = m_primaryTask->StartTaskSpiderExplo();
|
|
UpdateInterface();
|
|
return err;
|
|
}
|
|
|
|
// Shoots to the ant.
|
|
|
|
Error CBrain::StartTaskFireAnt(Math::Vector impact)
|
|
{
|
|
Error err;
|
|
|
|
if ( m_primaryTask != 0 )
|
|
{
|
|
delete m_primaryTask; // stops the current task
|
|
m_primaryTask = 0;
|
|
}
|
|
|
|
m_primaryTask = new CTaskManager(m_object);
|
|
err = m_primaryTask->StartTaskFireAnt(impact);
|
|
UpdateInterface();
|
|
return err;
|
|
}
|
|
|
|
// Adjusts upward.
|
|
|
|
Error CBrain::StartTaskGunGoal(float dirV, float dirH)
|
|
{
|
|
Error err;
|
|
|
|
if ( m_secondaryTask != 0 )
|
|
{
|
|
delete m_secondaryTask; // stops the current task
|
|
m_secondaryTask = 0;
|
|
}
|
|
|
|
m_secondaryTask = new CTaskManager(m_object);
|
|
err = m_secondaryTask->StartTaskGunGoal(dirV, dirH);
|
|
UpdateInterface();
|
|
return err;
|
|
}
|
|
|
|
// Reset.
|
|
|
|
Error CBrain::StartTaskReset(Math::Vector goal, Math::Vector angle)
|
|
{
|
|
Error err;
|
|
|
|
if ( m_primaryTask != 0 )
|
|
{
|
|
delete m_primaryTask; // stops the current task
|
|
m_primaryTask = 0;
|
|
}
|
|
|
|
m_primaryTask = new CTaskManager(m_object);
|
|
err = m_primaryTask->StartTaskReset(goal, angle);
|
|
UpdateInterface();
|
|
return err;
|
|
}
|
|
|
|
// Completes the task when the time came.
|
|
|
|
Error CBrain::EndedTask()
|
|
{
|
|
Error err;
|
|
|
|
if ( m_secondaryTask != 0 ) // current task?
|
|
{
|
|
err = m_secondaryTask->IsEnded();
|
|
if ( err != ERR_CONTINUE ) // job ended?
|
|
{
|
|
delete m_secondaryTask;
|
|
m_secondaryTask = 0;
|
|
UpdateInterface();
|
|
}
|
|
}
|
|
|
|
if ( m_primaryTask != 0 ) // current task?
|
|
{
|
|
err = m_primaryTask->IsEnded();
|
|
if ( err != ERR_CONTINUE ) // job ended?
|
|
{
|
|
delete m_primaryTask;
|
|
m_primaryTask = 0;
|
|
UpdateInterface();
|
|
}
|
|
return err;
|
|
}
|
|
return ERR_STOP;
|
|
}
|
|
|
|
|
|
|
|
// Shows flat areas in the field.
|
|
|
|
void CBrain::GroundFlat()
|
|
{
|
|
Math::Vector pos, speed;
|
|
Math::Point dim;
|
|
Error err;
|
|
float level;
|
|
|
|
if ( !m_physics->GetLand() )
|
|
{
|
|
err = ERR_FLAG_FLY;
|
|
pos = m_object->GetPosition(0);
|
|
if ( pos.y < m_water->GetLevel() ) err = ERR_FLAG_WATER;
|
|
m_main->DisplayError(err, m_object);
|
|
return;
|
|
}
|
|
|
|
pos = m_object->GetPosition(0);
|
|
m_terrain->ShowFlatGround(pos);
|
|
m_sound->Play(SOUND_GFLAT, pos);
|
|
|
|
level = m_terrain->GetFloorLevel(pos)+2.0f;
|
|
if ( pos.y < level ) pos.y = level; // not below the soil
|
|
speed = Math::Vector(0.0f, 0.0f, 0.0f);
|
|
dim.x = 40.0f;
|
|
dim.y = dim.x;
|
|
m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGFLAT, 1.0f);
|
|
}
|
|
|
|
|
|
// Not below the soil.
|
|
|
|
void CBrain::ColorFlag(int color)
|
|
{
|
|
m_flagColor = color;
|
|
UpdateInterface();
|
|
}
|
|
|
|
|
|
// Creates all the interface when the object is selected.
|
|
|
|
bool CBrain::CreateInterface(bool bSelect)
|
|
{
|
|
ObjectType type;
|
|
Ui::CWindow* pw;
|
|
Ui::CButton* pb;
|
|
Ui::CSlider* ps;
|
|
Ui::CColor* pc;
|
|
Ui::CTarget* pt;
|
|
Ui::CLabel* pl;
|
|
Math::Point pos, dim, ddim;
|
|
float ox, oy, sx, sy;
|
|
|
|
pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0));
|
|
if ( pw != 0 )
|
|
{
|
|
pw->Flush(); // destroys the window buttons
|
|
m_interface->DeleteControl(EVENT_WINDOW0); // destroys the window
|
|
}
|
|
m_defaultEnter = EVENT_NULL;
|
|
|
|
if ( !bSelect ) return true;
|
|
|
|
pos.x = 0.0f;
|
|
pos.y = 0.0f;
|
|
dim.x = 540.0f/640.0f;
|
|
if ( !m_main->GetShowMap() ) dim.x = 640.0f/640.0f;
|
|
dim.y = 86.0f/480.0f;
|
|
m_interface->CreateWindows(pos, dim, 3, EVENT_WINDOW0);
|
|
pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0));
|
|
if ( pw == 0 ) return false;
|
|
|
|
std::string tooltipLabel;
|
|
m_object->GetTooltipName(tooltipLabel);
|
|
pos.x = 0.0f;
|
|
pos.y = 64.0f/480.0f;
|
|
ddim.x = 540.0f/640.0f;
|
|
if ( !m_main->GetShowMap() ) ddim.x = 640.0f/640.0f;
|
|
ddim.y = 16.0f/480.0f;
|
|
pw->CreateLabel(pos, ddim, 0, EVENT_LABEL0, tooltipLabel);
|
|
|
|
dim.x = 33.0f/640.0f;
|
|
dim.y = 33.0f/480.0f;
|
|
ox = 3.0f/640.0f;
|
|
oy = 3.0f/480.0f;
|
|
sx = 33.0f/640.0f;
|
|
sy = 33.0f/480.0f;
|
|
|
|
type = m_object->GetType();
|
|
|
|
if ( type == OBJECT_MOBILEfa ||
|
|
type == OBJECT_MOBILEta ||
|
|
type == OBJECT_MOBILEwa ||
|
|
type == OBJECT_MOBILEia ||
|
|
type == OBJECT_MOBILEfc ||
|
|
type == OBJECT_MOBILEtc ||
|
|
type == OBJECT_MOBILEwc ||
|
|
type == OBJECT_MOBILEic ||
|
|
type == OBJECT_MOBILEfi ||
|
|
type == OBJECT_MOBILEti ||
|
|
type == OBJECT_MOBILEwi ||
|
|
type == OBJECT_MOBILEii ||
|
|
type == OBJECT_MOBILEfs ||
|
|
type == OBJECT_MOBILEts ||
|
|
type == OBJECT_MOBILEws ||
|
|
type == OBJECT_MOBILEis ||
|
|
type == OBJECT_MOBILErt ||
|
|
type == OBJECT_MOBILErc ||
|
|
type == OBJECT_MOBILErr ||
|
|
type == OBJECT_MOBILErs ||
|
|
type == OBJECT_MOBILEsa ||
|
|
type == OBJECT_MOBILEtg ||
|
|
type == OBJECT_MOBILEft ||
|
|
type == OBJECT_MOBILEtt ||
|
|
type == OBJECT_MOBILEwt ||
|
|
type == OBJECT_MOBILEit ||
|
|
type == OBJECT_MOBILEdr ||
|
|
type == OBJECT_MOTHER ||
|
|
type == OBJECT_ANT ||
|
|
type == OBJECT_SPIDER ||
|
|
type == OBJECT_BEE ||
|
|
type == OBJECT_WORM ||
|
|
type == OBJECT_CONTROLLER) // vehicle?
|
|
{
|
|
if (!(m_main->GetRetroMode()))
|
|
{
|
|
ddim.x = dim.x*5.1f;
|
|
ddim.y = dim.y*2.0f; // default => 2
|
|
pos.x = ox+sx*0.0f;
|
|
pos.y = oy+sy*0.0f;
|
|
|
|
pw->CreateList(pos, ddim, -1, EVENT_OBJECT_PROGLIST, -1.10f);
|
|
UpdateScript(pw);
|
|
|
|
pos.x = ox+sx*5.2f;
|
|
pos.y = oy+sy*1.0f;
|
|
pw->CreateButton(pos, dim, 8, EVENT_OBJECT_PROGRUN);
|
|
pos.y = oy+sy*0.0f;
|
|
pw->CreateButton(pos, dim, 22, EVENT_OBJECT_PROGEDIT);
|
|
}
|
|
}
|
|
|
|
if ( type == OBJECT_HUMAN ||
|
|
type == OBJECT_MOBILEfa ||
|
|
type == OBJECT_MOBILEfc ||
|
|
type == OBJECT_MOBILEfi ||
|
|
type == OBJECT_MOBILEfs ||
|
|
type == OBJECT_MOBILEft ||
|
|
type == OBJECT_BEE ||
|
|
type == OBJECT_CONTROLLER) // driving?
|
|
{
|
|
pos.x = ox+sx*6.4f;
|
|
pos.y = oy+sy*0;
|
|
pb = pw->CreateButton(pos, dim, 29, EVENT_OBJECT_GASDOWN);
|
|
pb->SetImmediat(true);
|
|
|
|
pos.x = ox+sx*6.4f;
|
|
pos.y = oy+sy*1;
|
|
pb = pw->CreateButton(pos, dim, 28, EVENT_OBJECT_GASUP);
|
|
pb->SetImmediat(true);
|
|
|
|
if ( (type != OBJECT_HUMAN &&
|
|
type != OBJECT_CONTROLLER) ||
|
|
m_object->GetOption() != 2 )
|
|
{
|
|
pos.x = ox+sx*15.3f;
|
|
pos.y = oy+sy*0;
|
|
ddim.x = 14.0f/640.0f;
|
|
ddim.y = 66.0f/480.0f;
|
|
pw->CreateGauge(pos, ddim, 2, EVENT_OBJECT_GRANGE);
|
|
}
|
|
}
|
|
|
|
if ( type == OBJECT_HUMAN ||
|
|
type == OBJECT_TECH )
|
|
{
|
|
pos.x = ox+sx*7.7f;
|
|
pos.y = oy+sy*0.5f;
|
|
pw->CreateButton(pos, dim, 31, EVENT_OBJECT_HTAKE);
|
|
DefaultEnter(pw, EVENT_OBJECT_HTAKE);
|
|
}
|
|
|
|
if ( (type == OBJECT_MOBILEfa ||
|
|
type == OBJECT_MOBILEta ||
|
|
type == OBJECT_MOBILEwa ||
|
|
type == OBJECT_MOBILEia ) && // arm?
|
|
!m_object->GetTrainer() )
|
|
{
|
|
pos.x = ox+sx*7.7f;
|
|
pos.y = oy+sy*0.5f;
|
|
pw->CreateButton(pos, dim, 32, EVENT_OBJECT_MTAKE);
|
|
DefaultEnter(pw, EVENT_OBJECT_MTAKE);
|
|
|
|
pos.x = ox+sx*8.9f;
|
|
pos.y = oy+sy*0.5f;
|
|
pw->CreateButton(pos, dim, 34, EVENT_OBJECT_MBACK);
|
|
|
|
pos.x = ox+sx*9.9f;
|
|
pos.y = oy+sy*0.5f;
|
|
pw->CreateButton(pos, dim, 35, EVENT_OBJECT_MPOWER);
|
|
|
|
pos.x = ox+sx*10.9f;
|
|
pos.y = oy+sy*0.5f;
|
|
pw->CreateButton(pos, dim, 33, EVENT_OBJECT_MFRONT);
|
|
}
|
|
|
|
if ( ( type == OBJECT_MOBILEsa && // underwater?
|
|
!m_object->GetTrainer() ) ||
|
|
type == OBJECT_BEE )
|
|
{
|
|
pos.x = ox+sx*7.7f;
|
|
pos.y = oy+sy*0.5f;
|
|
pw->CreateButton(pos, dim, 32, EVENT_OBJECT_MTAKE);
|
|
DefaultEnter(pw, EVENT_OBJECT_MTAKE);
|
|
}
|
|
|
|
if ( type == OBJECT_HUMAN ) // builder?
|
|
{
|
|
pos.x = 1.0f/640.0f;
|
|
pos.y = 4.0f/480.0f;
|
|
ddim.x = 212.0f/640.0f;
|
|
ddim.y = 64.0f/480.0f;
|
|
pw->CreateGroup(pos, ddim, 27, EVENT_NULL);
|
|
|
|
ddim.x = dim.x*0.9f;
|
|
ddim.y = dim.y*0.9f;
|
|
|
|
pos.x = ox+sx*0.0f;
|
|
pos.y = oy+sy*1.0f;
|
|
pw->CreateButton(pos, ddim, 128+35, EVENT_OBJECT_BRESEARCH);
|
|
DeadInterface(pw, EVENT_OBJECT_BRESEARCH, g_build&BUILD_RESEARCH);
|
|
|
|
pos.x = ox+sx*0.9f;
|
|
pos.y = oy+sy*1.0f;
|
|
pw->CreateButton(pos, ddim, 128+32, EVENT_OBJECT_BFACTORY);
|
|
DeadInterface(pw, EVENT_OBJECT_BFACTORY, g_build&BUILD_FACTORY);
|
|
|
|
pos.x = ox+sx*1.8f;
|
|
pos.y = oy+sy*1.0f;
|
|
pw->CreateButton(pos, ddim, 128+34, EVENT_OBJECT_BCONVERT);
|
|
DeadInterface(pw, EVENT_OBJECT_BCONVERT, g_build&BUILD_CONVERT);
|
|
|
|
pos.x = ox+sx*2.7f;
|
|
pos.y = oy+sy*1.0f;
|
|
pw->CreateButton(pos, ddim, 128+36, EVENT_OBJECT_BSTATION);
|
|
DeadInterface(pw, EVENT_OBJECT_BSTATION, g_build&BUILD_STATION);
|
|
|
|
pos.x = ox+sx*3.6f;
|
|
pos.y = oy+sy*1.0f;
|
|
pw->CreateButton(pos, ddim, 128+40, EVENT_OBJECT_BRADAR);
|
|
DeadInterface(pw, EVENT_OBJECT_BRADAR, g_build&BUILD_RADAR);
|
|
|
|
pos.x = ox+sx*4.5f;
|
|
pos.y = oy+sy*1.0f;
|
|
pw->CreateButton(pos, ddim, 128+41, EVENT_OBJECT_BREPAIR);
|
|
DeadInterface(pw, EVENT_OBJECT_BREPAIR, g_build&BUILD_REPAIR);
|
|
|
|
pos.x = ox+sx*5.4f;
|
|
pos.y = oy+sy*1.0f;
|
|
pw->CreateButton(pos, ddim, 128+44, EVENT_OBJECT_BINFO);
|
|
DeadInterface(pw, EVENT_OBJECT_BINFO, g_build&BUILD_INFO);
|
|
|
|
pos.x = ox+sx*0.0f;
|
|
pos.y = oy+sy*0.1f;
|
|
pw->CreateButton(pos, ddim, 128+37, EVENT_OBJECT_BTOWER);
|
|
DeadInterface(pw, EVENT_OBJECT_BTOWER,
|
|
(g_build&BUILD_TOWER) &&
|
|
(g_researchDone & RESEARCH_TOWER));
|
|
|
|
pos.x = ox+sx*0.9f;
|
|
pos.y = oy+sy*0.1f;
|
|
pw->CreateButton(pos, ddim, 128+39, EVENT_OBJECT_BENERGY);
|
|
DeadInterface(pw, EVENT_OBJECT_BENERGY, g_build&BUILD_ENERGY);
|
|
|
|
pos.x = ox+sx*1.8f;
|
|
pos.y = oy+sy*0.1f;
|
|
pw->CreateButton(pos, ddim, 128+33, EVENT_OBJECT_BDERRICK);
|
|
DeadInterface(pw, EVENT_OBJECT_BDERRICK, g_build&BUILD_DERRICK);
|
|
|
|
pos.x = ox+sx*2.7f;
|
|
pos.y = oy+sy*0.1f;
|
|
pw->CreateButton(pos, ddim, 128+42, EVENT_OBJECT_BNUCLEAR);
|
|
DeadInterface(pw, EVENT_OBJECT_BNUCLEAR,
|
|
(g_build&BUILD_NUCLEAR) &&
|
|
(g_researchDone & RESEARCH_ATOMIC));
|
|
|
|
pos.x = ox+sx*3.6f;
|
|
pos.y = oy+sy*0.1f;
|
|
pw->CreateButton(pos, ddim, 128+38, EVENT_OBJECT_BLABO);
|
|
DeadInterface(pw, EVENT_OBJECT_BLABO, g_build&BUILD_LABO);
|
|
|
|
pos.x = ox+sx*4.5f;
|
|
pos.y = oy+sy*0.1f;
|
|
pw->CreateButton(pos, ddim, 128+46, EVENT_OBJECT_BPARA);
|
|
DeadInterface(pw, EVENT_OBJECT_BPARA, g_build&BUILD_PARA);
|
|
|
|
pos.x = ox+sx*5.4f;
|
|
pos.y = oy+sy*0.1f;
|
|
pw->CreateButton(pos, ddim, 128+41, EVENT_OBJECT_BDESTROYER);
|
|
DeadInterface(pw, EVENT_OBJECT_BDESTROYER, g_build&BUILD_DESTROYER);
|
|
|
|
if ( g_build&BUILD_GFLAT )
|
|
{
|
|
pos.x = ox+sx*9.0f;
|
|
pos.y = oy+sy*0.5f;
|
|
pw->CreateButton(pos, dim, 64+47, EVENT_OBJECT_GFLAT);
|
|
}
|
|
|
|
if ( g_build&BUILD_FLAG )
|
|
{
|
|
pos.x = ox+sx*10.1f;
|
|
pos.y = oy+sy*0.5f;
|
|
pw->CreateButton(pos, dim, 64+54, EVENT_OBJECT_FCREATE);
|
|
|
|
pos.x = ox+sx*11.1f;
|
|
pos.y = oy+sy*0.5f;
|
|
pw->CreateButton(pos, dim, 64+55, EVENT_OBJECT_FDELETE);
|
|
|
|
ddim.x = dim.x*0.4f;
|
|
ddim.y = dim.y*0.4f;
|
|
pos.x = ox+sx*10.1f;
|
|
pos.y = oy+sy*2.0f-ddim.y;
|
|
pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_FCOLORb);
|
|
pc->SetColor(Gfx::Color(0.28f, 0.56f, 1.0f, 0.0f));
|
|
pos.x += ddim.x;
|
|
pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_FCOLORr);
|
|
pc->SetColor(Gfx::Color(1.0f, 0.0f, 0.0f, 0.0f));
|
|
pos.x += ddim.x;
|
|
pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_FCOLORg);
|
|
pc->SetColor(Gfx::Color(0.0f, 0.8f, 0.0f, 0.0f));
|
|
pos.x += ddim.x;
|
|
pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_FCOLORy);
|
|
pc->SetColor(Gfx::Color(1.0f, 0.93f, 0.0f, 0.0f)); //0x00ffec00
|
|
pos.x += ddim.x;
|
|
pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_FCOLORv);
|
|
pc->SetColor(Gfx::Color(0.82f, 0.004f, 0.99f, 0.0f)); //0x00d101fe
|
|
}
|
|
}
|
|
|
|
if ( (type == OBJECT_MOBILEfs ||
|
|
type == OBJECT_MOBILEts ||
|
|
type == OBJECT_MOBILEws ||
|
|
type == OBJECT_MOBILEis ) && // Investigator?
|
|
!m_object->GetTrainer() )
|
|
{
|
|
pos.x = ox+sx*7.7f;
|
|
pos.y = oy+sy*0.5f;
|
|
pw->CreateButton(pos, dim, 40, EVENT_OBJECT_SEARCH);
|
|
DefaultEnter(pw, EVENT_OBJECT_SEARCH);
|
|
}
|
|
|
|
if ( type == OBJECT_MOBILErt && // Terraformer?
|
|
!m_object->GetTrainer() )
|
|
{
|
|
pos.x = ox+sx*7.7f;
|
|
pos.y = oy+sy*0.5f;
|
|
pw->CreateButton(pos, dim, 128+18, EVENT_OBJECT_TERRAFORM);
|
|
DefaultEnter(pw, EVENT_OBJECT_TERRAFORM);
|
|
|
|
pos.x = ox+sx*10.2f;
|
|
pos.y = oy+sy*0.5f;
|
|
pw->CreateButton(pos, dim, 41, EVENT_OBJECT_LIMIT);
|
|
}
|
|
|
|
if ( type == OBJECT_MOBILErr && // recoverer?
|
|
!m_object->GetTrainer() )
|
|
{
|
|
pos.x = ox+sx*7.7f;
|
|
pos.y = oy+sy*0.5f;
|
|
pw->CreateButton(pos, dim, 128+20, EVENT_OBJECT_RECOVER);
|
|
DefaultEnter(pw, EVENT_OBJECT_RECOVER);
|
|
}
|
|
|
|
if ( type == OBJECT_MOBILErs && // shield?
|
|
!m_object->GetTrainer() )
|
|
{
|
|
pos.x = ox+sx*7.7f;
|
|
pos.y = oy+sy*0.5f;
|
|
pw->CreateButton(pos, dim, 39, EVENT_OBJECT_BEGSHIELD);
|
|
DefaultEnter(pw, EVENT_OBJECT_BEGSHIELD);
|
|
|
|
pos.x = ox+sx*9.0f;
|
|
pos.y = oy+sy*0.5f;
|
|
pw->CreateButton(pos, dim, 47, EVENT_OBJECT_ENDSHIELD);
|
|
|
|
//? pos.x = ox+sx*10.2f;
|
|
//? pos.y = oy+sy*0.5f;
|
|
//? pw->CreateButton(pos, dim, 41, EVENT_OBJECT_LIMIT);
|
|
|
|
pos.x = ox+sx*10.5f;
|
|
pos.y = oy+sy*0.0f;
|
|
ddim.x = dim.x*0.5f;
|
|
ddim.y = dim.y*2.0f;
|
|
ps = pw->CreateSlider(pos, ddim, 0, EVENT_OBJECT_DIMSHIELD);
|
|
ps->SetState(Ui::STATE_VALUE);
|
|
ps->SetLimit((RADIUS_SHIELD_MIN/g_unit), (RADIUS_SHIELD_MAX/g_unit));
|
|
ps->SetArrowStep(1.0f);
|
|
}
|
|
|
|
if ( (type == OBJECT_MOBILEfc ||
|
|
type == OBJECT_MOBILEtc ||
|
|
type == OBJECT_MOBILEwc ||
|
|
type == OBJECT_MOBILEic ||
|
|
type == OBJECT_MOBILEfi ||
|
|
type == OBJECT_MOBILEti ||
|
|
type == OBJECT_MOBILEwi ||
|
|
type == OBJECT_MOBILEii ||
|
|
type == OBJECT_MOBILErc ) && // cannon?
|
|
!m_object->GetTrainer() )
|
|
{
|
|
pos.x = ox+sx*7.7f;
|
|
pos.y = oy+sy*0.5f;
|
|
pb = pw->CreateButton(pos, dim, 42, EVENT_OBJECT_FIRE);
|
|
pb->SetImmediat(true);
|
|
DefaultEnter(pw, EVENT_OBJECT_FIRE);
|
|
|
|
//? pos.x = ox+sx*10.2f;
|
|
//? pos.y = oy+sy*0.5f;
|
|
//? pw->CreateButton(pos, dim, 41, EVENT_OBJECT_LIMIT);
|
|
}
|
|
|
|
if ( type == OBJECT_SPIDER )
|
|
{
|
|
pos.x = ox+sx*7.7f;
|
|
pos.y = oy+sy*0.5f;
|
|
pb = pw->CreateButton(pos, dim, 42, EVENT_OBJECT_SPIDEREXPLO);
|
|
pb->SetImmediat(true);
|
|
DefaultEnter(pw, EVENT_OBJECT_SPIDEREXPLO);
|
|
}
|
|
|
|
if ( type == OBJECT_MOBILEdr &&
|
|
m_object->GetManual() ) // scribbler in manual mode?
|
|
{
|
|
pos.x = ox+sx*6.9f;
|
|
pos.y = oy+sy*0.0f;
|
|
ddim.x = dim.x*2.2f;
|
|
ddim.y = dim.y*2.0f;
|
|
pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue bottom
|
|
|
|
pos.x = ox+sx*9.3f;
|
|
pos.y = oy+sy*0.0f;
|
|
ddim.x = dim.x*2.2f;
|
|
ddim.y = dim.y*2.0f;
|
|
pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue bottom
|
|
|
|
pos.x = ox+sx*9.90f;
|
|
pos.y = oy+sy*0.50f;
|
|
pw->CreateButton(pos, dim, 43, EVENT_OBJECT_PEN0);
|
|
|
|
ddim.x = dim.x*0.5f;
|
|
ddim.y = dim.y*0.5f;
|
|
pos.x = ox+sx*10.15f;
|
|
pos.y = oy+sy*1.50f;
|
|
pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN1); // black
|
|
pc->SetColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f));
|
|
pos.x = ox+sx*10.65f;
|
|
pos.y = oy+sy*1.25f;
|
|
pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN2); // yellow
|
|
pc->SetColor(Gfx::Color(1.0f, 1.0f, 0.0f, 0.0f ));
|
|
pos.x = ox+sx*10.90f;
|
|
pos.y = oy+sy*0.75f;
|
|
pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN3); // orange
|
|
pc->SetColor(Gfx::Color(1.0f, 0.53f, 0x00, 0x00));
|
|
pos.x = ox+sx*10.65f;
|
|
pos.y = oy+sy*0.25f;
|
|
pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN4); // red
|
|
pc->SetColor(Gfx::Color(1.0f, 0.0f, 0.0f, 0.0f));
|
|
pos.x = ox+sx*10.15f;
|
|
pos.y = oy+sy*0.00f;
|
|
pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN5); // violet
|
|
pc->SetColor(Gfx::Color(1.0f, 0.0f, 1.0f, 0.0f));
|
|
pos.x = ox+sx*9.65f;
|
|
pos.y = oy+sy*0.25f;
|
|
pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN6); // blue
|
|
pc->SetColor(Gfx::Color(0.0f, 0.4f, 1.0f, 0.0f));//0x000066ff));
|
|
pos.x = ox+sx*9.40f;
|
|
pos.y = oy+sy*0.75f;
|
|
pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN7); // green
|
|
pc->SetColor(Gfx::Color(0.0f, 0.0f, 0.8f, 0.0f));//0x0000cc00));
|
|
pos.x = ox+sx*9.65f;
|
|
pos.y = oy+sy*1.25f;
|
|
pc = pw->CreateColor(pos, ddim, -1, EVENT_OBJECT_PEN8); // brown
|
|
pc->SetColor(Gfx::Color(0.53f, 0.27f, 0.0f, 0.0f));//0x00884400));
|
|
|
|
pos.x = ox+sx*6.9f;
|
|
pos.y = oy+sy*1.2f;
|
|
ddim.x = dim.x*2.2f;
|
|
ddim.y = dim.y*0.4f;
|
|
|
|
std::string recordLabel;
|
|
GetResource(RES_TEXT, RT_INTERFACE_REC, recordLabel);
|
|
pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, recordLabel);
|
|
pl->SetFontSize(9.0f);
|
|
|
|
pos.x = ox+sx*7.0f;
|
|
pos.y = oy+sy*0.3f;
|
|
pw->CreateButton(pos, dim, 44, EVENT_OBJECT_REC);
|
|
pos.x = ox+sx*8.0f;
|
|
pos.y = oy+sy*0.3f;
|
|
pw->CreateButton(pos, dim, 45, EVENT_OBJECT_STOP);
|
|
}
|
|
|
|
if ( m_object->GetToy() )
|
|
{
|
|
pos.x = ox+sx*12.1f;
|
|
pos.y = oy+sy*-0.1f;
|
|
ddim.x = dim.x*1.2f;
|
|
ddim.y = dim.y*2.1f;
|
|
pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue bottom
|
|
|
|
pos.x = ox+sx*12.2f;
|
|
pos.y = oy+sy*1;
|
|
pw->CreateGroup(pos, dim, 19, EVENT_NULL); // sign SatCom
|
|
|
|
pos.x = ox+sx*12.2f;
|
|
pos.y = oy+sy*0.0f;
|
|
pw->CreateButton(pos, dim, 128+57, EVENT_OBJECT_BHELP);
|
|
}
|
|
else
|
|
{
|
|
pos.x = ox+sx*12.3f;
|
|
pos.y = oy+sy*-0.1f;
|
|
ddim.x = dim.x*1.0f;
|
|
ddim.y = dim.y*2.1f;
|
|
pw->CreateGroup(pos, ddim, 20, EVENT_NULL); // solid blue bottom
|
|
|
|
pos.x = ox+sx*12.3f;
|
|
pos.y = oy+sy*1;
|
|
pw->CreateGroup(pos, dim, 19, EVENT_NULL); // sign SatCom
|
|
|
|
pos.x = ox+sx*12.4f;
|
|
pos.y = oy+sy*0.5f;
|
|
ddim.x = dim.x*0.8f;
|
|
ddim.y = dim.y*0.5f;
|
|
pw->CreateButton(pos, ddim, 18, EVENT_OBJECT_BHELP);
|
|
pos.y = oy+sy*0.0f;
|
|
pw->CreateButton(pos, ddim, 19, EVENT_OBJECT_HELP);
|
|
}
|
|
|
|
if ( type != OBJECT_HUMAN &&
|
|
type != OBJECT_TECH &&
|
|
!m_object->GetCameraLock() )
|
|
{
|
|
//? if ( m_main->GetShowMap() )
|
|
if ( true )
|
|
{
|
|
pos.x = ox+sx*13.4f;
|
|
pos.y = oy+sy*1;
|
|
pw->CreateButton(pos, dim, 13, EVENT_OBJECT_CAMERA);
|
|
}
|
|
else
|
|
{
|
|
ddim.x = dim.x*0.66f;
|
|
ddim.y = dim.y*0.66f;
|
|
pos.x = ox+sx*(17.0f+0.66f);
|
|
pos.y = oy+sy*0.66f;
|
|
pw->CreateButton(pos, ddim, 13, EVENT_OBJECT_CAMERA);
|
|
}
|
|
}
|
|
|
|
if ( m_object->GetToy() && !m_object->GetManual() )
|
|
{
|
|
#if 0
|
|
ddim.x = dim.x*0.66f;
|
|
ddim.y = dim.y*0.66f;
|
|
pos.x = ox+sx*10.0f;
|
|
pos.y = oy+sy*0.66f;
|
|
pb = pw->CreateButton(pos, ddim, 55, EVENT_OBJECT_CAMERAleft);
|
|
pb->SetImmediat(true);
|
|
pos.x = ox+sx*(10.0f+0.66f*2.0f);
|
|
pos.y = oy+sy*0.66f;
|
|
pb = pw->CreateButton(pos, ddim, 48, EVENT_OBJECT_CAMERAright);
|
|
pb->SetImmediat(true);
|
|
pos.x = ox+sx*(10.0f+0.66f);
|
|
pos.y = oy+sy*(0.66f*2.0f);
|
|
pb = pw->CreateButton(pos, ddim, 49, EVENT_OBJECT_CAMERAnear);
|
|
pb->SetImmediat(true);
|
|
pos.x = ox+sx*(10.0f+0.66f);
|
|
pos.y = oy+sy*0.0f;
|
|
pb = pw->CreateButton(pos, ddim, 50, EVENT_OBJECT_CAMERAaway);
|
|
pb->SetImmediat(true);
|
|
#else
|
|
pos.x = ox+sx*9.0f;
|
|
pos.y = oy+sy*0;
|
|
pb = pw->CreateButton(pos, dim, 55, EVENT_OBJECT_CAMERAleft);
|
|
pb->SetImmediat(true);
|
|
pos.x = ox+sx*11.0f;
|
|
pos.y = oy+sy*0;
|
|
pb = pw->CreateButton(pos, dim, 48, EVENT_OBJECT_CAMERAright);
|
|
pb->SetImmediat(true);
|
|
pos.x = ox+sx*10.0f;
|
|
pos.y = oy+sy*1;
|
|
pb = pw->CreateButton(pos, dim, 49, EVENT_OBJECT_CAMERAnear);
|
|
pb->SetImmediat(true);
|
|
pos.x = ox+sx*10.0f;
|
|
pos.y = oy+sy*0;
|
|
pb = pw->CreateButton(pos, dim, 50, EVENT_OBJECT_CAMERAaway);
|
|
pb->SetImmediat(true);
|
|
#endif
|
|
}
|
|
|
|
pos.x = ox+sx*13.4f;
|
|
pos.y = oy+sy*0;
|
|
if ( m_object->GetTrainer() ) // Training?
|
|
{
|
|
pw->CreateButton(pos, dim, 9, EVENT_OBJECT_RESET);
|
|
}
|
|
else
|
|
{
|
|
pw->CreateButton(pos, dim, 10, EVENT_OBJECT_DESELECT);
|
|
}
|
|
|
|
if ( type == OBJECT_MOBILEfa ||
|
|
type == OBJECT_MOBILEta ||
|
|
type == OBJECT_MOBILEwa ||
|
|
type == OBJECT_MOBILEia ||
|
|
type == OBJECT_MOBILEfc ||
|
|
type == OBJECT_MOBILEtc ||
|
|
type == OBJECT_MOBILEwc ||
|
|
type == OBJECT_MOBILEic ||
|
|
type == OBJECT_MOBILEfi ||
|
|
type == OBJECT_MOBILEti ||
|
|
type == OBJECT_MOBILEwi ||
|
|
type == OBJECT_MOBILEii ||
|
|
type == OBJECT_MOBILEfs ||
|
|
type == OBJECT_MOBILEts ||
|
|
type == OBJECT_MOBILEws ||
|
|
type == OBJECT_MOBILEis ||
|
|
type == OBJECT_MOBILErt ||
|
|
type == OBJECT_MOBILErc ||
|
|
type == OBJECT_MOBILErr ||
|
|
type == OBJECT_MOBILErs ||
|
|
type == OBJECT_MOBILEsa ||
|
|
type == OBJECT_MOBILEft ||
|
|
type == OBJECT_MOBILEtt ||
|
|
type == OBJECT_MOBILEwt ||
|
|
type == OBJECT_MOBILEit ) // vehicle?
|
|
{
|
|
pos.x = ox+sx*14.5f;
|
|
pos.y = oy+sy*0;
|
|
ddim.x = 14.0f/640.0f;
|
|
ddim.y = 66.0f/480.0f;
|
|
pw->CreateGauge(pos, ddim, 0, EVENT_OBJECT_GENERGY);
|
|
}
|
|
|
|
if ( type == OBJECT_HUMAN ||
|
|
type == OBJECT_TECH ||
|
|
type == OBJECT_MOBILEfa ||
|
|
type == OBJECT_MOBILEta ||
|
|
type == OBJECT_MOBILEwa ||
|
|
type == OBJECT_MOBILEia ||
|
|
type == OBJECT_MOBILEfc ||
|
|
type == OBJECT_MOBILEtc ||
|
|
type == OBJECT_MOBILEwc ||
|
|
type == OBJECT_MOBILEic ||
|
|
type == OBJECT_MOBILEfi ||
|
|
type == OBJECT_MOBILEti ||
|
|
type == OBJECT_MOBILEwi ||
|
|
type == OBJECT_MOBILEii ||
|
|
type == OBJECT_MOBILEfs ||
|
|
type == OBJECT_MOBILEts ||
|
|
type == OBJECT_MOBILEws ||
|
|
type == OBJECT_MOBILEis ||
|
|
type == OBJECT_MOBILErt ||
|
|
type == OBJECT_MOBILErc ||
|
|
type == OBJECT_MOBILErr ||
|
|
type == OBJECT_MOBILErs ||
|
|
type == OBJECT_MOBILEsa ||
|
|
type == OBJECT_MOBILEtg ||
|
|
type == OBJECT_MOBILEft ||
|
|
type == OBJECT_MOBILEtt ||
|
|
type == OBJECT_MOBILEwt ||
|
|
type == OBJECT_MOBILEit ) // vehicle?
|
|
{
|
|
pos.x = ox+sx*14.9f;
|
|
pos.y = oy+sy*0;
|
|
ddim.x = 14.0f/640.0f;
|
|
ddim.y = 66.0f/480.0f;
|
|
pw->CreateGauge(pos, ddim, 3, EVENT_OBJECT_GSHIELD);
|
|
}
|
|
|
|
#if 0
|
|
if ( false )
|
|
{
|
|
pos.x = 505.0f/640.0f;
|
|
pos.y = 3.0f/480.0f;
|
|
ddim.x = 33.0f/640.0f;
|
|
ddim.y = 33.0f/480.0f;
|
|
pw->CreateCompass(pos, ddim, 0, EVENT_OBJECT_COMPASS);
|
|
|
|
pc = (CCompass*)pw->SearchControl(EVENT_OBJECT_COMPASS);
|
|
if ( pc != 0 )
|
|
{
|
|
pc->SetState(Ui::STATE_VISIBLE, m_main->GetShowMap());
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if ( type == OBJECT_MOBILEfc ||
|
|
type == OBJECT_MOBILEtc ||
|
|
type == OBJECT_MOBILEwc ||
|
|
type == OBJECT_MOBILEic ||
|
|
type == OBJECT_MOBILEfi ||
|
|
type == OBJECT_MOBILEti ||
|
|
type == OBJECT_MOBILEwi ||
|
|
type == OBJECT_MOBILEii ||
|
|
type == OBJECT_MOBILErc ) // cannon?
|
|
{
|
|
ddim.x = 64.0f/640.0f;
|
|
ddim.y = 64.0f/480.0f;
|
|
pos.x = 0.5f-ddim.x/2.0f;
|
|
pos.y = 0.5f-ddim.y/2.0f;
|
|
pw->CreateGroup(pos, ddim, 12, EVENT_OBJECT_CROSSHAIR);
|
|
|
|
pos.x = 20.0f/640.0f;
|
|
pos.y = 100.0f/480.0f;
|
|
ddim.x = 600.0f/640.0f;
|
|
ddim.y = 340.0f/480.0f;
|
|
pt = pw->CreateTarget(pos, ddim, 0, EVENT_OBJECT_TARGET);
|
|
pt->ClearState(Ui::STATE_GLINT);
|
|
}
|
|
|
|
ddim.x = 64.0f/640.0f;
|
|
ddim.y = 64.0f/480.0f;
|
|
pos.x = 30.0f/640.0f;
|
|
pos.y = 430.0f/480.0f-ddim.y;
|
|
pw->CreateGroup(pos, ddim, 13, EVENT_OBJECT_CORNERul);
|
|
|
|
ddim.x = 64.0f/640.0f;
|
|
ddim.y = 64.0f/480.0f;
|
|
pos.x = 610.0f/640.0f-ddim.x;
|
|
pos.y = 430.0f/480.0f-ddim.y;
|
|
pw->CreateGroup(pos, ddim, 14, EVENT_OBJECT_CORNERur);
|
|
|
|
ddim.x = 64.0f/640.0f;
|
|
ddim.y = 64.0f/480.0f;
|
|
pos.x = 30.0f/640.0f;
|
|
pos.y = 110.0f/480.0f;
|
|
pw->CreateGroup(pos, ddim, 15, EVENT_OBJECT_CORNERdl);
|
|
|
|
ddim.x = 64.0f/640.0f;
|
|
ddim.y = 64.0f/480.0f;
|
|
pos.x = 610.0f/640.0f-ddim.x;
|
|
pos.y = 110.0f/480.0f;
|
|
pw->CreateGroup(pos, ddim, 16, EVENT_OBJECT_CORNERdr);
|
|
|
|
UpdateInterface();
|
|
m_lastUpdateTime = 0.0f;
|
|
UpdateInterface(0.0f);
|
|
|
|
return true;
|
|
}
|
|
|
|
// Updates the state of all buttons on the interface,
|
|
// following the time that elapses ...
|
|
|
|
void CBrain::UpdateInterface(float rTime)
|
|
{
|
|
Ui::CWindow* pw;
|
|
Ui::CButton* pb;
|
|
Ui::CGauge* pg;
|
|
Ui::CCompass* pc;
|
|
Ui::CGroup* pgr;
|
|
Ui::CTarget* ptg;
|
|
CObject* power;
|
|
Math::Vector pos, hPos;
|
|
Math::Point ppos;
|
|
float energy, limit, angle, range;
|
|
int icon;
|
|
bool bOnBoard;
|
|
|
|
m_lastAlarmTime += rTime;
|
|
if ( m_time < m_lastUpdateTime+0.1f ) return;
|
|
m_lastUpdateTime = m_time;
|
|
|
|
if ( !m_object->GetSelect() )
|
|
{
|
|
if ( m_soundChannelAlarm != -1 )
|
|
{
|
|
m_sound->FlushEnvelope(m_soundChannelAlarm);
|
|
m_sound->AddEnvelope(m_soundChannelAlarm, 0.0f, 1.0f, 0.1f, SOPER_STOP);
|
|
m_soundChannelAlarm = -1;
|
|
}
|
|
return;
|
|
}
|
|
|
|
pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0));
|
|
if ( pw == 0 ) return;
|
|
|
|
pg = static_cast< Ui::CGauge* >(pw->SearchControl(EVENT_OBJECT_GENERGY));
|
|
if ( pg != 0 )
|
|
{
|
|
power = m_object->GetPower();
|
|
if ( power == 0 )
|
|
{
|
|
energy = 0.0f;
|
|
limit = 0.0f;
|
|
}
|
|
else
|
|
{
|
|
energy = power->GetEnergy();
|
|
limit = energy*power->GetCapacity();
|
|
}
|
|
icon = 0; // red/green
|
|
|
|
if ( limit < 0.2f && energy != 0.0f ) // low but not zero?
|
|
{
|
|
if ( m_lastAlarmTime >= 0.8f ) // blinks?
|
|
{
|
|
energy = 1.0f;
|
|
icon = 1; // brun
|
|
}
|
|
if ( m_lastAlarmTime >= 1.0f )
|
|
{
|
|
m_sound->Play(SOUND_ALARM, 0.5f); // bip-bip-bip
|
|
m_lastAlarmTime = 0.0f;
|
|
}
|
|
}
|
|
pg->SetLevel(energy);
|
|
pg->SetIcon(icon);
|
|
}
|
|
|
|
pg = static_cast< Ui::CGauge* >(pw->SearchControl(EVENT_OBJECT_GSHIELD));
|
|
if ( pg != 0 )
|
|
{
|
|
pg->SetLevel(m_object->GetShield());
|
|
}
|
|
|
|
pg = static_cast< Ui::CGauge* >(pw->SearchControl(EVENT_OBJECT_GRANGE));
|
|
if ( pg != 0 )
|
|
{
|
|
icon = 2; // blue/red
|
|
range = m_physics->GetReactorRange();
|
|
|
|
if ( range < 0.2f && range != 0.0f && !m_physics->GetLand() )
|
|
{
|
|
if ( Math::Mod(m_time, 0.5f) >= 0.2f ) // blinks?
|
|
{
|
|
range = 1.0f;
|
|
icon = 1; // yellow
|
|
}
|
|
if ( m_soundChannelAlarm == -1 )
|
|
{
|
|
m_soundChannelAlarm = m_sound->Play(SOUND_ALARMt, m_object->GetPosition(0), 0.0f, 0.1f, true);
|
|
m_sound->AddEnvelope(m_soundChannelAlarm, 1.0f, 1.0f, 1.0f, SOPER_CONTINUE);
|
|
m_sound->AddEnvelope(m_soundChannelAlarm, 1.0f, 1.0f, 1.0f, SOPER_LOOP);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( m_soundChannelAlarm != -1 )
|
|
{
|
|
m_sound->FlushEnvelope(m_soundChannelAlarm);
|
|
m_sound->AddEnvelope(m_soundChannelAlarm, 0.0f, 0.1f, 1.0f, SOPER_STOP);
|
|
m_soundChannelAlarm = -1;
|
|
}
|
|
}
|
|
|
|
pg->SetLevel(1.0f-range);
|
|
pg->SetIcon(icon);
|
|
}
|
|
|
|
pc = static_cast< Ui::CCompass* >(pw->SearchControl(EVENT_OBJECT_COMPASS));
|
|
if ( pc != 0 )
|
|
{
|
|
angle = -(m_object->GetAngleY(0)+Math::PI/2.0f);
|
|
pc->SetDirection(angle);
|
|
|
|
pc->SetState(Ui::STATE_VISIBLE, m_main->GetShowMap());
|
|
}
|
|
|
|
pb = static_cast<Ui::CButton*>(pw->SearchControl(EVENT_OBJECT_REC));
|
|
if ( pb != 0 )
|
|
{
|
|
if ( m_bTraceRecord && Math::Mod(m_time, 0.4f) >= 0.2f )
|
|
{
|
|
pb->SetState(Ui::STATE_CHECK);
|
|
}
|
|
else
|
|
{
|
|
pb->ClearState(Ui::STATE_CHECK);
|
|
}
|
|
}
|
|
|
|
bOnBoard = m_camera->GetType() == Gfx::CAM_TYPE_ONBOARD;
|
|
|
|
pgr = static_cast< Ui::CGroup* >(pw->SearchControl(EVENT_OBJECT_CROSSHAIR));
|
|
if ( pgr != 0 )
|
|
{
|
|
if ( bOnBoard )
|
|
{
|
|
#if 0
|
|
angle = m_object->GetGunGoalV();
|
|
if ( m_object->GetType() != OBJECT_MOBILErc )
|
|
{
|
|
angle += 10.0f*Math::PI/360.0f;
|
|
}
|
|
ppos.x = 0.5f-(64.0f/640.0f)/2.0f;
|
|
ppos.y = 0.5f-(64.0f/480.0f)/2.0f;
|
|
ppos.y += sinf(angle)*0.6f;
|
|
pgr->SetPos(ppos);
|
|
#else
|
|
ppos.x = 0.50f-(64.0f/640.0f)/2.0f;
|
|
ppos.y = 0.50f-(64.0f/480.0f)/2.0f;
|
|
ppos.x += m_object->GetGunGoalH()/2.0f;
|
|
ppos.y += m_object->GetGunGoalV()/1.3f;
|
|
pgr->SetPos(ppos);
|
|
#endif
|
|
pgr->SetState(Ui::STATE_VISIBLE, !m_main->GetFriendAim());
|
|
}
|
|
else
|
|
{
|
|
pgr->ClearState(Ui::STATE_VISIBLE);
|
|
}
|
|
}
|
|
|
|
ptg = static_cast< Ui::CTarget* >(pw->SearchControl(EVENT_OBJECT_TARGET));
|
|
if ( ptg != 0 )
|
|
{
|
|
if ( bOnBoard )
|
|
{
|
|
ptg->SetState(Ui::STATE_VISIBLE);
|
|
}
|
|
else
|
|
{
|
|
ptg->ClearState(Ui::STATE_VISIBLE);
|
|
}
|
|
}
|
|
|
|
pgr = static_cast< Ui::CGroup* >(pw->SearchControl(EVENT_OBJECT_CORNERul));
|
|
if ( pgr != 0 )
|
|
{
|
|
pgr->SetState(Ui::STATE_VISIBLE, bOnBoard);
|
|
}
|
|
|
|
pgr = static_cast< Ui::CGroup* >(pw->SearchControl(EVENT_OBJECT_CORNERur));
|
|
if ( pgr != 0 )
|
|
{
|
|
pgr->SetState(Ui::STATE_VISIBLE, bOnBoard);
|
|
}
|
|
|
|
pgr = static_cast< Ui::CGroup* >(pw->SearchControl(EVENT_OBJECT_CORNERdl));
|
|
if ( pgr != 0 )
|
|
{
|
|
pgr->SetState(Ui::STATE_VISIBLE, bOnBoard);
|
|
}
|
|
|
|
pgr = static_cast< Ui::CGroup* >(pw->SearchControl(EVENT_OBJECT_CORNERdr));
|
|
if ( pgr != 0 )
|
|
{
|
|
pgr->SetState(Ui::STATE_VISIBLE, bOnBoard);
|
|
}
|
|
}
|
|
|
|
// Updates the status of all interface buttons.
|
|
|
|
void CBrain::UpdateInterface()
|
|
{
|
|
ObjectType type;
|
|
Ui::CWindow* pw;
|
|
Ui::CButton* pb;
|
|
Ui::CSlider* ps;
|
|
Ui::CColor* pc;
|
|
int color;
|
|
bool bEnable, bFly, bRun;
|
|
char title[100];
|
|
|
|
if ( !m_object->GetSelect() ) return;
|
|
|
|
pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0));
|
|
if ( pw == 0 ) return;
|
|
|
|
type = m_object->GetType();
|
|
|
|
bEnable = ( m_secondaryTask == 0 && m_program == -1 );
|
|
|
|
bEnable = ( m_primaryTask == 0 && m_program == -1 );
|
|
|
|
EnableInterface(pw, EVENT_OBJECT_PROGEDIT, (m_primaryTask == 0 && !m_bTraceRecord));
|
|
EnableInterface(pw, EVENT_OBJECT_PROGLIST, bEnable && !m_bTraceRecord);
|
|
EnableInterface(pw, EVENT_OBJECT_LEFT, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_RIGHT, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_UP, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_DOWN, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_HTAKE, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_MTAKE, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_MBACK, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_MPOWER, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_MFRONT, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_GFLAT, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_FCREATE, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_FDELETE, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_SEARCH, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_TERRAFORM, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_RECOVER, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_FIRE, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_SPIDEREXPLO, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_RESET, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_PEN0, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_PEN1, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_PEN2, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_PEN3, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_PEN4, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_PEN5, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_PEN6, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_PEN7, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_PEN8, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_REC, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_STOP, bEnable);
|
|
|
|
if ( type == OBJECT_HUMAN ) // builder?
|
|
{
|
|
EnableInterface(pw, EVENT_OBJECT_BFACTORY, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_BDERRICK, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_BCONVERT, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_BSTATION, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_BREPAIR, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_BTOWER, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_BRESEARCH, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_BRADAR, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_BENERGY, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_BLABO, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_BNUCLEAR, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_BPARA, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_BINFO, bEnable);
|
|
EnableInterface(pw, EVENT_OBJECT_BDESTROYER,bEnable);
|
|
}
|
|
|
|
pb = static_cast< Ui::CButton* >(pw->SearchControl(EVENT_OBJECT_GFLAT));
|
|
if ( pb != 0 )
|
|
{
|
|
pb->SetState(Ui::STATE_VISIBLE, m_engine->GetGroundSpot());
|
|
}
|
|
|
|
if ( type == OBJECT_HUMAN || // builder?
|
|
type == OBJECT_TECH )
|
|
{
|
|
CheckInterface(pw, EVENT_OBJECT_FCOLORb, m_flagColor==0);
|
|
CheckInterface(pw, EVENT_OBJECT_FCOLORr, m_flagColor==1);
|
|
CheckInterface(pw, EVENT_OBJECT_FCOLORg, m_flagColor==2);
|
|
CheckInterface(pw, EVENT_OBJECT_FCOLORy, m_flagColor==3);
|
|
CheckInterface(pw, EVENT_OBJECT_FCOLORv, m_flagColor==4);
|
|
}
|
|
|
|
if ( type == OBJECT_MOBILErs ) // shield?
|
|
{
|
|
if ( (m_secondaryTask == 0 || !m_secondaryTask->IsBusy()) && m_program == -1 )
|
|
{
|
|
EnableInterface(pw, EVENT_OBJECT_BEGSHIELD, (m_secondaryTask == 0));
|
|
EnableInterface(pw, EVENT_OBJECT_ENDSHIELD, (m_secondaryTask != 0));
|
|
DefaultEnter (pw, EVENT_OBJECT_BEGSHIELD, (m_secondaryTask == 0));
|
|
DefaultEnter (pw, EVENT_OBJECT_ENDSHIELD, (m_secondaryTask != 0));
|
|
}
|
|
else
|
|
{
|
|
EnableInterface(pw, EVENT_OBJECT_BEGSHIELD, false);
|
|
EnableInterface(pw, EVENT_OBJECT_ENDSHIELD, false);
|
|
DefaultEnter (pw, EVENT_OBJECT_BEGSHIELD, false);
|
|
DefaultEnter (pw, EVENT_OBJECT_ENDSHIELD, false);
|
|
}
|
|
|
|
ps = static_cast< Ui::CSlider* >(pw->SearchControl(EVENT_OBJECT_DIMSHIELD));
|
|
if ( ps != 0 )
|
|
{
|
|
ps->SetVisibleValue((RADIUS_SHIELD_MIN/g_unit)+m_object->GetParam()*((RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)/g_unit));
|
|
}
|
|
}
|
|
|
|
bFly = bEnable;
|
|
if ( bFly && (type == OBJECT_HUMAN || type == OBJECT_TECH) )
|
|
{
|
|
if ( m_object->GetFret() != 0 ) bFly = false; // if holder -> not fly
|
|
}
|
|
EnableInterface(pw, EVENT_OBJECT_GASUP, bFly);
|
|
EnableInterface(pw, EVENT_OBJECT_GASDOWN, bFly);
|
|
if ( m_object->GetTrainer() ) // Training?
|
|
{
|
|
DeadInterface(pw, EVENT_OBJECT_GASUP, false);
|
|
DeadInterface(pw, EVENT_OBJECT_GASDOWN, false);
|
|
}
|
|
else
|
|
{
|
|
DeadInterface(pw, EVENT_OBJECT_GASUP, g_researchDone&RESEARCH_FLY);
|
|
DeadInterface(pw, EVENT_OBJECT_GASDOWN, g_researchDone&RESEARCH_FLY);
|
|
}
|
|
|
|
if ( type == OBJECT_HUMAN ||
|
|
type == OBJECT_TECH ||
|
|
type == OBJECT_MOBILEfa ||
|
|
type == OBJECT_MOBILEta ||
|
|
type == OBJECT_MOBILEwa ||
|
|
type == OBJECT_MOBILEia ||
|
|
type == OBJECT_MOBILEfc ||
|
|
type == OBJECT_MOBILEtc ||
|
|
type == OBJECT_MOBILEwc ||
|
|
type == OBJECT_MOBILEic ||
|
|
type == OBJECT_MOBILEfi ||
|
|
type == OBJECT_MOBILEti ||
|
|
type == OBJECT_MOBILEwi ||
|
|
type == OBJECT_MOBILEii ||
|
|
type == OBJECT_MOBILEfs ||
|
|
type == OBJECT_MOBILEts ||
|
|
type == OBJECT_MOBILEws ||
|
|
type == OBJECT_MOBILEis ||
|
|
type == OBJECT_MOBILErt ||
|
|
type == OBJECT_MOBILErc ||
|
|
type == OBJECT_MOBILErr ||
|
|
type == OBJECT_MOBILErs ||
|
|
type == OBJECT_MOBILEsa ||
|
|
type == OBJECT_MOBILEtg ||
|
|
type == OBJECT_MOBILEft ||
|
|
type == OBJECT_MOBILEtt ||
|
|
type == OBJECT_MOBILEwt ||
|
|
type == OBJECT_MOBILEit ||
|
|
type == OBJECT_MOBILEdr ||
|
|
type == OBJECT_MOTHER ||
|
|
type == OBJECT_ANT ||
|
|
type == OBJECT_SPIDER ||
|
|
type == OBJECT_BEE ||
|
|
type == OBJECT_WORM ||
|
|
type == OBJECT_CONTROLLER) // vehicle?
|
|
{
|
|
bRun = false;
|
|
if ( m_script[m_selScript] != 0 )
|
|
{
|
|
m_script[m_selScript]->GetTitle(title);
|
|
if ( title[0] != 0 )
|
|
{
|
|
bRun = true;
|
|
}
|
|
}
|
|
if ( !bEnable && m_program == -1 ) bRun = false;
|
|
if ( m_bTraceRecord ) bRun = false;
|
|
EnableInterface(pw, EVENT_OBJECT_PROGRUN, bRun);
|
|
|
|
pb = static_cast< Ui::CButton* >(pw->SearchControl(EVENT_OBJECT_PROGRUN));
|
|
if ( pb != 0 )
|
|
{
|
|
pb->SetIcon(m_program==-1?21:8); // run/stop
|
|
}
|
|
|
|
//? pb = (CButton*)pw->SearchControl(EVENT_OBJECT_PROGEDIT);
|
|
//? if ( pb != 0 )
|
|
//? {
|
|
//? pb->SetIcon(m_program==-1?22:40); // edit/debug
|
|
//? }
|
|
|
|
BlinkScript(m_program != -1); // blinks if script execution
|
|
}
|
|
|
|
if ( type == OBJECT_MOBILEfa ||
|
|
type == OBJECT_MOBILEta ||
|
|
type == OBJECT_MOBILEwa ||
|
|
type == OBJECT_MOBILEia ) // arm?
|
|
{
|
|
CheckInterface(pw, EVENT_OBJECT_MPOWER, m_manipStyle==EVENT_OBJECT_MPOWER);
|
|
CheckInterface(pw, EVENT_OBJECT_MBACK, m_manipStyle==EVENT_OBJECT_MBACK);
|
|
CheckInterface(pw, EVENT_OBJECT_MFRONT, m_manipStyle==EVENT_OBJECT_MFRONT);
|
|
}
|
|
|
|
if ( m_object->GetTraceDown() )
|
|
{
|
|
pb = static_cast< Ui::CButton* >(pw->SearchControl(EVENT_OBJECT_PEN0));
|
|
if ( pb != 0 )
|
|
{
|
|
pb->ClearState(Ui::STATE_CHECK);
|
|
}
|
|
|
|
color = m_object->GetTraceColor();
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN1));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->SetState(Ui::STATE_CHECK, color==1);
|
|
}
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN2));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->SetState(Ui::STATE_CHECK, color==8);
|
|
}
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN3));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->SetState(Ui::STATE_CHECK, color==7);
|
|
}
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN4));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->SetState(Ui::STATE_CHECK, color==4);
|
|
}
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN5));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->SetState(Ui::STATE_CHECK, color==6);
|
|
}
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN6));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->SetState(Ui::STATE_CHECK, color==14);
|
|
}
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN7));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->SetState(Ui::STATE_CHECK, color==12);
|
|
}
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN8));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->SetState(Ui::STATE_CHECK, color==10);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pb = static_cast< Ui::CButton* >(pw->SearchControl(EVENT_OBJECT_PEN0));
|
|
if ( pb != 0 )
|
|
{
|
|
pb->SetState(Ui::STATE_CHECK);
|
|
}
|
|
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN1));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->ClearState(Ui::STATE_CHECK);
|
|
}
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN2));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->ClearState(Ui::STATE_CHECK);
|
|
}
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN3));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->ClearState(Ui::STATE_CHECK);
|
|
}
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN4));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->ClearState(Ui::STATE_CHECK);
|
|
}
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN5));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->ClearState(Ui::STATE_CHECK);
|
|
}
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN6));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->ClearState(Ui::STATE_CHECK);
|
|
}
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN7));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->ClearState(Ui::STATE_CHECK);
|
|
}
|
|
pc = static_cast< Ui::CColor* >(pw->SearchControl(EVENT_OBJECT_PEN8));
|
|
if ( pc != 0 )
|
|
{
|
|
pc->ClearState(Ui::STATE_CHECK);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Updates the list of programs.
|
|
|
|
void CBrain::UpdateScript(Ui::CWindow *pw)
|
|
{
|
|
Ui::CList* pl;
|
|
char name[100];
|
|
char title[100];
|
|
int i;
|
|
|
|
pl = static_cast< Ui::CList* >(pw->SearchControl(EVENT_OBJECT_PROGLIST));
|
|
if ( pl == 0 ) return;
|
|
|
|
for ( i=0 ; i<BRAINMAXSCRIPT ; i++ )
|
|
{
|
|
sprintf(name, "%d", i+1);
|
|
|
|
if ( m_script[i] != 0 )
|
|
{
|
|
m_script[i]->GetTitle(title);
|
|
if ( title[0] != 0 )
|
|
{
|
|
sprintf(name, "%d: %s", i+1, title);
|
|
}
|
|
}
|
|
|
|
pl->SetItemName(i, name);
|
|
}
|
|
|
|
pl->SetSelect(m_selScript);
|
|
pl->ShowSelect(true);
|
|
}
|
|
|
|
// Returns the rank of selected script.
|
|
|
|
int CBrain::GetSelScript()
|
|
{
|
|
Ui::CWindow* pw;
|
|
Ui::CList* pl;
|
|
|
|
pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0));
|
|
if ( pw == 0 ) return -1;
|
|
|
|
pl = static_cast< Ui::CList* >(pw->SearchControl(EVENT_OBJECT_PROGLIST));
|
|
if ( pl == 0 ) return -1;
|
|
|
|
return pl->GetSelect();
|
|
}
|
|
|
|
// Blinks the running program.
|
|
|
|
void CBrain::BlinkScript(bool bEnable)
|
|
{
|
|
Ui::CWindow* pw;
|
|
Ui::CList* pl;
|
|
|
|
if ( !m_object->GetSelect() ) return; // robot not selected?
|
|
|
|
pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0));
|
|
if ( pw == 0 ) return;
|
|
|
|
pl = static_cast< Ui::CList* >(pw->SearchControl(EVENT_OBJECT_PROGLIST));
|
|
if ( pl == 0 ) return;
|
|
|
|
pl->SetBlink(bEnable);
|
|
}
|
|
|
|
// Check the status of a button interface.
|
|
|
|
void CBrain::CheckInterface(Ui::CWindow *pw, EventType event, bool bState)
|
|
{
|
|
Ui::CControl* control;
|
|
|
|
control = pw->SearchControl(event);
|
|
if ( control == 0 ) return;
|
|
|
|
control->SetState(Ui::STATE_CHECK, bState);
|
|
}
|
|
|
|
// Changes the state of a button interface.
|
|
|
|
void CBrain::EnableInterface(Ui::CWindow *pw, EventType event, bool bState)
|
|
{
|
|
Ui::CControl* control;
|
|
|
|
control = pw->SearchControl(event);
|
|
if ( control == 0 ) return;
|
|
|
|
control->SetState(Ui::STATE_ENABLE, bState);
|
|
}
|
|
|
|
// Changes the state of a button on the interface.
|
|
|
|
void CBrain::DeadInterface(Ui::CWindow *pw, EventType event, bool bState)
|
|
{
|
|
Ui::CControl* control;
|
|
|
|
control = pw->SearchControl(event);
|
|
if ( control == 0 ) return;
|
|
|
|
control->SetState(Ui::STATE_DEAD, !bState);
|
|
}
|
|
|
|
// Change the default input state of a button interface.
|
|
|
|
void CBrain::DefaultEnter(Ui::CWindow *pw, EventType event, bool bState)
|
|
{
|
|
Ui::CControl* control;
|
|
|
|
control = pw->SearchControl(event);
|
|
if ( control == 0 ) return;
|
|
|
|
if ( bState )
|
|
{
|
|
control->SetState(Ui::STATE_DEFAULT);
|
|
m_defaultEnter = event;
|
|
}
|
|
else
|
|
{
|
|
control->ClearState(Ui::STATE_DEFAULT);
|
|
}
|
|
}
|
|
|
|
|
|
// Indicates whether the object is busy with a task.
|
|
|
|
bool CBrain::IsBusy()
|
|
{
|
|
return (m_primaryTask != 0);
|
|
}
|
|
|
|
// Management of the activity of an object.
|
|
|
|
void CBrain::SetActivity(bool bMode)
|
|
{
|
|
m_bActivity = bMode;
|
|
}
|
|
|
|
bool CBrain::GetActivity()
|
|
{
|
|
return m_bActivity;
|
|
}
|
|
|
|
// Indicates whether a program is running.
|
|
|
|
bool CBrain::IsProgram()
|
|
{
|
|
return ( m_program != -1 );
|
|
}
|
|
|
|
// Indicates whether a program exists.
|
|
|
|
bool CBrain::ProgramExist(int rank)
|
|
{
|
|
return ( m_script[rank] != 0 );
|
|
}
|
|
|
|
// Starts a program.
|
|
|
|
void CBrain::RunProgram(int rank)
|
|
{
|
|
if ( rank < 0 ) return;
|
|
|
|
if ( m_script[rank] != 0 &&
|
|
m_script[rank]->Run() )
|
|
{
|
|
m_program = rank; // start new program
|
|
BlinkScript(true); // blink
|
|
m_object->CreateSelectParticle();
|
|
m_main->UpdateShortcuts();
|
|
}
|
|
}
|
|
|
|
// Returns the first free program.
|
|
|
|
int CBrain::FreeProgram()
|
|
{
|
|
int i;
|
|
|
|
for ( i=0 ; i<BRAINMAXSCRIPT ; i++ )
|
|
{
|
|
if ( m_script[i] == 0 ) return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
// Returns the current program.
|
|
|
|
int CBrain::GetProgram()
|
|
{
|
|
return m_program;
|
|
}
|
|
|
|
|
|
// Name management scripts to load.
|
|
|
|
void CBrain::SetScriptRun(int rank)
|
|
{
|
|
m_scriptRun = rank;
|
|
}
|
|
|
|
int CBrain::GetScriptRun()
|
|
{
|
|
return m_scriptRun;
|
|
}
|
|
|
|
void CBrain::SetScriptName(int rank, char *name)
|
|
{
|
|
strcpy(m_scriptName[rank], name);
|
|
}
|
|
|
|
char* CBrain::GetScriptName(int rank)
|
|
{
|
|
return m_scriptName[rank];
|
|
}
|
|
|
|
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)
|
|
{
|
|
int rank, i;
|
|
|
|
rank = FreeProgram();
|
|
if ( rank == -1 ) return false;
|
|
|
|
if ( !ReadProgram(rank, filename) ) return false; // load solution
|
|
|
|
for ( i=0 ; i<BRAINMAXSCRIPT ; i++ )
|
|
{
|
|
if ( i == rank || m_script[i] == 0 ) continue;
|
|
|
|
if ( m_script[i]->Compare(m_script[rank]) ) // the same already?
|
|
{
|
|
delete m_script[rank];
|
|
m_script[rank] = 0;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Load a script from text buffer.
|
|
|
|
bool CBrain::SendProgram(int rank, const char* buffer)
|
|
{
|
|
if ( m_script[rank] == 0 )
|
|
{
|
|
m_script[rank] = new CScript(m_object, &m_secondaryTask);
|
|
}
|
|
|
|
if ( m_script[rank]->SendScript(buffer) ) return true;
|
|
|
|
delete m_script[rank];
|
|
m_script[rank] = 0;
|
|
|
|
return false;
|
|
}
|
|
|
|
// Load a script with a text file.
|
|
|
|
bool CBrain::ReadProgram(int rank, const char* filename)
|
|
{
|
|
if ( m_script[rank] == 0 )
|
|
{
|
|
m_script[rank] = new CScript(m_object, &m_secondaryTask);
|
|
}
|
|
|
|
if ( m_script[rank]->ReadScript(filename) ) return true;
|
|
|
|
delete m_script[rank];
|
|
m_script[rank] = 0;
|
|
|
|
return false;
|
|
}
|
|
|
|
// Indicates whether a program is compiled correctly.
|
|
|
|
bool CBrain::GetCompile(int rank)
|
|
{
|
|
if ( m_script[rank] == 0 ) return false;
|
|
return m_script[rank]->GetCompile();
|
|
}
|
|
|
|
// Saves a script in a text file.
|
|
|
|
bool CBrain::WriteProgram(int rank, char* filename)
|
|
{
|
|
if ( m_script[rank] == 0 )
|
|
{
|
|
m_script[rank] = new CScript(m_object, &m_secondaryTask);
|
|
}
|
|
|
|
if ( m_script[rank]->WriteScript(filename) ) return true;
|
|
|
|
delete m_script[rank];
|
|
m_script[rank] = 0;
|
|
|
|
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 && op < BRAINMAXSCRIPT )
|
|
{
|
|
m_program = op; // program restarts
|
|
m_selScript = op;
|
|
BlinkScript(true); // blink
|
|
|
|
if ( m_script[op] == 0 )
|
|
{
|
|
m_script[op] = new CScript(m_object, &m_secondaryTask);
|
|
}
|
|
if ( !m_script[op]->ReadStack(file) ) return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// ave the script implementation stack of a file.
|
|
|
|
bool CBrain::WriteStack(FILE *file)
|
|
{
|
|
short op;
|
|
|
|
if ( m_program != -1 && // current program?
|
|
m_script[m_program]->IsRunning() )
|
|
{
|
|
op = 1; // run
|
|
fWrite(&op, sizeof(short), 1, file);
|
|
|
|
op = m_program;
|
|
fWrite(&op, sizeof(short), 1, file);
|
|
|
|
return m_script[m_program]->WriteStack(file);
|
|
}
|
|
|
|
op = 0; // stop
|
|
fWrite(&op, sizeof(short), 1, file);
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
// Start of registration of the design.
|
|
|
|
void CBrain::TraceRecordStart()
|
|
{
|
|
m_traceOper = TO_STOP;
|
|
|
|
m_tracePos = m_object->GetPosition(0);
|
|
m_traceAngle = m_object->GetAngleY(0);
|
|
|
|
if ( m_object->GetTraceDown() ) // pencil down?
|
|
{
|
|
m_traceColor = m_object->GetTraceColor();
|
|
}
|
|
else // pen up?
|
|
{
|
|
m_traceColor = -1;
|
|
}
|
|
|
|
delete[] m_traceRecordBuffer;
|
|
m_traceRecordBuffer = new TraceRecord[MAXTRACERECORD];
|
|
m_traceRecordIndex = 0;
|
|
}
|
|
|
|
// Saving the current drawing.
|
|
|
|
void CBrain::TraceRecordFrame()
|
|
{
|
|
TraceOper oper = TO_STOP;
|
|
Math::Vector pos;
|
|
float angle, len, speed;
|
|
int color;
|
|
|
|
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;
|
|
|
|
if ( m_object->GetTraceDown() ) // pencil down?
|
|
{
|
|
color = m_object->GetTraceColor();
|
|
}
|
|
else // pen up?
|
|
{
|
|
color = -1;
|
|
}
|
|
|
|
if ( oper != m_traceOper ||
|
|
color != m_traceColor )
|
|
{
|
|
if ( m_traceOper == TO_ADVANCE ||
|
|
m_traceOper == TO_RECEDE )
|
|
{
|
|
pos = m_object->GetPosition(0);
|
|
len = Math::DistanceProjected(pos, m_tracePos);
|
|
TraceRecordOper(m_traceOper, len);
|
|
}
|
|
if ( m_traceOper == TO_TURN )
|
|
{
|
|
angle = m_object->GetAngleY(0)-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(0);
|
|
m_traceAngle = m_object->GetAngleY(0);
|
|
m_traceColor = color;
|
|
}
|
|
}
|
|
|
|
// End of the registration of the design. Program generates the CBOT.
|
|
|
|
void CBrain::TraceRecordStop()
|
|
{
|
|
TraceOper lastOper, curOper;
|
|
float lastParam, curParam;
|
|
int max, i;
|
|
char* buffer;
|
|
|
|
if ( m_traceRecordBuffer == nullptr ) return;
|
|
|
|
max = 10000;
|
|
buffer = new char[max];
|
|
*buffer = 0;
|
|
strncat(buffer, "extern void object::AutoDraw()\n{\n", max-1);
|
|
|
|
lastOper = TO_STOP;
|
|
lastParam = 0.0f;
|
|
for ( 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, max, lastOper, lastParam);
|
|
lastOper = curOper;
|
|
lastParam = curParam;
|
|
}
|
|
}
|
|
TraceRecordPut(buffer, max, lastOper, lastParam);
|
|
|
|
delete[] m_traceRecordBuffer;
|
|
m_traceRecordBuffer = nullptr;
|
|
|
|
strncat(buffer, "}\n", max-1);
|
|
buffer[max-1] = 0;
|
|
|
|
i = m_selScript;
|
|
if ( m_script[i] == 0 )
|
|
{
|
|
m_script[i] = new CScript(m_object, &m_secondaryTask);
|
|
}
|
|
m_script[i]->SendScript(buffer);
|
|
delete[] buffer;
|
|
}
|
|
|
|
// 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(char *buffer, int max, TraceOper oper, float param)
|
|
{
|
|
char line[100];
|
|
int color;
|
|
|
|
if ( oper == TO_ADVANCE )
|
|
{
|
|
param /= g_unit;
|
|
sprintf(line, "\tmove(%.1f);\n", param);
|
|
strncat(buffer, line, max-1);
|
|
}
|
|
|
|
if ( oper == TO_RECEDE )
|
|
{
|
|
param /= g_unit;
|
|
sprintf(line, "\tmove(-%.1f);\n", param);
|
|
strncat(buffer, line, max-1);
|
|
}
|
|
|
|
if ( oper == TO_TURN )
|
|
{
|
|
param = -param*180.0f/Math::PI;
|
|
sprintf(line, "\tturn(%d);\n", static_cast<int>(param));
|
|
//? sprintf(line, "\tturn(%.1f);\n", param);
|
|
strncat(buffer, line, max-1);
|
|
}
|
|
|
|
if ( oper == TO_PEN )
|
|
{
|
|
color = static_cast<int>(param);
|
|
if ( color == -1 ) strncat(buffer, "\tpenup();\n", max-1);
|
|
if ( color == 1 ) strncat(buffer, "\tpendown(Black);\n", max-1);
|
|
if ( color == 8 ) strncat(buffer, "\tpendown(Yellow);\n", max-1);
|
|
if ( color == 7 ) strncat(buffer, "\tpendown(Orange);\n", max-1);
|
|
if ( color == 4 ) strncat(buffer, "\tpendown(Red);\n", max-1);
|
|
if ( color == 6 ) strncat(buffer, "\tpendown(Purple);\n", max-1);
|
|
if ( color == 14 ) strncat(buffer, "\tpendown(Blue);\n", max-1);
|
|
if ( color == 12 ) strncat(buffer, "\tpendown(Green);\n", max-1);
|
|
if ( color == 10 ) strncat(buffer, "\tpendown(Brown);\n", max-1);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|