// * 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/.// robotmain.cpp #define STRICT #define D3D_OVERLOADS #include #include #include #include "cbot/cbotdll.h" #include "struct.h" #include "D3DEngine.h" #include "D3DMath.h" #include "language.h" #include "global.h" #include "event.h" #include "misc.h" #include "profile.h" #include "iman.h" #include "restext.h" #include "math3d.h" #include "light.h" #include "particule.h" #include "terrain.h" #include "water.h" #include "cloud.h" #include "blitz.h" #include "planet.h" #include "object.h" #include "motion.h" #include "motiontoto.h" #include "motionhuman.h" #include "physics.h" #include "brain.h" #include "pyro.h" #include "modfile.h" #include "model.h" #include "camera.h" #include "task.h" #include "taskmanip.h" #include "taskbuild.h" #include "auto.h" #include "autobase.h" #include "displayinfo.h" #include "interface.h" #include "shortcut.h" #include "map.h" #include "label.h" #include "button.h" #include "slider.h" #include "window.h" #include "edit.h" #include "displaytext.h" #include "text.h" #include "sound.h" #include "cbottoken.h" #include "cmdtoken.h" #include "mainmovie.h" #include "maindialog.h" #include "mainshort.h" #include "mainmap.h" #include "script.h" #include "robotmain.h" #define CBOT_STACK TRUE // enregistre le stack des programmes CBOT #define UNIT 4.0f // Variables globales. long g_id; // identificateur unique long g_build; // bâtiments constructibles long g_researchDone; // recherches effectuées long g_researchEnable; // recherches accessibles float g_unit; // facteur de conversion #include "classfile.cpp" // Compilation de la classe "point". CBotTypResult cPoint(CBotVar* pThis, CBotVar* &var) { if ( !pThis->IsElemOfClass("point") ) return CBotTypResult(CBotErrBadNum); if ( var == NULL ) return CBotTypResult(0); // ok si aucun paramètre // Premier paramètre (x) : if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); var = var->GivNext(); // Deuxième paramètre (y) : if ( var == NULL ) return CBotTypResult(CBotErrLowParam); if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); var = var->GivNext(); // Troisième paramètre (z) : if ( var == NULL ) // seulement 2 paramètres ? { return CBotTypResult(0); // cette fonction retourne void } if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); var = var->GivNext(); if ( var != NULL ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(0); // cette fonction retourne void } // Exécution de la classe "point". BOOL rPoint(CBotVar* pThis, CBotVar* var, CBotVar* pResult, int& Exception) { CBotVar *pX, *pY, *pZ; if ( var == NULL ) return TRUE; // constructeur sans paramètres est ok if ( var->GivType() > CBotTypDouble ) { Exception = CBotErrBadNum; return FALSE; } pX = pThis->GivItem("x"); if ( pX == NULL ) { Exception = CBotErrUndefItem; return FALSE; } pX->SetValFloat( var->GivValFloat() ); var = var->GivNext(); if ( var == NULL ) { Exception = CBotErrLowParam; return FALSE; } if ( var->GivType() > CBotTypDouble ) { Exception = CBotErrBadNum; return FALSE; } pY = pThis->GivItem("y"); if ( pY == NULL ) { Exception = CBotErrUndefItem; return FALSE; } pY->SetValFloat( var->GivValFloat() ); var = var->GivNext(); if ( var == NULL ) { return TRUE; // ok avec seulement 2 paramètres } pZ = pThis->GivItem("z"); if ( pZ == NULL ) { Exception = CBotErrUndefItem; return FALSE; } pZ->SetValFloat( var->GivValFloat() ); var = var->GivNext(); if ( var != NULL ) { Exception = CBotErrOverParam; return FALSE; } return TRUE; // pas d'interruption } // Constructeur de l'application robot. CRobotMain::CRobotMain(CInstanceManager* iMan) { ObjectType type; float fValue; int iValue, i; char* token; m_iMan = iMan; m_iMan->AddInstance(CLASS_MAIN, this); m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); m_cloud = (CCloud*)m_iMan->SearchInstance(CLASS_CLOUD); m_blitz = (CBlitz*)m_iMan->SearchInstance(CLASS_BLITZ); m_planet = (CPlanet*)m_iMan->SearchInstance(CLASS_PLANET); m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); m_interface = new CInterface(m_iMan); m_terrain = new CTerrain(m_iMan); m_model = new CModel(m_iMan); m_camera = new CCamera(m_iMan); m_displayText = new CDisplayText(m_iMan); m_movie = new CMainMovie(m_iMan); m_dialog = new CMainDialog(m_iMan); m_short = new CMainShort(m_iMan); m_map = new CMainMap(m_iMan); m_displayInfo = 0; m_engine->SetTerrain(m_terrain); m_filesDir = m_dialog->RetFilesDir(); m_time = 0.0f; m_gameTime = 0.0f; m_checkEndTime = 0.0f; m_phase = PHASE_NAME; m_cameraRank = -1; m_visitLast = EVENT_NULL; m_visitObject = 0; m_visitArrow = 0; m_audioTrack = 0; m_bAudioRepeat = TRUE; m_delayWriteMessage = 0; m_selectObject = 0; m_infoUsed = 0; m_bBeginSatCom = FALSE; m_bMovieLock = FALSE; m_bSatComLock = FALSE; m_bEditLock = FALSE; m_bEditFull = FALSE; m_bPause = FALSE; m_bHilite = FALSE; m_bFreePhoto = FALSE; m_bShowPos = FALSE; m_bSelectInsect = FALSE; m_bShowSoluce = FALSE; m_bShowAll = FALSE; m_bCheatRadar = FALSE; m_bFixScene = FALSE; m_bTrainerPilot = FALSE; m_bSuspend = FALSE; m_bFriendAim = FALSE; m_bResetCreate = FALSE; m_bShortCut = TRUE; m_engine->SetMovieLock(m_bMovieLock); m_movie->Flush(); m_movieInfoIndex = -1; m_tooltipPos = FPOINT(0.0f, 0.0f); m_tooltipName[0] = 0; m_tooltipTime = 0.0f; m_endingWinRank = 0; m_endingLostRank = 0; m_bWinTerminate = FALSE; FlushDisplayInfo(); m_fontSize = 9.0f; m_windowPos = FPOINT(0.15f, 0.17f); m_windowDim = FPOINT(0.70f, 0.66f); if ( GetProfileFloat("Edit", "FontSize", fValue) ) m_fontSize = fValue; if ( GetProfileFloat("Edit", "WindowPos.x", fValue) ) m_windowPos.x = fValue; if ( GetProfileFloat("Edit", "WindowPos.y", fValue) ) m_windowPos.y = fValue; if ( GetProfileFloat("Edit", "WindowDim.x", fValue) ) m_windowDim.x = fValue; if ( GetProfileFloat("Edit", "WindowDim.y", fValue) ) m_windowDim.y = fValue; m_IOPublic = FALSE; m_IODim = FPOINT(320.0f/640.0f, (121.0f+18.0f*8)/480.0f); m_IOPos.x = (1.0f-m_IODim.x)/2.0f; // au milieu m_IOPos.y = (1.0f-m_IODim.y)/2.0f; if ( GetProfileInt ("Edit", "IOPublic", iValue) ) m_IOPublic = iValue; if ( GetProfileFloat("Edit", "IOPos.x", fValue) ) m_IOPos.x = fValue; if ( GetProfileFloat("Edit", "IOPos.y", fValue) ) m_IOPos.y = fValue; if ( GetProfileFloat("Edit", "IODim.x", fValue) ) m_IODim.x = fValue; if ( GetProfileFloat("Edit", "IODim.y", fValue) ) m_IODim.y = fValue; m_short->FlushShortcuts(); InitEye(); m_engine->SetTracePrecision(1.0f); m_cameraPan = 0.0f; m_cameraZoom = 0.0f; g_id = 0; g_build = 0; g_researchDone = 0; // aucune recherche effectuée g_researchEnable = 0; g_unit = 4.0f; m_gamerName[0] = 0; GetProfileString("Gamer", "LastName", m_gamerName, 100); SetGlobalGamerName(m_gamerName); ReadFreeParam(); m_dialog->SetupRecall(); for ( i=0 ; iAddItem("x", CBotTypFloat); bc->AddItem("y", CBotTypFloat); bc->AddItem("z", CBotTypFloat); bc->AddFunction("point", rPoint, cPoint); // Ajoute la classe Object. bc = new CBotClass("object", NULL); bc->AddItem("category", CBotTypResult(CBotTypInt), PR_READ); bc->AddItem("position", CBotTypResult(CBotTypClass, "point"), PR_READ); bc->AddItem("orientation", CBotTypResult(CBotTypFloat), PR_READ); bc->AddItem("pitch", CBotTypResult(CBotTypFloat), PR_READ); bc->AddItem("roll", CBotTypResult(CBotTypFloat), PR_READ); bc->AddItem("energyLevel", CBotTypResult(CBotTypFloat), PR_READ); bc->AddItem("shieldLevel", CBotTypResult(CBotTypFloat), PR_READ); bc->AddItem("temperature", CBotTypResult(CBotTypFloat), PR_READ); bc->AddItem("altitude", CBotTypResult(CBotTypFloat), PR_READ); bc->AddItem("lifeTime", CBotTypResult(CBotTypFloat), PR_READ); bc->AddItem("material", CBotTypResult(CBotTypInt), PR_READ); bc->AddItem("energyCell", CBotTypResult(CBotTypPointer, "object"), PR_READ); bc->AddItem("load", CBotTypResult(CBotTypPointer, "object"), PR_READ); // Initialise la classe FILE. InitClassFILE(); CScript::InitFonctions(); } // Destructeur de l'application robot. CRobotMain::~CRobotMain() { delete m_movie; delete m_dialog; delete m_short; delete m_map; delete m_terrain; delete m_model; } // Crée le fichier colobot.ini la première fois. void CRobotMain::CreateIni() { int iValue; // colobot.ini inexistant ? if ( !GetProfileInt("Setup", "TotoMode", iValue) ) { m_dialog->SetupMemorize(); } } // Change de phase. void CRobotMain::ChangePhase(Phase phase) { CEdit* pe; CButton* pb; D3DCOLORVALUE color; FPOINT pos, dim, ddim; float ox, oy, sx, sy; char* read; int rank, numTry; BOOL bLoading; if ( m_phase == PHASE_SIMUL ) // termine une simulation ? { SaveAllScript(); m_sound->StopMusic(); m_camera->SetObject(0); #if _SCHOOL if ( TRUE ) #else if ( m_gameTime > 10.0f ) // a-t-on joué au moins 10 secondes ? #endif { rank = m_dialog->RetSceneRank(); numTry = m_dialog->RetGamerInfoTry(rank); m_dialog->SetGamerInfoTry(rank, numTry+1); m_dialog->WriteGamerInfo(); } } if ( phase == PHASE_WIN ) // gagné une simulation ? { rank = m_dialog->RetSceneRank(); m_dialog->SetGamerInfoPassed(rank, TRUE); m_dialog->NextMission(); // passe à la mission suivante m_dialog->WriteGamerInfo(); } DeleteAllObjects(); // supprime toute la scène 3D actuelle m_phase = phase; m_winDelay = 0.0f; m_lostDelay = 0.0f; m_bBeginSatCom = FALSE; m_bMovieLock = FALSE; m_bSatComLock = FALSE; m_bEditLock = FALSE; m_bFreePhoto = FALSE; m_bResetCreate = FALSE; m_engine->SetMovieLock(m_bMovieLock); ChangePause(FALSE); FlushDisplayInfo(); m_engine->SetRankView(0); m_engine->FlushObject(); color.r = color.g = color.b = color.a = 0.0f; m_engine->SetWaterAddColor(color); m_engine->SetBackground(""); m_engine->SetBackForce(FALSE); m_engine->SetFrontsizeName(""); m_engine->SetOverColor(); m_engine->GroundMarkDelete(0); SetSpeed(1.0f); m_terrain->SetWind(D3DVECTOR(0.0f, 0.0f, 0.0f)); m_terrain->FlushBuildingLevel(); m_terrain->FlushFlyingLimit(); m_light->FlushLight(); m_particule->FlushParticule(); m_water->Flush(); m_cloud->Flush(); m_blitz->Flush(); m_planet->Flush(); m_iMan->Flush(CLASS_OBJECT); m_iMan->Flush(CLASS_PHYSICS); m_iMan->Flush(CLASS_BRAIN); m_iMan->Flush(CLASS_PYRO); m_model->StopUserAction(); m_interface->Flush(); ClearInterface(); FlushNewScriptName(); m_sound->SetListener(D3DVECTOR(0.0f, 0.0f, 0.0f), D3DVECTOR(0.0f, 0.0f, 1.0f)); m_camera->SetType(CAMERA_DIALOG); m_movie->Flush(); m_movieInfoIndex = -1; m_cameraPan = 0.0f; m_cameraZoom = 0.0f; m_bShortCut = TRUE; // Crée et cache la console de commande. dim.x = 200.0f/640.0f; dim.y = 18.0f/480.0f; pos.x = 50.0f/640.0f; pos.y = 452.0f/480.0f; pe = m_interface->CreateEdit(pos, dim, 0, EVENT_CMD); if ( pe == 0 ) return; pe->ClearState(STATE_VISIBLE); m_bCmdEdit = FALSE; // caché pour l'instant // Crée l'indicateur de vitesse. #if _TEEN dim.x = 30.0f/640.0f; dim.y = 20.0f/480.0f; pos.x = 4.0f/640.0f; pos.y = 454.0f/480.0f; #else dim.x = 30.0f/640.0f; dim.y = 20.0f/480.0f; pos.x = 4.0f/640.0f; pos.y = 426.0f/480.0f; #endif pb = m_interface->CreateButton(pos, dim, 0, EVENT_SPEED); if ( pb == 0 ) return; pb->SetState(STATE_SIMPLY); pb->ClearState(STATE_VISIBLE); m_dialog->ChangePhase(m_phase); dim.x = 32.0f/640.0f; dim.y = 32.0f/480.0f; ox = 3.0f/640.0f; oy = 3.0f/480.0f; sx = (32.0f+2.0f)/640.0f; sy = (32.0f+2.0f)/480.0f; if ( m_phase != PHASE_PERSO ) { m_engine->SetDrawWorld(TRUE); m_engine->SetDrawFront(FALSE); m_bFixScene = FALSE; } if ( m_phase == PHASE_INIT ) { #if _NEWLOOK m_engine->FreeTexture("generna.tga"); m_engine->FreeTexture("genernb.tga"); m_engine->FreeTexture("genernc.tga"); m_engine->FreeTexture("genernd.tga"); #else #if _FRENCH #if _DEMO m_engine->FreeTexture("genedfa.tga"); m_engine->FreeTexture("genedfb.tga"); m_engine->FreeTexture("genedfc.tga"); m_engine->FreeTexture("genedfd.tga"); #else m_engine->FreeTexture("generfa.tga"); m_engine->FreeTexture("generfb.tga"); m_engine->FreeTexture("generfc.tga"); m_engine->FreeTexture("generfd.tga"); #endif #endif #if _ENGLISH #if _DEMO m_engine->FreeTexture("genedea.tga"); m_engine->FreeTexture("genedeb.tga"); m_engine->FreeTexture("genedec.tga"); m_engine->FreeTexture("geneded.tga"); #else m_engine->FreeTexture("generea.tga"); m_engine->FreeTexture("genereb.tga"); m_engine->FreeTexture("generec.tga"); m_engine->FreeTexture("genered.tga"); #endif #endif #if _GERMAN #if _DEMO m_engine->FreeTexture("genedda.tga"); m_engine->FreeTexture("geneddb.tga"); m_engine->FreeTexture("geneddc.tga"); m_engine->FreeTexture("geneddd.tga"); #else m_engine->FreeTexture("generea.tga"); m_engine->FreeTexture("genereb.tga"); m_engine->FreeTexture("generec.tga"); m_engine->FreeTexture("genered.tga"); #endif #endif #if _WG #if _DEMO m_engine->FreeTexture("genedda.tga"); m_engine->FreeTexture("geneddb.tga"); m_engine->FreeTexture("geneddc.tga"); m_engine->FreeTexture("geneddd.tga"); #else m_engine->FreeTexture("generda.tga"); m_engine->FreeTexture("generdb.tga"); m_engine->FreeTexture("generdc.tga"); m_engine->FreeTexture("generdd.tga"); #endif #endif #if _POLISH #if _DEMO m_engine->FreeTexture("genedpa.tga"); m_engine->FreeTexture("genedpb.tga"); m_engine->FreeTexture("genedpc.tga"); m_engine->FreeTexture("genedpd.tga"); #else m_engine->FreeTexture("generpa.tga"); m_engine->FreeTexture("generpb.tga"); m_engine->FreeTexture("generpc.tga"); m_engine->FreeTexture("generpd.tga"); #endif #endif #endif } if ( m_phase == PHASE_SIMUL ) { m_engine->FreeTexture("inter01a.tga"); m_engine->FreeTexture("inter01b.tga"); m_engine->FreeTexture("inter01c.tga"); m_engine->FreeTexture("inter01d.tga"); read = m_dialog->RetSceneRead(); bLoading = (read[0] != 0); m_map->CreateMap(); CreateScene(m_dialog->RetSceneSoluce(), FALSE, FALSE); // scène interractive if ( m_bMapImage ) { m_map->SetFixImage(m_mapFilename); } pos.x = 620.0f/640.0f; pos.y = 460.0f/480.0f; ddim.x = 20.0f/640.0f; ddim.y = 20.0f/480.0f; m_interface->CreateButton(pos, ddim, 11, EVENT_BUTTON_QUIT); if ( m_bImmediatSatCom && !bLoading && m_infoFilename[SATCOM_HUSTON][0] != 0 ) { StartDisplayInfo(SATCOM_HUSTON, FALSE); // affiche les instructions } m_sound->StopMusic(); if ( !m_bBase || bLoading ) StartMusic(); } if ( m_phase == PHASE_WIN ) { if ( m_endingWinRank == -1 ) { ChangePhase(PHASE_TERM); } else { #if _TEEN m_bWinTerminate = (m_endingWinRank == 900); m_dialog->SetSceneName("teenw"); #else m_bWinTerminate = (m_endingWinRank == 904); m_dialog->SetSceneName("win"); #endif m_dialog->SetSceneRank(m_endingWinRank); CreateScene(FALSE, TRUE, FALSE); // scène fixe pos.x = ox+sx*1; pos.y = oy+sy*1; ddim.x = dim.x*2; ddim.y = dim.y*2; m_interface->CreateButton(pos, ddim, 16, EVENT_BUTTON_OK); if ( m_bWinTerminate ) { #if _TEEN pos.x = ox+sx*3; pos.y = oy+sy*1; ddim.x = dim.x*15; ddim.y = dim.y*2; pe = m_interface->CreateEdit(pos, ddim, 0, EVENT_EDIT0); pe->SetFontType(FONT_COLOBOT); pe->SetEditCap(FALSE); pe->SetHiliteCap(FALSE); pe->ReadText("help\\teenw.txt"); #else pos.x = ox+sx*3; pos.y = oy+sy*0.2f; ddim.x = dim.x*15; ddim.y = dim.y*3.0f; pe = m_interface->CreateEdit(pos, ddim, 0, EVENT_EDIT0); pe->SetGenericMode(TRUE); pe->SetFontType(FONT_COLOBOT); pe->SetEditCap(FALSE); pe->SetHiliteCap(FALSE); pe->ReadText("help\\win.txt"); #endif } else { m_displayText->DisplayError(INFO_WIN, D3DVECTOR(0.0f,0.0f,0.0f), 15.0f, 60.0f, 1000.0f); } } m_sound->StopAll(); StartMusic(); } if ( m_phase == PHASE_LOST ) { if ( m_endingLostRank == -1 ) { ChangePhase(PHASE_TERM); } else { m_bWinTerminate = FALSE; m_dialog->SetSceneName("lost"); m_dialog->SetSceneRank(m_endingLostRank); CreateScene(FALSE, TRUE, FALSE); // scène fixe pos.x = ox+sx*1; pos.y = oy+sy*1; ddim.x = dim.x*2; ddim.y = dim.y*2; m_interface->CreateButton(pos, ddim, 16, EVENT_BUTTON_OK); m_displayText->DisplayError(INFO_LOST, D3DVECTOR(0.0f,0.0f,0.0f), 15.0f, 60.0f, 1000.0f); } m_sound->StopAll(); StartMusic(); } if ( m_phase == PHASE_MODEL ) { pos.x = ox+sx*0; pos.y = oy+sy*0; m_interface->CreateButton(pos, dim, 11, EVENT_BUTTON_CANCEL); CreateModel(); } if ( m_phase == PHASE_LOADING ) { m_engine->SetMouseHide(TRUE); } else { m_engine->SetMouseHide(FALSE); } m_engine->LoadAllTexture(); } // Traite un événement. BOOL CRobotMain::EventProcess(const Event &event) { CEdit* pe; CObject* pObj; Event newEvent; MainMovieType type; int i; if ( event.event == EVENT_FRAME ) { if ( !m_movie->EventProcess(event) ) // fin du film ? { type = m_movie->RetStopType(); if ( type == MM_SATCOMopen ) { ChangePause(FALSE); SelectObject(m_infoObject, FALSE); // remet les boutons de commande m_map->ShowMap(m_bMapShow); m_displayText->HideText(FALSE); i = m_movieInfoIndex; StartDisplayInfo(m_movieInfoIndex, FALSE); m_movieInfoIndex = i; } } m_dialog->EventProcess(event); m_displayText->EventProcess(event); RemoteCamera(m_cameraPan, m_cameraZoom, event.rTime); m_interface->EventProcess(event); if ( m_displayInfo != 0 ) // édition en cours ? { m_displayInfo->EventProcess(event); } return EventFrame(event); } // Gestion de la console de commande. #if 0 if ( m_phase != PHASE_NAME && !m_movie->IsExist() && event.event == EVENT_KEYDOWN && event.param == VK_PAUSE && (event.keyState&KS_CONTROL) != 0 ) #else if ( m_phase != PHASE_NAME && !m_movie->IsExist() && event.event == EVENT_KEYDOWN && event.param == VK_CANCEL ) // Ctrl+Pause ? #endif { pe = (CEdit*)m_interface->SearchControl(EVENT_CMD); if ( pe == 0 ) return FALSE; pe->SetState(STATE_VISIBLE); pe->SetFocus(TRUE); if ( m_phase == PHASE_SIMUL ) ChangePause(TRUE); m_bCmdEdit = TRUE; return FALSE; } if ( event.event == EVENT_KEYDOWN && event.param == VK_RETURN && m_bCmdEdit ) { char cmd[50]; pe = (CEdit*)m_interface->SearchControl(EVENT_CMD); if ( pe == 0 ) return FALSE; pe->GetText(cmd, 50); pe->SetText(""); pe->ClearState(STATE_VISIBLE); if ( m_phase == PHASE_SIMUL ) ChangePause(FALSE); ExecuteCmd(cmd); m_bCmdEdit = FALSE; return FALSE; } // Gestion du changement de vitesse. if ( event.event == EVENT_SPEED ) { SetSpeed(1.0f); } if ( !m_dialog->EventProcess(event) ) { if ( event.event == EVENT_MOUSEMOVE ) { m_lastMousePos = event.pos; HiliteObject(event.pos); } return FALSE; } if ( !m_displayText->EventProcess(event) ) { return FALSE; } if ( event.event == EVENT_MOUSEMOVE ) { m_lastMousePos = event.pos; HiliteObject(event.pos); } if ( m_displayInfo != 0 ) // info en cours ? { m_displayInfo->EventProcess(event); if ( event.event == EVENT_KEYDOWN ) { if ( event.param == m_engine->RetKey(KEYRANK_HELP, 0) || event.param == m_engine->RetKey(KEYRANK_HELP, 1) || event.param == m_engine->RetKey(KEYRANK_PROG, 0) || event.param == m_engine->RetKey(KEYRANK_PROG, 1) || event.param == VK_ESCAPE ) { StopDisplayInfo(); } } if ( event.event == EVENT_OBJECT_INFOOK ) { StopDisplayInfo(); } return FALSE; } // Phase de simulation du jeu. if ( m_phase == PHASE_SIMUL ) { UpdateInfoText(); if ( !m_bEditFull ) { m_camera->EventProcess(event); } switch( event.event ) { case EVENT_KEYDOWN: KeyCamera(event.event, event.param); HiliteClear(); if ( event.param == VK_F11 ) { m_particule->WriteWheelTrace("Savegame\\t.bmp", 256, 256, D3DVECTOR(16.0f, 0.0f, -368.0f), D3DVECTOR(140.0f, 0.0f, -248.0f)); return FALSE; } if ( m_bEditLock ) // édition en cours ? { if ( event.param == m_engine->RetKey(KEYRANK_HELP, 0) || event.param == m_engine->RetKey(KEYRANK_HELP, 1) ) { StartDisplayInfo(SATCOM_HUSTON, FALSE); return FALSE; } if ( event.param == m_engine->RetKey(KEYRANK_PROG, 0) || event.param == m_engine->RetKey(KEYRANK_PROG, 1) ) { StartDisplayInfo(SATCOM_PROG, FALSE); return FALSE; } break; } if ( m_bMovieLock ) // film en cours ? { if ( event.param == m_engine->RetKey(KEYRANK_QUIT, 0) || event.param == m_engine->RetKey(KEYRANK_QUIT, 1) || event.param == VK_ESCAPE ) { AbortMovie(); } return FALSE; } if ( m_camera->RetType() == CAMERA_VISIT ) { if ( event.param == m_engine->RetKey(KEYRANK_VISIT, 0) || event.param == m_engine->RetKey(KEYRANK_VISIT, 1) ) { StartDisplayVisit(EVENT_NULL); } if ( event.param == m_engine->RetKey(KEYRANK_QUIT, 0) || event.param == m_engine->RetKey(KEYRANK_QUIT, 1) || event.param == VK_ESCAPE ) { StopDisplayVisit(); } return FALSE; } if ( event.param == m_engine->RetKey(KEYRANK_QUIT, 0) || event.param == m_engine->RetKey(KEYRANK_QUIT, 1) ) { if ( m_movie->IsExist() ) { StartDisplayInfo(SATCOM_HUSTON, FALSE); } else if ( m_winDelay > 0.0f ) { ChangePhase(PHASE_WIN); } else if ( m_lostDelay > 0.0f ) { ChangePhase(PHASE_LOST); } else { m_dialog->StartAbort(); // voulez-vous quitter ? } } if ( event.param == VK_PAUSE ) { if ( !m_bMovieLock && !m_bEditLock && !m_bCmdEdit && m_camera->RetType() != CAMERA_VISIT && !m_movie->IsExist() ) { ChangePause(!m_engine->RetPause()); } } if ( event.param == m_engine->RetKey(KEYRANK_CAMERA, 0) || event.param == m_engine->RetKey(KEYRANK_CAMERA, 1) ) { ChangeCamera(); } if ( event.param == m_engine->RetKey(KEYRANK_DESEL, 0) || event.param == m_engine->RetKey(KEYRANK_DESEL, 1) ) { if ( m_bShortCut ) { DeselectObject(); } } if ( event.param == m_engine->RetKey(KEYRANK_HUMAN, 0) || event.param == m_engine->RetKey(KEYRANK_HUMAN, 1) ) { SelectHuman(); } if ( event.param == m_engine->RetKey(KEYRANK_NEXT, 0) || event.param == m_engine->RetKey(KEYRANK_NEXT, 1) ) { if ( m_bShortCut ) { m_short->SelectNext(); } } if ( event.param == m_engine->RetKey(KEYRANK_HELP, 0) || event.param == m_engine->RetKey(KEYRANK_HELP, 1) ) { StartDisplayInfo(SATCOM_HUSTON, TRUE); } if ( event.param == m_engine->RetKey(KEYRANK_PROG, 0) || event.param == m_engine->RetKey(KEYRANK_PROG, 1) ) { StartDisplayInfo(SATCOM_PROG, TRUE); } if ( event.param == m_engine->RetKey(KEYRANK_VISIT, 0) || event.param == m_engine->RetKey(KEYRANK_VISIT, 1) ) { StartDisplayVisit(EVENT_NULL); } if ( event.param == m_engine->RetKey(KEYRANK_SPEED10, 0) || event.param == m_engine->RetKey(KEYRANK_SPEED10, 1) ) { SetSpeed(1.0f); } if ( event.param == m_engine->RetKey(KEYRANK_SPEED15, 0) || event.param == m_engine->RetKey(KEYRANK_SPEED15, 1) ) { SetSpeed(1.5f); } if ( event.param == m_engine->RetKey(KEYRANK_SPEED20, 0) || event.param == m_engine->RetKey(KEYRANK_SPEED20, 1) ) { SetSpeed(2.0f); } if ( event.param == m_engine->RetKey(KEYRANK_SPEED30, 0) || event.param == m_engine->RetKey(KEYRANK_SPEED30, 1) ) { SetSpeed(3.0f); } break; case EVENT_KEYUP: KeyCamera(event.event, event.param); break; case EVENT_LBUTTONDOWN: pObj = DetectObject(event.pos); if ( !m_bShortCut ) pObj = 0; if ( pObj != 0 && pObj->RetType() == OBJECT_TOTO ) { if ( m_displayInfo != 0 ) // info en cours ? { StopDisplayInfo(); } else { if ( !m_bEditLock ) { StartDisplayInfo(SATCOM_HUSTON, TRUE); } } } else { SelectObject(pObj); } break; case EVENT_LBUTTONUP: m_cameraPan = 0.0f; m_cameraZoom = 0.0f; break; case EVENT_BUTTON_QUIT: if ( m_movie->IsExist() ) { StartDisplayInfo(SATCOM_HUSTON, FALSE); } else if ( m_winDelay > 0.0f ) { ChangePhase(PHASE_WIN); } else if ( m_lostDelay > 0.0f ) { ChangePhase(PHASE_LOST); } else { m_dialog->StartAbort(); // voulez-vous quitter ? } break; case EVENT_OBJECT_LIMIT: StartShowLimit(); break; case EVENT_OBJECT_DESELECT: if ( m_bShortCut ) { DeselectObject(); } break; case EVENT_OBJECT_HELP: HelpObject(); break; case EVENT_OBJECT_CAMERA: ChangeCamera(); break; case EVENT_OBJECT_CAMERAleft: m_cameraPan = -1.0f; break; case EVENT_OBJECT_CAMERAright: m_cameraPan = 1.0f; break; case EVENT_OBJECT_CAMERAnear: m_cameraZoom = -1.0f; break; case EVENT_OBJECT_CAMERAaway: m_cameraZoom = 1.0f; break; case EVENT_OBJECT_DELETE: m_dialog->StartDeleteObject(); // voulez-vous détruire ? break; case EVENT_OBJECT_BHELP: StartDisplayInfo(SATCOM_HUSTON, TRUE); break; case EVENT_OBJECT_SOLUCE: StartDisplayInfo(SATCOM_SOLUCE, TRUE); break; case EVENT_OBJECT_MAPZOOM: m_map->ZoomMap(); break; case EVENT_DT_VISIT0: case EVENT_DT_VISIT1: case EVENT_DT_VISIT2: case EVENT_DT_VISIT3: case EVENT_DT_VISIT4: StartDisplayVisit(event.event); break; case EVENT_DT_END: StopDisplayVisit(); break; case EVENT_OBJECT_SHORTCUT00: case EVENT_OBJECT_SHORTCUT01: case EVENT_OBJECT_SHORTCUT02: case EVENT_OBJECT_SHORTCUT03: case EVENT_OBJECT_SHORTCUT04: case EVENT_OBJECT_SHORTCUT05: case EVENT_OBJECT_SHORTCUT06: case EVENT_OBJECT_SHORTCUT07: case EVENT_OBJECT_SHORTCUT08: case EVENT_OBJECT_SHORTCUT09: case EVENT_OBJECT_SHORTCUT10: case EVENT_OBJECT_SHORTCUT11: case EVENT_OBJECT_SHORTCUT12: case EVENT_OBJECT_SHORTCUT13: case EVENT_OBJECT_SHORTCUT14: case EVENT_OBJECT_SHORTCUT15: case EVENT_OBJECT_SHORTCUT16: case EVENT_OBJECT_SHORTCUT17: case EVENT_OBJECT_SHORTCUT18: case EVENT_OBJECT_SHORTCUT19: m_short->SelectShortcut(event.event); break; case EVENT_OBJECT_MOVIELOCK: AbortMovie(); break; case EVENT_WIN: ChangePhase(PHASE_WIN); break; case EVENT_LOST: ChangePhase(PHASE_LOST); break; } EventObject(event); return FALSE; } if ( m_phase == PHASE_PERSO ) { EventObject(event); } if ( m_phase == PHASE_WIN || m_phase == PHASE_LOST ) { EventObject(event); switch( event.event ) { case EVENT_KEYDOWN: if ( event.param == VK_ESCAPE || event.param == VK_RETURN ) { if ( m_bWinTerminate ) { ChangePhase(PHASE_INIT); } else { ChangePhase(PHASE_TERM); } } break; case EVENT_BUTTON_OK: if ( m_bWinTerminate ) { ChangePhase(PHASE_INIT); } else { ChangePhase(PHASE_TERM); } break; } } if ( m_phase == PHASE_MODEL ) { switch( event.event ) { case EVENT_KEYDOWN: if ( event.param == VK_ESCAPE ) { ChangePhase(PHASE_INIT); } if ( event.param == VK_HOME ) { InitEye(); } break; case EVENT_BUTTON_CANCEL: ChangePhase(PHASE_INIT); break; } m_model->EventProcess(event); return FALSE; } return TRUE; } // Exécute une commande. void CRobotMain::ExecuteCmd(char *cmd) { if ( cmd[0] == 0 ) return; if ( m_phase == PHASE_SIMUL ) { if ( strcmp(cmd, "winmission") == 0 ) { Event newEvent; m_event->MakeEvent(newEvent, EVENT_WIN); m_event->AddEvent(newEvent); } if ( strcmp(cmd, "lostmission") == 0 ) { Event newEvent; m_event->MakeEvent(newEvent, EVENT_LOST); m_event->AddEvent(newEvent); } if ( strcmp(cmd, "trainerpilot") == 0 ) { m_bTrainerPilot = !m_bTrainerPilot; return; } if ( strcmp(cmd, "fly") == 0 ) { Event newEvent; g_researchDone |= RESEARCH_FLY; m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); m_event->AddEvent(newEvent); return; } if ( strcmp(cmd, "allresearch") == 0 ) { Event newEvent; g_researchDone = -1; // toutes les recherches sont effectuées m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); m_event->AddEvent(newEvent); return; } if ( strcmp(cmd, "nolimit") == 0 ) { m_terrain->SetFlyingMaxHeight(280.0f); return; } if ( strcmp(cmd, "photo1") == 0 ) { m_bFreePhoto = !m_bFreePhoto; if ( m_bFreePhoto ) { m_camera->SetType(CAMERA_FREE); ChangePause(TRUE); } else { m_camera->SetType(CAMERA_BACK); ChangePause(FALSE); } return; } if ( strcmp(cmd, "photo2") == 0 ) { m_bFreePhoto = !m_bFreePhoto; if ( m_bFreePhoto ) { m_camera->SetType(CAMERA_FREE); ChangePause(TRUE); DeselectAll(); // enlève les boutons de commande m_map->ShowMap(FALSE); m_displayText->HideText(TRUE); } else { m_camera->SetType(CAMERA_BACK); ChangePause(FALSE); m_map->ShowMap(m_bMapShow); m_displayText->HideText(FALSE); } return; } if ( strcmp(cmd, "noclip") == 0 ) { CObject* object; object = RetSelect(); if ( object != 0 ) { object->SetClip(FALSE); } return; } if ( strcmp(cmd, "clip") == 0 ) { CObject* object; object = RetSelect(); if ( object != 0 ) { object->SetClip(TRUE); } return; } if ( strcmp(cmd, "addhusky") == 0 ) { CObject* object; object = RetSelect(); if ( object != 0 ) { object->SetMagnifyDamage(object->RetMagnifyDamage()*0.1f); } return; } if ( strcmp(cmd, "addfreezer") == 0 ) { CObject* object; object = RetSelect(); if ( object != 0 ) { object->SetRange(object->RetRange()*10.0f); } return; } if ( strcmp(cmd, "fullpower") == 0 ) { CObject* object; CObject* power; CPhysics* physics; object = RetSelect(); if ( object != 0 ) { power = object->RetPower(); if ( power != 0 ) { power->SetEnergy(1.0f); } object->SetShield(1.0f); physics = object->RetPhysics(); if ( physics != 0 ) { physics->SetReactorRange(1.0f); } } return; } if ( strcmp(cmd, "fullenergy") == 0 ) { CObject* object; CObject* power; object = RetSelect(); if ( object != 0 ) { power = object->RetPower(); if ( power != 0 ) { power->SetEnergy(1.0f); } } return; } if ( strcmp(cmd, "fullshield") == 0 ) { CObject* object; object = RetSelect(); if ( object != 0 ) { object->SetShield(1.0f); } return; } if ( strcmp(cmd, "fullrange") == 0 ) { CObject* object; CPhysics* physics; object = RetSelect(); if ( object != 0 ) { physics = object->RetPhysics(); if ( physics != 0 ) { physics->SetReactorRange(1.0f); } } return; } } if ( strcmp(cmd, "debugmode") == 0 ) { m_engine->SetDebugMode(!m_engine->RetDebugMode()); return; } if ( strcmp(cmd, "showstat") == 0 ) { m_engine->SetShowStat(!m_engine->RetShowStat()); return; } if ( strcmp(cmd, "invshadow") == 0 ) { m_engine->SetShadow(!m_engine->RetShadow()); return; } if ( strcmp(cmd, "invdirty") == 0 ) { m_engine->SetDirty(!m_engine->RetDirty()); return; } if ( strcmp(cmd, "invfog") == 0 ) { m_engine->SetFog(!m_engine->RetFog()); return; } if ( strcmp(cmd, "invlens") == 0 ) { m_engine->SetLensMode(!m_engine->RetLensMode()); return; } if ( strcmp(cmd, "invwater") == 0 ) { m_engine->SetWaterMode(!m_engine->RetWaterMode()); return; } if ( strcmp(cmd, "invsky") == 0 ) { m_engine->SetSkyMode(!m_engine->RetSkyMode()); return; } if ( strcmp(cmd, "invplanet") == 0 ) { m_engine->SetPlanetMode(!m_engine->RetPlanetMode()); return; } if ( strcmp(cmd, "showpos") == 0 ) { m_bShowPos = !m_bShowPos; return; } if ( strcmp(cmd, "selectinsect") == 0 ) { m_bSelectInsect = !m_bSelectInsect; return; } if ( strcmp(cmd, "showsoluce") == 0 ) { m_bShowSoluce = !m_bShowSoluce; m_dialog->ShowSoluceUpdate(); return; } #if _TEEN if ( strcmp(cmd, "allteens") == 0 ) #else if ( strcmp(cmd, "allmission") == 0 ) #endif { m_bShowAll = !m_bShowAll; m_dialog->AllMissionUpdate(); return; } if ( strcmp(cmd, "invradar") == 0 ) { m_bCheatRadar = !m_bCheatRadar; return; } if ( m_phase == PHASE_SIMUL ) { m_displayText->DisplayError(ERR_CMD, D3DVECTOR(0.0f,0.0f,0.0f)); } } // Retourne le type de film en cours. MainMovieType CRobotMain::RetMainMovie() { return m_movie->RetType(); } // Efface l'affichage d'instructions. void CRobotMain::FlushDisplayInfo() { int i; for ( i=0 ; iRetType() == OBJECT_HUMAN ); if ( !m_bEditLock && bMovie && !m_movie->IsExist() && bHuman ) { motion = pObj->RetMotion(); if ( motion != 0 && motion->RetAction() == -1 ) { m_movieInfoIndex = index; m_movie->Start(MM_SATCOMopen, 2.5f); ChangePause(TRUE); //? m_map->ShowMap(FALSE); m_infoObject = DeselectAll(); // enlève les boutons de commande m_displayText->HideText(TRUE); return; } } if ( m_movie->IsExist() ) { m_movie->Stop(); ChangePause(FALSE); SelectObject(m_infoObject, FALSE); // remet les boutons de commande //? m_map->ShowMap(m_bMapShow); m_displayText->HideText(FALSE); } StartDisplayInfo(m_infoFilename[index], index); } // Début de l'affichage d'instructions. void CRobotMain::StartDisplayInfo(char *filename, int index) { CButton* pb; BOOL bSoluce; if ( m_bCmdEdit ) return; m_movieInfoIndex = -1; ClearInterface(); // enlève mise en évidence et tooltip if ( !m_bEditLock ) { //? m_map->ShowMap(FALSE); m_infoObject = DeselectAll(); // enlève les boutons de commande m_displayText->HideText(TRUE); m_sound->MuteAll(TRUE); } pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); if ( pb != 0 ) { pb->ClearState(STATE_VISIBLE); } bSoluce = m_dialog->RetSceneSoluce(); m_displayInfo = new CDisplayInfo(m_iMan); m_displayInfo->StartDisplayInfo(filename, index, bSoluce); m_infoIndex = index; if ( index != -1 ) { m_displayInfo->SetPosition(m_infoPos[index]); } } // Fin de l'affichage d'instructions. void CRobotMain::StopDisplayInfo() { CButton* pb; if ( m_movieInfoIndex != -1 ) // film pour lire le SatCom ? { m_movie->Start(MM_SATCOMclose, 2.0f); } if ( m_infoIndex != -1 ) { m_infoPos[m_infoIndex] = m_displayInfo->RetPosition(); } m_displayInfo->StopDisplayInfo(); delete m_displayInfo; m_displayInfo = 0; if ( !m_bEditLock ) { pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); if ( pb != 0 ) { pb->SetState(STATE_VISIBLE); } SelectObject(m_infoObject, FALSE); // remet les boutons de commande //? m_map->ShowMap(m_bMapShow); m_displayText->HideText(FALSE); m_sound->MuteAll(FALSE); } if ( m_infoUsed == 0 ) { m_displayText->ClearText(); // enlève message "voir SatCom ..." } m_infoUsed ++; } // Retourne le nom du texte à afficher. char* CRobotMain::RetDisplayInfoName(int index) { return m_infoFilename[index]; } // Retourne le nom du texte à afficher. int CRobotMain::RetDisplayInfoPosition(int index) { return m_infoPos[index]; } // Retourne le nom du texte à afficher. void CRobotMain::SetDisplayInfoPosition(int index, int pos) { m_infoPos[index] = pos; } // Début d'un dialogue pendant le jeu, void CRobotMain::StartSuspend() { CButton* pb; m_map->ShowMap(FALSE); m_infoObject = DeselectAll(); // enlève les boutons de commande m_displayText->HideText(TRUE); pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); if ( pb != 0 ) { pb->ClearState(STATE_VISIBLE); } m_bSuspend = TRUE; } // Fin d'un dialogue pendant le jeu, void CRobotMain::StopSuspend() { CButton* pb; pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT); if ( pb != 0 ) { pb->SetState(STATE_VISIBLE); } SelectObject(m_infoObject, FALSE); // remet les boutons de commande m_map->ShowMap(m_bMapShow); m_displayText->HideText(FALSE); m_bSuspend = FALSE; } // Retourne le temps absoul du jeu. float CRobotMain::RetGameTime() { return m_gameTime; } // Gestion de la taille des caractères par défaut. void CRobotMain::SetFontSize(float size) { m_fontSize = size; SetProfileFloat("Edit", "FontSize", m_fontSize); } float CRobotMain::RetFontSize() { return m_fontSize; } // Gestion de la taille de la fenêtre par défaut. void CRobotMain::SetWindowPos(FPOINT pos) { m_windowPos = pos; SetProfileFloat("Edit", "WindowPos.x", m_windowPos.x); SetProfileFloat("Edit", "WindowPos.y", m_windowPos.y); } FPOINT CRobotMain::RetWindowPos() { return m_windowPos; } void CRobotMain::SetWindowDim(FPOINT dim) { m_windowDim = dim; SetProfileFloat("Edit", "WindowDim.x", m_windowDim.x); SetProfileFloat("Edit", "WindowDim.y", m_windowDim.y); } FPOINT CRobotMain::RetWindowDim() { return m_windowDim; } // Gestion des fenêtres ouvrir/enregistrer. void CRobotMain::SetIOPublic(BOOL bMode) { m_IOPublic = bMode; SetProfileInt("Edit", "IOPublic", m_IOPublic); } BOOL CRobotMain::RetIOPublic() { return m_IOPublic; } void CRobotMain::SetIOPos(FPOINT pos) { m_IOPos = pos; SetProfileFloat("Edit", "IOPos.x", m_IOPos.x); SetProfileFloat("Edit", "IOPos.y", m_IOPos.y); } FPOINT CRobotMain::RetIOPos() { return m_IOPos; } void CRobotMain::SetIODim(FPOINT dim) { m_IODim = dim; SetProfileFloat("Edit", "IODim.x", m_IODim.x); SetProfileFloat("Edit", "IODim.y", m_IODim.y); } FPOINT CRobotMain::RetIODim() { return m_IODim; } // Début de la visite du lieu d'une erreur. void CRobotMain::StartDisplayVisit(EventMsg event) { CWindow* pw; CButton* button; CGroup* group; D3DVECTOR goal; FPOINT pos, dim; int i, j; if ( m_bEditLock ) return; pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2); if ( pw == 0 ) return; if ( event == EVENT_NULL ) // visite par raccourci clavier ? { if ( m_visitLast != EVENT_NULL ) // déjà une visite en cours ? { i = m_visitLast-EVENT_DT_VISIT0; } else { i = MAXDTLINE; } // Cherche la précédente. for ( j=0 ; jSearchControl(EventMsg(EVENT_DT_VISIT0+i)); if ( button == 0 || !button->TestState(STATE_ENABLE) ) continue; group = (CGroup*)pw->SearchControl(EventMsg(EVENT_DT_GROUP0+i)); if ( group != 0 ) { event = EventMsg(EVENT_DT_VISIT0+i); break; } } } if ( event == EVENT_NULL ) { m_sound->Play(SOUND_TZOING); // rien à voir ! return; } m_visitLast = event; ClearInterface(); // enlève mise en évidence et tooltip if ( m_camera->RetType() == CAMERA_VISIT ) // déjà une visite en cours ? { m_camera->StopVisit(); m_displayText->ClearVisit(); } else { m_visitObject = DeselectAll(); // enlève les boutons de commande } // Crée le bouton "continuer". if ( m_interface->SearchControl(EVENT_DT_END) == 0 ) { pos.x = 10.0f/640.0f; pos.y = 10.0f/480.0f; dim.x = 50.0f/640.0f; dim.y = 50.0f/480.0f; m_interface->CreateButton(pos, dim, 16, EVENT_DT_END); } // Crée la flèche pour montrer l'endroit. if ( m_visitArrow != 0 ) { m_visitArrow->DeleteObject(); delete m_visitArrow; m_visitArrow = 0; } goal = m_displayText->RetVisitGoal(event); m_visitArrow = CreateObject(goal, 0.0f, 1.0f, 10.0f, OBJECT_SHOW, FALSE, FALSE, 0); m_visitPos = m_visitArrow->RetPosition(0); m_visitPosArrow = m_visitPos; m_visitPosArrow.y += m_displayText->RetVisitHeight(event); m_visitArrow->SetPosition(0, m_visitPosArrow); m_visitTime = 0.0; m_visitParticule = 0.0f; m_particule->DeleteParticule(PARTISHOW); m_camera->StartVisit(m_displayText->RetVisitGoal(event), m_displayText->RetVisitDist(event)); m_displayText->SetVisit(event); ChangePause(TRUE); } // Bouge la flèche de visite. void CRobotMain::FrameVisit(float rTime) { D3DVECTOR pos, speed; FPOINT dim; float level; if ( m_visitArrow == 0 ) return; // Bouge la flèche. m_visitTime += rTime; pos = m_visitPosArrow; pos.y += 1.5f+sinf(m_visitTime*4.0f)*4.0f; m_visitArrow->SetPosition(0, pos); m_visitArrow->SetAngleY(0, m_visitTime*2.0f); // Gère les particules "flèches". m_visitParticule -= rTime; if ( m_visitParticule <= 0.0f ) { m_visitParticule = 1.5f; pos = m_visitPos; level = m_terrain->RetFloorLevel(pos)+2.0f; if ( pos.y < level ) pos.y = level; // pas en-dessous du sol speed = D3DVECTOR(0.0f, 0.0f, 0.0f); dim.x = 30.0f; dim.y = dim.x; m_particule->CreateParticule(pos, speed, dim, PARTISHOW, 2.0f); } } // Fin de la visite du lieu d'une erreur. void CRobotMain::StopDisplayVisit() { m_visitLast = EVENT_NULL; // Supprime le bouton. m_interface->DeleteControl(EVENT_DT_END); // Supprime la flèche. if ( m_visitArrow != 0 ) { m_visitArrow->DeleteObject(); delete m_visitArrow; m_visitArrow = 0; } // Supprime les particules "flèches". m_particule->DeleteParticule(PARTISHOW); m_camera->StopVisit(); m_displayText->ClearVisit(); ChangePause(FALSE); if ( m_visitObject != 0 ) { SelectObject(m_visitObject, FALSE); // remet les boutons de commande m_visitObject = 0; } } // Met à jour tous les raccourcis. void CRobotMain::UpdateShortcuts() { m_short->UpdateShortcuts(); } // Retourne l'objet par défaut à sélectionner après la création d'une scène. CObject* CRobotMain::RetSelectObject() { if ( m_selectObject != 0 ) return m_selectObject; return SearchHuman(); } // Désélectionne tout, et retourne l'objet qui était sélectionné. CObject* CRobotMain::DeselectAll() { CObject* pObj; CObject* pPrev; int i; pPrev = 0; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( pObj->RetSelect() ) pPrev = pObj; pObj->SetSelect(FALSE); } return pPrev; } // Sélectionne un objet, sans s'occuper de désélectionner le reste. void CRobotMain::SelectOneObject(CObject* pObj, BOOL bDisplayError) { ObjectType type; CObject* toto; CMotionToto* mt; pObj->SetSelect(TRUE, bDisplayError); m_camera->SetObject(pObj); type = pObj->RetType(); if ( type == OBJECT_HUMAN || 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 || type == OBJECT_MOBILEdr || type == OBJECT_APOLLO2 ) { m_camera->SetType(pObj->RetCameraType()); m_camera->SetDist(pObj->RetCameraDist()); } else { m_camera->SetType(CAMERA_BACK); } toto = SearchToto(); if ( toto != 0 ) { mt = (CMotionToto*)toto->RetMotion(); if ( mt != 0 ) { mt->SetLinkType(type); } } } // Sélectionne l'objet visé par la souris. BOOL CRobotMain::SelectObject(CObject* pObj, BOOL bDisplayError) { CObject* pPrev; if ( m_camera->RetType() == CAMERA_VISIT ) { StopDisplayVisit(); } if ( m_bMovieLock || m_bEditLock || m_bPause ) return FALSE; if ( m_movie->IsExist() ) return FALSE; if ( pObj == 0 || !IsSelectable(pObj) ) return FALSE; pPrev = DeselectAll(); if ( pPrev != 0 && pPrev != pObj ) { pObj->AddDeselList(pPrev); } SelectOneObject(pObj, bDisplayError); m_short->UpdateShortcuts(); return TRUE; } // Désélectionne l'objet sélectionné. BOOL CRobotMain::DeselectObject() { CObject* pObj; CObject* pPrev; pPrev = DeselectAll(); if ( pPrev == 0 ) { pObj = SearchHuman(); } else { pObj = pPrev->SubDeselList(); } if ( pObj == 0 ) { pObj = SearchHuman(); } if ( pObj != 0 ) { SelectOneObject(pObj); } else { m_camera->SetType(CAMERA_FREE); } m_short->UpdateShortcuts(); return TRUE; } // Supprime rapidement tous les objets. void CRobotMain::DeleteAllObjects() { CPyro* pyro; CObject* pObj; int i; // Supprime tous les effets pyrotechniques en cours. while ( TRUE ) { pyro = (CPyro*)m_iMan->SearchInstance(CLASS_PYRO, 0); if ( pyro == 0 ) break; pyro->DeleteObject(); delete pyro; } // Supprime la flèche. if ( m_visitArrow != 0 ) { m_visitArrow->DeleteObject(); delete m_visitArrow; m_visitArrow = 0; } for ( i=0 ; iSearchInstance(CLASS_OBJECT, 0); if ( pObj == 0 ) break; pObj->DeleteObject(TRUE); // détruit rapidement delete pObj; } } // Sélectionne l'homme. void CRobotMain::SelectHuman() { SelectObject(SearchHuman()); } // Retourne l'objet de l'homme. CObject* CRobotMain::SearchHuman() { ObjectType type; CObject* pObj; int i; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; type = pObj->RetType(); if ( type == OBJECT_HUMAN ) { return pObj; } } return 0; } // Retourne l'objet de toto. CObject* CRobotMain::SearchToto() { ObjectType type; CObject* pObj; int i; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; type = pObj->RetType(); if ( type == OBJECT_TOTO ) { return pObj; } } return 0; } // Retourne l'objet sélectionnable le plus proche d'une position donnée. CObject* CRobotMain::SearchNearest(D3DVECTOR pos, CObject* pExclu) { ObjectType type; CObject *pObj, *pBest; D3DVECTOR oPos; float min, dist; int i; min = 100000.0f; pBest = 0; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( pObj == pExclu ) continue; if ( !IsSelectable(pObj) ) continue; type = pObj->RetType(); if ( type == OBJECT_TOTO ) continue; oPos = pObj->RetPosition(0); dist = Length2d(oPos, pos); if ( dist < min ) { min = dist; pBest = pObj; } } return pBest; } // Retourne l'objet sélectionné. CObject* CRobotMain::RetSelect() { CObject* pObj; int i; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( pObj->RetSelect() ) { return pObj; } } return 0; } CObject* CRobotMain::SearchObject(ObjectType type) { CObject* pObj; int i; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( pObj->RetType() == type ) { return pObj; } } return 0; } // Détecte l'objet visé par la souris. CObject* CRobotMain::DetectObject(FPOINT pos) { ObjectType type; CObject *pObj, *pTarget; int objRank, i, j, rank; objRank = m_engine->DetectObject(pos); for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( !pObj->RetActif() ) continue; if ( pObj->RetProxyActivate() ) continue; pTarget = 0; type = pObj->RetType(); if ( type == OBJECT_PORTICO || type == OBJECT_BASE || type == OBJECT_DERRICK || type == OBJECT_FACTORY || type == OBJECT_REPAIR || type == OBJECT_DESTROYER || type == OBJECT_STATION || type == OBJECT_CONVERT || type == OBJECT_TOWER || type == OBJECT_RESEARCH || type == OBJECT_RADAR || type == OBJECT_INFO || type == OBJECT_ENERGY || type == OBJECT_LABO || type == OBJECT_NUCLEAR || type == OBJECT_PARA || type == OBJECT_SAFE || type == OBJECT_HUSTON || type == OBJECT_TARGET1 || type == OBJECT_TARGET2 || type == OBJECT_START || type == OBJECT_END || type == OBJECT_STONE || type == OBJECT_URANIUM || type == OBJECT_BULLET || type == OBJECT_METAL || type == OBJECT_BBOX || type == OBJECT_KEYa || type == OBJECT_KEYb || type == OBJECT_KEYc || type == OBJECT_KEYd || type == OBJECT_TNT || type == OBJECT_SCRAP1 || type == OBJECT_SCRAP2 || type == OBJECT_SCRAP3 || type == OBJECT_SCRAP4 || type == OBJECT_SCRAP5 || type == OBJECT_BOMB || type == OBJECT_BAG || type == OBJECT_WAYPOINT || type == OBJECT_FLAGb || type == OBJECT_FLAGr || type == OBJECT_FLAGg || type == OBJECT_FLAGy || type == OBJECT_FLAGv || type == OBJECT_MARKPOWER || type == OBJECT_MARKSTONE || type == OBJECT_MARKURANIUM || type == OBJECT_MARKKEYa || type == OBJECT_MARKKEYb || type == OBJECT_MARKKEYc || type == OBJECT_MARKKEYd || type == OBJECT_HUMAN || type == OBJECT_TECH || type == OBJECT_TOTO || 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_EGG || type == OBJECT_RUINmobilew1 || type == OBJECT_RUINmobilew2 || type == OBJECT_RUINmobilet1 || type == OBJECT_RUINmobilet2 || type == OBJECT_RUINmobiler1 || type == OBJECT_RUINmobiler2 || type == OBJECT_RUINfactory || type == OBJECT_RUINdoor || type == OBJECT_RUINsupport || type == OBJECT_RUINradar || type == OBJECT_RUINconvert || type == OBJECT_RUINbase || type == OBJECT_RUINhead || type == OBJECT_APOLLO1 || type == OBJECT_APOLLO2 || type == OBJECT_APOLLO3 || type == OBJECT_APOLLO4 || type == OBJECT_APOLLO5 ) { pTarget = pObj; } else if ( (type == OBJECT_POWER || type == OBJECT_ATOMIC ) && pObj->RetTruck() != 0 ) // pile utilisée ? { pTarget = pObj->RetTruck(); } else if ( type == OBJECT_POWER || type == OBJECT_ATOMIC ) { pTarget = pObj; } for ( j=0 ; jRetObjectRank(j); if ( rank == -1 ) continue; if ( rank != objRank ) continue; return pTarget; } } return 0; } // Indique si un objet est sélectionnable. BOOL CRobotMain::IsSelectable(CObject* pObj) { ObjectType type; if ( !pObj->RetSelectable() ) return FALSE; type = pObj->RetType(); if ( type == OBJECT_HUMAN || type == OBJECT_TOTO || 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 || type == OBJECT_MOBILEdr || type == OBJECT_APOLLO2 || type == OBJECT_BASE || type == OBJECT_DERRICK || type == OBJECT_FACTORY || type == OBJECT_REPAIR || type == OBJECT_DESTROYER|| type == OBJECT_STATION || type == OBJECT_CONVERT || type == OBJECT_TOWER || type == OBJECT_RESEARCH || type == OBJECT_RADAR || type == OBJECT_INFO || type == OBJECT_ENERGY || type == OBJECT_LABO || type == OBJECT_NUCLEAR || type == OBJECT_PARA || type == OBJECT_SAFE || type == OBJECT_HUSTON ) { return TRUE; } if ( m_bSelectInsect ) { if ( type == OBJECT_MOTHER || type == OBJECT_ANT || type == OBJECT_SPIDER || type == OBJECT_BEE || type == OBJECT_WORM || type == OBJECT_MOBILEtg ) { return TRUE; } } return FALSE; } // Supprime l'objet sélectionné. BOOL CRobotMain::DeleteObject() { CObject* pObj; CPyro* pyro; pObj = RetSelect(); if ( pObj == 0 ) return FALSE; pyro = new CPyro(m_iMan); pyro->Create(PT_FRAGT, pObj); pObj->SetSelect(FALSE); // désélectionne l'objet m_camera->SetType(CAMERA_EXPLO); DeselectAll(); pObj->DeleteDeselList(pObj); return TRUE; } // Enlève la mise en évidence de l'objet survolé par la souris. void CRobotMain::HiliteClear() { CObject* pObj; int i; ClearTooltip(); m_tooltipName[0] = 0; // enlève vraiment le tooltip if ( !m_bHilite ) return; i = -1; m_engine->SetHiliteRank(&i); // plus rien de sélectionné for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; pObj->SetHilite(FALSE); m_map->SetHilite(0); m_short->SetHilite(0); } m_bHilite = FALSE; } // Met en évidence l'objet survolé par la souris. void CRobotMain::HiliteObject(FPOINT pos) { CObject* pObj; char name[100]; BOOL bInMap; if ( m_bFixScene && m_phase != PHASE_PERSO ) return; if ( m_bMovieLock ) return; if ( m_movie->IsExist() ) return; if ( m_engine->RetMouseHide() ) return; ClearInterface(); // enlève mise en évidence et tooltip pObj = m_short->DetectShort(pos); if ( m_dialog->RetTooltip() && m_interface->GetTooltip(pos, name) ) { m_tooltipPos = pos; strcpy(m_tooltipName, name); m_tooltipTime = 0.0f; if ( pObj == 0 ) return; } if ( m_bSuspend ) return; if ( pObj == 0 ) { pObj = m_map->DetectMap(pos, bInMap); if ( pObj == 0 ) { if ( bInMap ) return; pObj = DetectObject(pos); if ( m_camera->RetType() == CAMERA_ONBOARD && m_camera->RetObject() == pObj ) { return; } } } if ( pObj != 0 ) { if ( m_dialog->RetTooltip() && pObj->GetTooltipName(name) ) { m_tooltipPos = pos; strcpy(m_tooltipName, name); m_tooltipTime = 0.0f; } if ( IsSelectable(pObj) ) { pObj->SetHilite(TRUE); m_map->SetHilite(pObj); m_short->SetHilite(pObj); m_bHilite = TRUE; } } } // Met en évidence l'objet survolé par la souris. void CRobotMain::HiliteFrame(float rTime) { if ( m_bFixScene && m_phase != PHASE_PERSO ) return; if ( m_bMovieLock ) return; if ( m_movie->IsExist() ) return; m_tooltipTime += rTime; ClearTooltip(); if ( m_tooltipTime >= 0.2f && m_tooltipName[0] != 0 ) { CreateTooltip(m_tooltipPos, m_tooltipName); } } // Crée un tooltip. void CRobotMain::CreateTooltip(FPOINT pos, char* text) { CWindow* pw; FPOINT start, end, dim, offset, corner; corner.x = pos.x+0.022f; corner.y = pos.y-0.052f; m_engine->RetText()->DimText(text, corner, 1, SMALLFONT, NORMSTRETCH, FONT_COLOBOT, start, end); start.x -= 0.010f; start.y -= 0.002f; end.x += 0.010f; end.y += 0.004f; // ch'tite marge pos.x = start.x; pos.y = start.y; dim.x = end.x-start.x; dim.y = end.y-start.y; offset.x = 0.0f; offset.y = 0.0f; if ( pos.x+dim.x > 1.0f ) offset.x = 1.0f-(pos.x+dim.x); if ( pos.y < 0.0f ) offset.y = -pos.y; corner.x += offset.x; corner.y += offset.y; pos.x += offset.x; pos.y += offset.y; m_interface->CreateWindows(pos, dim, 1, EVENT_TOOLTIP); pw = (CWindow*)m_interface->SearchControl(EVENT_TOOLTIP); if ( pw != 0 ) { pw->SetState(STATE_SHADOW); pw->SetTrashEvent(FALSE); pos.y -= m_engine->RetText()->RetHeight(SMALLFONT, FONT_COLOBOT)/2.0f; pw->CreateLabel(pos, dim, -1, EVENT_LABEL2, text); } } // Efface le tooltip précédent. void CRobotMain::ClearTooltip() { m_interface->DeleteControl(EVENT_TOOLTIP); } // Affiche l'aide pour un objet. void CRobotMain::HelpObject() { CObject* pObj; char* filename; pObj = RetSelect(); if ( pObj == 0 ) return; filename = RetHelpFilename(pObj->RetType()); if ( filename[0] == 0 ) return; StartDisplayInfo(filename, -1); } // Change le mode de la caméra. void CRobotMain::ChangeCamera() { CObject* pObj; ObjectType oType; CameraType type; int i; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( pObj->RetSelect() ) { if ( pObj->RetCameraLock() ) return; oType = pObj->RetType(); type = pObj->RetCameraType(); if ( oType != OBJECT_MOBILEfa && oType != OBJECT_MOBILEta && oType != OBJECT_MOBILEwa && oType != OBJECT_MOBILEia && oType != OBJECT_MOBILEfc && oType != OBJECT_MOBILEtc && oType != OBJECT_MOBILEwc && oType != OBJECT_MOBILEic && oType != OBJECT_MOBILEfi && oType != OBJECT_MOBILEti && oType != OBJECT_MOBILEwi && oType != OBJECT_MOBILEii && oType != OBJECT_MOBILEfs && oType != OBJECT_MOBILEts && oType != OBJECT_MOBILEws && oType != OBJECT_MOBILEis && oType != OBJECT_MOBILErt && oType != OBJECT_MOBILErc && oType != OBJECT_MOBILErr && oType != OBJECT_MOBILErs && oType != OBJECT_MOBILEsa && oType != OBJECT_MOBILEtg && oType != OBJECT_MOBILEft && oType != OBJECT_MOBILEtt && oType != OBJECT_MOBILEwt && oType != OBJECT_MOBILEit && oType != OBJECT_MOBILEdr && oType != OBJECT_APOLLO2 ) return; if ( oType == OBJECT_MOBILEdr ) // dessinateur ? { if ( type == CAMERA_PLANE ) type = CAMERA_BACK; else if ( type == CAMERA_BACK ) type = CAMERA_PLANE; } else if ( pObj->RetTrainer() ) // entraînement ? { if ( type == CAMERA_ONBOARD ) type = CAMERA_FIX; else if ( type == CAMERA_FIX ) type = CAMERA_PLANE; else if ( type == CAMERA_PLANE ) type = CAMERA_BACK; else if ( type == CAMERA_BACK ) type = CAMERA_ONBOARD; } else { if ( type == CAMERA_ONBOARD ) type = CAMERA_BACK; else if ( type == CAMERA_BACK ) type = CAMERA_ONBOARD; } pObj->SetCameraType(type); m_camera->SetType(type); } } } // Télécommande la caméra avec les touches flèches. void CRobotMain::KeyCamera(EventMsg event, long param) { CObject* pObj; if ( event == EVENT_KEYUP ) { if ( param == m_engine->RetKey(KEYRANK_LEFT, 0) || param == m_engine->RetKey(KEYRANK_LEFT, 1) ) { m_cameraPan = 0.0f; } if ( param == m_engine->RetKey(KEYRANK_RIGHT, 0) || param == m_engine->RetKey(KEYRANK_RIGHT, 1) ) { m_cameraPan = 0.0f; } if ( param == m_engine->RetKey(KEYRANK_UP, 0) || param == m_engine->RetKey(KEYRANK_UP, 1) ) { m_cameraZoom = 0.0f; } if ( param == m_engine->RetKey(KEYRANK_DOWN, 0) || param == m_engine->RetKey(KEYRANK_DOWN, 1) ) { m_cameraZoom = 0.0f; } } if ( m_phase != PHASE_SIMUL ) return; if ( m_bEditLock ) return; // édition en cours ? if ( m_bTrainerPilot ) return; pObj = RetSelect(); if ( pObj == 0 ) return; if ( !pObj->RetTrainer() ) return; if ( event == EVENT_KEYDOWN ) { if ( param == m_engine->RetKey(KEYRANK_LEFT, 0) || param == m_engine->RetKey(KEYRANK_LEFT, 1) ) { m_cameraPan = -1.0f; } if ( param == m_engine->RetKey(KEYRANK_RIGHT, 0) || param == m_engine->RetKey(KEYRANK_RIGHT, 1) ) { m_cameraPan = 1.0f; } if ( param == m_engine->RetKey(KEYRANK_UP, 0) || param == m_engine->RetKey(KEYRANK_UP, 1) ) { m_cameraZoom = -1.0f; } if ( param == m_engine->RetKey(KEYRANK_DOWN, 0) || param == m_engine->RetKey(KEYRANK_DOWN, 1) ) { m_cameraZoom = 1.0f; } } } // Effectue un panoramique avec la caméra si un bouton est enfoncé. void CRobotMain::RemoteCamera(float pan, float zoom, float rTime) { float value; if ( pan != 0.0f ) { value = m_camera->RetRemotePan(); value += pan*rTime*1.5f; m_camera->SetRemotePan(value); } if ( zoom != 0.0f ) { value = m_camera->RetRemoteZoom(); value += zoom*rTime*0.3f; m_camera->SetRemoteZoom(value); } } // Annule le film en cours. void CRobotMain::AbortMovie() { CObject* pObj; CAuto* automat; int i; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; automat = pObj->RetAuto(); if ( automat != 0 ) { automat->Abort(); } } m_engine->SetMouseHide(FALSE); } // Met à jour le texte d'informations. void CRobotMain::UpdateInfoText() { CObject* pObj; D3DVECTOR pos; char info[100]; if ( m_bShowPos ) { pObj = RetSelect(); if ( pObj != 0 ) { pos = pObj->RetPosition(0); sprintf(info, "Pos = %.2f ; %.2f", pos.x/g_unit, pos.z/g_unit); m_engine->SetInfoText(4, info); } } } // Initialise le point de vue. void CRobotMain::InitEye() { if ( m_phase == PHASE_SIMUL ) { m_camera->Init(D3DVECTOR( 0.0f, 10.0f, 0.0f), D3DVECTOR(10.0f, 5.0f, 0.0f), 0.0f); } if ( m_phase == PHASE_MODEL ) { m_model->InitView(); } } // Fait progresser toute la scène. BOOL CRobotMain::EventFrame(const Event &event) { ObjectType type; CObject *pObj, *toto; CPyro* pPyro; CWindow* pw; CMap* pm; int i; m_time += event.rTime; if ( !m_bMovieLock ) m_gameTime += event.rTime; if ( !m_bImmediatSatCom && !m_bBeginSatCom && m_gameTime > 0.1f && m_phase == PHASE_SIMUL ) { m_displayText->DisplayError(INFO_BEGINSATCOM, D3DVECTOR(0.0f,0.0f,0.0f)); m_bBeginSatCom = TRUE; // message affiché } m_water->EventProcess(event); m_cloud->EventProcess(event); m_blitz->EventProcess(event); m_planet->EventProcess(event); pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1); if ( pw == 0 ) { pm = 0; } else { pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP); if ( pm != 0 ) pm->FlushObject(); } toto = 0; if ( !m_bFreePhoto ) { // Fait progresser tous les robots, mais pas toto. for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( pm != 0 ) pm->UpdateObject(pObj); if ( pObj->RetTruck() != 0 ) continue; type = pObj->RetType(); if ( type == OBJECT_TOTO ) { toto = pObj; } else { pObj->EventProcess(event); } } // Fait progresser tous les objets transportés par les robots. for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( pObj->RetTruck() == 0 ) continue; pObj->EventProcess(event); } // Fait progresser les effets pyrotechniques. for ( i=0 ; i<1000000 ; i++ ) { pPyro = (CPyro*)m_iMan->SearchInstance(CLASS_PYRO, i); if ( pPyro == 0 ) break; pPyro->EventProcess(event); if ( pPyro->IsEnded() != ERR_CONTINUE ) { pPyro->DeleteObject(); delete pPyro; } } } // Fait bouger la caméra après les objets, car sa position peut // dépendre de l'objet sélectionné (CAMERA_ONBOARD ou CAMERA_BACK). if ( m_phase == PHASE_SIMUL && !m_bEditFull ) { m_camera->EventProcess(event); if ( m_engine->RetFog() ) { m_camera->SetOverBaseColor(m_particule->RetFogColor(m_engine->RetEyePt())); } } if ( m_phase == PHASE_PERSO || m_phase == PHASE_WIN || m_phase == PHASE_LOST ) { m_camera->EventProcess(event); } // Fait progresser toto après la caméra, car sa position dépend // de la caméra. if ( toto != 0 ) { toto->EventProcess(event); } // Fait progresser le modèle. if ( m_phase == PHASE_MODEL ) { m_model->ViewMove(event, 2.0f); m_model->UpdateView(); m_model->EventProcess(event); } HiliteFrame(event.rTime); // Fait bouger l'indicateur de film. if ( m_bMovieLock && !m_bEditLock ) // film en cours ? { CControl* pc; FPOINT pos, dim; float zoom; pc = m_interface->SearchControl(EVENT_OBJECT_MOVIELOCK); if ( pc != 0 ) { dim.x = 32.0f/640.0f; dim.y = 32.0f/480.0f; pos.x = 20.0f/640.0f; pos.y = (480.0f-24.0f)/480.0f; zoom = 1.0f+sinf(m_time*6.0f)*0.1f; // 0.9 .. 1.1 dim.x *= zoom; dim.y *= zoom; pos.x -= dim.x/2.0f; pos.y -= dim.y/2.0f; pc->SetPos(pos); pc->SetDim(dim); } } // Fait bouger l'indicateur d'édition. if ( m_bEditLock || m_bPause ) // édition en cours ? { CControl* pc; FPOINT pos, dim; float zoom; pc = m_interface->SearchControl(EVENT_OBJECT_EDITLOCK); if ( pc != 0 ) { if ( m_bEditFull || m_bEditLock ) { dim.x = 10.0f/640.0f; dim.y = 10.0f/480.0f; pos.x = -20.0f/640.0f; pos.y = -20.0f/480.0f; // invisible ! } else { dim.x = 32.0f/640.0f; dim.y = 32.0f/480.0f; pos.x = 20.0f/640.0f; pos.y = (480.0f-24.0f)/480.0f; zoom = 1.0f+sinf(m_time*6.0f)*0.1f; // 0.9 .. 1.1 dim.x *= zoom; dim.y *= zoom; pos.x -= dim.x/2.0f; pos.y -= dim.y/2.0f; } pc->SetPos(pos); pc->SetDim(dim); } } // Fait bouger la flèche de visite. if ( m_camera->RetType() == CAMERA_VISIT ) { FrameVisit(event.rTime); } // Fait bouger les limites. FrameShowLimit(event.rTime); if ( m_phase == PHASE_SIMUL ) { if ( !m_bEditLock && m_checkEndTime+1.0f < m_time ) { m_checkEndTime = m_time; CheckEndMission(TRUE); } if ( m_winDelay > 0.0f && !m_bEditLock ) { m_winDelay -= event.rTime; if ( m_winDelay <= 0.0f ) { if ( m_bMovieLock ) { m_winDelay = 1.0f; } else { Event newEvent; m_event->MakeEvent(newEvent, EVENT_WIN); m_event->AddEvent(newEvent); } } } if ( m_lostDelay > 0.0f && !m_bEditLock ) { m_lostDelay -= event.rTime; if ( m_lostDelay <= 0.0f ) { if ( m_bMovieLock ) { m_winDelay = 1.0f; } else { Event newEvent; m_event->MakeEvent(newEvent, EVENT_LOST); m_event->AddEvent(newEvent); } } } } if ( m_delayWriteMessage > 0 ) { m_delayWriteMessage --; if ( m_delayWriteMessage == 0 ) { m_displayText->DisplayError(INFO_WRITEOK, D3DVECTOR(0.0f,0.0f,0.0f)); } } return S_OK; } // Donne l'événement à tous les robots. BOOL CRobotMain::EventObject(const Event &event) { CObject* pObj; int i; if ( m_bFreePhoto ) return S_OK; m_bResetCreate = FALSE; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; pObj->EventProcess(event); } if ( m_bResetCreate ) { ResetCreate(); } return S_OK; } // Calcule le point d'arrivée de la caméra. D3DVECTOR CRobotMain::LookatPoint(D3DVECTOR eye, float angleH, float angleV, float length) { D3DVECTOR lookat; lookat = eye; lookat.z += length; RotatePoint(eye, angleH, angleV, lookat); return lookat; } char* SkipNum(char *p) { while ( *p == ' ' || *p == '.' || *p == '-' || (*p >= '0' && *p <= '9') ) { p++; } return p; } // Conversion des unités. void CRobotMain::Convert() { FILE* file = NULL; FILE* fileNew = NULL; char line[500]; char lineNew[500]; char s[200]; char* base; char* p; int rank; D3DVECTOR pos; float value; base = m_dialog->RetSceneName(); rank = m_dialog->RetSceneRank(); m_dialog->BuildSceneName(line, base, rank); file = fopen(line, "r"); if ( file == NULL ) return; strcpy(line+strlen(line)-4, ".new"); fileNew = fopen(line, "w"); if ( fileNew == NULL ) return; while ( fgets(line, 500, file) != NULL ) { strcpy(lineNew, line); if ( Cmd(line, "DeepView") ) { p = strstr(line, "air="); if ( p != 0 ) { value = OpFloat(line, "air", 500.0f); value /= g_unit; p[0] = 0; p = SkipNum(p+4); strcpy(lineNew, line); strcat(lineNew, "air="); sprintf(s, "%.2f", value); strcat(lineNew, s); strcat(lineNew, " "); strcat(lineNew, p); } strcpy(line, lineNew); p = strstr(line, "water="); if ( p != 0 ) { value = OpFloat(line, "water", 100.0f); value /= g_unit; p[0] = 0; p = SkipNum(p+6); strcpy(lineNew, line); strcat(lineNew, "water="); sprintf(s, "%.2f", value); strcat(lineNew, s); strcat(lineNew, " "); strcat(lineNew, p); } strcpy(line, lineNew); } if ( Cmd(line, "TerrainGenerate") ) { p = strstr(line, "vision="); if ( p != 0 ) { value = OpFloat(line, "vision", 500.0f); value /= g_unit; p[0] = 0; p = SkipNum(p+7); strcpy(lineNew, line); strcat(lineNew, "vision="); sprintf(s, "%.2f", value); strcat(lineNew, s); strcat(lineNew, " "); strcat(lineNew, p); } } if ( Cmd(line, "CreateObject") || Cmd(line, "CreateSpot") ) { p = strstr(line, "pos="); if ( p != 0 ) { pos = OpPos(line, "pos"); pos.x /= g_unit; pos.y /= g_unit; pos.z /= g_unit; p[0] = 0; p = SkipNum(p+4); p = SkipNum(p+1); strcpy(lineNew, line); strcat(lineNew, "pos="); sprintf(s, "%.2f", pos.x); strcat(lineNew, s); strcat(lineNew, ";"); sprintf(s, "%.2f", pos.z); strcat(lineNew, s); strcat(lineNew, " "); strcat(lineNew, p); } } if ( Cmd(line, "EndMissionTake") ) { p = strstr(line, "pos="); if ( p != 0 ) { pos = OpPos(line, "pos"); pos.x /= g_unit; pos.y /= g_unit; pos.z /= g_unit; p[0] = 0; p = SkipNum(p+4); p = SkipNum(p+1); strcpy(lineNew, line); strcat(lineNew, "pos="); sprintf(s, "%.2f", pos.x); strcat(lineNew, s); strcat(lineNew, ";"); sprintf(s, "%.2f", pos.z); strcat(lineNew, s); strcat(lineNew, " "); strcat(lineNew, p); } strcpy(line, lineNew); p = strstr(line, "dist="); if ( p != 0 ) { value = OpFloat(line, "dist", 32.0f); value /= g_unit; p[0] = 0; p = SkipNum(p+5); strcpy(lineNew, line); strcat(lineNew, "dist="); sprintf(s, "%.2f", value); strcat(lineNew, s); strcat(lineNew, " "); strcat(lineNew, p); } strcpy(line, lineNew); } if ( Cmd(line, "Camera") ) { p = strstr(line, "pos="); if ( p != 0 ) { pos = OpPos(line, "pos"); pos.x /= g_unit; pos.y /= g_unit; pos.z /= g_unit; p[0] = 0; p = SkipNum(p+4); p = SkipNum(p+1); strcpy(lineNew, line); strcat(lineNew, "pos="); sprintf(s, "%.2f", pos.x); strcat(lineNew, s); strcat(lineNew, ";"); sprintf(s, "%.2f", pos.z); strcat(lineNew, s); strcat(lineNew, " "); strcat(lineNew, p); } strcpy(line, lineNew); p = strstr(line, "h="); if ( p != 0 ) { value = OpFloat(line, "h", 32.0f); value /= g_unit; p[0] = 0; p = SkipNum(p+2); strcpy(lineNew, line); strcat(lineNew, "h="); sprintf(s, "%.2f", value); strcat(lineNew, s); strcat(lineNew, " "); strcat(lineNew, p); } strcpy(line, lineNew); } fputs(lineNew, fileNew); } fclose(fileNew); fclose(file); } // Charge la scène pour le personnage. void CRobotMain::ScenePerso() { CObject* pObj; DeleteAllObjects(); // supprime toute la scène 3D actuelle m_engine->FlushObject(); m_terrain->FlushRelief(); // tout plat m_terrain->FlushBuildingLevel(); m_terrain->FlushFlyingLimit(); m_light->FlushLight(); m_particule->FlushParticule(); m_iMan->Flush(CLASS_OBJECT); m_iMan->Flush(CLASS_PHYSICS); m_iMan->Flush(CLASS_BRAIN); m_iMan->Flush(CLASS_PYRO); m_dialog->SetSceneName("perso"); m_dialog->SetSceneRank(0); CreateScene(FALSE, TRUE, FALSE); // scène fixe m_engine->SetDrawWorld(FALSE); // ne dessine rien sous l'interface m_engine->SetDrawFront(TRUE); // dessine human sur l'interface pObj = SearchHuman(); if ( pObj != 0 ) { CMotionHuman* mh; pObj->SetDrawFront(TRUE); // dessine sur l'interface mh = (CMotionHuman*)pObj->RetMotion(); if ( mh != 0 ) { mh->StartDisplayPerso(); } } } // Crée toute la scène. void CRobotMain::CreateScene(BOOL bSoluce, BOOL bFixScene, BOOL bResetObject) { CObject* pObj; CObject* pSel; CMotion* motion; FILE* file = NULL; char line[500]; char name[200]; char dir[100]; char op[100]; char* read; char* stack; char* base; D3DCOLORVALUE color; D3DVECTOR pos; int rank, obj, i, rankObj, rankGadget; //? Convert(); base = m_dialog->RetSceneName(); rank = m_dialog->RetSceneRank(); read = m_dialog->RetSceneRead(); stack = m_dialog->RetStackRead(); m_dialog->SetUserDir(base, rank); m_bFixScene = bFixScene; g_id = 0; m_bBase = FALSE; if ( !bResetObject ) { g_build = 0; g_researchDone = 0; // aucune recherche effectuée g_researchEnable = 0; FlushDisplayInfo(); m_terrain->LevelFlush(); m_audioTrack = 0; m_bAudioRepeat = TRUE; m_displayText->SetDelay(1.0f); m_displayText->SetEnable(TRUE); m_bImmediatSatCom = FALSE; m_endingWinRank = 0; m_endingLostRank = 0; m_endTakeTotal = 0; m_endTakeResearch = 0; m_endTakeWinDelay = 2.0f; m_endTakeLostDelay = 2.0f; m_obligatoryTotal = 0; m_prohibitedTotal = 0; m_bMapShow = TRUE; m_bMapImage = FALSE; m_mapFilename[0] = 0; m_colorRefBot.r = 10.0f/256.0f; m_colorRefBot.g = 166.0f/256.0f; m_colorRefBot.b = 254.0f/256.0f; // bleu m_colorRefBot.a = 0.0f; m_colorNewBot = m_colorRefBot; m_colorRefAlien.r = 135.0f/256.0f; m_colorRefAlien.g = 170.0f/256.0f; m_colorRefAlien.b = 13.0f/256.0f; // vert m_colorRefAlien.a = 0.0f; m_colorNewAlien = m_colorRefAlien; m_colorRefGreen.r = 135.0f/256.0f; m_colorRefGreen.g = 170.0f/256.0f; m_colorRefGreen.b = 13.0f/256.0f; // vert m_colorRefGreen.a = 0.0f; m_colorNewGreen = m_colorRefGreen; m_colorRefWater.r = 25.0f/256.0f; m_colorRefWater.g = 255.0f/256.0f; m_colorRefWater.b = 240.0f/256.0f; // cyan m_colorRefWater.a = 0.0f; m_colorNewWater = m_colorRefWater; m_dialog->BuildResumeName(m_title, base, rank); m_dialog->BuildResumeName(m_resume, base, rank); GetResource(RES_TEXT, RT_SCRIPT_NEW, m_scriptName); m_scriptFile[0] = 0; } m_dialog->BuildSceneName(line, base, rank); file = fopen(line, "r"); if ( file == NULL ) return; rankObj = 0; rankGadget = 0; pSel = 0; while ( fgets(line, 500, file) != NULL ) { for ( i=0 ; i<500 ; i++ ) { if ( line[i] == '\t' ) line[i] = ' '; // remplace tab par space if ( line[i] == '/' && line[i+1] == '/' ) { line[i] = 0; break; } } sprintf(op, "Title.%c", RetLanguageLetter()); if ( Cmd(line, op) && !bResetObject ) { OpString(line, "text", m_title); } sprintf(op, "Resume.%c", RetLanguageLetter()); if ( Cmd(line, op) && !bResetObject ) { OpString(line, "text", m_resume); } sprintf(op, "ScriptName.%c", RetLanguageLetter()); if ( Cmd(line, op) && !bResetObject ) { OpString(line, "text", m_scriptName); } if ( Cmd(line, "ScriptFile") && !bResetObject ) { OpString(line, "name", m_scriptFile); } if ( Cmd(line, "Instructions") && !bResetObject ) { OpString(line, "name", name); //? sprintf(m_infoFilename[SATCOM_HUSTON], "help\\%s", name); UserDir(m_infoFilename[SATCOM_HUSTON], name, "help"); m_bImmediatSatCom = OpInt(line, "immediat", 0); } if ( Cmd(line, "Satellite") && !bResetObject ) { OpString(line, "name", name); //? sprintf(m_infoFilename[SATCOM_SAT], "help\\%s", name); UserDir(m_infoFilename[SATCOM_SAT], name, "help"); } if ( Cmd(line, "Loading") && !bResetObject ) { OpString(line, "name", name); //? sprintf(m_infoFilename[SATCOM_LOADING], "help\\%s", name); UserDir(m_infoFilename[SATCOM_LOADING], name, "help"); } if ( Cmd(line, "HelpFile") && !bResetObject ) { OpString(line, "name", name); //? sprintf(m_infoFilename[SATCOM_PROG], "help\\%s", name); UserDir(m_infoFilename[SATCOM_PROG], name, "help"); } if ( Cmd(line, "SoluceFile") && !bResetObject ) { OpString(line, "name", name); //? sprintf(m_infoFilename[SATCOM_SOLUCE], "help\\%s", name); UserDir(m_infoFilename[SATCOM_SOLUCE], name, "help"); } if ( Cmd(line, "EndingFile") && !bResetObject ) { m_endingWinRank = OpInt(line, "win", 0); m_endingLostRank = OpInt(line, "lost", 0); } if ( Cmd(line, "MessageDelay") && !bResetObject ) { m_displayText->SetDelay(OpFloat(line, "factor", 1.0f)); } if ( Cmd(line, "Audio") && !bResetObject ) { m_audioTrack = OpInt(line, "track", 0); m_bAudioRepeat = OpInt(line, "repeat", 1); } if ( Cmd(line, "AmbiantColor") && !bResetObject ) { m_engine->SetAmbiantColor(OpColor(line, "air", 0x88888888), 0); m_engine->SetAmbiantColor(OpColor(line, "water", 0x88888888), 1); } if ( Cmd(line, "FogColor") && !bResetObject ) { m_engine->SetFogColor(OpColor(line, "air", 0x88888888), 0); m_engine->SetFogColor(OpColor(line, "water", 0x88888888), 1); } if ( Cmd(line, "VehicleColor") && !bResetObject ) { m_colorNewBot = RetColor(OpColor(line, "color", 0x88888888)); } if ( Cmd(line, "InsectColor") && !bResetObject ) { m_colorNewAlien = RetColor(OpColor(line, "color", 0x88888888)); } if ( Cmd(line, "GreeneryColor") && !bResetObject ) { m_colorNewGreen = RetColor(OpColor(line, "color", 0x88888888)); } if ( Cmd(line, "DeepView") && !bResetObject ) { m_engine->SetDeepView(OpFloat(line, "air", 500.0f)*UNIT, 0, TRUE); m_engine->SetDeepView(OpFloat(line, "water", 100.0f)*UNIT, 1, TRUE); } if ( Cmd(line, "FogStart") && !bResetObject ) { m_engine->SetFogStart(OpFloat(line, "air", 0.5f), 0); m_engine->SetFogStart(OpFloat(line, "water", 0.5f), 1); } if ( Cmd(line, "SecondTexture") && !bResetObject ) { m_engine->SetSecondTexture(OpInt(line, "rank", 1)); } if ( Cmd(line, "Background") && !bResetObject ) { OpString(line, "image", name); UserDir(dir, name, ""); m_engine->SetBackground(dir, OpColor(line, "up", 0x00000000), OpColor(line, "down", 0x00000000), OpColor(line, "cloudUp", 0x00000000), OpColor(line, "cloudDown", 0x00000000), OpInt(line, "full", 0)); } if ( Cmd(line, "Planet") && !bResetObject ) { D3DVECTOR ppos, uv1, uv2; ppos = OpPos(line, "pos"); uv1 = OpPos(line, "uv1"); uv2 = OpPos(line, "uv2"); OpString(line, "image", name); UserDir(dir, name, ""); m_planet->Create(OpInt(line, "mode", 0), FPOINT(ppos.x, ppos.z), OpFloat(line, "dim", 0.2f), OpFloat(line, "speed", 0.0f), OpFloat(line, "dir", 0.0f), dir, FPOINT(uv1.x, uv1.z), FPOINT(uv2.x, uv2.z)); } if ( Cmd(line, "FrontsizeName") && !bResetObject ) { OpString(line, "image", name); UserDir(dir, name, ""); m_engine->SetFrontsizeName(dir); } if ( Cmd(line, "Global") && !bResetObject ) { g_unit = OpFloat(line, "unitScale", 4.0f); m_engine->SetTracePrecision(OpFloat(line, "traceQuality", 1.0f)); m_bShortCut = OpInt(line, "shortcut", 1); } if ( Cmd(line, "TerrainGenerate") && !bResetObject ) { m_terrain->Generate(OpInt(line, "mosaic", 20), OpInt(line, "brick", 3), OpFloat(line, "size", 20.0f), OpFloat(line, "vision", 500.0f)*UNIT, OpInt(line, "depth", 2), OpFloat(line, "hard", 0.5f)); } if ( Cmd(line, "TerrainWind") && !bResetObject ) { m_terrain->SetWind(OpPos(line, "speed")); } if ( Cmd(line, "TerrainRelief") && !bResetObject ) { OpString(line, "image", name); UserDir(dir, name, "textures"); m_terrain->ReliefFromBMP(dir, OpFloat(line, "factor", 1.0f), OpInt(line, "border", 1)); } if ( Cmd(line, "TerrainReliefDXF") && !bResetObject ) { OpString(line, "image", name); UserDir(dir, name, "textures"); m_terrain->ReliefFromDXF(dir, OpFloat(line, "factor", 1.0f)); } if ( Cmd(line, "TerrainResource") && !bResetObject ) { OpString(line, "image", name); UserDir(dir, name, "textures"); m_terrain->ResFromBMP(dir); } if ( Cmd(line, "TerrainWater") && !bResetObject ) { OpString(line, "image", name); UserDir(dir, name, ""); pos.x = OpFloat(line, "moveX", 0.0f); pos.y = OpFloat(line, "moveY", 0.0f); pos.z = pos.x; m_water->Create(OpTypeWater(line, "air", WATER_TT), OpTypeWater(line, "water", WATER_TT), dir, RetColor(OpColor(line, "diffuse", 0xffffffff)), RetColor(OpColor(line, "ambiant", 0xffffffff)), OpFloat(line, "level", 100.0f)*UNIT, OpFloat(line, "glint", 1.0f), pos); m_colorNewWater = RetColor(OpColor(line, "color", RetColor(m_colorRefWater))); m_colorShiftWater = OpFloat(line, "brightness", 0.0f); } if ( Cmd(line, "TerrainLava") && !bResetObject ) { m_water->SetLava(OpInt(line, "mode", 0)); } if ( Cmd(line, "TerrainCloud") && !bResetObject ) { OpString(line, "image", name); UserDir(dir, name, ""); m_cloud->Create(dir, RetColor(OpColor(line, "diffuse", 0xffffffff)), RetColor(OpColor(line, "ambiant", 0xffffffff)), OpFloat(line, "level", 500.0f)*UNIT); } if ( Cmd(line, "TerrainBlitz") && !bResetObject ) { m_blitz->Create(OpFloat(line, "sleep", 0.0f), OpFloat(line, "delay", 3.0f), OpFloat(line, "magnetic", 50.0f)*UNIT); } if ( Cmd(line, "TerrainInitTextures") && !bResetObject ) { int dx, dy, tt[100]; char* op; OpString(line, "image", name); AddExt(name, ".tga"); dx = OpInt(line, "dx", 1); dy = OpInt(line, "dy", 1); op = SearchOp(line, "table"); for ( i=0 ; iInitTextures(name, tt, dx, dy); } if ( Cmd(line, "TerrainInit") && !bResetObject ) { m_terrain->LevelInit(OpInt(line, "id", 1)); } if ( Cmd(line, "TerrainMaterial") && !bResetObject ) { OpString(line, "image", name); AddExt(name, ".tga"); if ( strstr(name, "%user%") != 0 ) { CopyFileToTemp(name); } m_terrain->LevelMaterial(OpInt(line, "id", 0), name, OpFloat(line, "u", 0.0f), OpFloat(line, "v", 0.0f), OpInt(line, "up", 1), OpInt(line, "right", 1), OpInt(line, "down", 1), OpInt(line, "left", 1), OpFloat(line, "hard", 0.5f)); } if ( Cmd(line, "TerrainLevel") && !bResetObject ) { int id[50]; char* op; op = SearchOp(line, "id"); i = 0; while ( TRUE ) { id[i] = GetInt(op, i, 0); if ( id[i++] == 0 ) break; } m_terrain->LevelGenerate(id, OpFloat(line, "min", 0.0f)*UNIT, OpFloat(line, "max", 100.0f)*UNIT, OpFloat(line, "slope", 5.0f), OpFloat(line, "freq", 100.0f), OpPos(line, "center")*g_unit, OpFloat(line, "radius", 0.0f)*g_unit); } if ( Cmd(line, "TerrainCreate") && !bResetObject ) { m_terrain->CreateObjects(TRUE); } if ( Cmd(line, "BeginObject") ) { InitEye(); SetMovieLock(FALSE); if ( !m_bFixScene ) { //? CreateObject(D3DVECTOR(0.0f, 0.0f, 0.0f), 0.0f, 0.0f, OBJECT_TOTO); } if ( read[0] != 0 ) // loading file ? { pSel = IOReadScene(read, stack); } } if ( Cmd(line, "CreateObject") && read[0] == 0 ) { CObject* pObj; CBrain* pBrain; CAuto* pAuto; CPyro* pyro; ObjectType type; PyroType pType; CameraType cType; Info info; float dir; char op[20]; char text[100]; char* p; int run, gadget; type = OpTypeObject(line, "type", OBJECT_NULL); gadget = OpInt(line, "gadget", -1); if ( gadget == -1 ) { gadget = 0; if ( type == OBJECT_TECH || (type >= OBJECT_PLANT0 && type <= OBJECT_PLANT19 ) || (type >= OBJECT_TREE0 && type <= OBJECT_TREE9 ) || (type >= OBJECT_TEEN0 && type <= OBJECT_TEEN49 ) || (type >= OBJECT_QUARTZ0 && type <= OBJECT_QUARTZ9 ) || (type >= OBJECT_ROOT0 && type <= OBJECT_ROOT4 ) ) // pas ROOT5 ! { if ( type != OBJECT_TEEN11 && // lampe ? type != OBJECT_TEEN12 && // coke ? type != OBJECT_TEEN20 && // mur ? type != OBJECT_TEEN21 && // mur ? type != OBJECT_TEEN22 && // mur ? type != OBJECT_TEEN26 && // lampe ? type != OBJECT_TEEN28 && // bouteille ? type != OBJECT_TEEN34 ) // pierre ? { gadget = 1; } } } if ( gadget != 0 ) // est-ce un gadget ? { if ( !TestGadgetQuantity(rankGadget++) ) continue; } pos = OpPos(line, "pos")*g_unit; dir = OpFloat(line, "dir", 0.0f)*PI; pObj = CreateObject(pos, dir, OpFloat(line, "z", 1.0f), OpFloat(line, "h", 0.0f), type, OpFloat(line, "power", 1.0f), OpInt(line, "trainer", 0), OpInt(line, "toy", 0), OpInt(line, "option", 0)); if ( pObj != 0 ) { pObj->SetDefRank(rankObj); if ( type == OBJECT_BASE ) m_bBase = TRUE; cType = OpCamera(line, "camera"); if ( cType != CAMERA_NULL ) { pObj->SetCameraType(cType); } pObj->SetCameraDist(OpFloat(line, "cameraDist", 50.0f)); pObj->SetCameraLock(OpInt(line, "cameraLock", 0)); pType = OpPyro(line, "pyro"); if ( pType != PT_NULL ) { pyro = new CPyro(m_iMan); pyro->Create(pType, pObj); } // Met les infos dans borne (OBJECT_INFO). for ( i=0 ; iRetGamerColorCombi(); colorRef2.r = 255.0f/256.0f; colorRef2.g = 132.0f/256.0f; colorRef2.b = 1.0f/256.0f; // orange colorNew2 = m_dialog->RetGamerColorBand(); exclu[0] = FPOINT(192.0f/256.0f, 0.0f/256.0f); exclu[1] = FPOINT(256.0f/256.0f, 64.0f/256.0f); // crystaux + bombonnes exclu[2] = FPOINT(208.0f/256.0f, 224.0f/256.0f); exclu[3] = FPOINT(256.0f/256.0f, 256.0f/256.0f); // écran SatCom exclu[4] = FPOINT(0.0f, 0.0f); exclu[5] = FPOINT(0.0f, 0.0f); // terminateur m_engine->ChangeColor("human.tga", colorRef1, colorNew1, colorRef2, colorNew2, 0.30f, 0.01f, ts, ti, exclu); face = RetGamerFace(); if ( face == 0 ) // normal ? { colorRef1.r = 90.0f/256.0f; colorRef1.g = 95.0f/256.0f; colorRef1.b = 85.0f/256.0f; // noir tolerance = 0.15f; } if ( face == 1 ) // chauve ? { colorRef1.r = 74.0f/256.0f; colorRef1.g = 58.0f/256.0f; colorRef1.b = 46.0f/256.0f; // brun tolerance = 0.20f; } if ( face == 2 ) // carlos ? { colorRef1.r = 70.0f/256.0f; colorRef1.g = 40.0f/256.0f; colorRef1.b = 8.0f/256.0f; // brun tolerance = 0.30f; } if ( face == 3 ) // blond ? { colorRef1.r = 74.0f/256.0f; colorRef1.g = 16.0f/256.0f; colorRef1.b = 0.0f/256.0f; // jaune tolerance = 0.20f; } colorNew1 = m_dialog->RetGamerColorHair(); colorRef2.r = 0.0f; colorRef2.g = 0.0f; colorRef2.b = 0.0f; colorNew2.r = 0.0f; colorNew2.g = 0.0f; colorNew2.b = 0.0f; sprintf(name, "face%.2d.tga", face+1); exclu[0] = FPOINT(105.0f/256.0f, 47.0f/166.0f); exclu[1] = FPOINT(153.0f/256.0f, 79.0f/166.0f); // bombonne bleu exclu[2] = FPOINT(0.0f, 0.0f); exclu[3] = FPOINT(0.0f, 0.0f); // terminateur m_engine->ChangeColor(name, colorRef1, colorNew1, colorRef2, colorNew2, tolerance, 0.00f, ts, ti, exclu); colorRef2.r = 0.0f; colorRef2.g = 0.0f; colorRef2.b = 0.0f; colorNew2.r = 0.0f; colorNew2.g = 0.0f; colorNew2.b = 0.0f; m_engine->ChangeColor("base1.tga", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, TRUE); m_engine->ChangeColor("convert.tga", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, TRUE); m_engine->ChangeColor("derrick.tga", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, TRUE); m_engine->ChangeColor("factory.tga", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, TRUE); m_engine->ChangeColor("lemt.tga", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, TRUE); m_engine->ChangeColor("roller.tga", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, TRUE); m_engine->ChangeColor("search.tga", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, 0, 0, TRUE); exclu[0] = FPOINT( 0.0f/256.0f, 160.0f/256.0f); exclu[1] = FPOINT(256.0f/256.0f, 256.0f/256.0f); // crayons exclu[2] = FPOINT(0.0f, 0.0f); exclu[3] = FPOINT(0.0f, 0.0f); // terminateur m_engine->ChangeColor("drawer.tga", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, exclu, 0, TRUE); exclu[0] = FPOINT(237.0f/256.0f, 176.0f/256.0f); exclu[1] = FPOINT(256.0f/256.0f, 220.0f/256.0f); // bombonne bleu exclu[2] = FPOINT(106.0f/256.0f, 150.0f/256.0f); exclu[3] = FPOINT(130.0f/256.0f, 214.0f/256.0f); // emplacement safe exclu[4] = FPOINT(0.0f, 0.0f); exclu[5] = FPOINT(0.0f, 0.0f); // terminateur m_engine->ChangeColor("subm.tga", m_colorRefBot, m_colorNewBot, colorRef2, colorNew2, 0.10f, -1.0f, ts, ti, exclu, 0, TRUE); exclu[0] = FPOINT(128.0f/256.0f, 160.0f/256.0f); exclu[1] = FPOINT(256.0f/256.0f, 256.0f/256.0f); // SatCom exclu[2] = FPOINT(0.0f, 0.0f); exclu[3] = FPOINT(0.0f, 0.0f); // terminateur m_engine->ChangeColor("ant.tga", m_colorRefAlien, m_colorNewAlien, colorRef2, colorNew2, 0.50f, -1.0f, ts, ti, exclu); m_engine->ChangeColor("mother.tga", m_colorRefAlien, m_colorNewAlien, colorRef2, colorNew2, 0.50f, -1.0f, ts, ti); m_engine->ChangeColor("plant.tga", m_colorRefGreen, m_colorNewGreen, colorRef2, colorNew2, 0.50f, -1.0f, ts, ti); // PARTIPLOUF0 et PARTIDROP : ts = FPOINT(0.500f, 0.500f); ti = FPOINT(0.875f, 0.750f); m_engine->ChangeColor("effect00.tga", m_colorRefWater, m_colorNewWater, colorRef2, colorNew2, 0.20f, -1.0f, ts, ti, 0, m_colorShiftWater, TRUE); // PARTIFLIC : ts = FPOINT(0.00f, 0.75f); ti = FPOINT(0.25f, 1.00f); m_engine->ChangeColor("effect02.tga", m_colorRefWater, m_colorNewWater, colorRef2, colorNew2, 0.20f, -1.0f, ts, ti, 0, m_colorShiftWater, TRUE); } // Met à jour le nombre d'objets non indispansables. BOOL CRobotMain::TestGadgetQuantity(int rank) { float percent; int *table; static int table10[10] = {0,1,0,0,0,0,0,0,0,0}; static int table20[10] = {0,1,0,0,0,1,0,0,0,0}; static int table30[10] = {0,1,0,1,0,1,0,0,0,0}; static int table40[10] = {0,1,0,1,0,1,0,1,0,0}; static int table50[10] = {0,1,0,1,0,1,0,1,0,1}; static int table60[10] = {0,1,0,1,1,1,0,1,0,1}; static int table70[10] = {0,1,0,1,1,1,0,1,1,1}; static int table80[10] = {0,1,1,1,1,1,0,1,1,1}; static int table90[10] = {0,1,1,1,1,1,1,1,1,1}; percent = m_engine->RetGadgetQuantity(); if ( percent == 0.0f ) return FALSE; if ( percent == 1.0f ) return TRUE; if ( percent <= 0.15f ) table = table10; else if ( percent <= 0.25f ) table = table20; else if ( percent <= 0.35f ) table = table30; else if ( percent <= 0.45f ) table = table40; else if ( percent <= 0.55f ) table = table50; else if ( percent <= 0.65f ) table = table60; else if ( percent <= 0.75f ) table = table70; else if ( percent <= 0.85f ) table = table80; else table = table90; return table[rank%10]; } // Calcule la distance jusqu'à l'objet le plus proche. float CRobotMain::SearchNearestObject(D3DVECTOR center, CObject *exclu) { CObject* pObj; ObjectType type; D3DVECTOR oPos; float min, dist, oRadius; int i, j; min = 100000.0f; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( !pObj->RetActif() ) continue; // inactif ? if ( pObj->RetTruck() != 0 ) continue; // objet porté ? if ( pObj == exclu ) continue; type = pObj->RetType(); if ( type == OBJECT_BASE ) { oPos = pObj->RetPosition(0); if ( oPos.x != center.x || oPos.z != center.z ) { dist = Length(center, oPos)-80.0f; if ( dist < 0.0f ) dist = 0.0f; min = Min(min, dist); continue; } } if ( type == OBJECT_STATION || type == OBJECT_REPAIR || type == OBJECT_DESTROYER ) { oPos = pObj->RetPosition(0); dist = Length(center, oPos)-8.0f; if ( dist < 0.0f ) dist = 0.0f; min = Min(min, dist); } j = 0; while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) { dist = Length(center, oPos)-oRadius; if ( dist < 0.0f ) dist = 0.0f; min = Min(min, dist); } } return min; } // Calcule un emplacement libre. BOOL CRobotMain::FreeSpace(D3DVECTOR ¢er, float minRadius, float maxRadius, float space, CObject *exclu) { D3DVECTOR pos; FPOINT p; float radius, ia, angle, dist, flat; if ( minRadius < maxRadius ) // de l'intérieur vers l'extérieur ? { for ( radius=minRadius ; radius<=maxRadius ; radius+=space ) { ia = space/radius; for ( angle=0.0f ; angleMoveOnFloor(pos, TRUE); dist = SearchNearestObject(pos, exclu); if ( dist >= space ) { flat = m_terrain->RetFlatZoneRadius(pos, dist/2.0f); if ( flat >= dist/2.0f ) { center = pos; return TRUE; } } } } } else // de l'extérieur vers l'intérieur ? { for ( radius=maxRadius ; radius>=minRadius ; radius-=space ) { ia = space/radius; for ( angle=0.0f ; angleMoveOnFloor(pos, TRUE); dist = SearchNearestObject(pos, exclu); if ( dist >= space ) { flat = m_terrain->RetFlatZoneRadius(pos, dist/2.0f); if ( flat >= dist/2.0f ) { center = pos; return TRUE; } } } } } return FALSE; } // Calcule le rayon maximal d'un emplacement libre. float CRobotMain::RetFlatZoneRadius(D3DVECTOR center, float maxRadius, CObject *exclu) { float dist; dist = SearchNearestObject(center, exclu); if ( dist == 0.0f ) return 0.0f; if ( dist < maxRadius ) { maxRadius = dist; } return m_terrain->RetFlatZoneRadius(center, maxRadius); } // Cache la zone constructible lorsqu'un cube de métal est repris. void CRobotMain::HideDropZone(CObject* metal) { if ( m_showLimit[1].bUsed && m_showLimit[1].link == metal ) { FlushShowLimit(1); } if ( m_showLimit[2].bUsed && m_showLimit[2].link == metal ) { FlushShowLimit(2); } } // Montre la zone constructible lorsqu'un cube de métal est déposé. void CRobotMain::ShowDropZone(CObject* metal, CObject* truck) { CObject* pObj; ObjectType type; D3DVECTOR center, oPos; float oMax, tMax, dist, oRadius, radius; int i, j; if ( metal == 0 ) return; center = metal->RetPosition(0); // Calcule le rayon maximal possible en fonction des autres objets. oMax = 30.0f; // rayon permettant de construire le plus grand bâtiment for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( !pObj->RetActif() ) continue; // inactif ? if ( pObj->RetTruck() != 0 ) continue; // objet porté ? if ( pObj == metal ) continue; if ( pObj == truck ) continue; type = pObj->RetType(); if ( type == OBJECT_BASE ) { oPos = pObj->RetPosition(0); dist = Length(center, oPos)-80.0f; oMax = Min(oMax, dist); } else { j = 0; while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) { dist = Length(center, oPos)-oRadius; oMax = Min(oMax, dist); } } if ( type == OBJECT_DERRICK || type == OBJECT_FACTORY || type == OBJECT_STATION || type == OBJECT_CONVERT || type == OBJECT_REPAIR || type == OBJECT_DESTROYER|| type == OBJECT_TOWER || type == OBJECT_RESEARCH || type == OBJECT_RADAR || type == OBJECT_ENERGY || type == OBJECT_LABO || type == OBJECT_NUCLEAR || type == OBJECT_START || type == OBJECT_END || type == OBJECT_INFO || type == OBJECT_PARA || type == OBJECT_SAFE || type == OBJECT_HUSTON ) // bâtiment ? { j = 0; while ( pObj->GetCrashSphere(j++, oPos, oRadius) ) { dist = Length(center, oPos)-oRadius-BUILDMARGIN; oMax = Min(oMax, dist); } } } // Calcule le rayon maximal possible en fonction du terrain. if ( oMax >= 2.0f ) { tMax = m_terrain->RetFlatZoneRadius(center, 30.0f); } else { tMax = 0.0f; } radius = Min(oMax, tMax); if ( radius >= 2.0f ) { SetShowLimit(1, PARTILIMIT2, metal, center, radius, 10.0f); } } // Efface les limites montrées. void CRobotMain::FlushShowLimit(int i) { int j; if ( m_showLimit[i].link != 0 ) { m_showLimit[i].link->StopShowLimit(); } for ( j=0 ; jDeleteParticule(m_showLimit[i].parti[j]); m_showLimit[i].parti[j] = 0; } m_showLimit[i].total = 0; m_showLimit[i].link = 0; m_showLimit[i].bUsed = FALSE; } // Spécifie les limites à montrer. void CRobotMain::SetShowLimit(int i, ParticuleType parti, CObject *pObj, D3DVECTOR pos, float radius, float duration) { FPOINT dim; float dist; int j; FlushShowLimit(i); // efface les limites actuelles if ( radius <= 0.0f ) return; if ( radius <= 50.0f ) { dim = FPOINT(0.3f, 0.3f); dist = 2.5f; } else { dim = FPOINT(1.5f, 1.5f); dist = 10.0f; } m_showLimit[i].bUsed = TRUE; m_showLimit[i].link = pObj; m_showLimit[i].pos = pos; m_showLimit[i].radius = radius; m_showLimit[i].duration = duration; m_showLimit[i].total = (int)((radius*2.0f*PI)/dist); if ( m_showLimit[i].total > MAXSHOWPARTI ) m_showLimit[i].total = MAXSHOWPARTI; m_showLimit[i].time = 0.0f; for ( j=0 ; jCreateParticule(pos, D3DVECTOR(0.0f, 0.0f, 0.0f), dim, parti, duration); } } // Ajuste les limites à montrer. void CRobotMain::AdjustShowLimit(int i, D3DVECTOR pos) { m_showLimit[i].pos = pos; } // Monter les limites de l'objet sélectionné. void CRobotMain::StartShowLimit() { CObject* pObj; pObj = RetSelect(); if ( pObj == 0 ) return; pObj->StartShowLimit(); } // Fait avancer les limites montrées. void CRobotMain::FrameShowLimit(float rTime) { D3DVECTOR pos; FPOINT center, rotate; float angle, factor, speed; int i, j; if ( m_engine->RetPause() ) return; for ( i=0 ; i= m_showLimit[i].duration ) { FlushShowLimit(i); continue; } if ( m_showLimit[i].time < 1.0f ) { factor = m_showLimit[i].time; } else if ( m_showLimit[i].time > m_showLimit[i].duration-1.0f ) { factor = m_showLimit[i].duration-m_showLimit[i].time; } else { factor = 1.0f; } speed = 0.4f-m_showLimit[i].radius*0.001f; if ( speed < 0.1f ) speed = 0.1f; angle = m_showLimit[i].time*speed; for ( j=0 ; jMoveOnFloor(pos, TRUE); if ( m_showLimit[i].radius <= 50.0f ) pos.y += 0.5f; else pos.y += 2.0f; m_particule->SetPosition(m_showLimit[i].parti[j], pos); //? m_particule->SetAngle(m_showLimit[i].parti[j], angle-PI/2.0f); angle += (2.0f*PI)/m_showLimit[i].total; } } } // Retourne un pointeur sur le dernier backslash d'un nom de fichier. char* SearchLastDir(char *filename) { char* p = filename; while ( *p++ != 0 ); p --; // ^sur le zéro terminateur while ( p != filename ) { if ( *(--p) == '\\' ) return p; } return 0; } // Compile tous les scripts des robots. void CRobotMain::CompileScript(BOOL bSoluce) { CObject* pObj; CBrain* brain; int i, j, nbError, lastError, run; char* name; nbError = 0; do { lastError = nbError; nbError = 0; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( pObj->RetTruck() != 0 ) continue; brain = pObj->RetBrain(); if ( brain == 0 ) continue; for ( j=0 ; j<10 ; j++ ) { if ( brain->RetCompile(j) ) continue; name = brain->RetScriptName(j); if ( name[0] != 0 ) { brain->ReadProgram(j, name); if ( !brain->RetCompile(j) ) nbError++; } } LoadOneScript(pObj, nbError); } } while ( nbError > 0 && nbError != lastError ); // Charge toutes les solutions. if ( bSoluce ) { for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( pObj->RetTruck() != 0 ) continue; brain = pObj->RetBrain(); if ( brain == 0 ) continue; name = brain->RetSoluceName(); if ( name[0] != 0 ) { brain->ReadSoluce(name); // charge solution } } } // Démarre tous les programmes selon la commande "run". for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( pObj->RetTruck() != 0 ) continue; brain = pObj->RetBrain(); if ( brain == 0 ) continue; run = brain->RetScriptRun(); if ( run != -1 ) { brain->RunProgram(run); // démarre le programme } } } // Charge tous les programmes d'un robot. void CRobotMain::LoadOneScript(CObject *pObj, int &nbError) { ObjectType type; CBrain* brain; char filename[_MAX_FNAME]; char* name; int rank, i, objRank; brain = pObj->RetBrain(); if ( brain == 0 ) return; if ( !IsSelectable(pObj) ) return; type = pObj->RetType(); if ( type == OBJECT_HUMAN ) return; objRank = pObj->RetDefRank(); if ( objRank == -1 ) return; name = m_dialog->RetSceneName(); rank = m_dialog->RetSceneRank(); for ( i=0 ; iRetCompile(i) ) continue; //? if ( brain->ProgramExist(i) ) continue; sprintf(filename, "%s\\%s\\%c%.3d%.3d%.1d.txt", RetSavegameDir(), m_gamerName, name[0], rank, objRank, i); brain->ReadProgram(i, filename); if ( !brain->RetCompile(i) ) nbError++; } } // Charge tous les programmes d'un robot. void CRobotMain::LoadFileScript(CObject *pObj, char* filename, int objRank, int &nbError) { ObjectType type; CBrain* brain; char fn[_MAX_FNAME]; char* ldir; char* name; int rank, i; if ( objRank == -1 ) return; brain = pObj->RetBrain(); if ( brain == 0 ) return; type = pObj->RetType(); if ( type == OBJECT_HUMAN ) return; name = m_dialog->RetSceneName(); rank = m_dialog->RetSceneRank(); strcpy(fn, filename); ldir = SearchLastDir(fn); if ( ldir == 0 ) return; for ( i=0 ; iRetCompile(i) ) continue; //? if ( brain->ProgramExist(i) ) continue; sprintf(ldir, "\\prog%.3d%.1d.txt", objRank, i); brain->ReadProgram(i, fn); if ( !brain->RetCompile(i) ) nbError++; } } // Sauve tous les programmes de tous les robots. void CRobotMain::SaveAllScript() { CObject* pObj; int i; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; SaveOneScript(pObj); } } // Sauve tous les programmes d'un robot. // Si un programme n'existe pas, le fichier correspondant est détruit. void CRobotMain::SaveOneScript(CObject *pObj) { ObjectType type; CBrain* brain; char filename[_MAX_FNAME]; char* name; int rank, i, objRank; brain = pObj->RetBrain(); if ( brain == 0 ) return; if ( !IsSelectable(pObj) ) return; type = pObj->RetType(); if ( type == OBJECT_HUMAN ) return; objRank = pObj->RetDefRank(); if ( objRank == -1 ) return; name = m_dialog->RetSceneName(); rank = m_dialog->RetSceneRank(); for ( i=0 ; iWriteProgram(i, filename); } } // Sauve tous les programmes d'un robot. // Si un programme n'existe pas, le fichier correspondant est détruit. void CRobotMain::SaveFileScript(CObject *pObj, char* filename, int objRank) { ObjectType type; CBrain* brain; char fn[_MAX_FNAME]; char* ldir; char* name; int rank, i; if ( objRank == -1 ) return; brain = pObj->RetBrain(); if ( brain == 0 ) return; type = pObj->RetType(); if ( type == OBJECT_HUMAN ) return; name = m_dialog->RetSceneName(); rank = m_dialog->RetSceneRank(); strcpy(fn, filename); ldir = SearchLastDir(fn); if ( ldir == 0 ) return; for ( i=0 ; iWriteProgram(i, fn); } } // Sauve le stack du programme en exécution d'un robot. BOOL CRobotMain::SaveFileStack(CObject *pObj, FILE *file, int objRank) { ObjectType type; CBrain* brain; if ( objRank == -1 ) return TRUE; brain = pObj->RetBrain(); if ( brain == 0 ) return TRUE; type = pObj->RetType(); if ( type == OBJECT_HUMAN ) return TRUE; return brain->WriteStack(file); } // Reprend le stack du programme en exécution d'un robot. BOOL CRobotMain::ReadFileStack(CObject *pObj, FILE *file, int objRank) { ObjectType type; CBrain* brain; if ( objRank == -1 ) return TRUE; brain = pObj->RetBrain(); if ( brain == 0 ) return TRUE; type = pObj->RetType(); if ( type == OBJECT_HUMAN ) return TRUE; return brain->ReadStack(file); } // Vide la liste. BOOL CRobotMain::FlushNewScriptName() { int i; for ( i=0 ; i 0 ) return TRUE; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; pBrain = pObj->RetBrain(); if ( pBrain != 0 ) { if ( pBrain->IsBusy() ) return TRUE; } //? pAuto = pObj->RetAuto(); //? if ( pAuto != 0 ) //? { //? if ( pAuto->RetBusy() ) return TRUE; //? } } return FALSE; } // Ecrit un objet dans le fichier de sauvegarde. void CRobotMain::IOWriteObject(FILE *file, CObject* pObj, char *cmd) { D3DVECTOR pos; CBrain* pBrain; char line[3000]; char name[100]; int run, i; if ( pObj->RetType() == OBJECT_FIX ) return; strcpy(line, cmd); sprintf(name, " type=%s", GetTypeObject(pObj->RetType())); strcat(line, name); sprintf(name, " id=%d", pObj->RetID()); strcat(line, name); pos = pObj->RetPosition(0)/g_unit; sprintf(name, " pos=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); strcat(line, name); pos = pObj->RetAngle(0)/(PI/180.0f); sprintf(name, " angle=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); strcat(line, name); pos = pObj->RetZoom(0); sprintf(name, " zoom=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); strcat(line, name); for ( i=1 ; iRetObjectRank(i) == -1 ) continue; pos = pObj->RetPosition(i); if ( pos.x != 0.0f || pos.y != 0.0f || pos.z != 0.0f ) { pos /= g_unit; sprintf(name, " p%d=%.2f;%.2f;%.2f", i, pos.x, pos.y, pos.z); strcat(line, name); } pos = pObj->RetAngle(i); if ( pos.x != 0.0f || pos.y != 0.0f || pos.z != 0.0f ) { pos /= (PI/180.0f); sprintf(name, " a%d=%.2f;%.2f;%.2f", i, pos.x, pos.y, pos.z); strcat(line, name); } pos = pObj->RetZoom(i); if ( pos.x != 1.0f || pos.y != 1.0f || pos.z != 1.0f ) { sprintf(name, " z%d=%.2f;%.2f;%.2f", i, pos.x, pos.y, pos.z); strcat(line, name); } } sprintf(name, " trainer=%d", pObj->RetTrainer()); strcat(line, name); sprintf(name, " option=%d", pObj->RetOption()); strcat(line, name); if ( pObj == m_infoObject ) // objet sélectionné ? { sprintf(name, " select=1"); strcat(line, name); } pObj->Write(line); if ( pObj->RetType() == OBJECT_BASE ) { sprintf(name, " run=3"); // stoppé et ouvert (PARAM_FIXSCENE) strcat(line, name); } pBrain = pObj->RetBrain(); if ( pBrain != 0 ) { run = pBrain->RetProgram(); if ( run != -1 ) { sprintf(name, " run=%d", run+1); strcat(line, name); } } strcat(line, "\n"); fputs(line, file); } // Enregistre la partie en cours. BOOL CRobotMain::IOWriteScene(char *filename, char *filecbot, char *info) { FILE* file; char line[500]; char* name; CObject *pObj, *pPower, *pFret; float sleep, delay, magnetic, progress; int i, objRank; long version; file = fopen(filename, "w"); if ( file == NULL ) return FALSE; sprintf(line, "Title text=\"%s\"\n", info); fputs(line, file); sprintf(line, "Version maj=%d min=%d\n", 0, 1); fputs(line, file); name = m_dialog->RetSceneName(); if ( strcmp(name, "user") == 0 ) { sprintf(line, "Mission base=\"%s\" rank=%.3d dir=\"%s\"\n", name, m_dialog->RetSceneRank(), m_dialog->RetSceneDir()); } else { sprintf(line, "Mission base=\"%s\" rank=%.3d\n", name, m_dialog->RetSceneRank()); } fputs(line, file); sprintf(line, "Map zoom=%.2f\n", m_map->RetZoomMap()); fputs(line, file); sprintf(line, "DoneResearch bits=%d\n", g_researchDone); fputs(line, file); if ( m_blitz->GetStatus(sleep, delay, magnetic, progress) ) { sprintf(line, "BlitzMode sleep=%.2f delay=%.2f magnetic=%.2f progress=%.2f\n", sleep, delay, magnetic/g_unit, progress); fputs(line, file); } objRank = 0; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( pObj->RetType() == OBJECT_TOTO ) continue; if ( pObj->RetType() == OBJECT_FIX ) continue; if ( pObj->RetTruck() != 0 ) continue; if ( pObj->RetBurn() ) continue; if ( pObj->RetDead() ) continue; if ( pObj->RetExplo() ) continue; pPower = pObj->RetPower(); pFret = pObj->RetFret(); if ( pFret != 0 ) // objet transporté ? { IOWriteObject(file, pFret, "CreateFret"); } if ( pPower != 0 ) // pile transportée ? { IOWriteObject(file, pPower, "CreatePower"); } IOWriteObject(file, pObj, "CreateObject"); SaveFileScript(pObj, filename, objRank++); } fclose(file); #if CBOT_STACK // Ecrit le fichier des stacks d'exécution. file = fOpen(filecbot, "wb"); if ( file == NULL ) return FALSE; version = 1; fWrite(&version, sizeof(long), 1, file); // version de COLOBOT version = CBotProgram::GivVersion(); fWrite(&version, sizeof(long), 1, file); // version de CBOT objRank = 0; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( pObj->RetType() == OBJECT_TOTO ) continue; if ( pObj->RetType() == OBJECT_FIX ) continue; if ( pObj->RetTruck() != 0 ) continue; if ( pObj->RetBurn() ) continue; if ( pObj->RetDead() ) continue; if ( !SaveFileStack(pObj, file, objRank++) ) break; } CBotClass::SaveStaticState(file); fClose(file); #endif m_delayWriteMessage = 4; // affiche message dans 3 frames return TRUE; } // Reprend un objet enregistré. CObject* CRobotMain::IOReadObject(char *line, char* filename, int objRank) { CObject* pObj; //? CBrain* pBrain; CAuto* pAuto; D3DVECTOR pos, dir, zoom; ObjectType type; int id, run, trainer, toy, option, i; char op[10]; pos = OpDir(line, "pos")*g_unit; dir = OpDir(line, "angle")*(PI/180.0f); zoom = OpDir(line, "zoom"); type = OpTypeObject(line, "type", OBJECT_NULL); id = OpInt(line, "id", 0); if ( type == OBJECT_NULL ) return 0; trainer = OpInt(line, "trainer", 0); toy = OpInt(line, "toy", 0); option = OpInt(line, "option", 0); pObj = CreateObject(pos, dir.y, 1.0f, 0.0f, type, 0.0f, trainer, toy, option); pObj->SetDefRank(objRank); pObj->SetPosition(0, pos); pObj->SetAngle(0, dir); pObj->SetID(id); if ( g_id < id ) g_id = id; if ( zoom.x != 0.0f || zoom.y != 0.0f || zoom.z != 0.0f ) { pObj->SetZoom(0, zoom); } for ( i=1 ; iRetObjectRank(i) == -1 ) continue; sprintf(op, "p%d", i); pos = OpDir(line, op); if ( pos.x != 0.0f || pos.y != 0.0f || pos.z != 0.0f ) { pObj->SetPosition(i, pos*g_unit); } sprintf(op, "a%d", i); dir = OpDir(line, op); if ( dir.x != 0.0f || dir.y != 0.0f || dir.z != 0.0f ) { pObj->SetAngle(i, dir*(PI/180.0f)); } sprintf(op, "z%d", i); zoom = OpDir(line, op); if ( zoom.x != 0.0f || zoom.y != 0.0f || zoom.z != 0.0f ) { pObj->SetZoom(i, zoom); } } if ( type == OBJECT_BASE ) m_bBase = TRUE; pObj->Read(line); #if CBOT_STACK #else LoadFileScript(pObj, filename, objRank, i); #endif run = OpInt(line, "run", -1); if ( run != -1 ) { #if CBOT_STACK #else pBrain = pObj->RetBrain(); if ( pBrain != 0 ) { pBrain->RunProgram(run-1); // démarre le programme } #endif pAuto = pObj->RetAuto(); if ( pAuto != 0 ) { pAuto->Start(run); // démarre le film } } return pObj; } // Reprend une partie enregistrée. CObject* CRobotMain::IOReadScene(char *filename, char *filecbot) { FILE* file; CObject *pObj, *pPower, *pFret, *pSel; char line[3000]; float sleep, delay, progress, magnetic; int i, objRank, nbError, lastError; long version; m_bBase = FALSE; file = fopen(filename, "r"); if ( file == NULL ) return 0; pFret = 0; pPower = 0; pSel = 0; objRank = 0; while ( fgets(line, 3000, file) != NULL ) { for ( i=0 ; i<3000 ; i++ ) { if ( line[i] == '\t' ) line[i] = ' '; // remplace tab par space if ( line[i] == '/' && line[i+1] == '/' ) { line[i] = 0; break; } } if ( Cmd(line, "Map") ) { m_map->ZoomMap(OpFloat(line, "zoom", 1.0f)); } if ( Cmd(line, "DoneResearch") ) { g_researchDone = OpInt(line, "bits", 0); } if ( Cmd(line, "BlitzMode") ) { sleep = OpFloat(line, "sleep", 0.0f); delay = OpFloat(line, "delay", 3.0f); magnetic = OpFloat(line, "magnetic", 50.0f)*g_unit; progress = OpFloat(line, "progress", 0.0f); m_blitz->SetStatus(sleep, delay, magnetic, progress); } if ( Cmd(line, "CreateFret") ) { pFret = IOReadObject(line, filename, -1); } if ( Cmd(line, "CreatePower") ) { pPower = IOReadObject(line, filename, -1); } if ( Cmd(line, "CreateObject") ) { pObj = IOReadObject(line, filename, objRank++); if ( OpInt(line, "select", 0) ) { pSel = pObj; } if ( pFret != 0 ) { CTaskManip* task; pObj->SetFret(pFret); task = new CTaskManip(m_iMan, pObj); task->Start(TMO_AUTO, TMA_GRAB); // tient l'objet ! delete task; } if ( pPower != 0 ) { pObj->SetPower(pPower); pPower->SetTruck(pObj); } pFret = 0; pPower = 0; } } fclose(file); #if CBOT_STACK // Compile les scripts. nbError = 0; do { lastError = nbError; nbError = 0; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( pObj->RetTruck() != 0 ) continue; objRank = pObj->RetDefRank(); if ( objRank == -1 ) continue; LoadFileScript(pObj, filename, objRank, nbError); } } while ( nbError > 0 && nbError != lastError ); // Lit le fichier des stacks d'exécution. file = fOpen(filecbot, "rb"); if ( file != NULL ) { fRead(&version, sizeof(long), 1, file); // version de COLOBOT if ( version == 1 ) { fRead(&version, sizeof(long), 1, file); // version de CBOT if ( version == CBotProgram::GivVersion() ) { objRank = 0; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; if ( pObj->RetType() == OBJECT_TOTO ) continue; if ( pObj->RetType() == OBJECT_FIX ) continue; if ( pObj->RetTruck() != 0 ) continue; if ( pObj->RetBurn() ) continue; if ( pObj->RetDead() ) continue; if ( !ReadFileStack(pObj, file, objRank++) ) break; } } } CBotClass::RestoreStaticState(file); fClose(file); } #endif return pSel; } // Ecrit les paramètres globaux pour le jeu libre. void CRobotMain::WriteFreeParam() { FILE* file; char filename[_MAX_FNAME]; char line[100]; m_freeResearch |= g_researchDone; m_freeBuild |= g_build; if ( m_gamerName[0] == 0 ) return; sprintf(filename, "%s\\%s\\research.gam", RetSavegameDir(), m_gamerName); file = fopen(filename, "w"); if ( file == NULL ) return; sprintf(line, "research=%d build=%d\n", m_freeResearch, m_freeBuild); fputs(line, file); fclose(file); } // Lit les paramètres globaux pour le jeu libre. void CRobotMain::ReadFreeParam() { FILE* file; char filename[_MAX_FNAME]; char line[100]; m_freeResearch = 0; m_freeBuild = 0; if ( m_gamerName[0] == 0 ) return; sprintf(filename, "%s\\%s\\research.gam", RetSavegameDir(), m_gamerName); file = fopen(filename, "r"); if ( file == NULL ) return; if ( fgets(line, 100, file) != NULL ) { sscanf(line, "research=%d build=%d\n", &m_freeResearch, &m_freeBuild); } fclose(file); } // Remet tous les objets à leur place initiale. void CRobotMain::ResetObject() { #if 0 CObject* pObj; CObject* pTruck; CAuto* pAuto; CBrain* brain; CPyro* pyro; ResetCap cap; D3DVECTOR pos, angle; int i; // Supprime tous les effets pyrotechniques en cours. while ( TRUE ) { pyro = (CPyro*)m_iMan->SearchInstance(CLASS_PYRO, 0); if ( pyro == 0 ) break; pyro->DeleteObject(); delete pyro; } // Supprime toutes les balles en cours. m_particule->DeleteParticule(PARTIGUN1); m_particule->DeleteParticule(PARTIGUN2); m_particule->DeleteParticule(PARTIGUN3); m_particule->DeleteParticule(PARTIGUN4); for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; cap = pObj->RetResetCap(); if ( cap == RESET_NONE ) continue; if ( cap == RESET_DELETE ) { pTruck = pObj->RetTruck(); if ( pTruck != 0 ) { pTruck->SetFret(0); pObj->SetTruck(0); } pObj->DeleteObject(); delete pObj; i --; continue; } pAuto = pObj->RetAuto(); if ( pAuto != 0 ) { pAuto->Abort(); } if ( pObj->RetEnable() ) // objet toujours actif ? { brain = pObj->RetBrain(); if ( brain != 0 ) { pos = pObj->RetResetPosition(); angle = pObj->RetResetAngle(); if ( pos == pObj->RetPosition(0) && angle == pObj->RetAngle(0) ) continue; brain->StartTaskReset(pos, angle); continue; } } pObj->SetEnable(TRUE); // de nouveau actif pos = pObj->RetResetPosition(); angle = pObj->RetResetAngle(); if ( pos == pObj->RetPosition(0) && angle == pObj->RetAngle(0) ) continue; pyro = new CPyro(m_iMan); pyro->Create(PT_RESET, pObj); brain = pObj->RetBrain(); if ( brain != 0 ) { brain->RunProgram(pObj->RetResetRun()); } } #else m_bResetCreate = TRUE; #endif } // Remet tous les objets à leur place initiale. void CRobotMain::ResetCreate() { CObject* pObj; CPyro* pyro; ResetCap cap; int i; SaveAllScript(); // Supprime toutes les balles en cours. m_particule->DeleteParticule(PARTIGUN1); m_particule->DeleteParticule(PARTIGUN2); m_particule->DeleteParticule(PARTIGUN3); m_particule->DeleteParticule(PARTIGUN4); DeselectAll(); // enlève les boutons de commande DeleteAllObjects(); // supprime toute la scène 3D actuelle m_particule->FlushParticule(); m_terrain->FlushBuildingLevel(); m_iMan->Flush(CLASS_OBJECT); m_iMan->Flush(CLASS_PHYSICS); m_iMan->Flush(CLASS_BRAIN); m_iMan->Flush(CLASS_PYRO); m_camera->SetType(CAMERA_DIALOG); CreateScene(m_dialog->RetSceneSoluce(), FALSE, TRUE); if ( !RetNiceReset() ) return; for ( i=0 ; i<1000000 ; i++ ) { pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; cap = pObj->RetResetCap(); if ( cap == RESET_NONE ) continue; pyro = new CPyro(m_iMan); pyro->Create(PT_RESET, pObj); } } // Vérifie si la mission est terminée. Error CRobotMain::CheckEndMission(BOOL bFrame) { CObject* pObj; D3DVECTOR bPos, oPos; ObjectType type; int t, i, nb; for ( t=0 ; tSearchInstance(CLASS_OBJECT, i); if ( pObj == 0 ) break; // Ne pas utiliser RetActif(), car un ver invisible (sous terre) // doit être considéré comme existant ici ! if ( pObj->RetLock() ) continue; if ( pObj->RetRuin() ) continue; if ( !pObj->RetEnable() ) continue; type = pObj->RetType(); if ( type == OBJECT_SCRAP2 || type == OBJECT_SCRAP3 || type == OBJECT_SCRAP4 || type == OBJECT_SCRAP5 ) // déchet ? { type = OBJECT_SCRAP1; } if ( type != m_endTake[t].type ) continue; if ( pObj->RetTruck() == 0 ) { oPos = pObj->RetPosition(0); } else { oPos = pObj->RetTruck()->RetPosition(0); } oPos.y = 0.0f; if ( Length2d(oPos, bPos) <= m_endTake[t].dist ) { nb ++; } } if ( nb <= m_endTake[t].lost ) { if ( m_endTake[t].type == OBJECT_HUMAN ) { if ( m_lostDelay == 0.0f ) { m_lostDelay = 0.1f; // perdu immédiatement m_winDelay = 0.0f; } m_displayText->SetEnable(FALSE); return INFO_LOSTq; } else { if ( m_lostDelay == 0.0f ) { m_displayText->DisplayError(INFO_LOST, D3DVECTOR(0.0f,0.0f,0.0f)); m_lostDelay = m_endTakeLostDelay; // perdu dans 6 secondes m_winDelay = 0.0f; } m_displayText->SetEnable(FALSE); return INFO_LOST; } } if ( nb < m_endTake[t].min || nb > m_endTake[t].max ) { m_displayText->SetEnable(TRUE); return ERR_MISSION_NOTERM; } if ( m_endTake[t].bImmediat ) { if ( m_winDelay == 0.0f ) { m_winDelay = m_endTakeWinDelay; // gagné dans x seconde m_lostDelay = 0.0f; } m_displayText->SetEnable(FALSE); return ERR_OK; // mission terminée } } if ( m_endTakeResearch != 0 ) { if ( m_endTakeResearch != (m_endTakeResearch&g_researchDone) ) { m_displayText->SetEnable(TRUE); return ERR_MISSION_NOTERM; } } if ( m_endTakeWinDelay == -1.0f ) { m_winDelay = 1.0f; // gagné dans 1 seconde m_lostDelay = 0.0f; m_displayText->SetEnable(FALSE); return ERR_OK; // mission terminée } if ( bFrame && m_bBase ) return ERR_MISSION_NOTERM; if ( m_winDelay == 0.0f ) { m_displayText->DisplayError(INFO_WIN, D3DVECTOR(0.0f,0.0f,0.0f)); m_winDelay = m_endTakeWinDelay; // gagné dans 2 secondes m_lostDelay = 0.0f; } m_displayText->SetEnable(FALSE); return ERR_OK; // mission terminée } // Vérifie si la mission est terminée suite à l'affichage d'un message. void CRobotMain::CheckEndMessage(char *message) { int t; for ( t=0 ; tDisplayError(INFO_WIN, D3DVECTOR(0.0f,0.0f,0.0f)); m_winDelay = m_endTakeWinDelay; // gagné dans 2 secondes m_lostDelay = 0.0f; } } } // Retourne le nombre d'instructions obligatoires. int CRobotMain::RetObligatoryToken() { return m_obligatoryTotal; } // Retourne le nom d'une instruction obligatoire. char* CRobotMain::RetObligatoryToken(int i) { return m_obligatoryToken[i]; } // Vérifie si une instruction fait partie de la liste obligatoire. int CRobotMain::IsObligatoryToken(char *token) { int i; for ( i=0 ; iRetGlint(); } BOOL CRobotMain::RetSoluce4() { return m_dialog->RetSoluce4(); } BOOL CRobotMain::RetMovies() { return m_dialog->RetMovies(); } BOOL CRobotMain::RetNiceReset() { return m_dialog->RetNiceReset(); } BOOL CRobotMain::RetHimselfDamage() { return m_dialog->RetHimselfDamage(); } BOOL CRobotMain::RetShowSoluce() { return m_bShowSoluce; } BOOL CRobotMain::RetSceneSoluce() { if ( m_infoFilename[SATCOM_SOLUCE][0] == 0 ) return FALSE; return m_dialog->RetSceneSoluce(); } BOOL CRobotMain::RetShowAll() { return m_bShowAll; } BOOL CRobotMain::RetCheatRadar() { return m_bCheatRadar; } char* CRobotMain::RetSavegameDir() { return m_dialog->RetSavegameDir(); } char* CRobotMain::RetPublicDir() { return m_dialog->RetPublicDir(); } char* CRobotMain::RetFilesDir() { return m_dialog->RetFilesDir(); } // Change le nom du joueur. void CRobotMain::SetGamerName(char *name) { strcpy(m_gamerName, name); SetGlobalGamerName(m_gamerName); ReadFreeParam(); } // Donne le nom du joueur. char* CRobotMain::RetGamerName() { return m_gamerName; } // Retourne la représentation à utiliser pour le joueur. int CRobotMain::RetGamerFace() { return m_dialog->RetGamerFace(); } // Retourne la représentation à utiliser pour le joueur. int CRobotMain::RetGamerGlasses() { return m_dialog->RetGamerGlasses(); } // Retourne le mode avec seulement la tête. BOOL CRobotMain::RetGamerOnlyHead() { return m_dialog->RetGamerOnlyHead(); } // Retourne l'angle de présentation. float CRobotMain::RetPersoAngle() { return m_dialog->RetPersoAngle(); } // Change le mode de pause. void CRobotMain::ChangePause(BOOL bPause) { m_bPause = bPause; m_engine->SetPause(m_bPause); m_sound->MuteAll(m_bPause); CreateShortcuts(); if ( m_bPause ) HiliteClear(); } // Change la vitesse du jeu. void CRobotMain::SetSpeed(float speed) { CButton* pb; char text[10]; m_engine->SetSpeed(speed); pb = (CButton*)m_interface->SearchControl(EVENT_SPEED); if ( pb != 0 ) { if ( speed == 1.0f ) { pb->ClearState(STATE_VISIBLE); } else { sprintf(text, "x%.1f", speed); pb->SetName(text); pb->SetState(STATE_VISIBLE); } } } float CRobotMain::RetSpeed() { return m_engine->RetSpeed(); } // Crée l'interface des raccourcis aux unités. BOOL CRobotMain::CreateShortcuts() { if ( m_phase != PHASE_SIMUL ) return FALSE; if ( !m_bShortCut ) return FALSE; return m_short->CreateShortcuts(); } // Met à jour la carte. void CRobotMain::UpdateMap() { m_map->UpdateMap(); } // Indique si la mini-carte est visible. BOOL CRobotMain::RetShowMap() { return m_map->RetShowMap() && m_bMapShow; } // Gestion du mode de blocage pendant les films. void CRobotMain::SetMovieLock(BOOL bLock) { m_bMovieLock = bLock; m_engine->SetMovieLock(m_bMovieLock); CreateShortcuts(); m_map->ShowMap(!m_bMovieLock && m_bMapShow); if ( m_bMovieLock ) HiliteClear(); m_engine->SetMouseHide(m_bMovieLock); } BOOL CRobotMain::RetMovieLock() { return m_bMovieLock; } BOOL CRobotMain::RetInfoLock() { return ( m_displayInfo != 0 ); // info en cours ? } // Gestion du blocage de l'appel du SatCom. void CRobotMain::SetSatComLock(BOOL bLock) { m_bSatComLock = bLock; } BOOL CRobotMain::RetSatComLock() { return m_bSatComLock; } // Gestion du mode de blocage pendant l'édition. void CRobotMain::SetEditLock(BOOL bLock, BOOL bEdit) { m_bEditLock = bLock; CreateShortcuts(); // N'enlève pas la carte si elle contient une image fixe. if ( !bLock || !m_map->RetFixImage() ) { m_map->ShowMap(!m_bEditLock && m_bMapShow); } m_displayText->HideText(bLock); m_engine->FlushPressKey(); if ( m_bEditLock ) { HiliteClear(); } else { m_bEditFull = FALSE; } } BOOL CRobotMain::RetEditLock() { return m_bEditLock; } // Gestion du mode plein écran pendant l'édition. void CRobotMain::SetEditFull(BOOL bFull) { m_bEditFull = bFull; } BOOL CRobotMain::RetEditFull() { return m_bEditFull; } BOOL CRobotMain::RetFreePhoto() { return m_bFreePhoto; } // Indique si la souris vise un objet ami, sur lequel il ne faut // pas tirer. void CRobotMain::SetFriendAim(BOOL bFriend) { m_bFriendAim = bFriend; } BOOL CRobotMain::RetFriendAim() { return m_bFriendAim; } // Gestion de la précision du dessin au sol. void CRobotMain::SetTracePrecision(float factor) { m_engine->SetTracePrecision(factor); } float CRobotMain::RetTracePrecision() { return m_engine->RetTracePrecision(); } // Débute la musique d'une mission. void CRobotMain::StartMusic() { if ( m_audioTrack != 0 ) { m_sound->StopMusic(); m_sound->PlayMusic(m_audioTrack, m_bAudioRepeat); } } // Enlève hilite et tooltip. void CRobotMain::ClearInterface() { HiliteClear(); // enlève la mise en évidence m_tooltipName[0] = 0; // enlève vraiment le tooltip }