|
|
@ -1532,6 +1532,8 @@ namespace CSMWorld
|
|
|
|
|
|
|
|
|
|
|
|
virtual ~ActorAiRefIdAdapter() {}
|
|
|
|
virtual ~ActorAiRefIdAdapter() {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// FIXME: should check if the AI package type is already in the list and use a default
|
|
|
|
|
|
|
|
// that wasn't used already (in extreme case do not add anything at all?
|
|
|
|
virtual void addNestedRow (const RefIdColumn *column,
|
|
|
|
virtual void addNestedRow (const RefIdColumn *column,
|
|
|
|
RefIdData& data, int index, int position) const
|
|
|
|
RefIdData& data, int index, int position) const
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -1615,6 +1617,7 @@ namespace CSMWorld
|
|
|
|
switch (subColIndex)
|
|
|
|
switch (subColIndex)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
case 0:
|
|
|
|
|
|
|
|
// FIXME: should more than one AI package type be allowed? Check vanilla
|
|
|
|
switch (content.mType)
|
|
|
|
switch (content.mType)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
case ESM::AI_Wander: return 0;
|
|
|
|
case ESM::AI_Wander: return 0;
|
|
|
@ -1642,47 +1645,52 @@ namespace CSMWorld
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return QVariant();
|
|
|
|
return QVariant();
|
|
|
|
case 4: // wander idle
|
|
|
|
case 4: // wander idle
|
|
|
|
|
|
|
|
case 5:
|
|
|
|
|
|
|
|
case 6:
|
|
|
|
|
|
|
|
case 7:
|
|
|
|
|
|
|
|
case 8:
|
|
|
|
|
|
|
|
case 9:
|
|
|
|
|
|
|
|
case 10:
|
|
|
|
|
|
|
|
case 11:
|
|
|
|
if (content.mType == ESM::AI_Wander)
|
|
|
|
if (content.mType == ESM::AI_Wander)
|
|
|
|
{
|
|
|
|
return static_cast<int>(content.mWander.mIdle[subColIndex-4]);
|
|
|
|
return static_cast<int>(content.mWander.mIdle[0]); // FIXME:
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return QVariant();
|
|
|
|
return QVariant();
|
|
|
|
case 5: // wander repeat
|
|
|
|
case 12: // wander repeat
|
|
|
|
if (content.mType == ESM::AI_Wander)
|
|
|
|
if (content.mType == ESM::AI_Wander)
|
|
|
|
return content.mWander.mShouldRepeat != 0;
|
|
|
|
return content.mWander.mShouldRepeat != 0;
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return QVariant();
|
|
|
|
return QVariant();
|
|
|
|
case 6: // activate name
|
|
|
|
case 13: // activate name
|
|
|
|
if (content.mType == ESM::AI_Activate)
|
|
|
|
if (content.mType == ESM::AI_Activate)
|
|
|
|
return QString(content.mActivate.mName.toString().c_str());
|
|
|
|
return QString(content.mActivate.mName.toString().c_str());
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return QVariant();
|
|
|
|
return QVariant();
|
|
|
|
case 7: // target id
|
|
|
|
case 14: // target id
|
|
|
|
if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
return QString(content.mTarget.mId.toString().c_str());
|
|
|
|
return QString(content.mTarget.mId.toString().c_str());
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return QVariant();
|
|
|
|
return QVariant();
|
|
|
|
case 8: // target cell
|
|
|
|
case 15: // target cell
|
|
|
|
if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
return QString::fromUtf8(content.mCellName.c_str());
|
|
|
|
return QString::fromUtf8(content.mCellName.c_str());
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return QVariant();
|
|
|
|
return QVariant();
|
|
|
|
case 9:
|
|
|
|
case 16:
|
|
|
|
if (content.mType == ESM::AI_Travel)
|
|
|
|
if (content.mType == ESM::AI_Travel)
|
|
|
|
return content.mTravel.mX;
|
|
|
|
return content.mTravel.mX;
|
|
|
|
else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
return content.mTarget.mX;
|
|
|
|
return content.mTarget.mX;
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return QVariant();
|
|
|
|
return QVariant();
|
|
|
|
case 10:
|
|
|
|
case 17:
|
|
|
|
if (content.mType == ESM::AI_Travel)
|
|
|
|
if (content.mType == ESM::AI_Travel)
|
|
|
|
return content.mTravel.mY;
|
|
|
|
return content.mTravel.mY;
|
|
|
|
else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
return content.mTarget.mY;
|
|
|
|
return content.mTarget.mY;
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return QVariant();
|
|
|
|
return QVariant();
|
|
|
|
case 11:
|
|
|
|
case 18:
|
|
|
|
if (content.mType == ESM::AI_Travel)
|
|
|
|
if (content.mType == ESM::AI_Travel)
|
|
|
|
return content.mTravel.mZ;
|
|
|
|
return content.mTravel.mZ;
|
|
|
|
else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
@ -1712,11 +1720,12 @@ namespace CSMWorld
|
|
|
|
case 0: // ai package type
|
|
|
|
case 0: // ai package type
|
|
|
|
switch (value.toInt())
|
|
|
|
switch (value.toInt())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
case 0: content.mType = ESM::AI_Wander;
|
|
|
|
case 0: content.mType = ESM::AI_Wander; break;
|
|
|
|
case 1: content.mType = ESM::AI_Travel;
|
|
|
|
case 1: content.mType = ESM::AI_Travel; break;
|
|
|
|
case 2: content.mType = ESM::AI_Follow;
|
|
|
|
case 2: content.mType = ESM::AI_Follow; break;
|
|
|
|
case 3: content.mType = ESM::AI_Escort;
|
|
|
|
case 3: content.mType = ESM::AI_Escort; break;
|
|
|
|
case 4: content.mType = ESM::AI_Activate;
|
|
|
|
case 4: content.mType = ESM::AI_Activate; break;
|
|
|
|
|
|
|
|
default: return; // return without saving
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break; // always save
|
|
|
|
break; // always save
|
|
|
|
|
|
|
|
|
|
|
@ -1725,6 +1734,8 @@ namespace CSMWorld
|
|
|
|
content.mWander.mDistance = static_cast<short>(value.toInt());
|
|
|
|
content.mWander.mDistance = static_cast<short>(value.toInt());
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return; // return without saving
|
|
|
|
return; // return without saving
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break; // always save
|
|
|
|
case 2:
|
|
|
|
case 2:
|
|
|
|
if (content.mType == ESM::AI_Wander ||
|
|
|
|
if (content.mType == ESM::AI_Wander ||
|
|
|
|
content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
@ -1736,62 +1747,77 @@ namespace CSMWorld
|
|
|
|
content.mWander.mTimeOfDay = static_cast<unsigned char>(value.toInt());
|
|
|
|
content.mWander.mTimeOfDay = static_cast<unsigned char>(value.toInt());
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return; // return without saving
|
|
|
|
return; // return without saving
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break; // always save
|
|
|
|
case 4:
|
|
|
|
case 4:
|
|
|
|
|
|
|
|
case 5:
|
|
|
|
|
|
|
|
case 6:
|
|
|
|
|
|
|
|
case 7:
|
|
|
|
|
|
|
|
case 8:
|
|
|
|
|
|
|
|
case 9:
|
|
|
|
|
|
|
|
case 10:
|
|
|
|
|
|
|
|
case 11:
|
|
|
|
if (content.mType == ESM::AI_Wander)
|
|
|
|
if (content.mType == ESM::AI_Wander)
|
|
|
|
break; // FIXME: idle
|
|
|
|
content.mWander.mIdle[subColIndex-4] = static_cast<unsigned char>(value.toInt());
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return; // return without saving
|
|
|
|
return; // return without saving
|
|
|
|
case 5:
|
|
|
|
|
|
|
|
|
|
|
|
break; // always save
|
|
|
|
|
|
|
|
case 12:
|
|
|
|
if (content.mType == ESM::AI_Wander)
|
|
|
|
if (content.mType == ESM::AI_Wander)
|
|
|
|
{
|
|
|
|
|
|
|
|
content.mWander.mShouldRepeat = static_cast<unsigned char>(value.toInt());
|
|
|
|
content.mWander.mShouldRepeat = static_cast<unsigned char>(value.toInt());
|
|
|
|
break;
|
|
|
|
else
|
|
|
|
}
|
|
|
|
return; // return without saving
|
|
|
|
case 6: // NAME32
|
|
|
|
|
|
|
|
|
|
|
|
break; // always save
|
|
|
|
|
|
|
|
case 13: // NAME32
|
|
|
|
if (content.mType == ESM::AI_Activate)
|
|
|
|
if (content.mType == ESM::AI_Activate)
|
|
|
|
{
|
|
|
|
|
|
|
|
content.mActivate.mName.assign(value.toString().toUtf8().constData());
|
|
|
|
content.mActivate.mName.assign(value.toString().toUtf8().constData());
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return; // return without saving
|
|
|
|
return; // return without saving
|
|
|
|
case 7: // NAME32
|
|
|
|
|
|
|
|
|
|
|
|
break; // always save
|
|
|
|
|
|
|
|
case 14: // NAME32
|
|
|
|
if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
{
|
|
|
|
|
|
|
|
content.mTarget.mId.assign(value.toString().toUtf8().constData());
|
|
|
|
content.mTarget.mId.assign(value.toString().toUtf8().constData());
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return; // return without saving
|
|
|
|
return; // return without saving
|
|
|
|
case 8:
|
|
|
|
|
|
|
|
|
|
|
|
break; // always save
|
|
|
|
|
|
|
|
case 15:
|
|
|
|
if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
{
|
|
|
|
|
|
|
|
content.mCellName = std::string(value.toString().toUtf8().constData());
|
|
|
|
content.mCellName = std::string(value.toString().toUtf8().constData());
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return; // return without saving
|
|
|
|
return; // return without saving
|
|
|
|
case 9:
|
|
|
|
|
|
|
|
|
|
|
|
break; // always save
|
|
|
|
|
|
|
|
case 16:
|
|
|
|
if (content.mType == ESM::AI_Travel)
|
|
|
|
if (content.mType == ESM::AI_Travel)
|
|
|
|
content.mTravel.mZ = value.toFloat();
|
|
|
|
content.mTravel.mZ = value.toFloat();
|
|
|
|
else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
content.mTarget.mZ = value.toFloat();
|
|
|
|
content.mTarget.mZ = value.toFloat();
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return; // return without saving
|
|
|
|
return; // return without saving
|
|
|
|
case 10:
|
|
|
|
|
|
|
|
|
|
|
|
break; // always save
|
|
|
|
|
|
|
|
case 17:
|
|
|
|
if (content.mType == ESM::AI_Travel)
|
|
|
|
if (content.mType == ESM::AI_Travel)
|
|
|
|
content.mTravel.mZ = value.toFloat();
|
|
|
|
content.mTravel.mZ = value.toFloat();
|
|
|
|
else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
content.mTarget.mZ = value.toFloat();
|
|
|
|
content.mTarget.mZ = value.toFloat();
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return; // return without saving
|
|
|
|
return; // return without saving
|
|
|
|
case 11:
|
|
|
|
|
|
|
|
|
|
|
|
break; // always save
|
|
|
|
|
|
|
|
case 18:
|
|
|
|
if (content.mType == ESM::AI_Travel)
|
|
|
|
if (content.mType == ESM::AI_Travel)
|
|
|
|
content.mTravel.mZ = value.toFloat();
|
|
|
|
content.mTravel.mZ = value.toFloat();
|
|
|
|
else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
else if (content.mType == ESM::AI_Follow || content.mType == ESM::AI_Escort)
|
|
|
|
content.mTarget.mZ = value.toFloat();
|
|
|
|
content.mTarget.mZ = value.toFloat();
|
|
|
|
else
|
|
|
|
else
|
|
|
|
return; // return without saving
|
|
|
|
return; // return without saving
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break; // always save
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
throw std::runtime_error("Trying to access non-existing column in the nested table!");
|
|
|
|
throw std::runtime_error("Trying to access non-existing column in the nested table!");
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1801,7 +1827,7 @@ namespace CSMWorld
|
|
|
|
|
|
|
|
|
|
|
|
virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const
|
|
|
|
virtual int getNestedColumnsCount(const RefIdColumn *column, const RefIdData& data) const
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return 12;
|
|
|
|
return 19;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const
|
|
|
|
virtual int getNestedRowsCount(const RefIdColumn *column, const RefIdData& data, int index) const
|
|
|
|