Commit 22f01b12 authored by scrawl's avatar scrawl

Merge branch 'master' of https://github.com/OpenMW/openmw into osg

Conflicts:
	apps/launcher/graphicspage.cpp
	apps/opencs/editor.cpp
	apps/opencs/model/doc/document.cpp
	apps/opencs/view/render/cell.cpp
	apps/opencs/view/render/mousestate.cpp
	apps/opencs/view/render/textoverlay.cpp
	apps/opencs/view/render/worldspacewidget.cpp
	apps/openmw/mwclass/creature.cpp
	apps/openmw/mwclass/npc.cpp
	apps/openmw/mwgui/inventorywindow.cpp
	apps/openmw/mwgui/loadingscreen.cpp
	apps/openmw/mwgui/mapwindow.cpp
	apps/openmw/mwgui/pickpocketitemmodel.cpp
	apps/openmw/mwgui/waitdialog.cpp
	apps/openmw/mwmechanics/combat.cpp
	apps/openmw/mwmechanics/mechanicsmanagerimp.cpp
	apps/openmw/mwrender/globalmap.cpp
	apps/openmw/mwworld/physicssystem.cpp
	apps/openmw/mwworld/refdata.cpp
	apps/openmw/mwworld/scene.cpp
	apps/openmw/mwworld/worldimp.cpp
	components/sdlutil/sdlinputwrapper.cpp
	extern/shiny/Main/Factory.cpp
	extern/shiny/Main/MaterialInstance.cpp
	extern/shiny/Main/Platform.cpp
	extern/shiny/Main/ShaderSet.cpp
