mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-31 15:45:35 +00:00
Merge remote-tracking branch 'cc9cii/topicinfos-conditions'
This commit is contained in:
commit
73e01b0520
8 changed files with 426 additions and 2 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
// ||| +-------------- comparison type, ['0'..'5']; e.g. !=, <, >=, etc
|
||||
// ||+---------------- function index (encoded, where function == '1')
|
||||
// |+----------------- function, ['1'..'C']; e.g. Global, Local, Not ID, etc
|
||||
// +------------------ unknown
|
||||
//
|
||||
InfoConditionAdapter::InfoConditionAdapter () {}
|
||||
|
||||
void InfoConditionAdapter::addRow(Record<Info>& record, int position) const
|
||||
{
|
||||
Info info = record.get();
|
||||
|
||||
std::vector<ESM::DialInfo::SelectStruct>& conditions = info.mSelects;
|
||||
|
||||
// blank row
|
||||
ESM::DialInfo::SelectStruct condStruct;
|
||||
condStruct.mSelectRule = "00000";
|
||||
condStruct.mValue = ESM::Variant();
|
||||
condStruct.mValue.setType(ESM::VT_Int); // default to ints
|
||||
|
||||
conditions.insert(conditions.begin()+position, condStruct);
|
||||
|
||||
record.setModified (info);
|
||||
}
|
||||
|
||||
void InfoConditionAdapter::removeRow(Record<Info>& record, int rowToRemove) const
|
||||
{
|
||||
Info info = record.get();
|
||||
|
||||
std::vector<ESM::DialInfo::SelectStruct>& conditions = info.mSelects;
|
||||
|
||||
if (rowToRemove < 0 || rowToRemove >= static_cast<int> (conditions.size()))
|
||||
throw std::runtime_error ("index out of range");
|
||||
|
||||
conditions.erase(conditions.begin()+rowToRemove);
|
||||
|
||||
record.setModified (info);
|
||||
}
|
||||
|
||||
void InfoConditionAdapter::setTable(Record<Info>& record,
|
||||
const NestedTableWrapperBase& nestedTable) const
|
||||
{
|
||||
Info info = record.get();
|
||||
|
||||
info.mSelects =
|
||||
static_cast<const NestedTableWrapper<std::vector<ESM::DialInfo::SelectStruct> >&>(nestedTable).mNestedTable;
|
||||
|
||||
record.setModified (info);
|
||||
}
|
||||
|
||||
NestedTableWrapperBase* InfoConditionAdapter::table(const Record<Info>& record) const
|
||||
{
|
||||
// deleted by dtor of NestedTableStoring
|
||||
return new NestedTableWrapper<std::vector<ESM::DialInfo::SelectStruct> >(record.get().mSelects);
|
||||
}
|
||||
|
||||
// See the mappings in MWDialogue::SelectWrapper::getArgument
|
||||
// from ESM::Attribute, ESM::Skill and MWMechanics::CreatureStats (for AI)
|
||||
static std::map<const std::string, std::string> populateEncToInfoFunc()
|
||||
{
|
||||
std::map<const std::string, std::string> funcMap;
|
||||
funcMap["00"] = "Rank Low";
|
||||
funcMap["01"] = "Rank High";
|
||||
funcMap["02"] = "Rank Requirement";
|
||||
funcMap["03"] = "Reputation";
|
||||
funcMap["04"] = "Health Percent";
|
||||
funcMap["05"] = "PC Reputation";
|
||||
funcMap["06"] = "PC Level";
|
||||
funcMap["07"] = "PC Health Percent";
|
||||
funcMap["08"] = "PC Magicka";
|
||||
funcMap["09"] = "PC Fatigue";
|
||||
funcMap["10"] = "PC Strength";
|
||||
funcMap["11"] = "PC Block";
|
||||
funcMap["12"] = "PC Armoror";
|
||||
funcMap["13"] = "PC Medium Armor";
|
||||
funcMap["14"] = "PC Heavy Armor";
|
||||
funcMap["15"] = "PC Blunt Weapon";
|
||||
funcMap["16"] = "PC Long Blade";
|
||||
funcMap["17"] = "PC Axe";
|
||||
funcMap["18"] = "PC Spear";
|
||||
funcMap["19"] = "PC Athletics";
|
||||
funcMap["20"] = "PC Enchant";
|
||||
funcMap["21"] = "PC Destruction";
|
||||
funcMap["22"] = "PC Alteration";
|
||||
funcMap["23"] = "PC Illusion";
|
||||
funcMap["24"] = "PC Conjuration";
|
||||
funcMap["25"] = "PC Mysticism";
|
||||
funcMap["26"] = "PC Restoration";
|
||||
funcMap["27"] = "PC Alchemy";
|
||||
funcMap["28"] = "PC Unarmored";
|
||||
funcMap["29"] = "PC Security";
|
||||
funcMap["30"] = "PC Sneak";
|
||||
funcMap["31"] = "PC Acrobatics";
|
||||
funcMap["32"] = "PC Light Armor";
|
||||
funcMap["33"] = "PC Short Blade";
|
||||
funcMap["34"] = "PC Marksman";
|
||||
funcMap["35"] = "PC Merchantile";
|
||||
funcMap["36"] = "PC Speechcraft";
|
||||
funcMap["37"] = "PC Hand To Hand";
|
||||
funcMap["38"] = "PC Sex";
|
||||
funcMap["39"] = "PC Expelled";
|
||||
funcMap["40"] = "PC Common Disease";
|
||||
funcMap["41"] = "PC Blight Disease";
|
||||
funcMap["42"] = "PC Clothing Modifier";
|
||||
funcMap["43"] = "PC Crime Level";
|
||||
funcMap["44"] = "Same Sex";
|
||||
funcMap["45"] = "Same Race";
|
||||
funcMap["46"] = "Same Faction";
|
||||
funcMap["47"] = "Faction Rank Difference";
|
||||
funcMap["48"] = "Detected";
|
||||
funcMap["49"] = "Alarmed";
|
||||
funcMap["50"] = "Choice";
|
||||
funcMap["51"] = "PC Intelligence";
|
||||
funcMap["52"] = "PC Willpower";
|
||||
funcMap["53"] = "PC Agility";
|
||||
funcMap["54"] = "PC Speed";
|
||||
funcMap["55"] = "PC Endurance";
|
||||
funcMap["56"] = "PC Personality";
|
||||
funcMap["57"] = "PC Luck";
|
||||
funcMap["58"] = "PC Corpus";
|
||||
funcMap["59"] = "Weather";
|
||||
funcMap["60"] = "PC Vampire";
|
||||
funcMap["61"] = "Level";
|
||||
funcMap["62"] = "Attacked";
|
||||
funcMap["63"] = "Talked To PC";
|
||||
funcMap["64"] = "PC Health";
|
||||
funcMap["65"] = "Creature Target";
|
||||
funcMap["66"] = "Friend Hit";
|
||||
funcMap["67"] = "Fight";
|
||||
funcMap["68"] = "Hello";
|
||||
funcMap["69"] = "Alarm";
|
||||
funcMap["70"] = "Flee";
|
||||
funcMap["71"] = "Should Attack";
|
||||
funcMap["72"] = "Werewolf";
|
||||
funcMap["73"] = "PC Werewolf Kills";
|
||||
return funcMap;
|
||||
}
|
||||
static const std::map<const std::string, std::string> sEncToInfoFunc = populateEncToInfoFunc();
|
||||
|
||||
QVariant InfoConditionAdapter::getData(const Record<Info>& record,
|
||||
int subRowIndex, int subColIndex) const
|
||||
{
|
||||
Info info = record.get();
|
||||
|
||||
std::vector<ESM::DialInfo::SelectStruct>& conditions = info.mSelects;
|
||||
|
||||
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (conditions.size()))
|
||||
throw std::runtime_error ("index out of range");
|
||||
|
||||
switch (subColIndex)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
char condType = conditions[subRowIndex].mSelectRule[1];
|
||||
switch (condType)
|
||||
{
|
||||
case '0': return 0; // blank space
|
||||
case '1': return 1; // Function
|
||||
case '2': return 2; // Global
|
||||
case '3': return 3; // Local
|
||||
case '4': return 4; // Journal
|
||||
case '5': return 5; // Item
|
||||
case '6': return 6; // Dead
|
||||
case '7': return 7; // Not ID
|
||||
case '8': return 8; // Not Factio
|
||||
case '9': return 9; // Not Class
|
||||
case 'A': return 10; // Not Race
|
||||
case 'B': return 11; // Not Cell
|
||||
case 'C': return 12; // Not Local
|
||||
default: return QVariant(); // TODO: log an error?
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (conditions[subRowIndex].mSelectRule[1] == '1')
|
||||
{
|
||||
// throws an exception if the encoding is not found
|
||||
return sEncToInfoFunc.at(conditions[subRowIndex].mSelectRule.substr(2, 2)).c_str();
|
||||
}
|
||||
else
|
||||
return QString(conditions[subRowIndex].mSelectRule.substr(5).c_str());
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
char compType = conditions[subRowIndex].mSelectRule[4];
|
||||
switch (compType)
|
||||
{
|
||||
case '0': return 3; // =
|
||||
case '1': return 0; // !=
|
||||
case '2': return 4; // >
|
||||
case '3': return 5; // >=
|
||||
case '4': return 1; // <
|
||||
case '5': return 2; // <=
|
||||
default: return QVariant(); // TODO: log an error?
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
switch (conditions[subRowIndex].mValue.getType())
|
||||
{
|
||||
case ESM::VT_String:
|
||||
{
|
||||
return QString::fromUtf8 (conditions[subRowIndex].mValue.getString().c_str());
|
||||
}
|
||||
case ESM::VT_Int:
|
||||
case ESM::VT_Short:
|
||||
case ESM::VT_Long:
|
||||
{
|
||||
return conditions[subRowIndex].mValue.getInteger();
|
||||
}
|
||||
case ESM::VT_Float:
|
||||
{
|
||||
return conditions[subRowIndex].mValue.getFloat();
|
||||
}
|
||||
default: return QVariant();
|
||||
}
|
||||
}
|
||||
default: throw std::runtime_error("Info condition subcolumn index out of range");
|
||||
}
|
||||
}
|
||||
|
||||
void InfoConditionAdapter::setData(Record<Info>& record,
|
||||
const QVariant& value, int subRowIndex, int subColIndex) const
|
||||
{
|
||||
Info info = record.get();
|
||||
|
||||
std::vector<ESM::DialInfo::SelectStruct>& conditions = info.mSelects;
|
||||
|
||||
if (subRowIndex < 0 || subRowIndex >= static_cast<int> (conditions.size()))
|
||||
throw std::runtime_error ("index out of range");
|
||||
|
||||
switch (subColIndex)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// See sInfoCondFunc in columns.cpp for the enum values
|
||||
switch (value.toInt())
|
||||
{
|
||||
// FIXME: when these change the values of the other columns need to change
|
||||
// correspondingly (and automatically)
|
||||
case 1:
|
||||
{
|
||||
conditions[subRowIndex].mSelectRule[1] = '1'; // Function
|
||||
// default to "Rank Low"
|
||||
conditions[subRowIndex].mSelectRule[2] = '0';
|
||||
conditions[subRowIndex].mSelectRule[3] = '0';
|
||||
break;
|
||||
}
|
||||
case 2: conditions[subRowIndex].mSelectRule[1] = '2'; break; // Global
|
||||
case 3: conditions[subRowIndex].mSelectRule[1] = '3'; break; // Local
|
||||
case 4: conditions[subRowIndex].mSelectRule[1] = '4'; break; // Journal
|
||||
case 5: conditions[subRowIndex].mSelectRule[1] = '5'; break; // Item
|
||||
case 6: conditions[subRowIndex].mSelectRule[1] = '6'; break; // Dead
|
||||
case 7: conditions[subRowIndex].mSelectRule[1] = '7'; break; // Not ID
|
||||
case 8: conditions[subRowIndex].mSelectRule[1] = '8'; break; // Not Faction
|
||||
case 9: conditions[subRowIndex].mSelectRule[1] = '9'; break; // Not Class
|
||||
case 10: conditions[subRowIndex].mSelectRule[1] = 'A'; break; // Not Race
|
||||
case 11: conditions[subRowIndex].mSelectRule[1] = 'B'; break; // Not Cell
|
||||
case 12: conditions[subRowIndex].mSelectRule[1] = 'C'; break; // Not Local
|
||||
default: return; // return without saving
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (conditions[subRowIndex].mSelectRule[1] == '1')
|
||||
{
|
||||
std::map<const std::string, std::string>::const_iterator it = sEncToInfoFunc.begin();
|
||||
for (;it != sEncToInfoFunc.end(); ++it)
|
||||
{
|
||||
if (it->second == value.toString().toUtf8().constData())
|
||||
{
|
||||
std::string rule = conditions[subRowIndex].mSelectRule.substr(0, 2);
|
||||
rule.append(it->first);
|
||||
// leave old values for undo (NOTE: may not be vanilla's behaviour)
|
||||
rule.append(conditions[subRowIndex].mSelectRule.substr(4));
|
||||
conditions[subRowIndex].mSelectRule = rule;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (it == sEncToInfoFunc.end())
|
||||
return; // return without saving; TODO: maybe log an error here
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: validate the string values before saving, based on the current function
|
||||
std::string rule = conditions[subRowIndex].mSelectRule.substr(0, 5);
|
||||
conditions[subRowIndex].mSelectRule = rule.append(value.toString().toUtf8().constData());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
// See sInfoCondComp in columns.cpp for the enum values
|
||||
switch (value.toInt())
|
||||
{
|
||||
case 0: conditions[subRowIndex].mSelectRule[4] = '1'; break; // !=
|
||||
case 1: conditions[subRowIndex].mSelectRule[4] = '4'; break; // <
|
||||
case 2: conditions[subRowIndex].mSelectRule[4] = '5'; break; // <=
|
||||
case 3: conditions[subRowIndex].mSelectRule[4] = '0'; break; // =
|
||||
case 4: conditions[subRowIndex].mSelectRule[4] = '2'; break; // >
|
||||
case 5: conditions[subRowIndex].mSelectRule[4] = '3'; break; // >=
|
||||
default: return; // return without saving
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
switch (conditions[subRowIndex].mValue.getType())
|
||||
{
|
||||
case ESM::VT_String:
|
||||
{
|
||||
conditions[subRowIndex].mValue.setString (value.toString().toUtf8().constData());
|
||||
break;
|
||||
}
|
||||
case ESM::VT_Int:
|
||||
case ESM::VT_Short:
|
||||
case ESM::VT_Long:
|
||||
{
|
||||
conditions[subRowIndex].mValue.setInteger (value.toInt());
|
||||
break;
|
||||
}
|
||||
case ESM::VT_Float:
|
||||
{
|
||||
conditions[subRowIndex].mValue.setFloat (value.toFloat());
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: throw std::runtime_error("Info condition subcolumn index out of range");
|
||||
}
|
||||
|
||||
record.setModified (info);
|
||||
}
|
||||
|
||||
int InfoConditionAdapter::getColumnsCount(const Record<Info>& record) const
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
int InfoConditionAdapter::getRowsCount(const Record<Info>& record) const
|
||||
{
|
||||
return static_cast<int>(record.get().mSelects.size());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -412,6 +412,31 @@ namespace CSMWorld
|
|||
|
||||
virtual int getRowsCount(const Record<Info>& record) const;
|
||||
};
|
||||
|
||||
class InfoConditionAdapter : public NestedColumnAdapter<Info>
|
||||
{
|
||||
public:
|
||||
InfoConditionAdapter ();
|
||||
|
||||
virtual void addRow(Record<Info>& record, int position) const;
|
||||
|
||||
virtual void removeRow(Record<Info>& record, int rowToRemove) const;
|
||||
|
||||
virtual void setTable(Record<Info>& record,
|
||||
const NestedTableWrapperBase& nestedTable) const;
|
||||
|
||||
virtual NestedTableWrapperBase* table(const Record<Info>& record) const;
|
||||
|
||||
virtual QVariant getData(const Record<Info>& record,
|
||||
int subRowIndex, int subColIndex) const;
|
||||
|
||||
virtual void setData(Record<Info>& record,
|
||||
const QVariant& value, int subRowIndex, int subColIndex) const;
|
||||
|
||||
virtual int getColumnsCount(const Record<Info>& record) const;
|
||||
|
||||
virtual int getRowsCount(const Record<Info>& record) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CSM_WOLRD_NESTEDCOLADAPTERIMP_H
|
||||
|
|
|
@ -90,7 +90,9 @@ CSVDoc::ViewManager::ViewManager (CSMDoc::DocumentManager& documentManager)
|
|||
{ CSMWorld::ColumnBase::Display_EffectId, CSMWorld::Columns::ColumnId_EffectId, false },
|
||||
{ CSMWorld::ColumnBase::Display_PartRefType, CSMWorld::Columns::ColumnId_PartRefType, false },
|
||||
{ CSMWorld::ColumnBase::Display_AiPackageType, CSMWorld::Columns::ColumnId_AiPackageType, false },
|
||||
{ CSMWorld::ColumnBase::Display_YesNo, CSMWorld::Columns::ColumnId_AiWanderRepeat, false }
|
||||
{ CSMWorld::ColumnBase::Display_YesNo, CSMWorld::Columns::ColumnId_AiWanderRepeat, false },
|
||||
{ CSMWorld::ColumnBase::Display_InfoCondFunc, CSMWorld::Columns::ColumnId_InfoCondFunc, false },
|
||||
{ CSMWorld::ColumnBase::Display_InfoCondComp, CSMWorld::Columns::ColumnId_InfoCondComp, false }
|
||||
};
|
||||
|
||||
for (std::size_t i=0; i<sizeof (sMapping)/sizeof (Mapping); ++i)
|
||||
|
|
Loading…
Reference in a new issue