diff options
author | Didier Raboud <odyx@debian.org> | 2013-04-28 11:27:27 +0200 |
---|---|---|
committer | Didier Raboud <odyx@debian.org> | 2013-04-28 11:27:27 +0200 |
commit | e60a610f013f75c4ca54768b756348d6a37ae2d2 (patch) | |
tree | f1872f00c691192e36f3fa4d01b6a27eb4b6f75a | |
parent | d36d4b9a25980d9fb6b18961ca8200f6eaa8c311 (diff) | |
parent | 0ce02b21f40ed8a0086dffe2c4bb01eeff942e58 (diff) | |
download | colobot-e60a610f013f75c4ca54768b756348d6a37ae2d2.tar.gz colobot-e60a610f013f75c4ca54768b756348d6a37ae2d2.tar.bz2 colobot-e60a610f013f75c4ca54768b756348d6a37ae2d2.zip |
New snapshot of dev branch (296-g0ce02b2)
30 files changed, 482 insertions, 428 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 9183668..5f5f1f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,7 +110,7 @@ find_package(SDL_ttf 2.0 REQUIRED) find_package(PNG 1.2 REQUIRED) find_package(Gettext REQUIRED) -set(Boost_USE_STATIC_LIBS OFF) +set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) set(Boost_USE_STATIC_RUNTIME OFF) diff --git a/debian/changelog b/debian/changelog index 15ebc67..c3db051 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -colobot (0.1.0~pre-alpha-git-dev~r264-gbc760e3-1~OdyX0) UNRELEASED; urgency=low +colobot (0.1.0~pre-alpha-git-dev~r296-g0ce02b2-1~OdyX0) UNRELEASED; urgency=low * Initial release. (Closes: #695829) - -- Didier Raboud <odyx@debian.org> Fri, 12 Apr 2013 12:08:31 +0200 + -- Didier Raboud <odyx@debian.org> Sun, 28 Apr 2013 11:27:27 +0200 diff --git a/src/CBot/CBot.cpp b/src/CBot/CBot.cpp index ed6831d..4a16b6b 100644 --- a/src/CBot/CBot.cpp +++ b/src/CBot/CBot.cpp @@ -186,7 +186,7 @@ CBotInstr* CBotInstr::Compile(CBotToken* &p, CBotCStack* pStack) { type = pp->GetType(); // these instructions accept only lable - if (!IsOfTypeList(pp, ID_WHILE, ID_FOR, ID_DO, ID_REPEAT, 0)) + if (!IsOfTypeList(pp, ID_WHILE, ID_FOR, ID_DO, 0)) { pStack->SetError(TX_LABEL, pp->GetStart()); return NULL; @@ -205,9 +205,6 @@ CBotInstr* CBotInstr::Compile(CBotToken* &p, CBotCStack* pStack) case ID_DO: return CBotDo::Compile(p, pStack); - case ID_REPEAT: - return CBotRepeat::Compile(p, pStack); - case ID_BREAK: case ID_CONTINUE: return CBotBreak::Compile(p, pStack); diff --git a/src/CBot/CBot.h b/src/CBot/CBot.h index 8886308..f5d78c8 100644 --- a/src/CBot/CBot.h +++ b/src/CBot/CBot.h @@ -57,7 +57,6 @@ class CBotExprVar; // a variable name as class CBotWhile; // while (...) {...}; class CBotIf; // if (...) {...} else {...} class CBotDefParam; // paramerer list of a function -class CBotRepeat; // repeat (nb) {...} @@ -492,32 +491,6 @@ public: void RestoreState(CBotStack* &pj, bool bMain); }; -class CBotRepeat : public CBotInstr -{ -private: - /// Number of iterations - CBotInstr* m_NbIter; - - /// Instructions - CBotInstr* m_Block; - - /// Label - CBotString m_label; // a label if there is - -public: - CBotRepeat(); - ~CBotRepeat(); - - /// Static method used for compilation - static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack); - - /// Execute - bool Execute(CBotStack* &pj); - - /// Restore state - void RestoreState(CBotStack* &pj, bool bMain); -}; - class CBotDo : public CBotInstr { private: diff --git a/src/CBot/CBotString.cpp b/src/CBot/CBotString.cpp index b1b5fc4..51cae52 100644 --- a/src/CBot/CBotString.cpp +++ b/src/CBot/CBotString.cpp @@ -54,7 +54,6 @@ const std::map<EID,const char *> CBotString::s_keywordString = {ID_STATIC, "static"}, {ID_PROTECTED, "protected"}, {ID_PRIVATE, "private"}, - {ID_REPEAT, "repeat"}, {ID_DEBUGDD, "STARTDEBUGDD"}, {ID_INT, "int"}, {ID_FLOAT, "float"}, diff --git a/src/CBot/CBotWhile.cpp b/src/CBot/CBotWhile.cpp index dfd69bf..d24dc4b 100644 --- a/src/CBot/CBotWhile.cpp +++ b/src/CBot/CBotWhile.cpp @@ -158,149 +158,6 @@ void CBotWhile :: RestoreState(CBotStack* &pj, bool bMain) /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// -// compiles instruction "repeat" - -CBotRepeat::CBotRepeat() -{ - m_NbIter = - m_Block = NULL; // NULL so that delete is not possible further - name = "CBotRepeat"; // debug -} - -CBotRepeat::~CBotRepeat() -{ - delete m_NbIter; // frees the condition - delete m_Block; // frees the instruction block -} - -CBotInstr* CBotRepeat::Compile(CBotToken* &p, CBotCStack* pStack) -{ - CBotRepeat* inst = new CBotRepeat(); // creates the object - CBotToken* pp = p; // preserves at the ^ token (starting position) - - if ( IsOfType( p, TokenTypVar ) && - IsOfType( p, ID_DOTS ) ) - { - inst->m_label = pp->GetString(); // register the name of label - } - - inst->SetToken(p); - if (!IsOfType(p, ID_REPEAT)) return NULL; // should never happen - - CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp - - if ( IsOfType(p, ID_OPENPAR ) ) - { - CBotToken* ppp = p; // preserves the ^ token (starting position) - if ( NULL != (inst->m_NbIter = CBotExpression::Compile( p, pStk )) ) - { - if ( pStk->GetType() < CBotTypLong ) - { - if ( IsOfType(p, ID_CLOSEPAR ) ) - { - - IncLvl(inst->m_label); - inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true ); - DecLvl(); - - if ( pStk->IsOk() ) - { - // the statement block is ok (it may be empty! - - return pStack->Return(inst, pStk); // return an object to the application - } - } - pStack->SetError(TX_CLOSEPAR, p->GetStart()); - } - pStk->SetStartError(ppp->GetStart()); - pStk->SetError( TX_BADTYPE, p->GetStart() ); - } - pStack->SetError(TX_ENDOF, p); - } - pStack->SetError(TX_OPENPAR, p->GetStart()); // missing parenthesis - - delete inst; // error, frees up - return pStack->Return(NULL, pStk); // no object, the error is on the stack -} - -// execution of intruction "repeat" - -bool CBotRepeat :: Execute(CBotStack* &pj) -{ - CBotStack* pile = pj->AddStack(this); // adds an item to the stack - // or find in case of recovery -// if ( pile == EOX ) return true; - - if ( pile->IfStep() ) return false; - - while( true ) switch( pile->GetState() ) // executes the loop - { // there are two possible states (depending on recovery) - case 0: - // evaluates the number of iterations - if ( !m_NbIter->Execute(pile) ) return false; // interrupted here ? - - // the result of the condition is on the stack - - // terminates if an error or if the condition is false - int n; - if ( !pile->IsOk() || ( n = pile->GetVal() ) < 1 ) - { - return pj->Return(pile); // sends the results and releases the stack - } - - // puts the number of iterations +1 to the "state" - - if (!pile->SetState(n+1)) return false; // ready for further - continue; // continue as a result - - case 1: - // normal end of the loop - return pj->Return(pile); // sends the results and releases the stack - - default: - // evaluates the associated statement block - if ( m_Block != NULL && - !m_Block->Execute(pile) ) - { - if (pile->IfContinue(pile->GetState()-1, m_label)) continue; // if continued, will return to test - return pj->BreakReturn(pile, m_label); // sends the results and releases the stack - } - - // terminates if there is an error - if ( !pile->IsOk() ) - { - return pj->Return(pile); // sends the results and releases the stack - } - - // returns to the test again - if (!pile->SetState(pile->GetState()-1, 0)) return false; - continue; - } -} - -void CBotRepeat :: RestoreState(CBotStack* &pj, bool bMain) -{ - if ( !bMain ) return; - CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack - if ( pile == NULL ) return; - - switch( pile->GetState() ) - { // there are two possible states (depending on recovery) - case 0: - // evaluates the condition - m_NbIter->RestoreState(pile, bMain); - return; - - case 1: - // evaluates the associated statement block - if ( m_Block != NULL ) m_Block->RestoreState(pile, bMain); - return; - } -} - -/////////////////////////////////////////////////////////////////////////// - -/////////////////////////////////////////////////////////////////////////// // compile the instruction "do" CBotDo::CBotDo() diff --git a/src/CBot/resource.h b/src/CBot/resource.h index ed14240..f0449b0 100644 --- a/src/CBot/resource.h +++ b/src/CBot/resource.h @@ -47,7 +47,6 @@ enum EID ID_STATIC, ID_PROTECTED, ID_PRIVATE, - ID_REPEAT, ID_DEBUGDD, ID_INT, ID_FLOAT, diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d9c3d57..26c02bc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -186,6 +186,7 @@ ${OPENAL_SRC} set(LIBS CBot +clipboard ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} @@ -196,7 +197,6 @@ ${Boost_LIBRARIES} ${LIBSNDFILE_LIBRARY} ${OPTIONAL_LIBS} ${PLATFORM_LIBS} -clipboard ) # Local diff --git a/src/app/app.cpp b/src/app/app.cpp index 3801f95..6231eb6 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -449,6 +449,7 @@ bool CApplication::Create() // Enable translating key codes of key press events to unicode chars SDL_EnableUNICODE(1); + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); // Don't generate joystick events SDL_JoystickEventState(SDL_IGNORE); diff --git a/src/common/global.h b/src/common/global.h index 7a5fdfd..db601df 100644 --- a/src/common/global.h +++ b/src/common/global.h @@ -55,6 +55,8 @@ enum Error ERR_BUILD_BASE = 129, //! < too close to the rocket ERR_BUILD_NARROW = 130, //! < buildings too close ERR_BUILD_MOTOR = 131, //! < built: not possible in movement + ERR_BUILD_DISABLED = 132, //! < built: can not produce this object in this mission + ERR_BUILD_RESEARCH = 133, //! < built: can not produce not researched object ERR_SEARCH_FLY = 140, //! < not possible in flight ERR_SEARCH_VEH = 141, //! < inappropriate vehicle ERR_SEARCH_MOTOR = 142, //! < impossible in movement diff --git a/src/common/restext.cpp b/src/common/restext.cpp index 729a883..9af73e4 100644 --- a/src/common/restext.cpp +++ b/src/common/restext.cpp @@ -563,6 +563,8 @@ void InitializeRestext() stringsErr[ERR_BUILD_NARROW] = "Too close to a building"; stringsErr[ERR_BUILD_MOTOR] = "Impossible when moving"; stringsErr[ERR_SEARCH_FLY] = "Impossible when flying"; + stringsErr[ERR_BUILD_DISABLED] = "Can not produce this object in this mission"; + stringsErr[ERR_BUILD_RESEARCH] = "Can not produce not researched object"; stringsErr[ERR_SEARCH_VEH] = "Inappropriate bot"; stringsErr[ERR_SEARCH_MOTOR] = "Impossible when moving"; stringsErr[ERR_TERRA_VEH] = "Inappropriate bot"; diff --git a/src/object/brain.cpp b/src/object/brain.cpp index 951a763..f42ea7e 100644 --- a/src/object/brain.cpp +++ b/src/object/brain.cpp @@ -1313,10 +1313,11 @@ bool CBrain::CreateInterface(bool bSelect) { if (!(m_main->GetRetroMode())) { ddim.x = dim.x*5.1f; - ddim.y = dim.y*2.0f; + ddim.y = dim.y*2.0f; // default => 2 pos.x = ox+sx*0.0f; pos.y = oy+sy*0.0f; - pw->CreateList(pos, ddim, -1, EVENT_OBJECT_PROGLIST, 1.10f); + + pw->CreateList(pos, ddim, -1, EVENT_OBJECT_PROGLIST, -1.10f); UpdateScript(pw); pos.x = ox+sx*5.2f; diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp index 9f95e10..6ba09a5 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -643,7 +643,7 @@ CRobotMain::CRobotMain(CApplication* app) m_visitLast = EVENT_NULL; m_visitObject = 0; m_visitArrow = 0; - m_audioTrack = 0; + m_audioTrack = ""; m_audioRepeat = true; m_delayWriteMessage = 0; m_selectObject = 0; @@ -1768,6 +1768,23 @@ void CRobotMain::ExecuteCmd(char *cmd) return; } + if (strcmp(cmd, "allbuildings") == 0) + { + g_build = -1; // all buildings are available + + m_eventQueue->AddEvent(Event(EVENT_UPDINTERFACE)); + return; + } + + if (strcmp(cmd, "all") == 0) + { + g_researchDone = -1; // all research are done + g_build = -1; // all buildings are available + + m_eventQueue->AddEvent(Event(EVENT_UPDINTERFACE)); + return; + } + if (strcmp(cmd, "nolimit") == 0) { m_terrain->SetFlyingMaxHeight(280.0f); @@ -2006,6 +2023,11 @@ void CRobotMain::ExecuteCmd(char *cmd) UpdateSpeedLabel(); return; } + if (strcmp(cmd, "crazy") == 0) { + SetSpeed(1000.0f); + UpdateSpeedLabel(); + return; + } if (m_phase == PHASE_SIMUL) m_displayText->DisplayError(ERR_CMD, Math::Vector(0.0f,0.0f,0.0f)); @@ -2688,6 +2710,8 @@ CObject* CRobotMain::DetectObject(Math::Point pos) if (obj == nullptr) break; if (!obj->GetActif()) continue; + CObject* truck = obj->GetTruck(); + if (truck != nullptr) if (!truck->GetActif()) continue; if (obj->GetProxyActivate()) continue; CObject* target = nullptr; @@ -3454,6 +3478,7 @@ bool CRobotMain::EventFrame(const Event &event) { m_checkEndTime = m_time; CheckEndMission(true); + UpdateAudio(true); } if (m_winDelay > 0.0f && !m_editLock) @@ -3643,7 +3668,7 @@ void CRobotMain::Convert() } } - if (Cmd(line, "EndMissionTake")) + if (Cmd(line, "EndMissionTake") || Cmd(line, "AudioChange")) { char* p = strstr(line, "pos="); if (p != 0) @@ -3794,7 +3819,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) FlushDisplayInfo(); m_terrain->FlushMaterials(); - m_audioTrack = 0; + m_audioTrack = ""; m_audioRepeat = true; m_displayText->SetDelay(1.0f); m_displayText->SetEnable(true); @@ -3802,6 +3827,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) m_lockedSatCom = false; m_endingWinRank = 0; m_endingLostRank = 0; + m_audioChangeTotal = 0; m_endTakeTotal = 0; m_endTakeResearch = 0; m_endTakeWinDelay = 2.0f; @@ -3954,11 +3980,44 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) { m_displayText->SetDelay(OpFloat(line, "factor", 1.0f)); } + + if (Cmd(line, "AudioChange") && !resetObject && m_version >= 2) + { + int i = m_audioChangeTotal; + if (i < 10) + { + m_audioChange[i].pos = OpPos(line, "pos")*g_unit; + m_audioChange[i].dist = OpFloat(line, "dist", 8.0f)*g_unit; + m_audioChange[i].type = OpTypeObject(line, "type", OBJECT_NULL); + m_audioChange[i].min = OpInt(line, "min", 1); + m_audioChange[i].max = OpInt(line, "max", 9999); + m_audioChange[i].powermin = OpInt(line, "powermin", -1); + m_audioChange[i].powermax = OpInt(line, "powermax", 100); + OpString(line, "filename", m_audioChange[i].music); + m_audioChange[i].repeat = OpInt(line, "repeat", 1); + m_audioChange[i].changed = false; + m_sound->CacheMusic(m_audioChange[i].music); + m_audioChangeTotal ++; + } + continue; + } if (Cmd(line, "Audio") && !resetObject) { - m_audioTrack = OpInt(line, "track", 0); + if(m_version < 2) { + int trackid = OpInt(line, "track", 0); + if(trackid != 0) { + std::stringstream filename; + filename << "music" << std::setfill('0') << std::setw(3) << trackid << ".ogg"; + m_audioTrack = filename.str(); + } + } else { + char trackname[100]; + OpString(line, "filename", trackname); + m_audioTrack = trackname; + } m_audioRepeat = OpInt(line, "repeat", 1); + if(m_audioTrack != "") m_sound->CacheMusic(m_audioTrack); } if (Cmd(line, "AmbientColor") && !resetObject) @@ -4188,6 +4247,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) m_terrain->InitTextures(name, tt, dx, dy); m_terrainInitTextures = true; + continue; } if (Cmd(line, "TerrainInit") && !resetObject) { @@ -4403,8 +4463,11 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) obj->SetShield(OpFloat(line, "shield", 1.0f)); obj->SetMagnifyDamage(OpFloat(line, "magnifyDamage", 1.0f)); obj->SetClip(OpInt(line, "clip", 1)); - obj->SetCheckToken(m_version >= 2 ? trainer : OpInt(line, "manual", 1)); - obj->SetManual(m_version >= 2 ? !trainer : OpInt(line, "manual", 0)); + obj->SetCheckToken(m_version >= 2 ? trainer : OpInt(line, "checkToken", 1)); + // SetManual will affect bot speed + if (type == OBJECT_MOBILEdr) { + obj->SetManual(m_version >= 2 ? !trainer : OpInt(line, "manual", 0)); + } if(m_version >= 2) { Math::Vector zoom = OpDir(line, "zoom"); @@ -4613,12 +4676,19 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject) int i = m_endTakeTotal; if (i < 10) { - m_endTake[i].pos = OpPos(line, "pos")*g_unit; - m_endTake[i].dist = OpFloat(line, "dist", 8.0f)*g_unit; - m_endTake[i].type = OpTypeObject(line, "type", OBJECT_NULL); - m_endTake[i].min = OpInt(line, "min", 1); - m_endTake[i].max = OpInt(line, "max", 9999); - m_endTake[i].lost = OpInt(line, "lost", -1); + m_endTake[i].pos = OpPos(line, "pos")*g_unit; + m_endTake[i].dist = OpFloat(line, "dist", 8.0f)*g_unit; + m_endTake[i].type = OpTypeObject(line, "type", OBJECT_NULL); + m_endTake[i].min = OpInt(line, "min", 1); + m_endTake[i].max = OpInt(line, "max", 9999); + if (m_version >= 2) { + m_endTake[i].powermin = OpInt(line, "powermin", -1); + m_endTake[i].powermax = OpInt(line, "powermax", 100); + } else { + m_endTake[i].powermin = -1; + m_endTake[i].powermax = 100; + } + m_endTake[i].lost = OpInt(line, "lost", -1); m_endTake[i].immediat = OpInt(line, "immediat", 0); OpString(line, "message", m_endTake[i].message); m_endTakeTotal ++; @@ -5647,7 +5717,7 @@ char* SearchLastDir(char *filename) while (p != filename) { - if (*(--p) == '/') return p; + if (*(--p) == '/' || *p == '\\') return p; } return 0; } @@ -6545,6 +6615,73 @@ void CRobotMain::ResetCreate() } } +//! Updates the audiotracks +void CRobotMain::UpdateAudio(bool frame) +{ + CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); + + for (int t = 0; t < m_audioChangeTotal; t++) + { + if(m_audioChange[t].changed) continue; + + Math::Vector bPos = m_audioChange[t].pos; + bPos.y = 0.0f; + + Math::Vector oPos; + + int nb = 0; + for (int i = 0; i < 1000000; i++) + { + CObject* obj = static_cast<CObject*>(iMan->SearchInstance(CLASS_OBJECT, i)); + if (obj == nullptr) break; + + // Do not use GetActif () because an invisible worm (underground) + // should be regarded as existing here! + if (obj->GetLock()) continue; + if (obj->GetRuin()) continue; + if (!obj->GetEnable()) continue; + + ObjectType type = obj->GetType(); + if (type == OBJECT_SCRAP2 || + type == OBJECT_SCRAP3 || + type == OBJECT_SCRAP4 || + type == OBJECT_SCRAP5) // wastes? + { + type = OBJECT_SCRAP1; + } + + if (type != m_audioChange[t].type) continue; + + float energyLevel = -1; + CObject* power = obj->GetPower(); + if (power != nullptr) { + energyLevel = power->GetEnergy(); + if (power->GetType() == OBJECT_ATOMIC) energyLevel *= 100; + } + if (energyLevel < m_audioChange[t].powermin || energyLevel > m_audioChange[t].powermax) continue; + + if (obj->GetTruck() == 0) + oPos = obj->GetPosition(0); + else + oPos = obj->GetTruck()->GetPosition(0); + + oPos.y = 0.0f; + + if (Math::DistanceProjected(oPos, bPos) <= m_audioChange[t].dist) + nb ++; + } + + if (nb >= m_audioChange[t].min && + nb <= m_audioChange[t].max) + { + CLogger::GetInstancePointer()->Debug("Changing music...\n"); + m_sound->StopMusic(); + m_sound->PlayMusic(std::string(m_audioChange[t].music), m_audioChange[t].repeat); + m_audioChange[t].changed = true; + } + } +} + //! Checks if the mission is over Error CRobotMain::CheckEndMission(bool frame) { @@ -6582,6 +6719,14 @@ Error CRobotMain::CheckEndMission(bool frame) if (type != m_endTake[t].type) continue; + float energyLevel = -1; + CObject* power = obj->GetPower(); + if (power != nullptr) { + energyLevel = power->GetEnergy(); + if (power->GetType() == OBJECT_ATOMIC) energyLevel *= 100; + } + if (energyLevel < m_endTake[t].powermin || energyLevel > m_endTake[t].powermax) continue; + if (obj->GetTruck() == 0) oPos = obj->GetPosition(0); else @@ -7045,11 +7190,12 @@ float CRobotMain::GetTracePrecision() //! Starts music with a mission void CRobotMain::StartMusic() { - if (m_audioTrack != 0) + CLogger::GetInstancePointer()->Debug("Starting music...\n"); + if (m_audioTrack != "") { m_sound->StopMusic(); m_sound->PlayMusic(m_audioTrack, m_audioRepeat); - } + } } //! Removes hilite and tooltip diff --git a/src/object/robotmain.h b/src/object/robotmain.h index fc62072..7ed84c5 100644 --- a/src/object/robotmain.h +++ b/src/object/robotmain.h @@ -99,13 +99,29 @@ struct EndTake Math::Vector pos; float dist; ObjectType type; - int min; // wins if> + int min; // wins if > int max; // wins if < int lost; // lost if <= + float powermin; // wins if energy cell >= + float powermax; // wins if energy cell <= bool immediat; char message[100]; }; +struct AudioChange +{ + Math::Vector pos; + float dist; + ObjectType type; + int min; // change if > + int max; // change if < + float powermin; // change if energy cell >= + float powermax; // change if energy cell <= + char music[100]; + bool repeat; + bool changed; +}; + const int MAXNEWSCRIPTNAME = 20; @@ -248,6 +264,7 @@ public: void ResetObject(); void ResetCreate(); + void UpdateAudio(bool frame); Error CheckEndMission(bool frame); void CheckEndMessage(const char* message); int GetObligatoryToken(); @@ -448,7 +465,7 @@ protected: bool m_cheatRadar; bool m_audioRepeat; bool m_shortCut; - int m_audioTrack; + std::string m_audioTrack; int m_delayWriteMessage; int m_movieInfoIndex; @@ -522,6 +539,9 @@ protected: long m_endTakeResearch; float m_endTakeWinDelay; float m_endTakeLostDelay; + + int m_audioChangeTotal; + AudioChange m_audioChange[10]; int m_obligatoryTotal; char m_obligatoryToken[100][20]; diff --git a/src/object/task/taskgoto.cpp b/src/object/task/taskgoto.cpp index c4a2939..19d129d 100644 --- a/src/object/task/taskgoto.cpp +++ b/src/object/task/taskgoto.cpp @@ -90,8 +90,10 @@ bool CTaskGoto::EventProcess(const Event &event) rot.x = m_leakPos.x-pos.x; rot.y = m_leakPos.z-pos.z; dist = Math::Point(rot.x, rot.y).Length(); - rot.x /= dist; - rot.y /= dist; + if (dist != 0) { + rot.x /= dist; + rot.y /= dist; + } a = m_object->GetAngleY(0); g = Math::RotateAngle(rot.x, -rot.y); // CW ! diff --git a/src/object/task/tasksearch.cpp b/src/object/task/tasksearch.cpp index b219185..e2c2524 100644 --- a/src/object/task/tasksearch.cpp +++ b/src/object/task/tasksearch.cpp @@ -218,6 +218,12 @@ Error CTaskSearch::IsEnded() bool CTaskSearch::Abort() { + m_hand = TSH_UP; + InitAngle(); + for (int i = 0; i < 3; i++) { + m_object->SetAngleZ(i+1, m_finalAngle[i]); + } + m_camera->StopCentering(m_object, 2.0f); m_physics->SetFreeze(false); // is moving again return true; diff --git a/src/script/cbottoken.cpp b/src/script/cbottoken.cpp index 95b259b..0bd52da 100644 --- a/src/script/cbottoken.cpp +++ b/src/script/cbottoken.cpp @@ -220,7 +220,6 @@ std::string GetHelpFilename(const char *token) { if ( strcmp(token, "if" ) == 0 ) return std::string("help/") + CApplication::GetInstancePointer()->GetLanguageChar() + std::string("/cbot/if.txt"); if ( strcmp(token, "else" ) == 0 ) return std::string("help/") + CApplication::GetInstancePointer()->GetLanguageChar() + std::string("/cbot/if.txt"); - if ( strcmp(token, "repeat" ) == 0 ) return std::string("help/") + CApplication::GetInstancePointer()->GetLanguageChar() + std::string("/cbot/repeat.txt"); if ( strcmp(token, "for" ) == 0 ) return std::string("help/") + CApplication::GetInstancePointer()->GetLanguageChar() + std::string("/cbot/for.txt"); if ( strcmp(token, "while" ) == 0 ) return std::string("help/") + CApplication::GetInstancePointer()->GetLanguageChar() + std::string("/cbot/while.txt"); if ( strcmp(token, "do" ) == 0 ) return std::string("help/") + CApplication::GetInstancePointer()->GetLanguageChar() + std::string("/cbot/do.txt"); @@ -262,8 +261,8 @@ std::string GetHelpFilename(const char *token) if ( strcmp(token, "move" ) == 0 ) return std::string("help/") + CApplication::GetInstancePointer()->GetLanguageChar() + std::string("/cbot/move.txt"); if ( strcmp(token, "turn" ) == 0 ) return std::string("help/") + CApplication::GetInstancePointer()->GetLanguageChar() + std::string("/cbot/turn.txt"); if ( strcmp(token, "goto" ) == 0 ) return std::string("help/") + CApplication::GetInstancePointer()->GetLanguageChar() + std::string("/cbot/goto.txt"); - if ( strcmp(token, "find" ) == 0 ) return std::string("help/") + CApplication::GetInstancePointer()->GetLanguageChar() + std::string("/cbot/find.txt"); if ( strcmp(token, "grab" ) == 0 ) return std::string("help/") + CApplication::GetInstancePointer()->GetLanguageChar() + std::string("/cbot/grab.txt"); + if ( strcmp(token, "build" ) == 0 ) return std::string("help/") + CApplication::GetInstancePointer()->GetLanguageChar() + std::string("/cbot/build.txt"); if ( strcmp(token, "drop" ) == 0 ) return std::string("help/") + CApplication::GetInstancePointer()->GetLanguageChar() + std::string("/cbot/drop.txt"); if ( strcmp(token, "sniff" ) == 0 ) return std::string("help/") + CApplication::GetInstancePointer()->GetLanguageChar() + std::string("/cbot/sniff.txt"); if ( strcmp(token, "receive" ) == 0 ) return std::string("help/") + CApplication::GetInstancePointer()->GetLanguageChar() + std::string("/cbot/receive.txt"); @@ -380,8 +379,8 @@ bool IsFunction(const char *token) if ( strcmp(token, "move" ) == 0 ) return true; if ( strcmp(token, "turn" ) == 0 ) return true; if ( strcmp(token, "goto" ) == 0 ) return true; - if ( strcmp(token, "find" ) == 0 ) return true; if ( strcmp(token, "grab" ) == 0 ) return true; + if ( strcmp(token, "build" ) == 0 ) return true; if ( strcmp(token, "drop" ) == 0 ) return true; if ( strcmp(token, "sniff" ) == 0 ) return true; if ( strcmp(token, "receive" ) == 0 ) return true; @@ -432,7 +431,6 @@ const char* GetHelpText(const char *token) { if ( strcmp(token, "if" ) == 0 ) return "if ( condition ) { bloc }"; if ( strcmp(token, "else" ) == 0 ) return "else { bloc }"; - if ( strcmp(token, "repeat" ) == 0 ) return "repeat ( number )"; if ( strcmp(token, "for" ) == 0 ) return "for ( before ; condition ; end )"; if ( strcmp(token, "while" ) == 0 ) return "while ( condition ) { bloc }"; if ( strcmp(token, "do" ) == 0 ) return "do { bloc } while ( condition );"; @@ -464,8 +462,8 @@ const char* GetHelpText(const char *token) if ( strcmp(token, "move" ) == 0 ) return "move ( distance );"; if ( strcmp(token, "turn" ) == 0 ) return "turn ( angle );"; if ( strcmp(token, "goto" ) == 0 ) return "goto ( position, altitude );"; - if ( strcmp(token, "find" ) == 0 ) return "find ( cat );"; if ( strcmp(token, "grab" ) == 0 ) return "grab ( order );"; + if ( strcmp(token, "build" ) == 0 ) return "build ( category );"; if ( strcmp(token, "drop" ) == 0 ) return "drop ( order );"; if ( strcmp(token, "sniff" ) == 0 ) return "sniff ( );"; if ( strcmp(token, "receive" ) == 0 ) return "receive ( name, power );"; diff --git a/src/script/script.cpp b/src/script/script.cpp index 6095e05..c95cd4b 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -1003,6 +1003,88 @@ bool CScript::rDirection(CBotVar* var, CBotVar* result, int& exception, void* us return true; } +// Instruction "build(type)" +// draws error if can not build (wher errormode stop), otherwise 0 <- 1 + +bool CScript::rBuild(CBotVar* var, CBotVar* result, int& exception, void* user) +{ + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); + CObject* pThis = static_cast<CObject *>(user); + ObjectType oType; + ObjectType category; + Error err; + + exception = 0; + + oType = pThis->GetType(); + + if ( oType != OBJECT_MOBILEfa && // allowed only for grabber bots + oType != OBJECT_MOBILEta && + oType != OBJECT_MOBILEwa && + oType != OBJECT_MOBILEia) + { + err = ERR_MANIP_VEH; //Wrong vehicle; + } + else + { + category = static_cast<ObjectType>(var->GetValInt()); //get category parameter + + //if we want to produce one of these buildings + if ( (category == OBJECT_DERRICK && (g_build & BUILD_DERRICK)) || + (category == OBJECT_FACTORY && (g_build & BUILD_FACTORY)) || + (category == OBJECT_STATION && (g_build & BUILD_STATION)) || + (category == OBJECT_CONVERT && (g_build & BUILD_CONVERT)) || + (category == OBJECT_REPAIR && (g_build & BUILD_REPAIR)) || + (category == OBJECT_TOWER && (g_build & BUILD_TOWER)) || + (category == OBJECT_RESEARCH && (g_build & BUILD_RESEARCH)) || + (category == OBJECT_RADAR && (g_build & BUILD_RADAR)) || + (category == OBJECT_ENERGY && (g_build & BUILD_ENERGY)) || + (category == OBJECT_LABO && (g_build & BUILD_LABO)) || + (category == OBJECT_NUCLEAR && (g_build & BUILD_NUCLEAR)) || + (category == OBJECT_INFO && (g_build & BUILD_INFO )) || + (category == OBJECT_PARA && (g_build & BUILD_PARA ))) + { + + //if we want to build not researched one + if ( (category == OBJECT_TOWER && !(g_researchDone & RESEARCH_TOWER)) || + (category == OBJECT_NUCLEAR && !(g_researchDone & RESEARCH_ATOMIC)) + ) + { + err = ERR_BUILD_RESEARCH; + } + else if (script->m_primaryTask == 0) //if we have no other tasks + { + script->m_primaryTask = new CTaskManager(script->m_object); + err = script->m_primaryTask->StartTaskBuild(category); + + if (err != ERR_OK) + { + delete script->m_primaryTask; + script->m_primaryTask = 0; + } + } + + } + else //if we can't build this object + { + err = ERR_BUILD_DISABLED; + } + } + + if ( err != ERR_OK ) + { + result->SetValInt(err); // return error + if ( script->m_errMode == ERM_STOP ) + { + exception = err; + return false; + } + return true; + } + + return Process(script, result, exception); + +} // Compilation of the instruction "produce(pos, angle, type[, scriptName[, power]])" // or "produce(type[, power])". @@ -1266,7 +1348,10 @@ bool CScript::rProduce(CBotVar* var, CBotVar* result, int& exception, void* user physics->SetFreeze(false); // can move } object->SetLock(false); // vehicle useable - object->SetManual(true); + // SetManual will affect bot speed + if (type == OBJECT_MOBILEdr) { + object->SetManual(true); + } object->SetActivity(true); script->m_main->CreateShortcuts(); } @@ -1632,147 +1717,6 @@ bool CScript::rGoto(CBotVar* var, CBotVar* result, int& exception, void* user) return Process(script, result, exception); } -// Instruction "find(type)". - -bool CScript::rFind(CBotVar* var, CBotVar* result, int& exception, void* user) -{ - CScript* script = (static_cast<CObject *>(user))->GetRunScript(); - Math::Vector pos; - TaskGotoGoal goal; - TaskGotoCrash crash; - float altitude; - Error err; - CObject* pThis = static_cast<CObject *>(user); - CObject *pObj, *pBest; - CBotVar* array; - Math::Vector iPos, oPos; - float best, minDist, maxDist, iAngle, focus, d, a; - int type, oType, i; - bool bArray; - - exception = 0; - - if ( script->m_primaryTask == 0 ) // no task in progress? - { - type = OBJECT_NULL; - focus = Math::PI*2.0f; - minDist = 0.0f*g_unit; - maxDist = 1000.0f*g_unit; - - if ( var->GetType() == CBotTypArrayPointer ) - { - array = var->GetItemList(); - bArray = true; - } - else - { - type = var->GetValInt(); - bArray = false; - } - - CInstanceManager* iMan = CInstanceManager::GetInstancePointer(); - - best = 100000.0f; - pBest = 0; - for ( i=0 ; i<1000000 ; i++ ) - { - pObj = static_cast<CObject*>(iMan->SearchInstance(CLASS_OBJECT, i)); - if ( pObj == 0 ) break; - if ( pObj == pThis ) continue; - - if ( pObj->GetTruck() != 0 ) continue; // object transported? - if ( !pObj->GetActif() ) continue; - if ( pObj->GetProxyActivate() ) continue; - - oType = pObj->GetType(); - if ( oType == OBJECT_TOTO ) continue; - - if ( oType == OBJECT_RUINmobilew2 || - oType == OBJECT_RUINmobilet1 || - oType == OBJECT_RUINmobilet2 || - oType == OBJECT_RUINmobiler1 || - oType == OBJECT_RUINmobiler2 ) - { - oType = OBJECT_RUINmobilew1; // any ruin - } - - if ( oType == OBJECT_SCRAP2 || - oType == OBJECT_SCRAP3 || - oType == OBJECT_SCRAP4 || - oType == OBJECT_SCRAP5 ) // wastes? - { - oType = OBJECT_SCRAP1; // any waste - } - - if ( oType == OBJECT_BARRIER2 || - oType == OBJECT_BARRIER3 ) // barriers? - { - oType = OBJECT_BARRIER1; // any barrier - } - - if ( bArray ) - { - if ( !FindList(array, oType) ) continue; - } - else - { - if ( type != oType && type != OBJECT_NULL ) continue; - } - - oPos = pObj->GetPosition(0); - d = Math::DistanceProjected(iPos, oPos); - if ( d < minDist || d > maxDist ) continue; // too close or too far? - - if ( focus >= Math::PI*2.0f ) - { - if ( d < best ) - { - best = d; - pBest = pObj; - } - continue; - } - - a = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! - if ( Math::TestAngle(a, iAngle-focus/2.0f, iAngle+focus/2.0f) ) - { - if ( d < best ) - { - best = d; - pBest = pObj; - } - } - } - - if ( pBest == 0 ) - { - exception = ERR_FIND_IMPOSSIBLE; - return false; - } - - pos = pBest->GetPosition(0); - goal = TGG_DEFAULT; - crash = TGC_DEFAULT; - altitude = 0.0f*g_unit; - - script->m_primaryTask = new CTaskManager(script->m_object); - err = script->m_primaryTask->StartTaskGoto(pos, altitude, goal, crash); - if ( err != ERR_OK ) - { - delete script->m_primaryTask; - script->m_primaryTask = 0; - result->SetValInt(err); // shows the error - if ( script->m_errMode == ERM_STOP ) - { - exception = err; - return false; - } - return true; - } - } - return Process(script, result, exception); -} - // Compilation "grab/drop(oper)". CBotTypResult CScript::cGrabDrop(CBotVar* &var, void* user) @@ -2968,7 +2912,6 @@ void CScript::InitFonctions() CBotProgram::AddFunction("move", rMove, CScript::cOneFloat); CBotProgram::AddFunction("turn", rTurn, CScript::cOneFloat); CBotProgram::AddFunction("goto", rGoto, CScript::cGoto); - CBotProgram::AddFunction("find", rFind, CScript::cOneFloat); CBotProgram::AddFunction("grab", rGrab, CScript::cGrabDrop); CBotProgram::AddFunction("drop", rDrop, CScript::cGrabDrop); CBotProgram::AddFunction("sniff", rSniff, CScript::cNull); @@ -2995,6 +2938,9 @@ void CScript::InitFonctions() CBotProgram::AddFunction("penup", rPenUp, CScript::cNull); CBotProgram::AddFunction("pencolor", rPenColor, CScript::cOneFloat); CBotProgram::AddFunction("penwidth", rPenWidth, CScript::cOneFloat); + + CBotProgram::AddFunction("build", rBuild, CScript::cOneFloat); + } // Object's destructor. diff --git a/src/script/script.h b/src/script/script.h index 0d2726a..597486b 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -104,7 +104,7 @@ private: static CBotTypResult cSearch(CBotVar* &var, void* user); static CBotTypResult cRadar(CBotVar* &var, void* user); static CBotTypResult cDetect(CBotVar* &var, void* user); - static CBotTypResult cDirection(CBotVar* &var, void* user); + static CBotTypResult cDirection(CBotVar* &var, void* user); static CBotTypResult cProduce(CBotVar* &var, void* user); static CBotTypResult cDistance(CBotVar* &var, void* user); static CBotTypResult cSpace(CBotVar* &var, void* user); @@ -139,6 +139,7 @@ private: static bool rRadar(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rDetect(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rDirection(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rBuild(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rProduce(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rDistance(CBotVar* var, CBotVar* result, int& exception, void* user); static bool rDistance2d(CBotVar* var, CBotVar* result, int& exception, void* user); diff --git a/src/sound/oalsound/alsound.cpp b/src/sound/oalsound/alsound.cpp index 68bf515..cfb0c70 100644 --- a/src/sound/oalsound/alsound.cpp +++ b/src/sound/oalsound/alsound.cpp @@ -43,19 +43,26 @@ void ALSound::CleanUp() if (mEnabled) { GetLogger()->Info("Unloading files and closing device...\n"); StopAll(); + StopMusic(); for (auto channel : mChannels) { delete channel.second; } + if (mCurrentMusic) { + delete mCurrentMusic; + } + for (auto item : mSounds) { delete item.second; } + for (auto item : mMusic) { + delete item.second; + } + mEnabled = false; - mCurrentMusic->FreeBuffer(); - delete mCurrentMusic; alcDestroyContext(mContext); alcCloseDevice(mDevice); } @@ -160,6 +167,18 @@ bool ALSound::Cache(Sound sound, std::string filename) return false; } +bool ALSound::CacheMusic(std::string filename) +{ + Buffer *buffer = new Buffer(); + std::stringstream file; + file << m_soundPath << "/" << filename; + if (buffer->LoadFromFile(file.str(), static_cast<Sound>(-1))) { + mMusic[filename] = buffer; + return true; + } + return false; +} + int ALSound::GetPriority(Sound sound) { @@ -314,12 +333,12 @@ int ALSound::Play(Sound sound, Math::Vector pos, float amplitude, float frequenc return -1; } } - + Position(channel, pos); if (!m3D) { ComputeVolumePan2D(channel, pos); } else { - mChannels[channel]->SetVolume(1.0f); + mChannels[channel]->SetVolumeAtrib(1.0f); } // setting initial values @@ -328,7 +347,7 @@ int ALSound::Play(Sound sound, Math::Vector pos, float amplitude, float frequenc mChannels[channel]->SetChangeFrequency(1.0f); mChannels[channel]->ResetOper(); mChannels[channel]->SetFrequency(frequency); - mChannels[channel]->SetVolume(powf(amplitude * mChannels[channel]->GetVolume(), 0.2f) * mAudioVolume); + mChannels[channel]->SetVolume(powf(amplitude * mChannels[channel]->GetVolumeAtrib(), 0.2f) * mAudioVolume); mChannels[channel]->SetLoop(bLoop); mChannels[channel]->Play(); @@ -378,9 +397,14 @@ bool ALSound::Position(int channel, Math::Vector pos) } if (m3D) { - mChannels[channel]->SetPosition(pos); + mChannels[channel]->SetPan(pos); } else { ComputeVolumePan2D(channel, pos); + + if (!mChannels[channel]->HasEnvelope()) { + float volume = mChannels[channel]->GetStartAmplitude(); + mChannels[channel]->SetVolume(powf(volume * mChannels[channel]->GetVolumeAtrib(), 0.2f) * mAudioVolume); + } } return true; } @@ -477,8 +501,8 @@ void ALSound::FrameMove(float delta) // setting volume volume = progress * (oper.finalAmplitude - it.second->GetStartAmplitude()); - volume = (volume + it.second->GetStartAmplitude()); - it.second->SetVolume(powf(volume, 0.2f) * mAudioVolume); + volume = volume + it.second->GetStartAmplitude(); + it.second->SetVolume(powf(volume * it.second->GetVolumeAtrib(), 0.2f) * mAudioVolume); // setting frequency frequency = progress; @@ -518,46 +542,51 @@ void ALSound::SetListener(Math::Vector eye, Math::Vector lookat) float orientation[] = {0.0f, 0.0f, 0.0f, 0.f, 1.f, 0.f}; alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f); alListenerfv(AL_ORIENTATION, orientation); + + // recalculate sound position + for (auto it : mChannels) { + if (it.second->IsPlaying()) { + Math::Vector pos = it.second->GetPosition(); + ComputeVolumePan2D(it.first, pos); + + if (!it.second->HasEnvelope()) { + float volume = it.second->GetStartAmplitude(); + it.second->SetVolume(powf(volume * it.second->GetVolumeAtrib(), 0.2f) * mAudioVolume); + } + } + } } } - bool ALSound::PlayMusic(int rank, bool bRepeat) { + std::stringstream filename; + filename << "music" << std::setfill('0') << std::setw(3) << rank << ".ogg"; + return PlayMusic(filename.str(), bRepeat); +} + +bool ALSound::PlayMusic(std::string filename, bool bRepeat) +{ if (!mEnabled) { return false; } - - if (static_cast<int>(mCurrentMusic->GetSoundType()) != rank) { - // check if we have music in cache - for (auto music : mMusicCache) { - if (static_cast<int>(music->GetSoundType()) == rank) { - GetLogger()->Debug("Music loaded from cache\n"); - mCurrentMusic->SetBuffer(music); - - mCurrentMusic->SetVolume(mMusicVolume); - mCurrentMusic->SetLoop(bRepeat); - mCurrentMusic->Play(); - return true; - } - } - - // we cache only 3 music files - if (mMusicCache.size() == 3) { - mCurrentMusic->FreeBuffer(); - mMusicCache.pop_back(); - } - if (mMusic.find(rank) == mMusic.end()) { - GetLogger()->Info("Requested music %d was not found.\n", rank); + std::stringstream file; + file << m_soundPath << "/" << filename; + + // check if we have music in cache + if (mMusic.find(filename) == mMusic.end()) { + GetLogger()->Warn("Music %s was not cached!\n", filename.c_str()); + if (!boost::filesystem::exists(file.str())) { + GetLogger()->Warn("Requested music %s was not found.\n", filename.c_str()); return false; } - Buffer *buffer = new Buffer(); - mMusicCache.push_front(buffer); - buffer->LoadFromFile(mMusic.at(rank), static_cast<Sound>(rank)); + buffer->LoadFromFile(file.str(), static_cast<Sound>(-1)); mCurrentMusic->SetBuffer(buffer); - mMusicCache[rank] = buffer; + } else { + GetLogger()->Debug("Music loaded from cache\n"); + mCurrentMusic->SetBuffer(mMusic[filename]); } mCurrentMusic->SetVolume(mMusicVolume); @@ -612,24 +641,25 @@ void ALSound::SuspendMusic() void ALSound::ComputeVolumePan2D(int channel, Math::Vector &pos) { float dist, a, g; + mChannels[channel]->SetPosition(pos); if (VectorsEqual(pos, mEye)) { - mChannels[channel]->SetVolume(1.0f); // maximum volume - mChannels[channel]->SetPosition(Math::Vector()); // at the center + mChannels[channel]->SetVolumeAtrib(1.0f); // maximum volume + mChannels[channel]->SetPan(Math::Vector()); // at the center return; } dist = Distance(pos, mEye); if ( dist >= 110.0f ) { // very far? - mChannels[channel]->SetVolume(0.0f); // silence - mChannels[channel]->SetPosition(Math::Vector()); // at the center + mChannels[channel]->SetVolumeAtrib(0.0f); // silence + mChannels[channel]->SetPan(Math::Vector()); // at the center return; } else if ( dist <= 10.0f ) { // very close? - mChannels[channel]->SetVolume(1.0f); // maximum volume - mChannels[channel]->SetPosition(Math::Vector()); // at the center + mChannels[channel]->SetVolumeAtrib(1.0f); // maximum volume + mChannels[channel]->SetPan(Math::Vector()); // at the center return; } - mChannels[channel]->SetVolume(1.0f - ((dist - 10.0f) / 100.0f)); + mChannels[channel]->SetVolumeAtrib(1.0f - ((dist - 10.0f) / 100.0f)); a = fmodf(Angle(mLookat, mEye), Math::PI * 2.0f); g = fmodf(Angle(pos, mEye), Math::PI * 2.0f); @@ -651,5 +681,5 @@ void ALSound::ComputeVolumePan2D(int channel, Math::Vector &pos) } } - mChannels[channel]->SetPosition( Math::Vector(sinf(g - a), 0.0f, 0.0f) ); + mChannels[channel]->SetPan( Math::Vector(sinf(g - a), 0.0f, 0.0f) ); } diff --git a/src/sound/oalsound/alsound.h b/src/sound/oalsound/alsound.h index 5701997..b8afd4d 100644 --- a/src/sound/oalsound/alsound.h +++ b/src/sound/oalsound/alsound.h @@ -40,6 +40,7 @@ class ALSound : public CSoundInterface bool Create(bool b3D); bool Cache(Sound, std::string); + bool CacheMusic(std::string); bool GetEnable(); @@ -66,6 +67,7 @@ class ALSound : public CSoundInterface bool MuteAll(bool bMute); bool PlayMusic(int rank, bool bRepeat); + bool PlayMusic(std::string filename, bool bRepeat); bool RestartMusic(); void SuspendMusic(); void StopMusic(); @@ -90,8 +92,8 @@ class ALSound : public CSoundInterface ALCdevice* mDevice; ALCcontext* mContext; std::map<Sound, Buffer*> mSounds; + std::map<std::string, Buffer*> mMusic; std::map<int, Channel*> mChannels; - std::deque<Buffer*> mMusicCache; Channel *mCurrentMusic; Math::Vector mEye; Math::Vector mLookat; diff --git a/src/sound/oalsound/channel.cpp b/src/sound/oalsound/channel.cpp index 686e909..c5b05fa 100644 --- a/src/sound/oalsound/channel.cpp +++ b/src/sound/oalsound/channel.cpp @@ -17,7 +17,8 @@ #include "channel.h" -Channel::Channel() { +Channel::Channel() +{ alGenSources(1, &mSource); if (alCheck()) { @@ -35,10 +36,12 @@ Channel::Channel() { mStartAmplitude = 0.0f; mStartFrequency = 0.0f; mChangeFrequency = 0.0f; + mVolume = 0.0f; } -Channel::~Channel() { +Channel::~Channel() +{ if (mReady) { alSourceStop(mSource); alSourcei(mSource, AL_BUFFER, 0); @@ -49,7 +52,8 @@ Channel::~Channel() { } -bool Channel::Play() { +bool Channel::Play() +{ if (!mReady || mBuffer == nullptr) { return false; } @@ -65,7 +69,8 @@ bool Channel::Play() { } -bool Channel::SetPosition(Math::Vector pos) { +bool Channel::SetPan(Math::Vector pos) +{ if (!mReady || mBuffer == nullptr) { return false; } @@ -79,6 +84,18 @@ bool Channel::SetPosition(Math::Vector pos) { } +void Channel::SetPosition(Math::Vector pos) +{ + mPosition = pos; +} + + +Math::Vector Channel::GetPosition() +{ + return mPosition; +} + + bool Channel::SetFrequency(float freq) { if (!mReady || mBuffer == nullptr) { @@ -143,6 +160,19 @@ float Channel::GetVolume() } +void Channel::SetVolumeAtrib(float volume) +{ + mVolume = volume; +} + + +float Channel::GetVolumeAtrib() +{ + return mVolume; +} + + + int Channel::GetPriority() { return mPriority; @@ -158,7 +188,6 @@ void Channel::SetPriority(int pri) void Channel::SetStartAmplitude(float gain) { mStartAmplitude = gain; - SetVolume(mStartAmplitude); } diff --git a/src/sound/oalsound/channel.h b/src/sound/oalsound/channel.h index f5f3bb9..6717f03 100644 --- a/src/sound/oalsound/channel.h +++ b/src/sound/oalsound/channel.h @@ -48,7 +48,10 @@ class Channel bool Play(); bool Stop(); - bool SetPosition(Math::Vector); + + bool SetPan(Math::Vector); + void SetPosition(Math::Vector); + Math::Vector GetPosition(); bool SetFrequency(float); float GetFrequency(); @@ -59,6 +62,9 @@ class Channel bool SetVolume(float); float GetVolume(); + void SetVolumeAtrib(float); + float GetVolumeAtrib(); + bool IsPlaying(); bool IsReady(); bool IsLoaded(); @@ -98,8 +104,10 @@ class Channel float mStartFrequency; float mChangeFrequency; float mInitFrequency; + float mVolume; std::deque<SoundOper> mOper; bool mReady; bool mLoop; bool mMute; + Math::Vector mPosition; }; diff --git a/src/sound/sound.h b/src/sound/sound.h index 70139ea..a2302c4 100644 --- a/src/sound/sound.h +++ b/src/sound/sound.h @@ -177,12 +177,9 @@ class CSoundInterface /** Function called to add all music files to list */ inline void AddMusicFiles(std::string path) { - for ( int i = 1; i <= 12; i++ ) { - std::stringstream filename; - filename << path << "/music" << std::setfill('0') << std::setw(3) << i << ".ogg"; - if (boost::filesystem::exists(filename.str())) - mMusic[i] = filename.str(); - } + m_soundPath = path; + CacheMusic("music010.ogg"); + CacheMusic("music011.ogg"); }; /** Function called to cache sound effect file. @@ -193,6 +190,13 @@ class CSoundInterface */ inline virtual bool Cache(Sound bSound, std::string bFile) { return true; }; + /** Function called to cache music file. + * This function is called by CRobotMain for each file used in the mission. + * \param bFile - file to load + * \return return true on success + */ + inline virtual bool CacheMusic(std::string bFile) { return true; }; + /** Return if plugin is enabled * \return return true if plugin is enabled */ @@ -317,6 +321,13 @@ class CSoundInterface */ inline virtual bool PlayMusic(int rank, bool bRepeat) {return true;}; + /** Start playing music + * \param filename - name of file to play + * \param bRepeat - repeat playing + * \return return true on success + */ + inline virtual bool PlayMusic(std::string filename, bool bRepeat) {return true;}; + /** Restart music * @return return true on success */ @@ -338,6 +349,6 @@ class CSoundInterface inline virtual bool IsPlayingMusic() {return true;}; protected: - std::map<int, std::string> mMusic; + std::string m_soundPath; }; diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 24d2626..893cd05 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -197,6 +197,9 @@ CSlider* CInterface::CreateSlider(Math::Point pos, Math::Point dim, int icon, Ev } // Creates a new list. +// if expand is less then zero, then the list would try to use expand's absolute value, +// and try to scale items to some size, so that dim of the list would not change after +// adjusting CList* CInterface::CreateList(Math::Point pos, Math::Point dim, int icon, EventType eventMsg, float expand) { diff --git a/src/ui/list.cpp b/src/ui/list.cpp index 84aa8ca..fae7af9 100644 --- a/src/ui/list.cpp +++ b/src/ui/list.cpp @@ -68,6 +68,9 @@ CList::~CList() // Creates a new list. +// if expand is less then zero, then the list would try to use expand's absolute value, +// and try to scale items to some size, so that dim of the list would not change after +// adjusting bool CList::Create(Math::Point pos, Math::Point dim, int icon, EventType eventMsg, float expand) { @@ -109,14 +112,22 @@ bool CList::MoveAdjust() idim.x = m_dim.x - marging * 2.0f / 640.f; idim.y = m_dim.y - marging * 2.0f / 480.f; - h = m_engine->GetText()->GetHeight(m_fontType, m_fontSize) * m_expand; - + //If m_expand is less then zero, then try to apply it's absolute value + h = m_engine->GetText()->GetHeight(m_fontType, m_fontSize) * ((m_expand < 0) ? -m_expand : m_expand); m_displayLine = static_cast<int>(idim.y / h); + if (m_displayLine == 0) return false; if (m_displayLine > LISTMAXDISPLAY) m_displayLine = LISTMAXDISPLAY; - idim.y = h * m_displayLine; + + // Stretch lines to fill whole area of a list, if needed + if (m_expand < 0 && (idim.y - (h * m_displayLine) < h)) + { + h = idim.y / m_displayLine; + } + + idim.y = h * m_displayLine; //Here cuts list size if height of shown elements is less then designed height m_dim.y = idim.y + marging * 2.0f / 480.f; ppos.x = ipos.x; diff --git a/src/ui/maindialog.cpp b/src/ui/maindialog.cpp index b75fab6..092903d 100644 --- a/src/ui/maindialog.cpp +++ b/src/ui/maindialog.cpp @@ -63,7 +63,7 @@ const int KEY_VISIBLE = 6; // number of visible keys redefinable const int KEY_TOTAL = 21; // total number of keys redefinable -const float WELCOME_LENGTH = 2.0f; +const float WELCOME_LENGTH = 3.0f; const int MAX_FNAME = 255; // TODO: remove after rewrite to std::string @@ -1769,7 +1769,7 @@ pos.y -= 0.048f; ddim.y = 0.0f; pw = m_interface->CreateWindows(pos, ddim, -1, EVENT_WINDOW5); - m_engine->SetOverColor(Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f), Gfx::ENG_RSTATE_TCOLOR_BLACK); // TODO: color ok? + m_engine->SetOverColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f), Gfx::ENG_RSTATE_TCOLOR_WHITE); // TODO: color ok? m_engine->SetOverFront(true); m_engine->SetBackground("colobot.png", @@ -2006,28 +2006,35 @@ bool CMainDialog::EventProcess(const Event &event) m_phase == PHASE_WELCOME3 ) { float intensity; - int mode = Gfx::ENG_RSTATE_TCOLOR_BLACK; + int mode = Gfx::ENG_RSTATE_TCOLOR_WHITE; - if ( m_phaseTime < 1.5f ) + // 1/4 of display time is animating + float animatingTime = welcomeLength / 4.0f; + + if ( m_phaseTime < animatingTime ) { - intensity = 1.0f-(m_phaseTime-0.5f); + //appearing + intensity = m_phaseTime / animatingTime; } - else if ( m_phaseTime < welcomeLength-1.0f ) + else if ( m_phaseTime < welcomeLength - animatingTime ) { - intensity = 0.0f; + //showing + intensity = 1.0f; } else { - intensity = m_phaseTime-(welcomeLength-1.0f); + //hiding + intensity = (welcomeLength - m_phaseTime) / animatingTime; } + if ( intensity < 0.0f ) intensity = 0.0f; if ( intensity > 1.0f ) intensity = 1.0f; - if ( (m_phase == PHASE_WELCOME2 && m_phaseTime > welcomeLength/2.0f) || - m_phase == PHASE_WELCOME3 ) + //white first, others -> black fadding + if ( (m_phase == PHASE_WELCOME1) && ( m_phaseTime < welcomeLength/2.0f)) { - intensity = 1.0f-intensity; - mode = Gfx::ENG_RSTATE_TCOLOR_WHITE; + intensity = 1.0f - intensity; + mode = Gfx::ENG_RSTATE_TCOLOR_BLACK; } m_engine->SetOverColor(Gfx::Color(intensity, intensity, intensity, intensity), mode); // TODO: color ok? diff --git a/src/ui/window.cpp b/src/ui/window.cpp index 6013d37..69ef857 100644 --- a/src/ui/window.cpp +++ b/src/ui/window.cpp @@ -355,6 +355,9 @@ CSlider* CWindow::CreateSlider(Math::Point pos, Math::Point dim, int icon, Event } // Creates a new list. +// if expand is less then zero, then the list would try to use expand's absolute value, +// and try to scale items to some size, so that dim of the list would not change after +// adjusting CList* CWindow::CreateList(Math::Point pos, Math::Point dim, int icon, EventType eventMsg, float expand) diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 7ad7afd..fbe9e7c 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -8,7 +8,7 @@ elseif (${PLATFORM_WINDOWS}) set(PLATFORM_LIBS "-lintl") elseif(${PLATFORM_LINUX}) # for clock_gettime - set(PLATFORM_LIBS "-lrt") + set(PLATFORM_LIBS "-lrt -lX11") endif() @@ -211,6 +211,7 @@ set(LIBS gtest gmock CBot +clipboard ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLTTF_LIBRARY} @@ -221,13 +222,12 @@ ${Boost_LIBRARIES} ${OPTIONAL_LIBS} ${PLATFORM_LIBS} ${LIBSNDFILE_LIBRARY} -clipboard ) add_executable(colobot_ut ${COLOBOT_SOURCES} ${UT_SOURCES} ${OPENAL_SOURCES}) target_link_libraries(colobot_ut ${LIBS}) -add_test(colobot_ut ./colobot_ut) +#add_test(colobot_ut ./colobot_ut) # TODO: change the unit cases to independent automated tests to be included in colobot_ut add_subdirectory(common) diff --git a/test/unit/ui/CMakeLists.txt b/test/unit/ui/CMakeLists.txt index 041d4a1..148e45e 100644 --- a/test/unit/ui/CMakeLists.txt +++ b/test/unit/ui/CMakeLists.txt @@ -13,10 +13,10 @@ if (${PLATFORM_WINDOWS}) set(SYSTEM_CPP_MODULE "system_windows.cpp") elseif(${PLATFORM_LINUX}) set(SYSTEM_CPP_MODULE "system_linux.cpp") - set(ADDITIONAL_LIB X11) + set(ADDITIONAL_LIB "-lX11") else() set(SYSTEM_CPP_MODULE "system_other.cpp") - set(ADDITIONAL_LIB X11) + set(ADDITIONAL_LIB "-lX11") endif() add_executable(edit_test @@ -40,7 +40,7 @@ stubs/restext_stub.cpp stubs/robotmain_stub.cpp edit_test.cpp) -target_link_libraries(edit_test gtest gmock ${SDL_LIBRARY} ${SDLTTF_LIBRARY} ${Boost_LIBRARIES} ${ADDITIONAL_LIB} clipboard) +target_link_libraries(edit_test gtest gmock clipboard ${SDL_LIBRARY} ${SDLTTF_LIBRARY} ${Boost_LIBRARIES} ${ADDITIONAL_LIB}) |