Merge pull request #421 from TES3MP/0.6.3 while resolving conflicts
Conflicts: apps/openmw-mp/Script/Functions/Actors.cpp apps/openmw-mp/Script/Functions/Actors.hpp apps/openmw-mp/Script/Functions/Cells.cpp
|
@ -15,6 +15,7 @@ Programmers
|
|||
Adam Hogan (aurix)
|
||||
Aesylwinn
|
||||
aegis
|
||||
AHSauge
|
||||
Aleksandar Jovanov
|
||||
Alex Haddad (rainChu)
|
||||
Alex McKibben
|
||||
|
@ -156,6 +157,8 @@ Programmers
|
|||
terrorfisch
|
||||
thegriglat
|
||||
Thomas Luppi (Digmaster)
|
||||
tri4ng1e
|
||||
unelsson
|
||||
Will Herrmann (Thunderforge)
|
||||
Tom Mason (wheybags)
|
||||
Torben Leif Carrington (TorbenC)
|
||||
|
@ -225,7 +228,7 @@ Artwork
|
|||
|
||||
Necrod - OpenMW Logo
|
||||
Mickey Lyle (raevol) - Wordpress Theme
|
||||
Tom Koenderink (Okulo), SirHerrbatka, crysthala, Shnatsel - OpenMW Editor Icons
|
||||
Tom Koenderink (Okulo), SirHerrbatka, crysthala, Shnatsel, Lamoot - OpenMW Editor Icons
|
||||
|
||||
Inactive Contributors
|
||||
---------------------
|
||||
|
|
|
@ -1040,45 +1040,47 @@ void Record<ESM::NPC>::print()
|
|||
|
||||
if (mData.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
||||
{
|
||||
std::cout << " Level: " << mData.mNpdt12.mLevel << std::endl;
|
||||
std::cout << " Reputation: " << (int)mData.mNpdt12.mReputation << std::endl;
|
||||
std::cout << " Disposition: " << (int)mData.mNpdt12.mDisposition << std::endl;
|
||||
std::cout << " Rank: " << (int)mData.mNpdt12.mRank << std::endl;
|
||||
std::cout << " Unknown1: "
|
||||
<< (unsigned int)((unsigned char)mData.mNpdt12.mUnknown1) << std::endl;
|
||||
std::cout << " Unknown2: "
|
||||
<< (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl;
|
||||
std::cout << " Unknown3: "
|
||||
<< (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl;
|
||||
std::cout << " Gold: " << mData.mNpdt12.mGold << std::endl;
|
||||
std::cout << " Level: " << mData.mNpdt.mLevel << std::endl;
|
||||
std::cout << " Reputation: " << (int)mData.mNpdt.mReputation << std::endl;
|
||||
std::cout << " Disposition: " << (int)mData.mNpdt.mDisposition << std::endl;
|
||||
std::cout << " Rank: " << (int)mData.mNpdt.mRank << std::endl;
|
||||
//Why do we want to print these fields? They are padding in the struct and contain
|
||||
// nothing of real value. Now we don't deal with NPDTstruct12 in runtime either...
|
||||
//std::cout << " Unknown1: "
|
||||
// << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown1) << std::endl;
|
||||
//std::cout << " Unknown2: "
|
||||
// << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl;
|
||||
//std::cout << " Unknown3: "
|
||||
// << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl;
|
||||
std::cout << " Gold: " << mData.mNpdt.mGold << std::endl;
|
||||
}
|
||||
else {
|
||||
std::cout << " Level: " << mData.mNpdt52.mLevel << std::endl;
|
||||
std::cout << " Reputation: " << (int)mData.mNpdt52.mReputation << std::endl;
|
||||
std::cout << " Disposition: " << (int)mData.mNpdt52.mDisposition << std::endl;
|
||||
std::cout << " Rank: " << (int)mData.mNpdt52.mRank << std::endl;
|
||||
std::cout << " FactionID: " << (int)mData.mNpdt52.mFactionID << std::endl;
|
||||
std::cout << " Level: " << mData.mNpdt.mLevel << std::endl;
|
||||
std::cout << " Reputation: " << (int)mData.mNpdt.mReputation << std::endl;
|
||||
std::cout << " Disposition: " << (int)mData.mNpdt.mDisposition << std::endl;
|
||||
std::cout << " Rank: " << (int)mData.mNpdt.mRank << std::endl;
|
||||
std::cout << " FactionID: " << (int)mData.mNpdt.mFactionID << std::endl;
|
||||
|
||||
std::cout << " Attributes:" << std::endl;
|
||||
std::cout << " Strength: " << (int)mData.mNpdt52.mStrength << std::endl;
|
||||
std::cout << " Intelligence: " << (int)mData.mNpdt52.mIntelligence << std::endl;
|
||||
std::cout << " Willpower: " << (int)mData.mNpdt52.mWillpower << std::endl;
|
||||
std::cout << " Agility: " << (int)mData.mNpdt52.mAgility << std::endl;
|
||||
std::cout << " Speed: " << (int)mData.mNpdt52.mSpeed << std::endl;
|
||||
std::cout << " Endurance: " << (int)mData.mNpdt52.mEndurance << std::endl;
|
||||
std::cout << " Personality: " << (int)mData.mNpdt52.mPersonality << std::endl;
|
||||
std::cout << " Luck: " << (int)mData.mNpdt52.mLuck << std::endl;
|
||||
std::cout << " Strength: " << (int)mData.mNpdt.mStrength << std::endl;
|
||||
std::cout << " Intelligence: " << (int)mData.mNpdt.mIntelligence << std::endl;
|
||||
std::cout << " Willpower: " << (int)mData.mNpdt.mWillpower << std::endl;
|
||||
std::cout << " Agility: " << (int)mData.mNpdt.mAgility << std::endl;
|
||||
std::cout << " Speed: " << (int)mData.mNpdt.mSpeed << std::endl;
|
||||
std::cout << " Endurance: " << (int)mData.mNpdt.mEndurance << std::endl;
|
||||
std::cout << " Personality: " << (int)mData.mNpdt.mPersonality << std::endl;
|
||||
std::cout << " Luck: " << (int)mData.mNpdt.mLuck << std::endl;
|
||||
|
||||
std::cout << " Skills:" << std::endl;
|
||||
for (int i = 0; i != ESM::Skill::Length; i++)
|
||||
std::cout << " " << skillLabel(i) << ": "
|
||||
<< (int)(mData.mNpdt52.mSkills[i]) << std::endl;
|
||||
<< (int)(mData.mNpdt.mSkills[i]) << std::endl;
|
||||
|
||||
std::cout << " Health: " << mData.mNpdt52.mHealth << std::endl;
|
||||
std::cout << " Magicka: " << mData.mNpdt52.mMana << std::endl;
|
||||
std::cout << " Fatigue: " << mData.mNpdt52.mFatigue << std::endl;
|
||||
std::cout << " Unknown: " << (int)mData.mNpdt52.mUnknown << std::endl;
|
||||
std::cout << " Gold: " << mData.mNpdt52.mGold << std::endl;
|
||||
std::cout << " Health: " << mData.mNpdt.mHealth << std::endl;
|
||||
std::cout << " Magicka: " << mData.mNpdt.mMana << std::endl;
|
||||
std::cout << " Fatigue: " << mData.mNpdt.mFatigue << std::endl;
|
||||
std::cout << " Unknown: " << (int)mData.mNpdt.mUnknown << std::endl;
|
||||
std::cout << " Gold: " << mData.mNpdt.mGold << std::endl;
|
||||
}
|
||||
|
||||
std::vector<ESM::ContItem>::iterator cit;
|
||||
|
|
|
@ -122,7 +122,7 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
mContext->mPlayer.mObject.mCreatureStats.mLevel = npc.mNpdt52.mLevel;
|
||||
mContext->mPlayer.mObject.mCreatureStats.mLevel = npc.mNpdt.mLevel;
|
||||
mContext->mPlayerBase = npc;
|
||||
ESM::SpellState::SpellParams empty;
|
||||
// FIXME: player start spells and birthsign spells aren't listed here,
|
||||
|
|
|
@ -377,7 +377,7 @@ namespace ESSImport
|
|||
profile.mPlayerClassName = context.mCustomPlayerClassName;
|
||||
else
|
||||
profile.mPlayerClassId = context.mPlayerBase.mClass;
|
||||
profile.mPlayerLevel = context.mPlayerBase.mNpdt52.mLevel;
|
||||
profile.mPlayerLevel = context.mPlayerBase.mNpdt.mLevel;
|
||||
profile.mPlayerName = header.mGameData.mPlayerName.toString();
|
||||
|
||||
writeScreenshot(header, profile);
|
||||
|
|
|
@ -32,9 +32,6 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
|||
if (class_.mName.empty())
|
||||
messages.push_back (std::make_pair (id, class_.mId + " has an empty name"));
|
||||
|
||||
if (class_.mDescription.empty())
|
||||
messages.push_back (std::make_pair (id, class_.mId + " has an empty description"));
|
||||
|
||||
// test for invalid attributes
|
||||
for (int i=0; i<2; ++i)
|
||||
if (class_.mData.mAttribute[i]==-1)
|
||||
|
|
|
@ -239,9 +239,7 @@ void CSMTools::ReferenceableCheckStage::bookCheck(
|
|||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||
|
||||
if (baseRecord.isDeleted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const ESM::Book& book = (dynamic_cast<const CSMWorld::Record<ESM::Book>& >(baseRecord)).get();
|
||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Book, book.mId);
|
||||
|
@ -260,9 +258,7 @@ void CSMTools::ReferenceableCheckStage::activatorCheck(
|
|||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||
|
||||
if (baseRecord.isDeleted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const ESM::Activator& activator = (dynamic_cast<const CSMWorld::Record<ESM::Activator>& >(baseRecord)).get();
|
||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Activator, activator.mId);
|
||||
|
@ -283,9 +279,7 @@ void CSMTools::ReferenceableCheckStage::potionCheck(
|
|||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||
|
||||
if (baseRecord.isDeleted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const ESM::Potion& potion = (dynamic_cast<const CSMWorld::Record<ESM::Potion>& >(baseRecord)).get();
|
||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Potion, potion.mId);
|
||||
|
@ -306,9 +300,7 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck(
|
|||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||
|
||||
if (baseRecord.isDeleted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const ESM::Apparatus& apparatus = (dynamic_cast<const CSMWorld::Record<ESM::Apparatus>& >(baseRecord)).get();
|
||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Apparatus, apparatus.mId);
|
||||
|
@ -329,9 +321,7 @@ void CSMTools::ReferenceableCheckStage::armorCheck(
|
|||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||
|
||||
if (baseRecord.isDeleted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const ESM::Armor& armor = (dynamic_cast<const CSMWorld::Record<ESM::Armor>& >(baseRecord)).get();
|
||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Armor, armor.mId);
|
||||
|
@ -358,9 +348,7 @@ void CSMTools::ReferenceableCheckStage::clothingCheck(
|
|||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||
|
||||
if (baseRecord.isDeleted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const ESM::Clothing& clothing = (dynamic_cast<const CSMWorld::Record<ESM::Clothing>& >(baseRecord)).get();
|
||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Clothing, clothing.mId);
|
||||
|
@ -378,9 +366,7 @@ void CSMTools::ReferenceableCheckStage::containerCheck(
|
|||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||
|
||||
if (baseRecord.isDeleted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const ESM::Container& container = (dynamic_cast<const CSMWorld::Record<ESM::Container>& >(baseRecord)).get();
|
||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Container, container.mId);
|
||||
|
@ -512,9 +498,7 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck(
|
|||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||
|
||||
if (baseRecord.isDeleted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const ESM::Ingredient& ingredient = (dynamic_cast<const CSMWorld::Record<ESM::Ingredient>& >(baseRecord)).get();
|
||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Ingredient, ingredient.mId);
|
||||
|
@ -577,13 +561,8 @@ void CSMTools::ReferenceableCheckStage::lightCheck(
|
|||
messages.push_back (std::make_pair (id, light.mId + " has negative light radius"));
|
||||
|
||||
if (light.mData.mFlags & ESM::Light::Carry)
|
||||
{
|
||||
inventoryItemCheck<ESM::Light>(light, messages, id.toString());
|
||||
|
||||
if (light.mData.mTime == 0)
|
||||
messages.push_back (std::make_pair (id, light.mId + " has zero duration"));
|
||||
}
|
||||
|
||||
// Check that mentioned scripts exist
|
||||
scriptCheck<ESM::Light>(light, messages, id.toString());
|
||||
}
|
||||
|
@ -596,9 +575,7 @@ void CSMTools::ReferenceableCheckStage::lockpickCheck(
|
|||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||
|
||||
if (baseRecord.isDeleted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const ESM::Lockpick& lockpick = (dynamic_cast<const CSMWorld::Record<ESM::Lockpick>& >(baseRecord)).get();
|
||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Lockpick, lockpick.mId);
|
||||
|
@ -619,9 +596,7 @@ void CSMTools::ReferenceableCheckStage::miscCheck(
|
|||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||
|
||||
if (baseRecord.isDeleted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const ESM::Miscellaneous& miscellaneous = (dynamic_cast<const CSMWorld::Record<ESM::Miscellaneous>& >(baseRecord)).get();
|
||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Miscellaneous, miscellaneous.mId);
|
||||
|
@ -644,12 +619,12 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
|
|||
const ESM::NPC& npc = (dynamic_cast<const CSMWorld::Record<ESM::NPC>& >(baseRecord)).get();
|
||||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Npc, npc.mId);
|
||||
|
||||
short level(npc.mNpdt52.mLevel);
|
||||
char disposition(npc.mNpdt52.mDisposition);
|
||||
char reputation(npc.mNpdt52.mReputation);
|
||||
char rank(npc.mNpdt52.mRank);
|
||||
short level(npc.mNpdt.mLevel);
|
||||
char disposition(npc.mNpdt.mDisposition);
|
||||
char reputation(npc.mNpdt.mReputation);
|
||||
char rank(npc.mNpdt.mRank);
|
||||
//Don't know what unknown is for
|
||||
int gold(npc.mNpdt52.mGold);
|
||||
int gold(npc.mNpdt.mGold);
|
||||
|
||||
//Detect if player is present
|
||||
if (Misc::StringUtils::ciEqual(npc.mId, "player")) //Happy now, scrawl?
|
||||
|
@ -663,36 +638,36 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
|
|||
return;
|
||||
}
|
||||
|
||||
level = npc.mNpdt12.mLevel;
|
||||
disposition = npc.mNpdt12.mDisposition;
|
||||
reputation = npc.mNpdt12.mReputation;
|
||||
rank = npc.mNpdt12.mRank;
|
||||
gold = npc.mNpdt12.mGold;
|
||||
level = npc.mNpdt.mLevel;
|
||||
disposition = npc.mNpdt.mDisposition;
|
||||
reputation = npc.mNpdt.mReputation;
|
||||
rank = npc.mNpdt.mRank;
|
||||
gold = npc.mNpdt.mGold;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (npc.mNpdt52.mAgility == 0)
|
||||
if (npc.mNpdt.mAgility == 0)
|
||||
messages.push_back (std::make_pair (id, npc.mId + " agility has zero value"));
|
||||
|
||||
if (npc.mNpdt52.mEndurance == 0)
|
||||
if (npc.mNpdt.mEndurance == 0)
|
||||
messages.push_back (std::make_pair (id, npc.mId + " endurance has zero value"));
|
||||
|
||||
if (npc.mNpdt52.mIntelligence == 0)
|
||||
if (npc.mNpdt.mIntelligence == 0)
|
||||
messages.push_back (std::make_pair (id, npc.mId + " intelligence has zero value"));
|
||||
|
||||
if (npc.mNpdt52.mLuck == 0)
|
||||
if (npc.mNpdt.mLuck == 0)
|
||||
messages.push_back (std::make_pair (id, npc.mId + " luck has zero value"));
|
||||
|
||||
if (npc.mNpdt52.mPersonality == 0)
|
||||
if (npc.mNpdt.mPersonality == 0)
|
||||
messages.push_back (std::make_pair (id, npc.mId + " personality has zero value"));
|
||||
|
||||
if (npc.mNpdt52.mStrength == 0)
|
||||
if (npc.mNpdt.mStrength == 0)
|
||||
messages.push_back (std::make_pair (id, npc.mId + " strength has zero value"));
|
||||
|
||||
if (npc.mNpdt52.mSpeed == 0)
|
||||
if (npc.mNpdt.mSpeed == 0)
|
||||
messages.push_back (std::make_pair (id, npc.mId + " speed has zero value"));
|
||||
|
||||
if (npc.mNpdt52.mWillpower == 0)
|
||||
if (npc.mNpdt.mWillpower == 0)
|
||||
messages.push_back (std::make_pair (id, npc.mId + " willpower has zero value"));
|
||||
}
|
||||
|
||||
|
@ -706,22 +681,14 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
|
|||
messages.push_back (std::make_pair (id, npc.mId + " has any empty name"));
|
||||
|
||||
if (npc.mClass.empty())
|
||||
{
|
||||
messages.push_back (std::make_pair (id, npc.mId + " has any empty class"));
|
||||
}
|
||||
messages.push_back (std::make_pair (id, npc.mId + " has an empty class"));
|
||||
else if (mClasses.searchId (npc.mClass) == -1)
|
||||
{
|
||||
messages.push_back (std::make_pair (id, npc.mId + " has invalid class"));
|
||||
}
|
||||
|
||||
if (npc.mRace.empty())
|
||||
{
|
||||
messages.push_back (std::make_pair (id, npc.mId + " has any empty race"));
|
||||
}
|
||||
messages.push_back (std::make_pair (id, npc.mId + " has an empty race"));
|
||||
else if (mRaces.searchId (npc.mRace) == -1)
|
||||
{
|
||||
messages.push_back (std::make_pair (id, npc.mId + " has invalid race"));
|
||||
}
|
||||
|
||||
if (disposition < 0)
|
||||
messages.push_back (std::make_pair (id, npc.mId + " has negative disposition"));
|
||||
|
@ -823,7 +790,7 @@ void CSMTools::ReferenceableCheckStage::weaponCheck(
|
|||
{
|
||||
//checking of health
|
||||
if (weapon.mData.mHealth <= 0)
|
||||
messages.push_back (std::make_pair (id, weapon.mId + " has non-positivie health"));
|
||||
messages.push_back (std::make_pair (id, weapon.mId + " has non-positive health"));
|
||||
|
||||
if (weapon.mData.mReach < 0)
|
||||
messages.push_back (std::make_pair (id, weapon.mId + " has negative reach"));
|
||||
|
@ -842,9 +809,7 @@ void CSMTools::ReferenceableCheckStage::probeCheck(
|
|||
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
|
||||
|
||||
if (baseRecord.isDeleted())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const ESM::Probe& probe = (dynamic_cast<const CSMWorld::Record<ESM::Probe>& >(baseRecord)).get();
|
||||
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Probe, probe.mId);
|
||||
|
|
|
@ -27,7 +27,7 @@ void CSMTools::SoundCheckStage::perform (int stage, CSMDoc::Messages& messages)
|
|||
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Sound, sound.mId);
|
||||
|
||||
if (sound.mData.mMinRange>sound.mData.mMaxRange)
|
||||
messages.push_back (std::make_pair (id, "Maximum range larger than minimum range"));
|
||||
messages.push_back (std::make_pair (id, "Minimum range larger than maximum range"));
|
||||
|
||||
/// \todo check, if the sound file exists
|
||||
}
|
||||
|
|
|
@ -61,12 +61,7 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
|
|||
connect (&mVerifier, SIGNAL (reportMessage (const CSMDoc::Message&, int)),
|
||||
this, SLOT (verifierMessage (const CSMDoc::Message&, int)));
|
||||
|
||||
std::vector<std::string> mandatoryIds; // I want C++11, damn it!
|
||||
mandatoryIds.push_back ("Day");
|
||||
mandatoryIds.push_back ("DaysPassed");
|
||||
mandatoryIds.push_back ("GameHour");
|
||||
mandatoryIds.push_back ("Month");
|
||||
mandatoryIds.push_back ("PCRace");
|
||||
std::vector<std::string> mandatoryIds {"Day", "DaysPassed", "GameHour", "Month", "PCRace"};
|
||||
|
||||
mVerifierOperation->appendStage (new MandatoryIdStage (mData.getGlobals(),
|
||||
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds));
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace CSMWorld
|
|||
{ ColumnId_SleepForbidden, "Sleep Forbidden" },
|
||||
{ ColumnId_InteriorWater, "Interior Water" },
|
||||
{ ColumnId_InteriorSky, "Interior Sky" },
|
||||
{ ColumnId_Model, "Model" },
|
||||
{ ColumnId_Model, "Model/Animation" },
|
||||
{ ColumnId_Script, "Script" },
|
||||
{ ColumnId_Icon, "Icon" },
|
||||
{ ColumnId_Weight, "Weight" },
|
||||
|
|
|
@ -962,6 +962,29 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base
|
|||
return mReader->getRecordCount();
|
||||
}
|
||||
|
||||
void CSMWorld::Data::loadFallbackEntries()
|
||||
{
|
||||
// Load default marker definitions, if game files do not have them for some reason
|
||||
std::pair<std::string, std::string> markers[] = {
|
||||
std::make_pair("divinemarker", "marker_divine.nif"),
|
||||
std::make_pair("doormarker", "marker_arrow.nif"),
|
||||
std::make_pair("northmarker", "marker_north.nif"),
|
||||
std::make_pair("templemarker", "marker_temple.nif"),
|
||||
std::make_pair("travelmarker", "marker_travel.nif")
|
||||
};
|
||||
|
||||
for (const std::pair<std::string, std::string> marker : markers)
|
||||
{
|
||||
if (mReferenceables.searchId (marker.first)==-1)
|
||||
{
|
||||
CSMWorld::Record<ESM::Static> record;
|
||||
record.mBase = ESM::Static(marker.first, marker.second);
|
||||
record.mState = CSMWorld::RecordBase::State_BaseOnly;
|
||||
mReferenceables.appendRecord (record, CSMWorld::UniversalId::Type_Static);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
|
||||
{
|
||||
if (!mReader)
|
||||
|
@ -983,6 +1006,9 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
|
|||
mReader = 0;
|
||||
|
||||
mDialogue = 0;
|
||||
|
||||
loadFallbackEntries();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -144,6 +144,8 @@ namespace CSMWorld
|
|||
|
||||
static int count (RecordBase::State state, const CollectionBase& collection);
|
||||
|
||||
void loadFallbackEntries();
|
||||
|
||||
public:
|
||||
|
||||
Data (ToUTF8::FromType encoding, bool fsStrict, const Files::PathContainer& dataPaths,
|
||||
|
|
|
@ -914,7 +914,7 @@ void CSMWorld::NpcAttributesRefIdAdapter::setNestedTable (const RefIdColumn* col
|
|||
ESM::NPC npc = record.get();
|
||||
|
||||
// store the whole struct
|
||||
npc.mNpdt52 =
|
||||
npc.mNpdt =
|
||||
static_cast<const NestedTableWrapper<std::vector<ESM::NPC::NPDTstruct52> > &>(nestedTable).mNestedTable.at(0);
|
||||
|
||||
record.setModified (npc);
|
||||
|
@ -928,7 +928,7 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::NpcAttributesRefIdAdapter::nestedTab
|
|||
|
||||
// return the whole struct
|
||||
std::vector<ESM::NPC::NPDTstruct52> wrap;
|
||||
wrap.push_back(record.get().mNpdt52);
|
||||
wrap.push_back(record.get().mNpdt);
|
||||
// deleted by dtor of NestedTableStoring
|
||||
return new NestedTableWrapper<std::vector<ESM::NPC::NPDTstruct52> >(wrap);
|
||||
}
|
||||
|
@ -939,7 +939,7 @@ QVariant CSMWorld::NpcAttributesRefIdAdapter::getNestedData (const RefIdColumn *
|
|||
const Record<ESM::NPC>& record =
|
||||
static_cast<const Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
|
||||
|
||||
const ESM::NPC::NPDTstruct52& npcStruct = record.get().mNpdt52;
|
||||
const ESM::NPC::NPDTstruct52& npcStruct = record.get().mNpdt;
|
||||
|
||||
if (subColIndex == 0)
|
||||
return subRowIndex;
|
||||
|
@ -966,7 +966,7 @@ void CSMWorld::NpcAttributesRefIdAdapter::setNestedData (const RefIdColumn *colu
|
|||
Record<ESM::NPC>& record =
|
||||
static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Npc)));
|
||||
ESM::NPC npc = record.get();
|
||||
ESM::NPC::NPDTstruct52& npcStruct = npc.mNpdt52;
|
||||
ESM::NPC::NPDTstruct52& npcStruct = npc.mNpdt;
|
||||
|
||||
if (subColIndex == 1)
|
||||
switch(subRowIndex)
|
||||
|
@ -1021,7 +1021,7 @@ void CSMWorld::NpcSkillsRefIdAdapter::setNestedTable (const RefIdColumn* column,
|
|||
ESM::NPC npc = record.get();
|
||||
|
||||
// store the whole struct
|
||||
npc.mNpdt52 =
|
||||
npc.mNpdt =
|
||||
static_cast<const NestedTableWrapper<std::vector<ESM::NPC::NPDTstruct52> > &>(nestedTable).mNestedTable.at(0);
|
||||
|
||||
record.setModified (npc);
|
||||
|
@ -1035,7 +1035,7 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::NpcSkillsRefIdAdapter::nestedTable (
|
|||
|
||||
// return the whole struct
|
||||
std::vector<ESM::NPC::NPDTstruct52> wrap;
|
||||
wrap.push_back(record.get().mNpdt52);
|
||||
wrap.push_back(record.get().mNpdt);
|
||||
// deleted by dtor of NestedTableStoring
|
||||
return new NestedTableWrapper<std::vector<ESM::NPC::NPDTstruct52> >(wrap);
|
||||
}
|
||||
|
@ -1046,7 +1046,7 @@ QVariant CSMWorld::NpcSkillsRefIdAdapter::getNestedData (const RefIdColumn *colu
|
|||
const Record<ESM::NPC>& record =
|
||||
static_cast<const Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc)));
|
||||
|
||||
const ESM::NPC::NPDTstruct52& npcStruct = record.get().mNpdt52;
|
||||
const ESM::NPC::NPDTstruct52& npcStruct = record.get().mNpdt;
|
||||
|
||||
if (subRowIndex < 0 || subRowIndex >= ESM::Skill::Length)
|
||||
throw std::runtime_error ("index out of range");
|
||||
|
@ -1065,7 +1065,7 @@ void CSMWorld::NpcSkillsRefIdAdapter::setNestedData (const RefIdColumn *column,
|
|||
Record<ESM::NPC>& record =
|
||||
static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Npc)));
|
||||
ESM::NPC npc = record.get();
|
||||
ESM::NPC::NPDTstruct52& npcStruct = npc.mNpdt52;
|
||||
ESM::NPC::NPDTstruct52& npcStruct = npc.mNpdt;
|
||||
|
||||
if (subRowIndex < 0 || subRowIndex >= ESM::Skill::Length)
|
||||
throw std::runtime_error ("index out of range");
|
||||
|
@ -1130,30 +1130,30 @@ QVariant CSMWorld::NpcMiscRefIdAdapter::getNestedData (const RefIdColumn *column
|
|||
if (autoCalc)
|
||||
switch (subColIndex)
|
||||
{
|
||||
case 0: return static_cast<int>(record.get().mNpdt12.mLevel);
|
||||
case 0: return static_cast<int>(record.get().mNpdt.mLevel);
|
||||
case 1: return QVariant(QVariant::UserType);
|
||||
case 2: return QVariant(QVariant::UserType);
|
||||
case 3: return QVariant(QVariant::UserType);
|
||||
case 4: return QVariant(QVariant::UserType);
|
||||
case 5: return static_cast<int>(record.get().mNpdt12.mDisposition);
|
||||
case 6: return static_cast<int>(record.get().mNpdt12.mReputation);
|
||||
case 7: return static_cast<int>(record.get().mNpdt12.mRank);
|
||||
case 8: return record.get().mNpdt12.mGold;
|
||||
case 5: return static_cast<int>(record.get().mNpdt.mDisposition);
|
||||
case 6: return static_cast<int>(record.get().mNpdt.mReputation);
|
||||
case 7: return static_cast<int>(record.get().mNpdt.mRank);
|
||||
case 8: return record.get().mNpdt.mGold;
|
||||
case 9: return record.get().mPersistent == true;
|
||||
default: return QVariant(); // throw an exception here?
|
||||
}
|
||||
else
|
||||
switch (subColIndex)
|
||||
{
|
||||
case 0: return static_cast<int>(record.get().mNpdt52.mLevel);
|
||||
case 1: return static_cast<int>(record.get().mNpdt52.mFactionID);
|
||||
case 2: return static_cast<int>(record.get().mNpdt52.mHealth);
|
||||
case 3: return static_cast<int>(record.get().mNpdt52.mMana);
|
||||
case 4: return static_cast<int>(record.get().mNpdt52.mFatigue);
|
||||
case 5: return static_cast<int>(record.get().mNpdt52.mDisposition);
|
||||
case 6: return static_cast<int>(record.get().mNpdt52.mReputation);
|
||||
case 7: return static_cast<int>(record.get().mNpdt52.mRank);
|
||||
case 8: return record.get().mNpdt52.mGold;
|
||||
case 0: return static_cast<int>(record.get().mNpdt.mLevel);
|
||||
case 1: return static_cast<int>(record.get().mNpdt.mFactionID);
|
||||
case 2: return static_cast<int>(record.get().mNpdt.mHealth);
|
||||
case 3: return static_cast<int>(record.get().mNpdt.mMana);
|
||||
case 4: return static_cast<int>(record.get().mNpdt.mFatigue);
|
||||
case 5: return static_cast<int>(record.get().mNpdt.mDisposition);
|
||||
case 6: return static_cast<int>(record.get().mNpdt.mReputation);
|
||||
case 7: return static_cast<int>(record.get().mNpdt.mRank);
|
||||
case 8: return record.get().mNpdt.mGold;
|
||||
case 9: return record.get().mPersistent == true;
|
||||
default: return QVariant(); // throw an exception here?
|
||||
}
|
||||
|
@ -1171,30 +1171,30 @@ void CSMWorld::NpcMiscRefIdAdapter::setNestedData (const RefIdColumn *column,
|
|||
if (autoCalc)
|
||||
switch(subColIndex)
|
||||
{
|
||||
case 0: npc.mNpdt12.mLevel = static_cast<short>(value.toInt()); break;
|
||||
case 0: npc.mNpdt.mLevel = static_cast<short>(value.toInt()); break;
|
||||
case 1: return;
|
||||
case 2: return;
|
||||
case 3: return;
|
||||
case 4: return;
|
||||
case 5: npc.mNpdt12.mDisposition = static_cast<signed char>(value.toInt()); break;
|
||||
case 6: npc.mNpdt12.mReputation = static_cast<signed char>(value.toInt()); break;
|
||||
case 7: npc.mNpdt12.mRank = static_cast<signed char>(value.toInt()); break;
|
||||
case 8: npc.mNpdt12.mGold = value.toInt(); break;
|
||||
case 5: npc.mNpdt.mDisposition = static_cast<signed char>(value.toInt()); break;
|
||||
case 6: npc.mNpdt.mReputation = static_cast<signed char>(value.toInt()); break;
|
||||
case 7: npc.mNpdt.mRank = static_cast<signed char>(value.toInt()); break;
|
||||
case 8: npc.mNpdt.mGold = value.toInt(); break;
|
||||
case 9: npc.mPersistent = value.toBool(); break;
|
||||
default: return; // throw an exception here?
|
||||
}
|
||||
else
|
||||
switch(subColIndex)
|
||||
{
|
||||
case 0: npc.mNpdt52.mLevel = static_cast<short>(value.toInt()); break;
|
||||
case 1: npc.mNpdt52.mFactionID = static_cast<char>(value.toInt()); break;
|
||||
case 2: npc.mNpdt52.mHealth = static_cast<unsigned short>(value.toInt()); break;
|
||||
case 3: npc.mNpdt52.mMana = static_cast<unsigned short>(value.toInt()); break;
|
||||
case 4: npc.mNpdt52.mFatigue = static_cast<unsigned short>(value.toInt()); break;
|
||||
case 5: npc.mNpdt52.mDisposition = static_cast<signed char>(value.toInt()); break;
|
||||
case 6: npc.mNpdt52.mReputation = static_cast<signed char>(value.toInt()); break;
|
||||
case 7: npc.mNpdt52.mRank = static_cast<signed char>(value.toInt()); break;
|
||||
case 8: npc.mNpdt52.mGold = value.toInt(); break;
|
||||
case 0: npc.mNpdt.mLevel = static_cast<short>(value.toInt()); break;
|
||||
case 1: npc.mNpdt.mFactionID = static_cast<char>(value.toInt()); break;
|
||||
case 2: npc.mNpdt.mHealth = static_cast<unsigned short>(value.toInt()); break;
|
||||
case 3: npc.mNpdt.mMana = static_cast<unsigned short>(value.toInt()); break;
|
||||
case 4: npc.mNpdt.mFatigue = static_cast<unsigned short>(value.toInt()); break;
|
||||
case 5: npc.mNpdt.mDisposition = static_cast<signed char>(value.toInt()); break;
|
||||
case 6: npc.mNpdt.mReputation = static_cast<signed char>(value.toInt()); break;
|
||||
case 7: npc.mNpdt.mRank = static_cast<signed char>(value.toInt()); break;
|
||||
case 8: npc.mNpdt.mGold = value.toInt(); break;
|
||||
case 9: npc.mPersistent = value.toBool(); break;
|
||||
default: return; // throw an exception here?
|
||||
}
|
||||
|
|
|
@ -64,21 +64,21 @@ namespace
|
|||
|
||||
static const TypeData sIdArg[] =
|
||||
{
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable", ":./globvar.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting", ":./GMST.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable", ":./global-variable.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting", ":./gmst.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill", ":./skill.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Class, "Class", ":./class.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Faction, "Faction", ":./faction.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Race, "Race", ":./race.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Sound, "Sound", ":./sound.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Script, "Script", ":./script.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Region, "Region", ":./land.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Region, "Region", ":./region.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Birthsign, "Birthsign", ":./birthsign.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell", ":./spell.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Topic, "Topic", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Journal, "Journal", 0 },
|
||||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_TopicInfo, "TopicInfo", 0 },
|
||||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_JournalInfo, "JournalInfo", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Topic, "Topic", ":./dialogue-topics.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Journal, "Journal", ":./journal-topics.png" },
|
||||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_TopicInfo, "TopicInfo", ":./dialogue-topic-infos.png" },
|
||||
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_JournalInfo, "JournalInfo", ":./journal-topic-infos.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell, "Cell", ":./cell.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell_Missing, "Cell", ":./cell.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Referenceable, "Object", 0 },
|
||||
|
@ -93,7 +93,7 @@ namespace
|
|||
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Door, "Door", ":./door.png" },
|
||||
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Ingredient, "Ingredient", ":./ingredient.png" },
|
||||
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_CreatureLevelledList,
|
||||
"Creature Levelled List", ":./creature.png" },
|
||||
"Creature Levelled List", ":./leveled-creature.png" },
|
||||
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_ItemLevelledList,
|
||||
"Item Levelled List", ":./leveled-item.png" },
|
||||
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Light, "Light", ":./light.png" },
|
||||
|
@ -109,20 +109,20 @@ namespace
|
|||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" },
|
||||
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Preview, "Preview", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Enchantment, "Enchantment", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_BodyPart, "Body Part", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Mesh, "Mesh", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Icon, "Icon", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Music, "Music", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_SoundRes, "Sound File", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Texture, "Texture", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Video, "Video", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Enchantment, "Enchantment", ":./enchantment.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_BodyPart, "Body Part", ":./body-part.png" },
|
||||
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Mesh, "Mesh", ":resources-mesh"},
|
||||
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Icon, "Icon", ":resources-icon"},
|
||||
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Music, "Music", ":resources-music" },
|
||||
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_SoundRes, "Sound File", ":resources-sound" },
|
||||
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Texture, "Texture", ":resources-texture"},
|
||||
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Video, "Video", ":resources-video"},
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_DebugProfile, "Debug Profile", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_SoundGen, "Sound Generator", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_MagicEffect, "Magic Effect", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Land, "Land", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_LandTexture, "LandTexture", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Pathgrid, "Pathgrid", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_SoundGen, "Sound Generator", ":./sound-generator.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_MagicEffect, "Magic Effect", ":./magic-effect.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Land, "Land", ":./land-heightmap.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_LandTexture, "LandTexture", ":./land-texture.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Pathgrid, "Pathgrid", ":./pathgrid.png" },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_StartScript, "Start Script", 0 },
|
||||
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_MetaData, "Meta Data", 0 },
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ osg::Vec3f CSVRender::InstanceMode::getScreenCoords(const osg::Vec3f& pos)
|
|||
}
|
||||
|
||||
CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent)
|
||||
: EditMode (worldspaceWidget, QIcon (":placeholder"), Mask_Reference | Mask_Terrain, "Instance editing",
|
||||
: EditMode (worldspaceWidget, QIcon (":scenetoolbar/editing-instance"), Mask_Reference | Mask_Terrain, "Instance editing",
|
||||
parent), mSubMode (0), mSubModeId ("move"), mSelectionMode (0), mDragMode (DragMode_None),
|
||||
mDragAxis (-1), mLocked (false), mUnitScaleDist(1)
|
||||
{
|
||||
|
@ -104,14 +104,14 @@ void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar)
|
|||
{
|
||||
mSubMode = new CSVWidget::SceneToolMode (toolbar, "Edit Sub-Mode");
|
||||
mSubMode->addButton (new InstanceMoveMode (this), "move");
|
||||
mSubMode->addButton (":placeholder", "rotate",
|
||||
mSubMode->addButton (":scenetoolbar/transform-rotate", "rotate",
|
||||
"Rotate selected instances"
|
||||
"<ul><li>Use {scene-edit-primary} to rotate instances freely</li>"
|
||||
"<li>Use {scene-edit-secondary} to rotate instances within the grid</li>"
|
||||
"<li>The center of the view acts as the axis of rotation</li>"
|
||||
"</ul>"
|
||||
"<font color=Red>Grid rotate not implemented yet</font color>");
|
||||
mSubMode->addButton (":placeholder", "scale",
|
||||
mSubMode->addButton (":scenetoolbar/transform-scale", "scale",
|
||||
"Scale selected instances"
|
||||
"<ul><li>Use {scene-edit-primary} to scale instances freely</li>"
|
||||
"<li>Use {scene-edit-secondary} to scale instances along the grid</li>"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "instancemovemode.hpp"
|
||||
|
||||
CSVRender::InstanceMoveMode::InstanceMoveMode (QWidget *parent)
|
||||
: ModeButton (QIcon (QPixmap (":placeholder")),
|
||||
: ModeButton (QIcon (QPixmap (":scenetoolbar/transform-move")),
|
||||
"Move selected instances"
|
||||
"<ul><li>Use {scene-edit-primary} to move instances around freely</li>"
|
||||
"<li>Use {scene-edit-secondary} to move instances around within the grid</li>"
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace CSVRender
|
|||
, mWorldspaceWidget(worldspaceWidget)
|
||||
, mInteractionMask(interactionMask)
|
||||
{
|
||||
addButton(":placeholder", "cube-centre",
|
||||
addButton(":scenetoolbar/selection-mode-cube", "cube-centre",
|
||||
"Centred cube"
|
||||
"<ul><li>Drag with {scene-select-primary} (make instances the selection) or {scene-select-secondary} "
|
||||
"(invert selection state) from the centre of the selection cube outwards</li>"
|
||||
|
@ -22,7 +22,7 @@ namespace CSVRender
|
|||
"starting on an instance will have the same effect</li>"
|
||||
"</ul>"
|
||||
"<font color=Red>Not implemented yet</font color>");
|
||||
addButton(":placeholder", "cube-corner",
|
||||
addButton(":scenetoolbar/selection-mode-cube-corner", "cube-corner",
|
||||
"Cube corner to corner"
|
||||
"<ul><li>Drag with {scene-select-primary} (make instances the selection) or {scene-select-secondary} "
|
||||
"(invert selection state) from one corner of the selection cube to the opposite corner</li>"
|
||||
|
@ -31,7 +31,7 @@ namespace CSVRender
|
|||
"starting on an instance will have the same effect</li>"
|
||||
"</ul>"
|
||||
"<font color=Red>Not implemented yet</font color>");
|
||||
addButton(":placeholder", "sphere",
|
||||
addButton(":scenetoolbar/selection-mode-cube-sphere", "sphere",
|
||||
"Centred sphere"
|
||||
"<ul><li>Drag with {scene-select-primary} (make instances the selection) or {scene-select-secondary} "
|
||||
"(invert selection state) from the centre of the selection sphere outwards</li>"
|
||||
|
|
|
@ -156,6 +156,7 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
|
|||
setSelectionMode (QAbstractItemView::ExtendedSelection);
|
||||
|
||||
mProxyModel = new QSortFilterProxyModel (this);
|
||||
mProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
|
||||
mProxyModel->setSourceModel (mModel);
|
||||
mProxyModel->setSortRole(Qt::UserRole);
|
||||
|
||||
|
|
|
@ -57,12 +57,12 @@ CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id,
|
|||
|
||||
// left section
|
||||
mPrevButton = new QToolButton (this);
|
||||
mPrevButton->setIcon(QIcon(":/go-previous.png"));
|
||||
mPrevButton->setIcon(QIcon(":record-previous"));
|
||||
mPrevButton->setToolTip ("Switch to previous record");
|
||||
buttonsLayout->addWidget (mPrevButton, 0);
|
||||
|
||||
mNextButton = new QToolButton (this);
|
||||
mNextButton->setIcon(QIcon(":/go-next.png"));
|
||||
mNextButton->setIcon(QIcon(":/record-next"));
|
||||
mNextButton->setToolTip ("Switch to next record");
|
||||
buttonsLayout->addWidget (mNextButton, 1);
|
||||
|
||||
|
@ -72,7 +72,7 @@ CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id,
|
|||
if (mTable.getFeatures() & CSMWorld::IdTable::Feature_Preview)
|
||||
{
|
||||
QToolButton* previewButton = new QToolButton (this);
|
||||
previewButton->setIcon(QIcon(":/edit-preview.png"));
|
||||
previewButton->setIcon(QIcon(":edit-preview"));
|
||||
previewButton->setToolTip ("Open a preview of this record");
|
||||
buttonsLayout->addWidget(previewButton);
|
||||
connect (previewButton, SIGNAL(clicked()), this, SIGNAL (showPreview()));
|
||||
|
@ -89,22 +89,22 @@ CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id,
|
|||
|
||||
// right section
|
||||
mCloneButton = new QToolButton (this);
|
||||
mCloneButton->setIcon(QIcon(":/edit-clone.png"));
|
||||
mCloneButton->setIcon(QIcon(":edit-clone"));
|
||||
mCloneButton->setToolTip ("Clone record");
|
||||
buttonsLayout->addWidget(mCloneButton);
|
||||
|
||||
mAddButton = new QToolButton (this);
|
||||
mAddButton->setIcon(QIcon(":/add.png"));
|
||||
mAddButton->setIcon(QIcon(":edit-add"));
|
||||
mAddButton->setToolTip ("Add new record");
|
||||
buttonsLayout->addWidget(mAddButton);
|
||||
|
||||
mDeleteButton = new QToolButton (this);
|
||||
mDeleteButton->setIcon(QIcon(":/edit-delete.png"));
|
||||
mDeleteButton->setIcon(QIcon(":edit-delete"));
|
||||
mDeleteButton->setToolTip ("Delete record");
|
||||
buttonsLayout->addWidget(mDeleteButton);
|
||||
|
||||
mRevertButton = new QToolButton (this);
|
||||
mRevertButton->setIcon(QIcon(":/edit-undo.png"));
|
||||
mRevertButton->setIcon(QIcon(":edit-undo"));
|
||||
mRevertButton->setToolTip ("Revert record");
|
||||
buttonsLayout->addWidget(mRevertButton);
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ CSVWorld::RecordStatusDelegateFactory::RecordStatusDelegateFactory()
|
|||
|
||||
static const char *sIcons[] =
|
||||
{
|
||||
":./base.png", ":./modified.png", ":./added.png", ":./removed.png", ":./removed.png", 0
|
||||
":list-base", ":list-modified", ":list-added", ":list-removed", ":list-removed", 0
|
||||
};
|
||||
|
||||
for (int i=0; sIcons[i]; ++i)
|
||||
|
|
|
@ -764,10 +764,8 @@ std::vector< CSMWorld::UniversalId > CSVWorld::Table::getDraggedRecords() const
|
|||
QModelIndexList selectedRows = selectionModel()->selectedRows();
|
||||
std::vector<CSMWorld::UniversalId> idToDrag;
|
||||
|
||||
foreach (QModelIndex it, selectedRows) //I had a dream. Dream where you could use C++11 in OpenMW.
|
||||
{
|
||||
for (QModelIndex& it : selectedRows)
|
||||
idToDrag.push_back (getUniversalId (it.row()));
|
||||
}
|
||||
|
||||
return idToDrag;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "Cell.hpp"
|
||||
#include "CellController.hpp"
|
||||
#include "Player.hpp"
|
||||
#include "Players.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -32,6 +33,9 @@ void Actor::Init(LuaState &lua)
|
|||
"getCell", &NetActor::getCell,
|
||||
"getInventory", &NetActor::getInventory,
|
||||
|
||||
"followPlayer", &Actor::followPlayer,
|
||||
"followActor", &Actor::followActor,
|
||||
|
||||
"refId", sol::property(&Actor::getRefId, &Actor::setRefId),
|
||||
"refNumIndex", sol::property(&Actor::getRefNumIndex, &Actor::setRefNumIndex),
|
||||
"mpNum", sol::property(&Actor::getMpNum, &Actor::setMpNum)
|
||||
|
@ -44,6 +48,32 @@ Actor::Actor() : NetActor()
|
|||
|
||||
}
|
||||
|
||||
void Actor::followPlayer(int pid)
|
||||
{
|
||||
actor->aiAction = mwmp::BaseActor::AIAction::Follow;
|
||||
|
||||
actor->hasAiTarget = true;
|
||||
actor->aiTarget.isPlayer = true;
|
||||
|
||||
auto player = Players::getPlayerByPID(pid).get();
|
||||
actor->aiTarget.guid = player->guid;
|
||||
|
||||
aiChanged = true;
|
||||
}
|
||||
|
||||
void Actor::followActor(unsigned int refNumIndex, unsigned int mpNum)
|
||||
{
|
||||
actor->aiAction = mwmp::BaseActor::AIAction::Follow;
|
||||
|
||||
actor->hasAiTarget = true;
|
||||
actor->aiTarget.isPlayer = false;
|
||||
|
||||
actor->aiTarget.refNumIndex = refNumIndex;
|
||||
actor->aiTarget.mpNum = mpNum;
|
||||
|
||||
aiChanged = true;
|
||||
}
|
||||
|
||||
std::string Actor::getRefId() const
|
||||
{
|
||||
return actor->refId;
|
||||
|
@ -141,6 +171,7 @@ void ActorController::sendActors(std::shared_ptr<Player> player, std::vector<std
|
|||
bool skillsChanged = false;
|
||||
bool baseInfoChanged = false;*/
|
||||
bool equipmentChanged = false;
|
||||
bool aiChanged = false;
|
||||
bool changedCell = false;
|
||||
|
||||
actorList.baseActors.clear();
|
||||
|
@ -152,6 +183,8 @@ void ActorController::sendActors(std::shared_ptr<Player> player, std::vector<std
|
|||
positionChanged = true;
|
||||
if (actor->statsChanged)
|
||||
statsChanged = true;
|
||||
if (actor->aiChanged)
|
||||
aiChanged = true;
|
||||
/*if (actor->attributesChanged)
|
||||
attributesChanged = true;
|
||||
if (actor->skillsChanged)
|
||||
|
@ -223,6 +256,15 @@ void ActorController::sendActors(std::shared_ptr<Player> player, std::vector<std
|
|||
if (sendToAll)
|
||||
serverCell->sendToLoaded(packet, &actorList);
|
||||
}
|
||||
if (aiChanged)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_AI);
|
||||
packet->setActorList(&actorList);
|
||||
packet->Send(actorList.guid);
|
||||
|
||||
if (sendToAll)
|
||||
serverCell->sendToLoaded(packet, &actorList);
|
||||
}
|
||||
if (changedCell)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_CELL_CHANGE);
|
||||
|
|
|
@ -25,6 +25,10 @@ public:
|
|||
void setRefNumIndex(unsigned refNumIndex);
|
||||
unsigned getMpNum() const;
|
||||
void setMpNum(unsigned mpNum);
|
||||
|
||||
void followPlayer(int pid);
|
||||
void followActor(unsigned int refNumIndex, unsigned int mpNum);
|
||||
|
||||
bool doesHavePosition() const; // ????
|
||||
bool doesHaveStatsDynamic() const; // ????
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ public:
|
|||
bool isPlayer() const { return isActorPlayer; }
|
||||
Player *toPlayer();
|
||||
protected:
|
||||
bool baseInfoChanged, shapeshiftChanged, levelChanged, statsChanged, positionChanged, momentumChanged, attributesChanged, skillsChanged;
|
||||
bool baseInfoChanged, shapeshiftChanged, levelChanged, statsChanged, positionChanged, momentumChanged, attributesChanged, skillsChanged, aiChanged;
|
||||
|
||||
mwmp::BasePlayer *basePlayer;
|
||||
mwmp::BaseNetCreature *netCreature;
|
||||
|
|
|
@ -327,40 +327,40 @@ namespace MWClass
|
|||
int gold=0;
|
||||
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
||||
{
|
||||
gold = ref->mBase->mNpdt52.mGold;
|
||||
gold = ref->mBase->mNpdt.mGold;
|
||||
|
||||
for (unsigned int i=0; i< ESM::Skill::Length; ++i)
|
||||
data->mNpcStats.getSkill (i).setBase (ref->mBase->mNpdt52.mSkills[i]);
|
||||
data->mNpcStats.getSkill (i).setBase (ref->mBase->mNpdt.mSkills[i]);
|
||||
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Strength, ref->mBase->mNpdt52.mStrength);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Intelligence, ref->mBase->mNpdt52.mIntelligence);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Willpower, ref->mBase->mNpdt52.mWillpower);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Agility, ref->mBase->mNpdt52.mAgility);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Speed, ref->mBase->mNpdt52.mSpeed);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Endurance, ref->mBase->mNpdt52.mEndurance);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Personality, ref->mBase->mNpdt52.mPersonality);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Luck, ref->mBase->mNpdt52.mLuck);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Strength, ref->mBase->mNpdt.mStrength);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Intelligence, ref->mBase->mNpdt.mIntelligence);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Willpower, ref->mBase->mNpdt.mWillpower);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Agility, ref->mBase->mNpdt.mAgility);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Speed, ref->mBase->mNpdt.mSpeed);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Endurance, ref->mBase->mNpdt.mEndurance);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Personality, ref->mBase->mNpdt.mPersonality);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Luck, ref->mBase->mNpdt.mLuck);
|
||||
|
||||
data->mNpcStats.setHealth (ref->mBase->mNpdt52.mHealth);
|
||||
data->mNpcStats.setMagicka (ref->mBase->mNpdt52.mMana);
|
||||
data->mNpcStats.setFatigue (ref->mBase->mNpdt52.mFatigue);
|
||||
data->mNpcStats.setHealth (ref->mBase->mNpdt.mHealth);
|
||||
data->mNpcStats.setMagicka (ref->mBase->mNpdt.mMana);
|
||||
data->mNpcStats.setFatigue (ref->mBase->mNpdt.mFatigue);
|
||||
|
||||
data->mNpcStats.setLevel(ref->mBase->mNpdt52.mLevel);
|
||||
data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt52.mDisposition);
|
||||
data->mNpcStats.setReputation(ref->mBase->mNpdt52.mReputation);
|
||||
data->mNpcStats.setLevel(ref->mBase->mNpdt.mLevel);
|
||||
data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt.mDisposition);
|
||||
data->mNpcStats.setReputation(ref->mBase->mNpdt.mReputation);
|
||||
|
||||
data->mNpcStats.setNeedRecalcDynamicStats(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
gold = ref->mBase->mNpdt12.mGold;
|
||||
gold = ref->mBase->mNpdt.mGold;
|
||||
|
||||
for (int i=0; i<3; ++i)
|
||||
data->mNpcStats.setDynamic (i, 10);
|
||||
|
||||
data->mNpcStats.setLevel(ref->mBase->mNpdt12.mLevel);
|
||||
data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt12.mDisposition);
|
||||
data->mNpcStats.setReputation(ref->mBase->mNpdt12.mReputation);
|
||||
data->mNpcStats.setLevel(ref->mBase->mNpdt.mLevel);
|
||||
data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt.mDisposition);
|
||||
data->mNpcStats.setReputation(ref->mBase->mNpdt.mReputation);
|
||||
|
||||
autoCalculateAttributes(ref->mBase, data->mNpcStats);
|
||||
autoCalculateSkills(ref->mBase, data->mNpcStats, ptr);
|
||||
|
@ -1476,10 +1476,7 @@ namespace MWClass
|
|||
int Npc::getBaseGold(const MWWorld::ConstPtr& ptr) const
|
||||
{
|
||||
const MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
||||
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
||||
return ref->mBase->mNpdt52.mGold;
|
||||
else
|
||||
return ref->mBase->mNpdt12.mGold;
|
||||
return ref->mBase->mNpdt.mGold;
|
||||
}
|
||||
|
||||
bool Npc::isClass(const MWWorld::ConstPtr& ptr, const std::string &className) const
|
||||
|
|
|
@ -426,7 +426,18 @@ namespace MWGui
|
|||
}
|
||||
else
|
||||
{
|
||||
setTitle("#{sConsoleTitle} (" + object.getCellRef().getRefId() + ")");
|
||||
/*
|
||||
Start of tes3mp change (major)
|
||||
|
||||
Display the selected object's refNumIndex and mpNum alongside its refId in the
|
||||
title of the console window, for easier debugging of almost everything
|
||||
*/
|
||||
setTitle("#{sConsoleTitle} (" + object.getCellRef().getRefId() + ", " +
|
||||
std::to_string(object.getCellRef().getRefNum().mIndex) + ", " +
|
||||
std::to_string(object.getCellRef().getMpNum()) + ")");
|
||||
/*
|
||||
End of tes3mp change (major)
|
||||
*/
|
||||
mPtr = object;
|
||||
}
|
||||
// User clicked on an object. Restore focus to the console command line.
|
||||
|
|
|
@ -92,21 +92,21 @@ namespace MWMechanics
|
|||
const ESM::NPC *player = ptr.get<ESM::NPC>()->mBase;
|
||||
|
||||
// reset
|
||||
creatureStats.setLevel(player->mNpdt52.mLevel);
|
||||
creatureStats.setLevel(player->mNpdt.mLevel);
|
||||
creatureStats.getSpells().clear();
|
||||
creatureStats.modifyMagicEffects(MagicEffects());
|
||||
|
||||
for (int i=0; i<27; ++i)
|
||||
npcStats.getSkill (i).setBase (player->mNpdt52.mSkills[i]);
|
||||
npcStats.getSkill (i).setBase (player->mNpdt.mSkills[i]);
|
||||
|
||||
creatureStats.setAttribute(ESM::Attribute::Strength, player->mNpdt52.mStrength);
|
||||
creatureStats.setAttribute(ESM::Attribute::Intelligence, player->mNpdt52.mIntelligence);
|
||||
creatureStats.setAttribute(ESM::Attribute::Willpower, player->mNpdt52.mWillpower);
|
||||
creatureStats.setAttribute(ESM::Attribute::Agility, player->mNpdt52.mAgility);
|
||||
creatureStats.setAttribute(ESM::Attribute::Speed, player->mNpdt52.mSpeed);
|
||||
creatureStats.setAttribute(ESM::Attribute::Endurance, player->mNpdt52.mEndurance);
|
||||
creatureStats.setAttribute(ESM::Attribute::Personality, player->mNpdt52.mPersonality);
|
||||
creatureStats.setAttribute(ESM::Attribute::Luck, player->mNpdt52.mLuck);
|
||||
creatureStats.setAttribute(ESM::Attribute::Strength, player->mNpdt.mStrength);
|
||||
creatureStats.setAttribute(ESM::Attribute::Intelligence, player->mNpdt.mIntelligence);
|
||||
creatureStats.setAttribute(ESM::Attribute::Willpower, player->mNpdt.mWillpower);
|
||||
creatureStats.setAttribute(ESM::Attribute::Agility, player->mNpdt.mAgility);
|
||||
creatureStats.setAttribute(ESM::Attribute::Speed, player->mNpdt.mSpeed);
|
||||
creatureStats.setAttribute(ESM::Attribute::Endurance, player->mNpdt.mEndurance);
|
||||
creatureStats.setAttribute(ESM::Attribute::Personality, player->mNpdt.mPersonality);
|
||||
creatureStats.setAttribute(ESM::Attribute::Luck, player->mNpdt.mLuck);
|
||||
const MWWorld::ESMStore &esmStore =
|
||||
MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
|
|
|
@ -239,6 +239,24 @@ void Cell::readSpeech(ActorList& actorList)
|
|||
}
|
||||
}
|
||||
|
||||
void Cell::readAI(ActorList& actorList)
|
||||
{
|
||||
initializeDedicatedActors(actorList);
|
||||
|
||||
for (const auto &baseActor : actorList.baseActors)
|
||||
{
|
||||
std::string mapIndex = Main::get().getCellController()->generateMapIndex(baseActor);
|
||||
|
||||
if (dedicatedActors.count(mapIndex) > 0)
|
||||
{
|
||||
DedicatedActor *actor = dedicatedActors[mapIndex];
|
||||
actor->aiAction = baseActor->aiAction;
|
||||
actor->aiTarget = baseActor->aiTarget;
|
||||
actor->setAI();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cell::readAttack(ActorList& actorList)
|
||||
{
|
||||
for (const auto &baseActor : actorList.baseActors)
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace mwmp
|
|||
void readStatsDynamic(ActorList& actorList);
|
||||
void readEquipment(ActorList& actorList);
|
||||
void readSpeech(ActorList& actorList);
|
||||
void readAI(ActorList& actorList);
|
||||
void readAttack(ActorList& actorList);
|
||||
void readCellChange(ActorList& actorList);
|
||||
|
||||
|
|
|
@ -154,6 +154,17 @@ void CellController::readSpeech(ActorList& actorList)
|
|||
cellsInitialized[mapIndex]->readSpeech(actorList);
|
||||
}
|
||||
|
||||
void CellController::readAI(ActorList& actorList)
|
||||
{
|
||||
std::string mapIndex = actorList.cell.getDescription();
|
||||
|
||||
initializeCell(actorList.cell);
|
||||
|
||||
// If this now exists, send it the data
|
||||
if (cellsInitialized.count(mapIndex) > 0)
|
||||
cellsInitialized[mapIndex]->readAI(actorList);
|
||||
}
|
||||
|
||||
void CellController::readAttack(ActorList& actorList)
|
||||
{
|
||||
std::string mapIndex = actorList.cell.getDescription();
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace mwmp
|
|||
void readStatsDynamic(mwmp::ActorList& actorList);
|
||||
void readEquipment(mwmp::ActorList& actorList);
|
||||
void readSpeech(mwmp::ActorList& actorList);
|
||||
void readAI(mwmp::ActorList& actorList);
|
||||
void readAttack(mwmp::ActorList& actorList);
|
||||
void readCellChange(mwmp::ActorList& actorList);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "../mwdialogue/dialoguemanagerimp.hpp"
|
||||
|
||||
#include "../mwmechanics/aifollow.hpp"
|
||||
#include "../mwmechanics/creaturestats.hpp"
|
||||
#include "../mwmechanics/mechanicsmanagerimp.hpp"
|
||||
#include "../mwmechanics/movement.hpp"
|
||||
|
@ -206,6 +207,41 @@ void DedicatedActor::setEquipment()
|
|||
}
|
||||
}
|
||||
|
||||
void DedicatedActor::setAI()
|
||||
{
|
||||
if (hasAiTarget)
|
||||
{
|
||||
MWWorld::Ptr targetPtr;
|
||||
|
||||
if (aiTarget.isPlayer)
|
||||
targetPtr = MechanicsHelper::getPlayerPtr(aiTarget);
|
||||
else
|
||||
{
|
||||
if (mwmp::Main::get().getCellController()->isLocalActor(aiTarget.refNumIndex, aiTarget.mpNum))
|
||||
targetPtr = mwmp::Main::get().getCellController()->getLocalActor(aiTarget.refNumIndex, aiTarget.mpNum)->getPtr();
|
||||
else if (mwmp::Main::get().getCellController()->isDedicatedActor(aiTarget.refNumIndex, aiTarget.mpNum))
|
||||
targetPtr = mwmp::Main::get().getCellController()->getDedicatedActor(aiTarget.refNumIndex, aiTarget.mpNum)->getPtr();
|
||||
else
|
||||
LOG_APPEND(Log::LOG_VERBOSE, "-- DedicatedActor %s %i-%i has invalid target AI target %i-%i",
|
||||
ptr.getCellRef().getRefId().c_str(), ptr.getCellRef().getRefNum().mIndex, ptr.getCellRef().getMpNum(),
|
||||
aiTarget.refNumIndex, aiTarget.mpNum);
|
||||
}
|
||||
|
||||
if (targetPtr)
|
||||
{
|
||||
LOG_APPEND(Log::LOG_VERBOSE, "-- DedicatedActor %s %i-%i has AI target %s %i-%i",
|
||||
ptr.getCellRef().getRefId().c_str(), ptr.getCellRef().getRefNum().mIndex, ptr.getCellRef().getMpNum(),
|
||||
targetPtr.getCellRef().getRefId().c_str(), aiTarget.refNumIndex, aiTarget.mpNum);
|
||||
|
||||
if (aiAction == mwmp::BaseActor::AIAction::Follow)
|
||||
{
|
||||
MWMechanics::AiFollow package(targetPtr.getCellRef().getRefId());
|
||||
ptr.getClass().getCreatureStats(ptr).getAiSequence().stack(package, ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DedicatedActor::playAnimation()
|
||||
{
|
||||
if (!animation.groupname.empty())
|
||||
|
|
|
@ -22,6 +22,7 @@ namespace mwmp
|
|||
void setAnimFlags();
|
||||
void setStatsDynamic();
|
||||
void setEquipment();
|
||||
void setAI();
|
||||
void playAnimation();
|
||||
void playSound();
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace mwmp
|
|||
|
||||
virtual void Do(ActorPacket &packet, ActorList &actorList)
|
||||
{
|
||||
//Main::get().getCellController()->readAI(actorList);
|
||||
Main::get().getCellController()->readAI(actorList);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
MWState::QuickSaveManager::QuickSaveManager(std::string &saveName, unsigned int maxSaves)
|
||||
: mSaveName(saveName)
|
||||
, mMaxSaves(maxSaves)
|
||||
, mOldestSlotVisited(NULL)
|
||||
, mSlotsVisited(0)
|
||||
, mOldestSlotVisited(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ void ESMStore::setUp()
|
|||
mMagicEffects.setUp();
|
||||
mAttributes.setUp();
|
||||
mDialogs.setUp();
|
||||
mStatics.setUp();
|
||||
}
|
||||
|
||||
int ESMStore::countSavedGameRecords() const
|
||||
|
|
|
@ -1053,6 +1053,32 @@ namespace MWWorld
|
|||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void Store<ESM::Static>::setUp()
|
||||
{
|
||||
// Load default marker definitions, if game files do not have them for some reason
|
||||
std::pair<std::string, std::string> markers[] = {
|
||||
std::make_pair("divinemarker", "marker_divine.nif"),
|
||||
std::make_pair("doormarker", "marker_arrow.nif"),
|
||||
std::make_pair("northmarker", "marker_north.nif"),
|
||||
std::make_pair("templemarker", "marker_temple.nif"),
|
||||
std::make_pair("travelmarker", "marker_travel.nif")
|
||||
};
|
||||
|
||||
for (const std::pair<std::string, std::string> marker : markers)
|
||||
{
|
||||
if (search(marker.first) == 0)
|
||||
{
|
||||
ESM::Static newMarker = ESM::Static(marker.first, marker.second);
|
||||
std::pair<typename Static::iterator, bool> ret = mStatic.insert(std::make_pair(marker.first, newMarker));
|
||||
if (ret.first != mStatic.end())
|
||||
{
|
||||
mShared.push_back(&ret.first->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
inline RecordId Store<ESM::Dialogue>::load(ESM::ESMReader &esm) {
|
||||
// The original letter case of a dialogue ID is saved, because it's printed
|
||||
|
|
|
@ -66,10 +66,8 @@ TEST(EsmFixedString, struct_size)
|
|||
|
||||
TEST(EsmFixedString, DISABLED_is_pod)
|
||||
{
|
||||
/* TODO: enable in C++11
|
||||
* ASSERT_TRUE(std::is_pod<ESM::NAME>::value);
|
||||
* ASSERT_TRUE(std::is_pod<ESM::NAME32>::value);
|
||||
* ASSERT_TRUE(std::is_pod<ESM::NAME64>::value);
|
||||
* ASSERT_TRUE(std::is_pod<ESM::NAME256>::value);
|
||||
*/
|
||||
ASSERT_TRUE(std::is_pod<ESM::NAME>::value);
|
||||
ASSERT_TRUE(std::is_pod<ESM::NAME32>::value);
|
||||
ASSERT_TRUE(std::is_pod<ESM::NAME64>::value);
|
||||
ASSERT_TRUE(std::is_pod<ESM::NAME256>::value);
|
||||
}
|
||||
|
|
|
@ -512,7 +512,9 @@ void ContentSelectorModel::ContentModel::sortFiles()
|
|||
//dependencies appear.
|
||||
for (int j = i + 1; j < fileCount; j++)
|
||||
{
|
||||
if (gamefiles.contains(mFiles.at(j)->fileName(), Qt::CaseInsensitive))
|
||||
if (gamefiles.contains(mFiles.at(j)->fileName(), Qt::CaseInsensitive)
|
||||
|| (!mFiles.at(i)->isGameFile() && gamefiles.isEmpty()
|
||||
&& mFiles.at(j)->fileName().compare("Morrowind.esm", Qt::CaseInsensitive) == 0)) // Hack: implicit dependency on Morrowind.esm for dependency-less files
|
||||
{
|
||||
mFiles.move(j, i);
|
||||
|
||||
|
|
|
@ -62,12 +62,23 @@ namespace ESM
|
|||
if (esm.getSubSize() == 52)
|
||||
{
|
||||
mNpdtType = NPC_DEFAULT;
|
||||
esm.getExact(&mNpdt52, 52);
|
||||
esm.getExact(&mNpdt, 52);
|
||||
}
|
||||
else if (esm.getSubSize() == 12)
|
||||
{
|
||||
//Reading into temporary NPDTstruct12 object
|
||||
NPDTstruct12 npdt12;
|
||||
mNpdtType = NPC_WITH_AUTOCALCULATED_STATS;
|
||||
esm.getExact(&mNpdt12, 12);
|
||||
esm.getExact(&npdt12, 12);
|
||||
|
||||
//Clearing the mNdpt struct to initialize all values
|
||||
blankNpdt();
|
||||
//Swiching to an internal representation
|
||||
mNpdt.mLevel = npdt12.mLevel;
|
||||
mNpdt.mDisposition = npdt12.mDisposition;
|
||||
mNpdt.mReputation = npdt12.mReputation;
|
||||
mNpdt.mRank = npdt12.mRank;
|
||||
mNpdt.mGold = npdt12.mGold;
|
||||
}
|
||||
else
|
||||
esm.fail("NPC_NPDT must be 12 or 52 bytes long");
|
||||
|
@ -135,9 +146,19 @@ namespace ESM
|
|||
esm.writeHNOCString("SCRI", mScript);
|
||||
|
||||
if (mNpdtType == NPC_DEFAULT)
|
||||
esm.writeHNT("NPDT", mNpdt52, 52);
|
||||
{
|
||||
esm.writeHNT("NPDT", mNpdt, 52);
|
||||
}
|
||||
else if (mNpdtType == NPC_WITH_AUTOCALCULATED_STATS)
|
||||
esm.writeHNT("NPDT", mNpdt12, 12);
|
||||
{
|
||||
NPDTstruct12 npdt12;
|
||||
npdt12.mLevel = mNpdt.mLevel;
|
||||
npdt12.mDisposition = mNpdt.mDisposition;
|
||||
npdt12.mReputation = mNpdt.mReputation;
|
||||
npdt12.mRank = mNpdt.mRank;
|
||||
npdt12.mGold = mNpdt.mGold;
|
||||
esm.writeHNT("NPDT", npdt12, 12);
|
||||
}
|
||||
|
||||
esm.writeHNT("FLAG", mFlags);
|
||||
|
||||
|
@ -171,25 +192,7 @@ namespace ESM
|
|||
void NPC::blank()
|
||||
{
|
||||
mNpdtType = NPC_DEFAULT;
|
||||
mNpdt52.mLevel = 0;
|
||||
mNpdt52.mStrength = mNpdt52.mIntelligence = mNpdt52.mWillpower = mNpdt52.mAgility =
|
||||
mNpdt52.mSpeed = mNpdt52.mEndurance = mNpdt52.mPersonality = mNpdt52.mLuck = 0;
|
||||
for (int i=0; i< Skill::Length; ++i) mNpdt52.mSkills[i] = 0;
|
||||
mNpdt52.mReputation = 0;
|
||||
mNpdt52.mHealth = mNpdt52.mMana = mNpdt52.mFatigue = 0;
|
||||
mNpdt52.mDisposition = 0;
|
||||
mNpdt52.mFactionID = 0;
|
||||
mNpdt52.mRank = 0;
|
||||
mNpdt52.mUnknown = 0;
|
||||
mNpdt52.mGold = 0;
|
||||
mNpdt12.mLevel = 0;
|
||||
mNpdt12.mDisposition = 0;
|
||||
mNpdt12.mReputation = 0;
|
||||
mNpdt12.mRank = 0;
|
||||
mNpdt12.mUnknown1 = 0;
|
||||
mNpdt12.mUnknown2 = 0;
|
||||
mNpdt12.mUnknown3 = 0;
|
||||
mNpdt12.mGold = 0;
|
||||
blankNpdt();
|
||||
mFlags = 0;
|
||||
mInventory.mList.clear();
|
||||
mSpells.mList.clear();
|
||||
|
@ -207,14 +210,27 @@ namespace ESM
|
|||
mHead.clear();
|
||||
}
|
||||
|
||||
void NPC::blankNpdt()
|
||||
{
|
||||
mNpdt.mLevel = 0;
|
||||
mNpdt.mStrength = mNpdt.mIntelligence = mNpdt.mWillpower = mNpdt.mAgility =
|
||||
mNpdt.mSpeed = mNpdt.mEndurance = mNpdt.mPersonality = mNpdt.mLuck = 0;
|
||||
for (int i=0; i< Skill::Length; ++i) mNpdt.mSkills[i] = 0;
|
||||
mNpdt.mReputation = 0;
|
||||
mNpdt.mHealth = mNpdt.mMana = mNpdt.mFatigue = 0;
|
||||
mNpdt.mDisposition = 0;
|
||||
mNpdt.mFactionID = 0;
|
||||
mNpdt.mRank = 0;
|
||||
mNpdt.mUnknown = 0;
|
||||
mNpdt.mGold = 0;
|
||||
}
|
||||
|
||||
int NPC::getFactionRank() const
|
||||
{
|
||||
if (mFaction.empty())
|
||||
return -1;
|
||||
else if (mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
||||
return mNpdt12.mRank;
|
||||
else // NPC_DEFAULT
|
||||
return mNpdt52.mRank;
|
||||
else
|
||||
return mNpdt.mRank;
|
||||
}
|
||||
|
||||
const std::vector<Transport::Dest>& NPC::getTransport() const
|
||||
|
|
|
@ -95,6 +95,8 @@ struct NPC
|
|||
int mGold;
|
||||
}; // 52 bytes
|
||||
|
||||
//Structure for autocalculated characters.
|
||||
// This is only used for load and save operations.
|
||||
struct NPDTstruct12
|
||||
{
|
||||
short mLevel;
|
||||
|
@ -106,8 +108,9 @@ struct NPC
|
|||
#pragma pack(pop)
|
||||
|
||||
unsigned char mNpdtType;
|
||||
NPDTstruct52 mNpdt52;
|
||||
NPDTstruct12 mNpdt12; //for autocalculated characters
|
||||
//Worth noting when saving the struct:
|
||||
// Although we might read a NPDTstruct12 in, we use NPDTstruct52 internally
|
||||
NPDTstruct52 mNpdt;
|
||||
|
||||
int getFactionRank() const; /// wrapper for mNpdt*, -1 = no rank
|
||||
|
||||
|
@ -141,6 +144,9 @@ struct NPC
|
|||
|
||||
void blank();
|
||||
///< Set record to default state (does not touch the ID).
|
||||
|
||||
/// Resets the mNpdt object
|
||||
void blankNpdt();
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -26,13 +26,23 @@ struct Static
|
|||
/// Return a string descriptor for this record type. Currently used for debugging / error logs only.
|
||||
static std::string getRecordType() { return "Static"; }
|
||||
|
||||
std::string mId, mModel;
|
||||
std::string mId, mModel;
|
||||
|
||||
void load(ESMReader &esm, bool &isDeleted);
|
||||
void save(ESMWriter &esm, bool isDeleted = false) const;
|
||||
void load(ESMReader &esm, bool &isDeleted);
|
||||
void save(ESMWriter &esm, bool isDeleted = false) const;
|
||||
|
||||
void blank();
|
||||
///< Set record to default state (does not touch the ID).
|
||||
|
||||
Static(const std::string id, const std::string &model)
|
||||
: mId(id)
|
||||
, mModel(model)
|
||||
{
|
||||
}
|
||||
|
||||
Static()
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,11 @@ namespace mwmp
|
|||
isFlying = false;
|
||||
}
|
||||
|
||||
enum class AIAction : uint8_t
|
||||
{
|
||||
Follow = 0
|
||||
};
|
||||
|
||||
std::string refId;
|
||||
unsigned refNumIndex;
|
||||
unsigned mpNum;
|
||||
|
@ -33,6 +38,10 @@ namespace mwmp
|
|||
|
||||
Animation animation;
|
||||
|
||||
bool hasAiTarget;
|
||||
Target aiTarget;
|
||||
AIAction aiAction;
|
||||
|
||||
bool hasPositionData;
|
||||
bool hasStatsDynamicData;
|
||||
};
|
||||
|
|
|
@ -11,5 +11,22 @@ PacketActorAI::PacketActorAI(RakNet::RakPeerInterface *peer) : ActorPacket(peer)
|
|||
|
||||
void PacketActorAI::Actor(BaseActor &actor, bool send)
|
||||
{
|
||||
// Placeholder to be filled in later
|
||||
RW(actor.aiAction, send);
|
||||
RW(actor.hasAiTarget, send);
|
||||
|
||||
if (actor.hasAiTarget)
|
||||
{
|
||||
RW(actor.aiTarget.isPlayer, send);
|
||||
|
||||
if (actor.aiTarget.isPlayer)
|
||||
{
|
||||
RW(actor.aiTarget.guid, send);
|
||||
}
|
||||
else
|
||||
{
|
||||
RW(actor.aiTarget.refId, send, 1);
|
||||
RW(actor.aiTarget.refNumIndex, send);
|
||||
RW(actor.aiTarget.mpNum, send);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 820 B |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 7 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 562 B |
Before Width: | Height: | Size: 520 B |
Before Width: | Height: | Size: 615 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 364 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 473 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 460 B |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 444 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 418 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 323 B |
BIN
files/opencs/brush-circle.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
files/opencs/brush-custom.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
files/opencs/brush-point.png
Normal file
After Width: | Height: | Size: 787 B |
BIN
files/opencs/brush-square.png
Normal file
After Width: | Height: | Size: 761 B |
BIN
files/opencs/camera-first-person.png
Normal file
After Width: | Height: | Size: 750 B |
BIN
files/opencs/camera-free.png
Normal file
After Width: | Height: | Size: 783 B |
BIN
files/opencs/camera-orbit.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 223 B |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 588 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 369 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 421 B |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 463 B |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 386 B |
BIN
files/opencs/dialogue-info.png
Normal file
After Width: | Height: | Size: 306 B |
BIN
files/opencs/dialogue-journal.png
Normal file
After Width: | Height: | Size: 288 B |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 362 B |
BIN
files/opencs/dialogue-regular.png
Normal file
After Width: | Height: | Size: 221 B |
Before Width: | Height: | Size: 1.9 KiB |
BIN
files/opencs/dialogue-topic-infos.png
Normal file
After Width: | Height: | Size: 306 B |
BIN
files/opencs/dialogue-topics.png
Normal file
After Width: | Height: | Size: 282 B |
BIN
files/opencs/dialogue-voice.png
Normal file
After Width: | Height: | Size: 294 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 381 B |
BIN
files/opencs/editing-instance.png
Normal file
After Width: | Height: | Size: 986 B |
BIN
files/opencs/editing-pathgrid.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
files/opencs/editing-terrain-movement.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
files/opencs/editing-terrain-shape.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
files/opencs/editing-terrain-texture.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
files/opencs/editing-terrain-vertex-paint.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 422 B |
Before Width: | Height: | Size: 7.2 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 389 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 299 B |
Before Width: | Height: | Size: 7.9 KiB |
BIN
files/opencs/global-variable.png
Normal file
After Width: | Height: | Size: 282 B |
Before Width: | Height: | Size: 2.3 KiB |
BIN
files/opencs/gmst.png
Normal file
After Width: | Height: | Size: 338 B |
Before Width: | Height: | Size: 676 B |
Before Width: | Height: | Size: 655 B |