/* * This file is part of the Colobot: Gold Edition source code * Copyright (C) 2001-2023, Daniel Roux, EPSITEC SA & TerranovaTeam * http://epsitec.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 "ui/object_interface.h" #include "app/app.h" #include "common/global.h" #include "common/restext.h" #include "graphics/core/color.h" #include "graphics/engine/engine.h" #include "graphics/engine/terrain.h" #include "graphics/engine/water.h" #include "level/robotmain.h" #include "math/geometry.h" #include "object/old_object.h" #include "object/interface/programmable_object.h" #include "object/interface/slotted_object.h" #include "object/interface/task_executor_object.h" #include "object/motion/motion.h" #include "object/motion/motionvehicle.h" #include "object/subclass/shielder.h" #include "physics/physics.h" #include "script/script.h" #include "sound/sound.h" #include "ui/studio.h" #include "ui/controls/button.h" #include "ui/controls/color.h" #include "ui/controls/gauge.h" #include "ui/controls/group.h" #include "ui/controls/interface.h" #include "ui/controls/label.h" #include "ui/controls/list.h" #include "ui/controls/slider.h" #include "ui/controls/target.h" #include "ui/controls/window.h" namespace Ui { CObjectInterface::CObjectInterface(COldObject* object) { m_object = object; assert(object->Implements(ObjectInterfaceType::TaskExecutor)); m_taskExecutor = dynamic_cast(m_object); assert(object->Implements(ObjectInterfaceType::Programmable)); m_programmable = dynamic_cast(m_object); assert(object->Implements(ObjectInterfaceType::ProgramStorage)); m_programStorage = dynamic_cast(m_object); m_physics = m_object->GetPhysics(); m_motion = m_object->GetMotion(); 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_time = 0.0f; m_lastUpdateTime = 0.0f; m_lastAlarmTime = 0.0f; m_soundChannelAlarm = -1; m_flagColor = 0; m_defaultEnter = EVENT_NULL; m_manipStyle = EVENT_OBJECT_MFRONT; m_selScript = 0; m_buildInterface = false; } // Object's destructor. CObjectInterface::~CObjectInterface() { } // Destroys the object. void CObjectInterface::DeleteObject(bool all) { 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 ( m_studio != nullptr ) // current edition? { StopEditScript(true); } } // Management of an event. bool CObjectInterface::EventProcess(const Event &event) { CWindow* pw; CControl* pc; CSlider* ps; EventType action; Error err; action = EVENT_NULL; bool isActionSlot = false; if (event.type == EVENT_KEY_DOWN && !m_main->GetEditLock()) { auto data = event.GetData(); isActionSlot = data->slot == INPUT_SLOT_ACTION; } if (isActionSlot) { pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw != nullptr ) { pc = pw->SearchControl(m_defaultEnter); if ( pc != nullptr ) { if ( pc->TestState(STATE_ENABLE) ) { action = m_defaultEnter; } } } } else { action = event.type; } if (event.type == EVENT_KEY_DOWN && m_object->GetSelect()) { auto data = event.GetData(); bool control = (event.kmodState & KEY_MOD(CTRL)) != 0; bool alt = (event.kmodState & KEY_MOD(ALT)) != 0; CEventQueue* queue = CApplication::GetInstancePointer()->GetEventQueue(); if (data->slot == INPUT_SLOT_ACTION && control) { queue->AddEvent(Event(m_studio == nullptr ? EVENT_OBJECT_PROGEDIT : EVENT_STUDIO_OK)); return false; } if (data->slot == INPUT_SLOT_ACTION && alt) { pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw != nullptr ) { CButton* pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_PROGRUN)); if(pb != nullptr) { if(pb->TestState(STATE_ENABLE)) { queue->AddEvent(Event(EVENT_OBJECT_PROGRUN)); } } } return false; } if (alt) { int index = GetSelScript(); if(data->slot == INPUT_SLOT_UP) index--; else if(data->slot == INPUT_SLOT_DOWN) index++; else if(data->key >= KEY(1) && data->key <= KEY(9)) index = data->key-KEY(1); else if(data->key == KEY(0)) index = 9; if(index < 0) index = m_programStorage->GetProgramCount()-1; if(index > static_cast(m_programStorage->GetProgramCount())-1) index = 0; if(GetSelScript() != index) { SetSelScript(index); queue->AddEvent(Event(EVENT_OBJECT_PROGLIST)); return false; } } } 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 != nullptr ) // current issue? { m_studio->EventProcess(event); if ( action == EVENT_OBJECT_PROGRUN ) { if ( !m_programmable->IsProgram() ) { if (m_selScript < m_programStorage->GetProgramCount()) { m_programmable->RunProgram(m_programStorage->GetProgram(m_selScript)); } } else { m_programmable->StopProgram(); } } if ( action == EVENT_OBJECT_PROGSTART ) { m_main->SaveOneScript(m_object); if (m_selScript < m_programStorage->GetProgramCount()) { m_programmable->RunProgram(m_programStorage->GetProgram(m_selScript)); } } if ( action == EVENT_OBJECT_PROGSTOP ) { m_programmable->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); } if( action == EVENT_STUDIO_CLONE ) { StopEditScript(true); Program* newProgram = m_programStorage->CloneProgram(m_programStorage->GetProgram(m_selScript)); m_selScript = m_programStorage->GetProgramIndex(newProgram); m_main->SaveOneScript(m_object); UpdateInterface(); CWindow* pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw != nullptr ) { UpdateScript(pw); } SetSelScript(m_selScript); StartEditScript(newProgram, ""); std::string res; GetResource(RES_TEXT, RT_STUDIO_CLONED, res); m_studio->SetInfoText(res, false); } return true; } if ( !m_object->GetSelect() ) return true; // robot not selected? if ( m_taskExecutor->IsBackgroundTask() ) // current task? { if ( action == EVENT_OBJECT_ENDSHIELD ) { m_taskExecutor->StartTaskShield(TSM_DOWN, 0.0f); } } if ( m_taskExecutor->IsForegroundTask() || // current task? m_programmable->IsProgram() ) { if ( action == EVENT_OBJECT_PROGRUN ) { m_programmable->StopProgram(); } if ( action == EVENT_OBJECT_PROGEDIT ) { if(m_selScript < m_programStorage->GetProgramCount()) { StartEditScript(m_programStorage->GetProgram(m_selScript), m_main->GetScriptName()); } } if ( !m_taskExecutor->IsForegroundTask() || !m_taskExecutor->GetForegroundTask()->IsPilot() ) return true; } if ( !m_programmable->IsProgram() ) { if( action == EVENT_OBJECT_PROGADD ) { Program* program = m_programStorage->AddProgram(); m_selScript = m_programStorage->GetProgramIndex(program); m_main->SaveOneScript(m_object); UpdateInterface(); CWindow* pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw != nullptr ) { UpdateScript(pw); } SetSelScript(m_selScript); } if( action == EVENT_OBJECT_PROGREMOVE ) { if(m_selScript < m_programStorage->GetProgramCount()) { if(m_programmable->GetCurrentProgram() == m_programStorage->GetProgram(m_selScript)) { m_programmable->StopProgram(); } m_programStorage->RemoveProgram(m_programStorage->GetProgram(m_selScript)); if(m_selScript >= m_programStorage->GetProgramCount()) m_selScript = m_programStorage->GetProgramCount()-1; m_main->SaveOneScript(m_object); UpdateInterface(); CWindow* pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw != nullptr ) { UpdateScript(pw); } SetSelScript(m_selScript); } } if( action == EVENT_OBJECT_PROGCLONE ) { if(m_selScript < m_programStorage->GetProgramCount()) { m_programStorage->CloneProgram(m_programStorage->GetProgram(m_selScript)); m_selScript = m_programStorage->GetProgramCount()-1; m_main->SaveOneScript(m_object); UpdateInterface(); CWindow* pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw != nullptr ) { UpdateScript(pw); } SetSelScript(m_selScript); } } if( action == EVENT_OBJECT_PROGMOVEUP ) { std::iter_swap(m_programStorage->GetPrograms().begin() + m_selScript, m_programStorage->GetPrograms().begin() + m_selScript - 1); m_selScript--; m_main->SaveOneScript(m_object); UpdateInterface(); CWindow* pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw != nullptr ) { UpdateScript(pw); } SetSelScript(m_selScript); } if( action == EVENT_OBJECT_PROGMOVEDOWN ) { std::iter_swap(m_programStorage->GetPrograms().begin() + m_selScript, m_programStorage->GetPrograms().begin() + m_selScript + 1); m_selScript++; m_main->SaveOneScript(m_object); UpdateInterface(); CWindow* pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw != nullptr ) { UpdateScript(pw); } SetSelScript(m_selScript); } } if ( action == EVENT_OBJECT_PROGLIST ) { m_selScript = GetSelScript(); UpdateInterface(); } if ( action == EVENT_OBJECT_PROGEDIT ) { if(m_selScript < m_programStorage->GetProgramCount()) { StartEditScript(m_programStorage->GetProgram(m_selScript), m_main->GetScriptName()); } } if ( action == EVENT_OBJECT_PROGRUN ) { m_programmable->StopProgram(); // stops the current program if(m_selScript < m_programStorage->GetProgramCount()) { m_programmable->RunProgram(m_programStorage->GetProgram(m_selScript)); } UpdateInterface(); } err = ERR_OK; if ( !m_programmable->IsProgram() && m_main->CanPlayerInteract() ) { if ( action == EVENT_OBJECT_HTAKE ) { err = m_taskExecutor->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 = m_taskExecutor->StartTaskManip(TMO_AUTO, TMA_FFRONT); } if ( m_manipStyle == EVENT_OBJECT_MBACK ) { err = m_taskExecutor->StartTaskManip(TMO_AUTO, TMA_FBACK); if ( err == ERR_OK ) { m_manipStyle = EVENT_OBJECT_MFRONT; UpdateInterface(); } } if ( m_manipStyle == EVENT_OBJECT_MPOWER ) { err = m_taskExecutor->StartTaskManip(TMO_AUTO, TMA_POWER); if ( err == ERR_OK ) { m_manipStyle = EVENT_OBJECT_MFRONT; UpdateInterface(); } } } if ( action == EVENT_OBJECT_BDERRICK ) { err = m_taskExecutor->StartTaskBuild(OBJECT_DERRICK); } if ( action == EVENT_OBJECT_BSTATION ) { err = m_taskExecutor->StartTaskBuild(OBJECT_STATION); } if ( action == EVENT_OBJECT_BFACTORY ) { err = m_taskExecutor->StartTaskBuild(OBJECT_FACTORY); } if ( action == EVENT_OBJECT_BREPAIR ) { err = m_taskExecutor->StartTaskBuild(OBJECT_REPAIR); } if ( action == EVENT_OBJECT_BCONVERT ) { err = m_taskExecutor->StartTaskBuild(OBJECT_CONVERT); } if ( action == EVENT_OBJECT_BTOWER ) { err = m_taskExecutor->StartTaskBuild(OBJECT_TOWER); } if ( action == EVENT_OBJECT_BRESEARCH ) { err = m_taskExecutor->StartTaskBuild(OBJECT_RESEARCH); } if ( action == EVENT_OBJECT_BRADAR ) { err = m_taskExecutor->StartTaskBuild(OBJECT_RADAR); } if ( action == EVENT_OBJECT_BENERGY ) { err = m_taskExecutor->StartTaskBuild(OBJECT_ENERGY); } if ( action == EVENT_OBJECT_BLABO ) { err = m_taskExecutor->StartTaskBuild(OBJECT_LABO); } if ( action == EVENT_OBJECT_BNUCLEAR ) { err = m_taskExecutor->StartTaskBuild(OBJECT_NUCLEAR); } if ( action == EVENT_OBJECT_BPARA ) { err = m_taskExecutor->StartTaskBuild(OBJECT_PARA); } if ( action == EVENT_OBJECT_BINFO ) { err = m_taskExecutor->StartTaskBuild(OBJECT_INFO); } if ( action == EVENT_OBJECT_BSAFE ) { err = m_taskExecutor->StartTaskBuild(OBJECT_SAFE); } if ( action == EVENT_OBJECT_GFLAT ) { GroundFlat(); } if ( action == EVENT_OBJECT_FCREATE ) { err = m_taskExecutor->StartTaskFlag(TFL_CREATE, m_flagColor); } if ( action == EVENT_OBJECT_FDELETE ) { err = m_taskExecutor->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 = m_taskExecutor->StartTaskSearch(); } if ( action == EVENT_OBJECT_DELSEARCH ) { err = m_taskExecutor->StartTaskDeleteMark(); } if ( action == EVENT_OBJECT_TERRAFORM ) { err = m_taskExecutor->StartTaskTerraform(); } if ( action == EVENT_OBJECT_RECOVER ) { err = m_taskExecutor->StartTaskRecover(); } if ( action == EVENT_OBJECT_BEGSHIELD ) { err = m_taskExecutor->StartTaskShield(TSM_UP); } if ( action == EVENT_OBJECT_DIMSHIELD ) { pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw != nullptr ) { ps = static_cast< CSlider* >(pw->SearchControl(EVENT_OBJECT_DIMSHIELD)); if ( ps != nullptr ) { dynamic_cast(*m_object).SetShieldRadius((ps->GetVisibleValue()-(RADIUS_SHIELD_MIN/g_unit))/((RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)/g_unit)); } } } if ( action == EVENT_OBJECT_FIRE && !m_taskExecutor->IsForegroundTask() && !m_object->GetTrainer() ) { if ( m_camera->GetType() != Gfx::CAM_TYPE_ONBOARD ) { m_camera->SetType(Gfx::CAM_TYPE_ONBOARD); } err = m_taskExecutor->StartTaskFire(0.0f); } if ( action == EVENT_OBJECT_TARGET && !m_object->GetTrainer() ) { err = m_taskExecutor->StartTaskGunGoal((event.mousePos.y-0.50f)*1.3f, (event.mousePos.x-0.50f)*2.0f); } if ( action == EVENT_OBJECT_FIREANT ) { //? err = m_taskExecutor->StartTaskFireAnt(); } if ( action == EVENT_OBJECT_SPIDEREXPLO && !m_taskExecutor->IsForegroundTask() ) { err = m_taskExecutor->StartTaskSpiderExplo(); } if ( action == EVENT_OBJECT_BUILD ) { m_buildInterface = !m_buildInterface; UpdateInterface(); } if ( action == EVENT_OBJECT_PEN0 ) // up { err = m_taskExecutor->StartTaskPen(false); } if ( action == EVENT_OBJECT_PEN1 ) // black { err = m_taskExecutor->StartTaskPen(true, TraceColor::Black); } if ( action == EVENT_OBJECT_PEN2 ) // yellow { err = m_taskExecutor->StartTaskPen(true, TraceColor::Yellow); } if ( action == EVENT_OBJECT_PEN3 ) // orange { err = m_taskExecutor->StartTaskPen(true, TraceColor::Orange); } if ( action == EVENT_OBJECT_PEN4 ) // red { err = m_taskExecutor->StartTaskPen(true, TraceColor::Red); } if ( action == EVENT_OBJECT_PEN5 ) // violet { err = m_taskExecutor->StartTaskPen(true, TraceColor::Purple); } if ( action == EVENT_OBJECT_PEN6 ) // blue { err = m_taskExecutor->StartTaskPen(true, TraceColor::Blue); } if ( action == EVENT_OBJECT_PEN7 ) // green { err = m_taskExecutor->StartTaskPen(true, TraceColor::Green); } if ( action == EVENT_OBJECT_PEN8 ) // brown { err = m_taskExecutor->StartTaskPen(true, TraceColor::Brown); } if ( action == EVENT_OBJECT_REC ) // registered? { if ( m_programmable->IsTraceRecord() ) { m_programmable->TraceRecordStop(); } else { m_programmable->TraceRecordStart(); } UpdateInterface(); pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw != nullptr ) { UpdateScript(pw); } } if ( action == EVENT_OBJECT_STOP ) // stops? { if ( m_programmable->IsTraceRecord() ) { m_programmable->TraceRecordStop(); } UpdateInterface(); pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw != nullptr ) { UpdateScript(pw); } } if ( action == EVENT_OBJECT_RESET ) { m_main->ResetObject(); // reset all objects UpdateInterface(); } } if ( err != ERR_OK ) { m_main->DisplayError(err, m_object); } return true; } // The brain is changing by time. bool CObjectInterface::EventFrame(const Event &event) { m_time += event.rTime; if ( m_soundChannelAlarm != -1 ) { m_sound->Position(m_soundChannelAlarm, m_object->GetPosition()); } if ( m_studio != nullptr ) // current edition? { m_studio->EventProcess(event); } UpdateInterface(event.rTime); return true; } // Start editing a program. void CObjectInterface::StartEditScript(Program* program, std::string name) { CreateInterface(false); // removes the control buttons m_studio = std::make_unique(); m_studio->StartEditScript(program->script.get(), name, program); } // End of editing a program. void CObjectInterface::StopEditScript(bool closeWithErrors) { if ( !m_studio->StopEditScript(closeWithErrors) ) return; m_studio.reset(); if ( !closeWithErrors ) m_programStorage->SetActiveVirus(false); CreateInterface(true); // puts the control buttons } // Shows flat areas in the field. void CObjectInterface::GroundFlat() { glm::vec3 pos, speed; glm::vec2 dim; Error err; float level; if ( !m_physics->GetLand() ) { err = ERR_FLAG_FLY; pos = m_object->GetPosition(); if ( pos.y < m_water->GetLevel() ) err = ERR_FLAG_WATER; m_main->DisplayError(err, m_object); return; } pos = m_object->GetPosition(); 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 = glm::vec3(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 CObjectInterface::ColorFlag(int color) { m_flagColor = color; UpdateInterface(); } // Creates all the interface when the object is selected. bool CObjectInterface::CreateInterface(bool bSelect) { ObjectType type; CWindow* pw; CButton* pb; CSlider* ps; CColor* pc; CTarget* pt; CLabel* pl; glm::vec2 pos, dim, ddim; float ox, oy, sx, sy; pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw != nullptr ) { 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< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == nullptr ) return false; 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, m_object->GetTooltipText()); 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_MOBILEfb || type == OBJECT_MOBILEtb || type == OBJECT_MOBILEwb || type == OBJECT_MOBILEib || 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_MOBILErp || type == OBJECT_MOBILEst || 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->GetMissionType() != MISSION_RETRO) { ddim.x = dim.x*5.1f; ddim.y = dim.y*1.5f; pos.x = ox+sx*0.0f; pos.y = oy+sy*0.5f; pw->CreateList(pos, ddim, -1, EVENT_OBJECT_PROGLIST, -1.10f); UpdateScript(pw); ddim.y = dim.y*0.5f; pos.y = oy+sy*0.0f; ddim.x = dim.x*1.1f; pos.x = ox+sx*0.0f; pw->CreateButton(pos, ddim, 24, EVENT_OBJECT_PROGADD); ddim.x = dim.x*1.0f; pos.x = ox+sx*1.1f; pw->CreateButton(pos, ddim, 25, EVENT_OBJECT_PROGREMOVE); pos.x = ox+sx*2.1f; pw->CreateButton(pos, ddim, 61, EVENT_OBJECT_PROGCLONE); pos.x = ox+sx*3.1f; pw->CreateButton(pos, ddim, 49, EVENT_OBJECT_PROGMOVEUP); pos.x = ox+sx*4.1f; pw->CreateButton(pos, ddim, 50, EVENT_OBJECT_PROGMOVEDOWN); 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 ( m_object->Implements(ObjectInterfaceType::Flying) ) { 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 ( m_object->Implements(ObjectInterfaceType::JetFlying) ) { if ( type != OBJECT_HUMAN || m_object->GetOption() != 2 ) // if not Me without a jetpack, display reactor temperature { 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 ) && !m_main->GetPlusExplorer() ) { 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 && !m_main->GetPlusExplorer()) // 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, m_main->CanBuild(OBJECT_RESEARCH, m_object->GetTeam())); 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, m_main->CanBuild(OBJECT_FACTORY, m_object->GetTeam())); 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, m_main->CanBuild(OBJECT_CONVERT, m_object->GetTeam())); 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, m_main->CanBuild(OBJECT_STATION, m_object->GetTeam())); 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, m_main->CanBuild(OBJECT_RADAR, m_object->GetTeam())); 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, m_main->CanBuild(OBJECT_REPAIR, m_object->GetTeam())); 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, m_main->CanBuild(OBJECT_INFO, m_object->GetTeam())); 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, m_main->CanBuild(OBJECT_TOWER, m_object->GetTeam())); 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, m_main->CanBuild(OBJECT_ENERGY, m_object->GetTeam())); 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, m_main->CanBuild(OBJECT_DERRICK, m_object->GetTeam())); 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, m_main->CanBuild(OBJECT_NUCLEAR, m_object->GetTeam())); 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, m_main->CanBuild(OBJECT_LABO, m_object->GetTeam())); 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, m_main->CanBuild(OBJECT_PARA, m_object->GetTeam())); pos.x = ox+sx*5.4f; pos.y = oy+sy*0.1f; pw->CreateButton(pos, ddim, 128+47, EVENT_OBJECT_BSAFE); DeadInterface(pw, EVENT_OBJECT_BSAFE, m_main->CanBuild(OBJECT_SAFE, m_object->GetTeam())); if ( m_main->IsBuildingEnabled(BUILD_GFLAT) ) { pos.x = ox+sx*9.0f; pos.y = oy+sy*0.5f; pw->CreateButton(pos, dim, 64+47, EVENT_OBJECT_GFLAT); } if ( m_main->IsBuildingEnabled(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); pos.x = ox+sx*9.0f; pos.y = oy+sy*0.5f; pw->CreateButton(pos, dim, 11, EVENT_OBJECT_DELSEARCH); if ( m_main->IsBuildingEnabled(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_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(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)); 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.8f, 0.0f, 0.0f)); 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)); 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); } //camera button no more disabled for humans 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); } } 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 ( HasPowerCellSlot(m_object) ) // 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 ( m_object->Implements(ObjectInterfaceType::Shielded) ) // 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 ( 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(STATE_GLINT); } if (type != OBJECT_HUMAN && type != OBJECT_TECH) { 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); } if ( (type == OBJECT_MOBILEfb || type == OBJECT_MOBILEtb || type == OBJECT_MOBILEwb || type == OBJECT_MOBILEib) && // builder? !m_object->GetTrainer() ) { pos.x = ox+sx*7.7f; pos.y = oy+sy*0.5f; pb = pw->CreateButton(pos, dim, 192+4, EVENT_OBJECT_BUILD); pb->SetImmediat(true); DefaultEnter(pw, EVENT_OBJECT_BUILD); pos.x = 0.0f; pos.y = oy+sy*2.6f; ddim.x = 214.5f/640.0f; ddim.y = 66.0f/480.0f; pw->CreateGroup(pos, ddim, 6, EVENT_WINDOW3); ddim.x = dim.x*0.9f; ddim.y = dim.y*0.9f; pos.y = oy+sy*3.6f; pos.x = ox+sx*0.0f; pw->CreateButton(pos, ddim, 128+35, EVENT_OBJECT_BRESEARCH); DeadInterface(pw, EVENT_OBJECT_BRESEARCH, m_main->CanBuild(OBJECT_RESEARCH, m_object->GetTeam())); pos.x = ox+sx*0.9f; pw->CreateButton(pos, ddim, 128+32, EVENT_OBJECT_BFACTORY); DeadInterface(pw, EVENT_OBJECT_BFACTORY, m_main->CanBuild(OBJECT_FACTORY, m_object->GetTeam())); pos.x = ox+sx*1.8f; pw->CreateButton(pos, ddim, 128+34, EVENT_OBJECT_BCONVERT); DeadInterface(pw, EVENT_OBJECT_BCONVERT, m_main->CanBuild(OBJECT_CONVERT, m_object->GetTeam())); pos.x = ox+sx*2.7f; pw->CreateButton(pos, ddim, 128+36, EVENT_OBJECT_BSTATION); DeadInterface(pw, EVENT_OBJECT_BSTATION, m_main->CanBuild(OBJECT_STATION, m_object->GetTeam())); pos.x = ox+sx*3.6f; pw->CreateButton(pos, ddim, 128+40, EVENT_OBJECT_BRADAR); DeadInterface(pw, EVENT_OBJECT_BRADAR, m_main->CanBuild(OBJECT_RADAR, m_object->GetTeam())); pos.x = ox+sx*4.5f; pw->CreateButton(pos, ddim, 128+41, EVENT_OBJECT_BREPAIR); DeadInterface(pw, EVENT_OBJECT_BREPAIR, m_main->CanBuild(OBJECT_REPAIR, m_object->GetTeam())); pos.x = ox+sx*5.4f; pw->CreateButton(pos, ddim, 128+44, EVENT_OBJECT_BINFO); DeadInterface(pw, EVENT_OBJECT_BINFO, m_main->CanBuild(OBJECT_INFO, m_object->GetTeam())); pos.y = oy+sy*2.7f; pos.x = ox+sx*0.0f; pw->CreateButton(pos, ddim, 128+37, EVENT_OBJECT_BTOWER); DeadInterface(pw, EVENT_OBJECT_BTOWER, m_main->CanBuild(OBJECT_TOWER, m_object->GetTeam())); pos.x = ox+sx*0.9f; pw->CreateButton(pos, ddim, 128+39, EVENT_OBJECT_BENERGY); DeadInterface(pw, EVENT_OBJECT_BENERGY, m_main->CanBuild(OBJECT_ENERGY, m_object->GetTeam())); pos.x = ox+sx*1.8f; pw->CreateButton(pos, ddim, 128+33, EVENT_OBJECT_BDERRICK); DeadInterface(pw, EVENT_OBJECT_BDERRICK, m_main->CanBuild(OBJECT_DERRICK, m_object->GetTeam())); pos.x = ox+sx*2.7f; pw->CreateButton(pos, ddim, 128+42, EVENT_OBJECT_BNUCLEAR); DeadInterface(pw, EVENT_OBJECT_BNUCLEAR, m_main->CanBuild(OBJECT_NUCLEAR, m_object->GetTeam())); pos.x = ox+sx*3.6f; pw->CreateButton(pos, ddim, 128+38, EVENT_OBJECT_BLABO); DeadInterface(pw, EVENT_OBJECT_BLABO, m_main->CanBuild(OBJECT_LABO, m_object->GetTeam())); pos.x = ox+sx*4.5f; pw->CreateButton(pos, ddim, 128+46, EVENT_OBJECT_BPARA); DeadInterface(pw, EVENT_OBJECT_BPARA, m_main->CanBuild(OBJECT_PARA, m_object->GetTeam())); pos.x = ox+sx*5.4f; pw->CreateButton(pos, ddim, 128+47, EVENT_OBJECT_BSAFE); DeadInterface(pw, EVENT_OBJECT_BSAFE, m_main->CanBuild(OBJECT_SAFE, m_object->GetTeam())); if ( m_main->IsBuildingEnabled(BUILD_GFLAT) ) { pos.x = ox+sx*9.0f; pos.y = oy+sy*0.5f; pw->CreateButton(pos, dim, 64+47, EVENT_OBJECT_GFLAT); } } 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 CObjectInterface::UpdateInterface(float rTime) { CWindow* pw; CButton* pb; CGroup* pgr; CTarget* ptg; glm::vec3 pos, hPos; glm::vec2 ppos; float 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< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == nullptr ) return; CGauge* pg = static_cast< CGauge* >(pw->SearchControl(EVENT_OBJECT_GENERGY)); if (pg != nullptr) { float energy = 0.0f; float limit = 0.0f; if (CPowerContainerObject* powerContainer = GetObjectPowerCell(m_object)) { energy = powerContainer->GetEnergyLevel(); limit = powerContainer->GetEnergy(); } 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< CGauge* >(pw->SearchControl(EVENT_OBJECT_GSHIELD)); if ( pg != nullptr ) { assert(m_object->Implements(ObjectInterfaceType::Shielded)); icon = 3; // orange/gray float shield = dynamic_cast(m_object)->GetShield(); if ( shield < 0.4f && shield != 0.0f) // low but not zero? { if ( m_lastAlarmTime >= 0.8f ) // blinks? { shield = 1.0f; icon = 2; // red } if ( m_lastAlarmTime >= 1.0f ) { m_sound->Play(SOUND_ALARMs, 0.5f); // beep-beep m_lastAlarmTime = 0.0f; } } pg->SetLevel(shield); pg->SetIcon(icon); } pg = static_cast< CGauge* >(pw->SearchControl(EVENT_OBJECT_GRANGE)); if ( pg != nullptr ) { assert(m_object->Implements(ObjectInterfaceType::JetFlying)); icon = 2; // blue/red range = dynamic_cast(m_object)->GetReactorRange(); if ( range < 0.2f && range != 0.0f && !m_physics->GetLand() ) // low but not zero/landed? { 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.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); } pb = static_cast(pw->SearchControl(EVENT_OBJECT_REC)); if ( pb != nullptr ) { if ( m_programmable->IsTraceRecord() && Math::Mod(m_time, 0.4f) >= 0.2f ) { pb->SetState(STATE_CHECK); } else { pb->ClearState(STATE_CHECK); } } bOnBoard = m_camera->GetType() == Gfx::CAM_TYPE_ONBOARD; pgr = static_cast< CGroup* >(pw->SearchControl(EVENT_OBJECT_CROSSHAIR)); if ( pgr != nullptr ) { if ( bOnBoard ) { 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); pgr->SetState(STATE_VISIBLE, !m_main->GetFriendAim()); } else { pgr->ClearState(STATE_VISIBLE); } } ptg = static_cast< CTarget* >(pw->SearchControl(EVENT_OBJECT_TARGET)); if ( ptg != nullptr ) { if ( bOnBoard ) { ptg->SetState(STATE_VISIBLE); } else { ptg->ClearState(STATE_VISIBLE); } } pgr = static_cast< CGroup* >(pw->SearchControl(EVENT_OBJECT_CORNERul)); if ( pgr != nullptr ) { pgr->SetState(STATE_VISIBLE, bOnBoard); } pgr = static_cast< CGroup* >(pw->SearchControl(EVENT_OBJECT_CORNERur)); if ( pgr != nullptr ) { pgr->SetState(STATE_VISIBLE, bOnBoard); } pgr = static_cast< CGroup* >(pw->SearchControl(EVENT_OBJECT_CORNERdl)); if ( pgr != nullptr ) { pgr->SetState(STATE_VISIBLE, bOnBoard); } pgr = static_cast< CGroup* >(pw->SearchControl(EVENT_OBJECT_CORNERdr)); if ( pgr != nullptr ) { pgr->SetState(STATE_VISIBLE, bOnBoard); } } // Updates the status of all interface buttons. void CObjectInterface::UpdateInterface() { ObjectType type; CWindow* pw; CButton* pb; CSlider* ps; CColor* pc; bool bFly, bRun; if ( !m_object->GetSelect() ) return; pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == nullptr ) return; // This is needed because currently started program is loaded by CProgrammableObject // TODO: Isn't there a better way to do it? if (m_programmable->IsProgram()) { SetSelScript(m_programStorage->GetProgramIndex(m_programmable->GetCurrentProgram())); } type = m_object->GetType(); bool bEnable = ( !m_taskExecutor->IsForegroundTask() && !m_programmable->IsProgram() ) && m_main->CanPlayerInteract(); bool bProgEnable = !m_programmable->IsProgram() && m_main->CanPlayerInteract(); bool scriptSelected = m_selScript >= 0 && m_selScript < m_programStorage->GetProgramCount(); EnableInterface(pw, EVENT_OBJECT_PROGEDIT, scriptSelected && !m_programmable->IsTraceRecord()); EnableInterface(pw, EVENT_OBJECT_PROGLIST, bProgEnable && !m_programmable->IsTraceRecord()); EnableInterface(pw, EVENT_OBJECT_PROGADD, bProgEnable); EnableInterface(pw, EVENT_OBJECT_PROGREMOVE, bProgEnable && scriptSelected && !m_programStorage->GetProgram(m_selScript)->readOnly); EnableInterface(pw, EVENT_OBJECT_PROGCLONE, bProgEnable && scriptSelected && m_programStorage->GetProgram(m_selScript)->runnable); EnableInterface(pw, EVENT_OBJECT_PROGMOVEUP, bProgEnable && scriptSelected && m_programStorage->GetProgramCount() >= 2 && m_selScript > 0); EnableInterface(pw, EVENT_OBJECT_PROGMOVEDOWN,bProgEnable && scriptSelected && m_programStorage->GetProgramCount() >= 2 && m_selScript < m_programStorage->GetProgramCount()-1); 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_DELSEARCH, bEnable); EnableInterface(pw, EVENT_OBJECT_TERRAFORM, bEnable); EnableInterface(pw, EVENT_OBJECT_RECOVER, bEnable); EnableInterface(pw, EVENT_OBJECT_FIRE, bEnable); EnableInterface(pw, EVENT_OBJECT_BUILD, 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? type == OBJECT_MOBILEfb || type == OBJECT_MOBILEtb || type == OBJECT_MOBILEwb || type == OBJECT_MOBILEib ) { 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_BSAFE, bEnable); } if ( type == OBJECT_HUMAN || // can create flags? type == OBJECT_TECH || type == OBJECT_MOBILEfs || type == OBJECT_MOBILEts || type == OBJECT_MOBILEws || type == OBJECT_MOBILEis ) { 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_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()); DefaultEnter (pw, EVENT_OBJECT_BEGSHIELD, !m_taskExecutor->IsBackgroundTask()); DefaultEnter (pw, EVENT_OBJECT_ENDSHIELD, m_taskExecutor->IsBackgroundTask()); } 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< CSlider* >(pw->SearchControl(EVENT_OBJECT_DIMSHIELD)); if ( ps != nullptr ) { ps->SetVisibleValue((RADIUS_SHIELD_MIN/g_unit)+dynamic_cast(*m_object).GetShieldRadius()*((RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)/g_unit)); } } if ( (type == OBJECT_MOBILEfb || type == OBJECT_MOBILEtb || type == OBJECT_MOBILEwb || type == OBJECT_MOBILEib) && // builder? !m_object->GetTrainer() ) { if(!bEnable) m_buildInterface = false; CheckInterface(pw, EVENT_OBJECT_BUILD, m_buildInterface); pb = static_cast< CButton* >(pw->SearchControl(EVENT_WINDOW3)); pb->SetState(STATE_VISIBLE, m_buildInterface); pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_BFACTORY)); pb->SetState(STATE_VISIBLE, m_buildInterface); pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_BDERRICK)); pb->SetState(STATE_VISIBLE, m_buildInterface); pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_BCONVERT)); pb->SetState(STATE_VISIBLE, m_buildInterface); pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_BSTATION)); pb->SetState(STATE_VISIBLE, m_buildInterface); pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_BREPAIR)); pb->SetState(STATE_VISIBLE, m_buildInterface); pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_BTOWER)); pb->SetState(STATE_VISIBLE, m_buildInterface); pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_BRESEARCH)); pb->SetState(STATE_VISIBLE, m_buildInterface); pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_BRADAR)); pb->SetState(STATE_VISIBLE, m_buildInterface); pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_BENERGY)); pb->SetState(STATE_VISIBLE, m_buildInterface); pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_BLABO)); pb->SetState(STATE_VISIBLE, m_buildInterface); pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_BNUCLEAR)); pb->SetState(STATE_VISIBLE, m_buildInterface); pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_BPARA)); pb->SetState(STATE_VISIBLE, m_buildInterface); pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_BSAFE)); pb->SetState(STATE_VISIBLE, m_buildInterface); pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_BINFO)); pb->SetState(STATE_VISIBLE, m_buildInterface); } bFly = bEnable; if ( bFly && (type == OBJECT_HUMAN || type == OBJECT_TECH) ) { if (dynamic_cast(*m_object).GetSlotContainedObjectOpt(CSlottedObject::Pseudoslot::CARRYING) != nullptr) bFly = false; } EnableInterface(pw, EVENT_OBJECT_GASUP, bFly && m_main->CanPlayerInteract()); EnableInterface(pw, EVENT_OBJECT_GASDOWN, bFly && m_main->CanPlayerInteract()); if ( m_object->GetTrainer() ) // Training? { DeadInterface(pw, EVENT_OBJECT_GASUP, false); DeadInterface(pw, EVENT_OBJECT_GASDOWN, false); } else { DeadInterface(pw, EVENT_OBJECT_GASUP, m_main->IsResearchDone(RESEARCH_FLY, m_object->GetTeam())); DeadInterface(pw, EVENT_OBJECT_GASDOWN, m_main->IsResearchDone(RESEARCH_FLY, m_object->GetTeam())); } if ( type == OBJECT_HUMAN || type == OBJECT_TECH || type == OBJECT_MOBILEfa || type == OBJECT_MOBILEta || type == OBJECT_MOBILEwa || type == OBJECT_MOBILEia || type == OBJECT_MOBILEfb || type == OBJECT_MOBILEtb || type == OBJECT_MOBILEwb || type == OBJECT_MOBILEib || 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_MOBILErp || type == OBJECT_MOBILEst || 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_selScript >= 0 && m_selScript < m_programStorage->GetProgramCount()) { if (m_programStorage->GetProgram(m_selScript)->runnable) { std::string title = m_programStorage->GetProgram(m_selScript)->script->GetTitle(); if ( !title.empty() ) { bRun = true; } } else { 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 != nullptr ) { pb->SetIcon(!m_programmable->IsProgram() ? 21 : 8); // run/stop } //? pb = (CButton*)pw->SearchControl(EVENT_OBJECT_PROGEDIT); //? if ( pb != 0 ) //? { //? pb->SetIcon(!m_programmable->IsProgram() ? 22 : 40); // edit/debug //? } BlinkScript(m_programmable->IsProgram()); // 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); } CTraceDrawingObject* traceDrawing = nullptr; if (m_object->Implements(ObjectInterfaceType::TraceDrawing)) traceDrawing = dynamic_cast(m_object); if (traceDrawing != nullptr && traceDrawing->GetTraceDown()) { pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_PEN0)); if ( pb != nullptr ) { pb->ClearState(STATE_CHECK); } TraceColor color = traceDrawing->GetTraceColor(); pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN1)); if ( pc != nullptr ) { pc->SetState(STATE_CHECK, color == TraceColor::Black); } pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN2)); if ( pc != nullptr ) { pc->SetState(STATE_CHECK, color == TraceColor::Yellow); } pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN3)); if ( pc != nullptr ) { pc->SetState(STATE_CHECK, color == TraceColor::Orange); } pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN4)); if ( pc != nullptr ) { pc->SetState(STATE_CHECK, color == TraceColor::Red); } pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN5)); if ( pc != nullptr ) { pc->SetState(STATE_CHECK, color == TraceColor::Purple); } pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN6)); if ( pc != nullptr ) { pc->SetState(STATE_CHECK, color == TraceColor::Blue); } pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN7)); if ( pc != nullptr ) { pc->SetState(STATE_CHECK, color == TraceColor::Green); } pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN8)); if ( pc != nullptr ) { pc->SetState(STATE_CHECK, color == TraceColor::Brown); } } else { pb = static_cast< CButton* >(pw->SearchControl(EVENT_OBJECT_PEN0)); if ( pb != nullptr ) { pb->SetState(STATE_CHECK); } pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN1)); if ( pc != nullptr ) { pc->ClearState(STATE_CHECK); } pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN2)); if ( pc != nullptr ) { pc->ClearState(STATE_CHECK); } pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN3)); if ( pc != nullptr ) { pc->ClearState(STATE_CHECK); } pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN4)); if ( pc != nullptr ) { pc->ClearState(STATE_CHECK); } pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN5)); if ( pc != nullptr ) { pc->ClearState(STATE_CHECK); } pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN6)); if ( pc != nullptr ) { pc->ClearState(STATE_CHECK); } pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN7)); if ( pc != nullptr ) { pc->ClearState(STATE_CHECK); } pc = static_cast< CColor* >(pw->SearchControl(EVENT_OBJECT_PEN8)); if ( pc != nullptr ) { pc->ClearState(STATE_CHECK); } } } // Updates the list of programs. void CObjectInterface::UpdateScript(CWindow *pw) { CList* pl; std::array name; pl = static_cast< CList* >(pw->SearchControl(EVENT_OBJECT_PROGLIST)); if ( pl == nullptr ) return; pl->Flush(); for ( int i = 0 ; i < m_programStorage->GetProgramCount() ; i++ ) { snprintf(name.data(), name.size(), "%d", i+1); std::string title = m_programStorage->GetProgram(i)->script->GetTitle(); if ( !title.empty() ) { if(!m_programStorage->GetProgram(i)->readOnly) { snprintf(name.data(), name.size(), "%d: %s", i+1, title.c_str()); } else { snprintf(name.data(), name.size(), "*%d: %s", i+1, title.c_str()); } } pl->SetItemName(i, name.data()); } pl->SetSelect(m_selScript); pl->ShowSelect(true); } // Returns the rank of selected script. int CObjectInterface::GetSelScript() { CWindow* pw; CList* pl; pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == nullptr ) return -1; pl = static_cast< CList* >(pw->SearchControl(EVENT_OBJECT_PROGLIST)); if ( pl == nullptr ) return -1; return pl->GetSelect(); } // Changes selected script void CObjectInterface::SetSelScript(int index) { CWindow* pw; CList* pl; pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == nullptr ) return; pl = static_cast< CList* >(pw->SearchControl(EVENT_OBJECT_PROGLIST)); if ( pl == nullptr ) return; pl->SetSelect(index); pl->ShowSelect(true); } // Blinks the running program. void CObjectInterface::BlinkScript(bool bEnable) { CWindow* pw; CList* pl; if ( !m_object->GetSelect() ) return; // robot not selected? pw = static_cast< CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == nullptr ) return; pl = static_cast< CList* >(pw->SearchControl(EVENT_OBJECT_PROGLIST)); if ( pl == nullptr ) return; pl->SetBlink(bEnable); } // Check the status of a button interface. void CObjectInterface::CheckInterface(CWindow *pw, EventType event, bool bState) { CControl* control; control = pw->SearchControl(event); if ( control == nullptr ) return; control->SetState(STATE_CHECK, bState); } // Changes the state of a button interface. void CObjectInterface::EnableInterface(CWindow *pw, EventType event, bool bState) { CControl* control; control = pw->SearchControl(event); if ( control == nullptr ) return; control->SetState(STATE_ENABLE, bState); } // Changes the state of a button on the interface. void CObjectInterface::DeadInterface(CWindow *pw, EventType event, bool bState) { CControl* control; control = pw->SearchControl(event); if ( control == nullptr ) return; control->SetState(STATE_DEAD, !bState); } // Change the default input state of a button interface. void CObjectInterface::DefaultEnter(CWindow *pw, EventType event, bool bState) { CControl* control; control = pw->SearchControl(event); if ( control == nullptr ) return; if ( bState ) { control->SetState(STATE_DEFAULT); m_defaultEnter = event; } else { control->ClearState(STATE_DEFAULT); } } } // namespace Ui