summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDidier Raboud <odyx@debian.org>2013-04-28 11:27:27 +0200
committerDidier Raboud <odyx@debian.org>2013-04-28 11:27:27 +0200
commite60a610f013f75c4ca54768b756348d6a37ae2d2 (patch)
treef1872f00c691192e36f3fa4d01b6a27eb4b6f75a
parentd36d4b9a25980d9fb6b18961ca8200f6eaa8c311 (diff)
parent0ce02b21f40ed8a0086dffe2c4bb01eeff942e58 (diff)
downloadcolobot-e60a610f013f75c4ca54768b756348d6a37ae2d2.tar.gz
colobot-e60a610f013f75c4ca54768b756348d6a37ae2d2.tar.bz2
colobot-e60a610f013f75c4ca54768b756348d6a37ae2d2.zip
New snapshot of dev branch (296-g0ce02b2)
-rw-r--r--CMakeLists.txt2
-rw-r--r--debian/changelog4
-rw-r--r--src/CBot/CBot.cpp5
-rw-r--r--src/CBot/CBot.h27
-rw-r--r--src/CBot/CBotString.cpp1
-rw-r--r--src/CBot/CBotWhile.cpp143
-rw-r--r--src/CBot/resource.h1
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/app/app.cpp1
-rw-r--r--src/common/global.h2
-rw-r--r--src/common/restext.cpp2
-rw-r--r--src/object/brain.cpp5
-rw-r--r--src/object/robotmain.cpp176
-rw-r--r--src/object/robotmain.h24
-rw-r--r--src/object/task/taskgoto.cpp6
-rw-r--r--src/object/task/tasksearch.cpp6
-rw-r--r--src/script/cbottoken.cpp8
-rw-r--r--src/script/script.cpp232
-rw-r--r--src/script/script.h3
-rw-r--r--src/sound/oalsound/alsound.cpp116
-rw-r--r--src/sound/oalsound/alsound.h4
-rw-r--r--src/sound/oalsound/channel.cpp39
-rw-r--r--src/sound/oalsound/channel.h10
-rw-r--r--src/sound/sound.h25
-rw-r--r--src/ui/interface.cpp3
-rw-r--r--src/ui/list.cpp17
-rw-r--r--src/ui/maindialog.cpp31
-rw-r--r--src/ui/window.cpp3
-rw-r--r--test/unit/CMakeLists.txt6
-rw-r--r--test/unit/ui/CMakeLists.txt6
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})