Fix AiWander sub-table editing. Should resolve bugs #2888 and #2930.

openmw-37
cc9cii 9 years ago
parent 998348e606
commit 3bbcf6a916

@ -249,7 +249,7 @@ namespace CSMWorld
{ ColumnId_AiWanderDist, "Wander Dist" }, { ColumnId_AiWanderDist, "Wander Dist" },
{ ColumnId_AiDuration, "Ai Duration" }, { ColumnId_AiDuration, "Ai Duration" },
{ ColumnId_AiWanderToD, "Wander ToD" }, { ColumnId_AiWanderToD, "Wander ToD" },
{ ColumnId_AiWanderIdle, "Wander Idle" }, //{ ColumnId_AiWanderIdle, "Wander Idle" },
{ ColumnId_AiWanderRepeat, "Wander Repeat" }, { ColumnId_AiWanderRepeat, "Wander Repeat" },
{ ColumnId_AiActivateName, "Activate" }, { ColumnId_AiActivateName, "Activate" },
{ ColumnId_AiTargetId, "Target ID" }, { ColumnId_AiTargetId, "Target ID" },
@ -316,6 +316,15 @@ namespace CSMWorld
{ ColumnId_MaxAttack, "Max Attack" }, { ColumnId_MaxAttack, "Max Attack" },
{ ColumnId_CreatureMisc, "Creature Misc" }, { ColumnId_CreatureMisc, "Creature Misc" },
{ ColumnId_Idle1, "Idle 1" },
{ ColumnId_Idle2, "Idle 2" },
{ ColumnId_Idle3, "Idle 3" },
{ ColumnId_Idle4, "Idle 4" },
{ ColumnId_Idle5, "Idle 5" },
{ ColumnId_Idle6, "Idle 6" },
{ ColumnId_Idle7, "Idle 7" },
{ ColumnId_Idle8, "Idle 8" },
{ ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue1, "Use value 1" },
{ ColumnId_UseValue2, "Use value 2" }, { ColumnId_UseValue2, "Use value 2" },
{ ColumnId_UseValue3, "Use value 3" }, { ColumnId_UseValue3, "Use value 3" },

@ -241,7 +241,7 @@ namespace CSMWorld
ColumnId_AiWanderDist = 221, ColumnId_AiWanderDist = 221,
ColumnId_AiDuration = 222, ColumnId_AiDuration = 222,
ColumnId_AiWanderToD = 223, ColumnId_AiWanderToD = 223,
ColumnId_AiWanderIdle = 224, // unused
ColumnId_AiWanderRepeat = 225, ColumnId_AiWanderRepeat = 225,
ColumnId_AiActivateName = 226, ColumnId_AiActivateName = 226,
// use ColumnId_PosX, etc for AI destinations // use ColumnId_PosX, etc for AI destinations
@ -316,6 +316,15 @@ namespace CSMWorld
ColumnId_MaxAttack = 284, ColumnId_MaxAttack = 284,
ColumnId_CreatureMisc = 285, ColumnId_CreatureMisc = 285,
ColumnId_Idle1 = 286,
ColumnId_Idle2 = 287,
ColumnId_Idle3 = 288,
ColumnId_Idle4 = 289,
ColumnId_Idle5 = 290,
ColumnId_Idle6 = 291,
ColumnId_Idle7 = 292,
ColumnId_Idle8 = 293,
// Allocated to a separate value range, so we don't get a collision should we ever need // Allocated to a separate value range, so we don't get a collision should we ever need
// to extend the number of use values. // to extend the number of use values.
ColumnId_UseValue1 = 0x10000, ColumnId_UseValue1 = 0x10000,

@ -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

@ -193,8 +193,24 @@ CSMWorld::RefIdCollection::RefIdCollection()
new RefIdColumn (Columns::ColumnId_AiDuration, CSMWorld::ColumnBase::Display_Integer)); new RefIdColumn (Columns::ColumnId_AiDuration, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_AiWanderToD, CSMWorld::ColumnBase::Display_Integer)); new RefIdColumn (Columns::ColumnId_AiWanderToD, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_Idle1, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_Idle2, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_Idle3, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_Idle4, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_AiWanderIdle, CSMWorld::ColumnBase::Display_Integer)); new RefIdColumn (Columns::ColumnId_Idle5, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_Idle6, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_Idle7, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_Idle8, CSMWorld::ColumnBase::Display_Integer));
mColumns.back().addColumn( mColumns.back().addColumn(
new RefIdColumn (Columns::ColumnId_AiWanderRepeat, CSMWorld::ColumnBase::Display_Boolean)); new RefIdColumn (Columns::ColumnId_AiWanderRepeat, CSMWorld::ColumnBase::Display_Boolean));
mColumns.back().addColumn( mColumns.back().addColumn(

Loading…
Cancel
Save