parents f2809ab6 53b4c15d
......@@ -98,6 +98,7 @@ Programmers
Sebastian Wick (swick)
Sergey Shambir
sir_herrbatka
smbas
Stefan Galowicz (bogglez)
Stanislav Bobrov (Jiub)
Sylvain Thesnieres (Garvek)
......@@ -109,6 +110,13 @@ Programmers
Vincent Heuken
vocollapse
Manual
------
Bodillium
Cramal
sir_herrbatka
Packagers
---------
......
0.36.0
------
Bug #923: Editor: Operations-Multithreading is broken
Bug #1317: Erene Llenim in Seyda Neen does not walk around
Bug #1405: Water rendering glitch near Seyda Neen lighthouse
Bug #1621: "Error Detecting Morrowind Installation" in the default directory
Bug #2216: Creating a clone of the player stops you moving.
Bug #2387: Casting bound weapon spell doesn't switch to "ready weapon" mode
Bug #2407: Default to (0, 0) when "unknown cell" is encountered.
Bug #2411: enchanted item charges don't update/refresh if spell list window is pinned open
Bug #2428: Editor: cloning / creating new container class results in invalid omwaddon file - openmw-0.35
Bug #2429: Editor - cloning omits some values or sets different values than the original has
Bug #2430: NPC with negative fatigue don't fall (LGNPC Vivec, Foreign Quarter v2.21)
Bug #2432: Error on startup with Uvirith's Legacy enabled
Bug #2435: Editor: changed entries in the objects window are not shown as such
Bug #2437: Editor: changing an entry of a container/NPC/clothing/ingredient/globals will not be saved in the omwaddon file
Bug #2447: Editor doesn't save terrain information
Bug #2451: Editor not listing files with accented characters
Bug #2453: Chargen: sex, race and hair sliders not initialized properly
Bug #2459: Minor terrain clipping through statics due to difference in triangle alignment
Bug #2461: Invisible sound mark has collision in Sandus Ancestral Tomb
Bug #2465: tainted gold stack
Bug #2475: cumulative stacks of 100 point fortify skill speechcraft boosts do not apply correctly
Bug #2498: Editor: crash when issuing undo command after the table subview is closed
Bug #2500: Editor: object table - can't undo delete record
Bug #2518: OpenMW detect spell returns false positives
Bug #2521: NPCs don't react to stealing when inventory menu is open.
Bug #2525: Can't click on red dialogue choice [rise of house telvanni][60fffec]
Bug #2530: GetSpellEffects not working as in vanilla
Bug #2557: Crash on first launch after choosing "Run installation wizard"
Feature #139: Editor: Global Search & Replace
Feature #1219: Editor: Add dialogue mode only columns
Feature #2024: Hotkey for hand to hand (i.e. unequip any weapon)
Feature #2119: "Always Sneak" key bind
Feature #2262: Editor: Handle moved instances
Feature #2425: Editor: Add start script table
Feature #2426: Editor: start script record verifier
Feature #2480: Launcher: Multiselect entries in the Data Files list
Feature #2505: Editor: optionally show a line number column in the script editor
Feature #2512: Editor: Offer use of monospace fonts in the script editor as an option
Feature #2514: Editor: focus on ID input field on clone/add
Feature #2519: it is not possible to change icons that appear on the map after casting the Detect <animal | enchantment | key> spells
Task #2460: OS X: Use Application Support directory as user data path
Task #2516: Editor: Change References / Referenceables terminology
0.35.1
------
......
......@@ -19,8 +19,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
message(STATUS "Configuring OpenMW...")
set(OPENMW_VERSION_MAJOR 0)
set(OPENMW_VERSION_MINOR 35)
set(OPENMW_VERSION_RELEASE 1)
set(OPENMW_VERSION_MINOR 36)
set(OPENMW_VERSION_RELEASE 0)
set(OPENMW_VERSION_COMMITHASH "")
set(OPENMW_VERSION_TAGHASH "")
......@@ -263,7 +263,7 @@ endif()
# CXX Compiler settings
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -Wno-reorder -std=c++98 -pedantic -Wno-long-long")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -std=c++98 -pedantic -Wno-long-long")
if (CMAKE_CXX_COMPILER_ID STREQUAL Clang AND NOT APPLE)
execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_VARIABLE CLANG_VERSION)
......
......@@ -6,7 +6,7 @@ OpenMW
OpenMW is an attempt at recreating the engine for the popular role-playing game
Morrowind by Bethesda Softworks. You need to own and install the original game for OpenMW to work.
* Version: 0.35.1
* Version: 0.36.0
* License: GPL (see docs/license/GPL3.txt for more information)
* Website: http://www.openmw.org
* IRC: #openmw on irc.freenode.net
......
......@@ -33,9 +33,9 @@ QString getAspect(int x, int y)
}
Launcher::GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSetting, QWidget *parent)
: mCfgMgr(cfg)
: QWidget(parent)
, mCfgMgr(cfg)
, mGraphicsSettings(graphicsSetting)
, QWidget(parent)
{
setObjectName ("GraphicsPage");
setupUi(this);
......
......@@ -59,14 +59,16 @@ int main(int argc, char *argv[])
Launcher::MainDialog mainWin;
if (!mainWin.showFirstRunDialog())
Launcher::FirstRunDialogResult result = mainWin.showFirstRunDialog();
if (result == Launcher::FirstRunDialogResultFailure)
return 0;
// if (!mainWin.setup()) {
// return 0;
// }
mainWin.show();
if (result == Launcher::FirstRunDialogResultContinue)
mainWin.show();
int returnValue = app.exec();
SDL_Quit();
......
......@@ -148,10 +148,10 @@ void Launcher::MainDialog::createPages()
}
bool Launcher::MainDialog::showFirstRunDialog()
Launcher::FirstRunDialogResult Launcher::MainDialog::showFirstRunDialog()
{
if (!setupLauncherSettings())
return false;
return FirstRunDialogResultFailure;
if (mLauncherSettings.value(QString("General/firstrun"), QString("true")) == QLatin1String("true"))
{
......@@ -176,14 +176,14 @@ bool Launcher::MainDialog::showFirstRunDialog()
if (msgBox.clickedButton() == wizardButton)
{
if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false)) {
return false;
return FirstRunDialogResultFailure;
} else {
return true;
return FirstRunDialogResultWizard;
}
}
}
return setup();
return setup() ? FirstRunDialogResultContinue : FirstRunDialogResultFailure;
}
bool Launcher::MainDialog::setup()
......
......@@ -31,6 +31,13 @@ namespace Launcher
class UnshieldThread;
class SettingsPage;
enum FirstRunDialogResult
{
FirstRunDialogResultFailure,
FirstRunDialogResultContinue,
FirstRunDialogResultWizard
};
#ifndef WIN32
bool expansions(Launcher::UnshieldThread& cd);
#endif
......@@ -44,7 +51,7 @@ namespace Launcher
~MainDialog();
bool setup();
bool showFirstRunDialog();
FirstRunDialogResult showFirstRunDialog();
bool reloadSettings();
bool writeSettings();
......
......@@ -18,10 +18,10 @@ using namespace Process;
Launcher::SettingsPage::SettingsPage(Files::ConfigurationManager &cfg,
Config::GameSettings &gameSettings,
Config::LauncherSettings &launcherSettings, MainDialog *parent)
: mCfgMgr(cfg)
: QWidget(parent)
, mCfgMgr(cfg)
, mGameSettings(gameSettings)
, mLauncherSettings(launcherSettings)
, QWidget(parent)
, mMain(parent)
{
setupUi(this);
......
......@@ -46,7 +46,7 @@ opencs_units_noqt (model/tools
opencs_units (view/doc
viewmanager view operations operation subview startup filedialog newgame
filewidget adjusterwidget loader globaldebugprofilemenu runlogsubview
filewidget adjusterwidget loader globaldebugprofilemenu runlogsubview sizehint
)
......
......@@ -14,10 +14,11 @@
#include "model/doc/document.hpp"
#include "model/world/data.hpp"
CS::Editor::Editor ()
: mUserSettings (mCfgMgr), mDocumentManager (mCfgMgr),
mViewManager (mDocumentManager),
mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL), mPid(""), mLock()
mViewManager (mDocumentManager), mPid(""),
mLock(), mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL)
{
std::pair<Files::PathContainer, std::vector<std::string> > config = readConfig();
......
......@@ -2250,11 +2250,12 @@ CSMDoc::Document::Document (const VFS::Manager* vfs, const Files::ConfigurationM
ToUTF8::FromType encoding, const CSMWorld::ResourcesManager& resourcesManager,
const std::vector<std::string>& blacklistedScripts)
: mVFS(vfs), mSavePath (savePath), mContentFiles (files), mNew (new_), mData (encoding, resourcesManager),
mTools (*this), mResDir(resDir),
mTools (*this),
mProjectPath ((configuration.getUserDataPath() / "projects") /
(savePath.filename().string() + ".project")),
mSavingOperation (*this, mProjectPath, encoding),
mSaving (&mSavingOperation),
mResDir(resDir),
mRunner (mProjectPath)
{
if (mContentFiles.empty())
......
......@@ -9,7 +9,7 @@
CSMFilter::ValueNode::ValueNode (int columnId, Type lowerType, Type upperType,
double lower, double upper)
: mColumnId (columnId), mLowerType (lowerType), mUpperType (upperType), mLower (lower), mUpper (upper){}
: mColumnId (columnId), mLower (lower), mUpper (upper), mLowerType (lowerType), mUpperType (upperType){}
bool CSMFilter::ValueNode::test (const CSMWorld::IdTableBase& table, int row,
const std::map<int, int>& columns) const
......@@ -27,7 +27,7 @@ bool CSMFilter::ValueNode::test (const CSMWorld::IdTableBase& table, int row,
QVariant data = table.data (index);
if (data.type()!=QVariant::Double && data.type()!=QVariant::Bool && data.type()!=QVariant::Int &&
data.type()!=QVariant::UInt)
data.type()!=QVariant::UInt && data.type()!=static_cast<QVariant::Type> (QMetaType::Float))
return false;
double value = data.toDouble();
......
......@@ -4,7 +4,7 @@
CSMSettings::Connector::Connector(CSVSettings::View *master,
QObject *parent)
: mMasterView (master), QObject(parent)
: QObject(parent), mMasterView (master)
{}
void CSMSettings::Connector::addSlaveView (CSVSettings::View *view,
......
......@@ -126,6 +126,24 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
minWidth->setDefaultValue (325);
minWidth->setRange (50, 10000);
minWidth->setToolTip ("Minimum width of subviews.");
QString defaultScroll = "Scrollbar Only";
QStringList scrollValues = QStringList() << defaultScroll << "Grow Only" << "Grow then Scroll";
Setting *mainwinScroll = createSetting (Type_RadioButton, "mainwindow-scrollbar",
"Add a horizontal scrollbar to the main view window.");
mainwinScroll->setDefaultValue (defaultScroll);
mainwinScroll->setDeclaredValues (scrollValues);
mainwinScroll->setToolTip ("Scrollbar Only: Simple addition of scrollbars, the view window does not grow"
" automatically.\n"
"Grow Only: Original Editor behaviour. The view window grows as subviews are added. No scrollbars.\n"
"Grow then Scroll: The view window grows. The scrollbar appears once it cannot grow any further.");
Setting *grow = createSetting (Type_CheckBox, "grow-limit", "Grow Limit Screen");
grow->setDefaultValue ("false");
grow->setToolTip ("When \"Grow then Scroll\" option is selected, the window size grows to"
" the width of the virtual desktop. \nIf this option is selected the the window growth"
"is limited to the current screen.");
}
declareSection ("records", "Records");
......@@ -189,6 +207,14 @@ void CSMSettings::UserSettings::buildSettingModelDefaults()
shiftCtrlDoubleClick->setDeclaredValues (values);
shiftCtrlDoubleClick->setDefaultValue (editRecordAndClose);
shiftCtrlDoubleClick->setToolTip ("Action on shift control double click in table:<p>" + toolTip);
QString defaultValue = "Jump and Select";
QStringList jumpValues = QStringList() << defaultValue << "Jump Only" << "No Jump";
Setting *jumpToAdded = createSetting (Type_RadioButton, "jump-to-added",
"Jump to the added or cloned record.");
jumpToAdded->setDefaultValue (defaultValue);
jumpToAdded->setDeclaredValues (jumpValues);
}
declareSection ("search", "Search & Replace");
......
......@@ -11,8 +11,8 @@ CSMTools::ReferenceableCheckStage::ReferenceableCheckStage(
const CSMWorld::IdCollection<ESM::Faction>& faction)
:
mReferencables(referenceable),
mClasses(classes),
mRaces(races),
mClasses(classes),
mFactions(faction),
mPlayerPresent(false)
{
......
......@@ -103,8 +103,8 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
}
CSMTools::Tools::Tools (CSMDoc::Document& document)
: mDocument (document), mData (document.getData()), mVerifierOperation (0), mNextReportNumber (0),
mSearchOperation (0)
: mDocument (document), mData (document.getData()), mVerifierOperation (0),
mSearchOperation (0), mNextReportNumber (0)
{
// index 0: load error log
mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel));
......
......@@ -3,7 +3,7 @@
#include "columns.hpp"
CSMWorld::ColumnBase::ColumnBase (int columnId, Display displayType, int flags)
: mColumnId (columnId), mDisplayType (displayType), mFlags (flags)
: mColumnId (columnId), mFlags (flags), mDisplayType (displayType)
{}
CSMWorld::ColumnBase::~ColumnBase() {}
......@@ -81,6 +81,9 @@ bool CSMWorld::ColumnBase::isId (Display display)
Display_PartRefType,
Display_AiPackageType,
Display_YesNo,
Display_InfoCondFunc,
Display_InfoCondVar,
Display_InfoCondComp,
Display_None
};
......
......@@ -116,6 +116,9 @@ namespace CSMWorld
Display_PartRefType,
Display_AiPackageType,
Display_YesNo,
Display_InfoCondFunc,
Display_InfoCondVar,
Display_InfoCondComp,
//top level columns that nest other columns
Display_NestedHeader
......
......@@ -172,7 +172,7 @@ namespace CSMWorld
{ ColumnId_Rank, "Rank" },
{ ColumnId_Gender, "Gender" },
{ ColumnId_PcRank, "PC Rank" },
{ ColumnId_ReferenceableId, "Referenceable ID" },
{ ColumnId_ReferenceableId, "Object ID" },
{ ColumnId_ContainerContent, "Content" },
{ ColumnId_ItemCount, "Count" },
......@@ -274,6 +274,11 @@ namespace CSMWorld
{ ColumnId_SkillImpact, "Skills" },
{ ColumnId_InfoList, "Info List" },
{ ColumnId_InfoCondition, "Info Conditions" },
{ ColumnId_InfoCondFunc, "Function" },
{ ColumnId_InfoCondVar, "Func/Variable" },
{ ColumnId_InfoCondComp, "Comp" },
{ ColumnId_InfoCondValue, "Value" },
{ ColumnId_OriginalCell, "Original Cell" },
{ ColumnId_UseValue1, "Use value 1" },
......@@ -502,6 +507,18 @@ namespace
"No", "Yes", 0
};
static const char *sInfoCondFunc[] =
{
" ", "Function", "Global", "Local", "Journal",
"Item", "Dead", "Not ID", "Not Faction", "Not Class",
"Not Race", "Not Cell", "Not Local", 0
};
static const char *sInfoCondComp[] =
{
"!=", "<", "<=", "=", ">", ">=", 0
};
const char **getEnumNames (CSMWorld::Columns::ColumnId column)
{
switch (column)
......@@ -530,6 +547,10 @@ namespace
case CSMWorld::Columns::ColumnId_PartRefType: return sPartRefType;
case CSMWorld::Columns::ColumnId_AiPackageType: return sAiPackageType;
case CSMWorld::Columns::ColumnId_AiWanderRepeat: return sAiWanderRepeat;
case CSMWorld::Columns::ColumnId_InfoCondFunc: return sInfoCondFunc;
// FIXME: don't have dynamic value enum delegate, use Display_String for now
//case CSMWorld::Columns::ColumnId_InfoCond: return sInfoCond;
case CSMWorld::Columns::ColumnId_InfoCondComp: return sInfoCondComp;
default: return 0;
}
......
......@@ -264,8 +264,13 @@ namespace CSMWorld
ColumnId_SkillImpact = 240, // impact from magic effects
ColumnId_InfoList = 241,
ColumnId_InfoCondition = 242,
ColumnId_InfoCondFunc = 243,
ColumnId_InfoCondVar = 244,
ColumnId_InfoCondComp = 245,
ColumnId_InfoCondValue = 246,
ColumnId_OriginalCell = 242,
ColumnId_OriginalCell = 247,
// Allocated to a separate value range, so we don't get a collision should we ever need
// to extend the number of use values.
......
......@@ -83,7 +83,7 @@ std::vector<std::string> CSMWorld::CommandDispatcher::getRevertableRecords() con
CSMWorld::CommandDispatcher::CommandDispatcher (CSMDoc::Document& document,
const CSMWorld::UniversalId& id, QObject *parent)
: QObject (parent), mDocument (document), mId (id), mLocked (false)
: QObject (parent), mLocked (false), mDocument (document), mId (id)
{}
void CSMWorld::CommandDispatcher::setEditLock (bool locked)
......
......@@ -14,7 +14,7 @@
CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelIndex& index,
const QVariant& new_, QUndoCommand* parent)
: QUndoCommand (parent), mModel (&model), mIndex (index), mNew (new_)
: QUndoCommand (parent), mModel (&model), mIndex (index), mNew (new_), mHasRecordState(false)
{
if (QAbstractProxyModel *proxy = dynamic_cast<QAbstractProxyModel *> (&model))
{
......@@ -27,6 +27,15 @@ CSMWorld::ModifyCommand::ModifyCommand (QAbstractItemModel& model, const QModelI
}
else
setText ("Modify " + mModel->headerData (mIndex.column(), Qt::Horizontal, Qt::DisplayRole).toString());
// Remember record state before the modification
if (CSMWorld::IdTable *table = dynamic_cast<IdTable *>(mModel))
{
mHasRecordState = true;
int stateColumnIndex = table->findColumnIndex(Columns::ColumnId_Modification);
mRecordStateIndex = table->index(mIndex.row(), stateColumnIndex);
mOldRecordState = static_cast<CSMWorld::RecordBase::State>(table->data(mRecordStateIndex).toInt());
}
}
void CSMWorld::ModifyCommand::redo()
......@@ -38,6 +47,10 @@ void CSMWorld::ModifyCommand::redo()
void CSMWorld::ModifyCommand::undo()
{
mModel->setData (mIndex, mOld);
if (mHasRecordState)
{
mModel->setData(mRecordStateIndex, mOldRecordState);
}
}
......@@ -235,12 +248,12 @@ CSMWorld::DeleteNestedCommand::DeleteNestedCommand (IdTree& model,
int nestedRow,
int parentColumn,
QUndoCommand* parent) :
mId(id),
QUndoCommand(parent),
NestedTableStoring(model, id, parentColumn),
mModel(model),
mId(id),
mParentColumn(parentColumn),
QUndoCommand(parent),
mNestedRow(nestedRow),
NestedTableStoring(model, id, parentColumn)
mNestedRow(nestedRow)
{
std::string title =
model.headerData(parentColumn, Qt::Horizontal, Qt::DisplayRole).toString().toUtf8().constData();
......@@ -263,12 +276,12 @@ void CSMWorld::DeleteNestedCommand::undo()
}
CSMWorld::AddNestedCommand::AddNestedCommand(IdTree& model, const std::string& id, int nestedRow, int parentColumn, QUndoCommand* parent)
: mModel(model),
: QUndoCommand(parent),
NestedTableStoring(model, id, parentColumn),
mModel(model),
mId(id),
mNewRow(nestedRow),
mParentColumn(parentColumn),
QUndoCommand(parent),
NestedTableStoring(model, id, parentColumn)
mParentColumn(parentColumn)
{
std::string title =
model.headerData(parentColumn, Qt::Horizontal, Qt::DisplayRole).toString().toUtf8().constData();
......
......@@ -31,6 +31,10 @@ namespace CSMWorld
QVariant mNew;
QVariant mOld;
bool mHasRecordState;
QModelIndex mRecordStateIndex;
CSMWorld::RecordBase::State mOldRecordState;
public:
ModifyCommand (QAbstractItemModel& model, const QModelIndex& index, const QVariant& new_,
......
......@@ -242,6 +242,19 @@ CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourc
mTopicInfos.addAdapter (std::make_pair(&mTopicInfos.getColumn(index), new InfoListAdapter ()));
mTopicInfos.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_ScriptText, ColumnBase::Display_ScriptLines));
// Special conditions
mTopicInfos.addColumn (new NestedParentColumn<Info> (Columns::ColumnId_InfoCondition));
index = mTopicInfos.getColumns()-1;
mTopicInfos.addAdapter (std::make_pair(&mTopicInfos.getColumn(index), new InfoConditionAdapter ()));
mTopicInfos.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_InfoCondFunc, ColumnBase::Display_InfoCondFunc));
// FIXME: don't have dynamic value enum delegate, use Display_String for now
mTopicInfos.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_InfoCondVar, ColumnBase::Display_String));
mTopicInfos.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_InfoCondComp, ColumnBase::Display_InfoCondComp));
mTopicInfos.getNestableColumn(index)->addColumn(
new NestedChildColumn (Columns::ColumnId_Value, ColumnBase::Display_Var));
mJournalInfos.addColumn (new StringIdColumn<Info> (true));
mJournalInfos.addColumn (new RecordStateColumn<Info>);
......
......@@ -528,4 +528,356 @@ namespace CSMWorld
{
return 1; // fixed at size 1
}
// ESM::DialInfo::SelectStruct.mSelectRule
// 012345...
// ^^^ ^^
// ||| ||
// ||| |+------------- condition variable string