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
sol2-server-rewrite
David Cernat 7 years ago
commit 7c8dd7380f

@ -15,6 +15,7 @@ Programmers
Adam Hogan (aurix) Adam Hogan (aurix)
Aesylwinn Aesylwinn
aegis aegis
AHSauge
Aleksandar Jovanov Aleksandar Jovanov
Alex Haddad (rainChu) Alex Haddad (rainChu)
Alex McKibben Alex McKibben
@ -156,6 +157,8 @@ Programmers
terrorfisch terrorfisch
thegriglat thegriglat
Thomas Luppi (Digmaster) Thomas Luppi (Digmaster)
tri4ng1e
unelsson
Will Herrmann (Thunderforge) Will Herrmann (Thunderforge)
Tom Mason (wheybags) Tom Mason (wheybags)
Torben Leif Carrington (TorbenC) Torben Leif Carrington (TorbenC)
@ -225,7 +228,7 @@ Artwork
Necrod - OpenMW Logo Necrod - OpenMW Logo
Mickey Lyle (raevol) - Wordpress Theme 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 Inactive Contributors
--------------------- ---------------------

@ -1040,45 +1040,47 @@ void Record<ESM::NPC>::print()
if (mData.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) if (mData.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
{ {
std::cout << " Level: " << mData.mNpdt12.mLevel << std::endl; std::cout << " Level: " << mData.mNpdt.mLevel << std::endl;
std::cout << " Reputation: " << (int)mData.mNpdt12.mReputation << std::endl; std::cout << " Reputation: " << (int)mData.mNpdt.mReputation << std::endl;
std::cout << " Disposition: " << (int)mData.mNpdt12.mDisposition << std::endl; std::cout << " Disposition: " << (int)mData.mNpdt.mDisposition << std::endl;
std::cout << " Rank: " << (int)mData.mNpdt12.mRank << std::endl; std::cout << " Rank: " << (int)mData.mNpdt.mRank << std::endl;
std::cout << " Unknown1: " //Why do we want to print these fields? They are padding in the struct and contain
<< (unsigned int)((unsigned char)mData.mNpdt12.mUnknown1) << std::endl; // nothing of real value. Now we don't deal with NPDTstruct12 in runtime either...
std::cout << " Unknown2: " //std::cout << " Unknown1: "
<< (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl; // << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown1) << std::endl;
std::cout << " Unknown3: " //std::cout << " Unknown2: "
<< (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl; // << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown2) << std::endl;
std::cout << " Gold: " << mData.mNpdt12.mGold << std::endl; //std::cout << " Unknown3: "
// << (unsigned int)((unsigned char)mData.mNpdt12.mUnknown3) << std::endl;
std::cout << " Gold: " << mData.mNpdt.mGold << std::endl;
} }
else { else {
std::cout << " Level: " << mData.mNpdt52.mLevel << std::endl; std::cout << " Level: " << mData.mNpdt.mLevel << std::endl;
std::cout << " Reputation: " << (int)mData.mNpdt52.mReputation << std::endl; std::cout << " Reputation: " << (int)mData.mNpdt.mReputation << std::endl;
std::cout << " Disposition: " << (int)mData.mNpdt52.mDisposition << std::endl; std::cout << " Disposition: " << (int)mData.mNpdt.mDisposition << std::endl;
std::cout << " Rank: " << (int)mData.mNpdt52.mRank << std::endl; std::cout << " Rank: " << (int)mData.mNpdt.mRank << std::endl;
std::cout << " FactionID: " << (int)mData.mNpdt52.mFactionID << std::endl; std::cout << " FactionID: " << (int)mData.mNpdt.mFactionID << std::endl;
std::cout << " Attributes:" << std::endl; std::cout << " Attributes:" << std::endl;
std::cout << " Strength: " << (int)mData.mNpdt52.mStrength << std::endl; std::cout << " Strength: " << (int)mData.mNpdt.mStrength << std::endl;
std::cout << " Intelligence: " << (int)mData.mNpdt52.mIntelligence << std::endl; std::cout << " Intelligence: " << (int)mData.mNpdt.mIntelligence << std::endl;
std::cout << " Willpower: " << (int)mData.mNpdt52.mWillpower << std::endl; std::cout << " Willpower: " << (int)mData.mNpdt.mWillpower << std::endl;
std::cout << " Agility: " << (int)mData.mNpdt52.mAgility << std::endl; std::cout << " Agility: " << (int)mData.mNpdt.mAgility << std::endl;
std::cout << " Speed: " << (int)mData.mNpdt52.mSpeed << std::endl; std::cout << " Speed: " << (int)mData.mNpdt.mSpeed << std::endl;
std::cout << " Endurance: " << (int)mData.mNpdt52.mEndurance << std::endl; std::cout << " Endurance: " << (int)mData.mNpdt.mEndurance << std::endl;
std::cout << " Personality: " << (int)mData.mNpdt52.mPersonality << std::endl; std::cout << " Personality: " << (int)mData.mNpdt.mPersonality << std::endl;
std::cout << " Luck: " << (int)mData.mNpdt52.mLuck << std::endl; std::cout << " Luck: " << (int)mData.mNpdt.mLuck << std::endl;
std::cout << " Skills:" << std::endl; std::cout << " Skills:" << std::endl;
for (int i = 0; i != ESM::Skill::Length; i++) for (int i = 0; i != ESM::Skill::Length; i++)
std::cout << " " << skillLabel(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 << " Health: " << mData.mNpdt.mHealth << std::endl;
std::cout << " Magicka: " << mData.mNpdt52.mMana << std::endl; std::cout << " Magicka: " << mData.mNpdt.mMana << std::endl;
std::cout << " Fatigue: " << mData.mNpdt52.mFatigue << std::endl; std::cout << " Fatigue: " << mData.mNpdt.mFatigue << std::endl;
std::cout << " Unknown: " << (int)mData.mNpdt52.mUnknown << std::endl; std::cout << " Unknown: " << (int)mData.mNpdt.mUnknown << std::endl;
std::cout << " Gold: " << mData.mNpdt52.mGold << std::endl; std::cout << " Gold: " << mData.mNpdt.mGold << std::endl;
} }
std::vector<ESM::ContItem>::iterator cit; std::vector<ESM::ContItem>::iterator cit;

@ -122,7 +122,7 @@ public:
} }
else else
{ {
mContext->mPlayer.mObject.mCreatureStats.mLevel = npc.mNpdt52.mLevel; mContext->mPlayer.mObject.mCreatureStats.mLevel = npc.mNpdt.mLevel;
mContext->mPlayerBase = npc; mContext->mPlayerBase = npc;
ESM::SpellState::SpellParams empty; ESM::SpellState::SpellParams empty;
// FIXME: player start spells and birthsign spells aren't listed here, // FIXME: player start spells and birthsign spells aren't listed here,

@ -377,7 +377,7 @@ namespace ESSImport
profile.mPlayerClassName = context.mCustomPlayerClassName; profile.mPlayerClassName = context.mCustomPlayerClassName;
else else
profile.mPlayerClassId = context.mPlayerBase.mClass; profile.mPlayerClassId = context.mPlayerBase.mClass;
profile.mPlayerLevel = context.mPlayerBase.mNpdt52.mLevel; profile.mPlayerLevel = context.mPlayerBase.mNpdt.mLevel;
profile.mPlayerName = header.mGameData.mPlayerName.toString(); profile.mPlayerName = header.mGameData.mPlayerName.toString();
writeScreenshot(header, profile); writeScreenshot(header, profile);

@ -32,9 +32,6 @@ void CSMTools::ClassCheckStage::perform (int stage, CSMDoc::Messages& messages)
if (class_.mName.empty()) if (class_.mName.empty())
messages.push_back (std::make_pair (id, class_.mId + " has an empty name")); 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 // test for invalid attributes
for (int i=0; i<2; ++i) for (int i=0; i<2; ++i)
if (class_.mData.mAttribute[i]==-1) if (class_.mData.mAttribute[i]==-1)

@ -239,9 +239,7 @@ void CSMTools::ReferenceableCheckStage::bookCheck(
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
if (baseRecord.isDeleted()) if (baseRecord.isDeleted())
{
return; return;
}
const ESM::Book& book = (dynamic_cast<const CSMWorld::Record<ESM::Book>& >(baseRecord)).get(); const ESM::Book& book = (dynamic_cast<const CSMWorld::Record<ESM::Book>& >(baseRecord)).get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Book, book.mId); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Book, book.mId);
@ -260,9 +258,7 @@ void CSMTools::ReferenceableCheckStage::activatorCheck(
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
if (baseRecord.isDeleted()) if (baseRecord.isDeleted())
{
return; return;
}
const ESM::Activator& activator = (dynamic_cast<const CSMWorld::Record<ESM::Activator>& >(baseRecord)).get(); const ESM::Activator& activator = (dynamic_cast<const CSMWorld::Record<ESM::Activator>& >(baseRecord)).get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Activator, activator.mId); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Activator, activator.mId);
@ -283,9 +279,7 @@ void CSMTools::ReferenceableCheckStage::potionCheck(
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
if (baseRecord.isDeleted()) if (baseRecord.isDeleted())
{
return; return;
}
const ESM::Potion& potion = (dynamic_cast<const CSMWorld::Record<ESM::Potion>& >(baseRecord)).get(); const ESM::Potion& potion = (dynamic_cast<const CSMWorld::Record<ESM::Potion>& >(baseRecord)).get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Potion, potion.mId); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Potion, potion.mId);
@ -306,9 +300,7 @@ void CSMTools::ReferenceableCheckStage::apparatusCheck(
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
if (baseRecord.isDeleted()) if (baseRecord.isDeleted())
{
return; return;
}
const ESM::Apparatus& apparatus = (dynamic_cast<const CSMWorld::Record<ESM::Apparatus>& >(baseRecord)).get(); const ESM::Apparatus& apparatus = (dynamic_cast<const CSMWorld::Record<ESM::Apparatus>& >(baseRecord)).get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Apparatus, apparatus.mId); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Apparatus, apparatus.mId);
@ -329,9 +321,7 @@ void CSMTools::ReferenceableCheckStage::armorCheck(
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
if (baseRecord.isDeleted()) if (baseRecord.isDeleted())
{
return; return;
}
const ESM::Armor& armor = (dynamic_cast<const CSMWorld::Record<ESM::Armor>& >(baseRecord)).get(); const ESM::Armor& armor = (dynamic_cast<const CSMWorld::Record<ESM::Armor>& >(baseRecord)).get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Armor, armor.mId); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Armor, armor.mId);
@ -358,9 +348,7 @@ void CSMTools::ReferenceableCheckStage::clothingCheck(
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
if (baseRecord.isDeleted()) if (baseRecord.isDeleted())
{
return; return;
}
const ESM::Clothing& clothing = (dynamic_cast<const CSMWorld::Record<ESM::Clothing>& >(baseRecord)).get(); const ESM::Clothing& clothing = (dynamic_cast<const CSMWorld::Record<ESM::Clothing>& >(baseRecord)).get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Clothing, clothing.mId); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Clothing, clothing.mId);
@ -378,9 +366,7 @@ void CSMTools::ReferenceableCheckStage::containerCheck(
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
if (baseRecord.isDeleted()) if (baseRecord.isDeleted())
{
return; return;
}
const ESM::Container& container = (dynamic_cast<const CSMWorld::Record<ESM::Container>& >(baseRecord)).get(); const ESM::Container& container = (dynamic_cast<const CSMWorld::Record<ESM::Container>& >(baseRecord)).get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Container, container.mId); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Container, container.mId);
@ -512,9 +498,7 @@ void CSMTools::ReferenceableCheckStage::ingredientCheck(
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
if (baseRecord.isDeleted()) if (baseRecord.isDeleted())
{
return; return;
}
const ESM::Ingredient& ingredient = (dynamic_cast<const CSMWorld::Record<ESM::Ingredient>& >(baseRecord)).get(); const ESM::Ingredient& ingredient = (dynamic_cast<const CSMWorld::Record<ESM::Ingredient>& >(baseRecord)).get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Ingredient, ingredient.mId); 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")); messages.push_back (std::make_pair (id, light.mId + " has negative light radius"));
if (light.mData.mFlags & ESM::Light::Carry) if (light.mData.mFlags & ESM::Light::Carry)
{
inventoryItemCheck<ESM::Light>(light, messages, id.toString()); 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 // Check that mentioned scripts exist
scriptCheck<ESM::Light>(light, messages, id.toString()); scriptCheck<ESM::Light>(light, messages, id.toString());
} }
@ -596,9 +575,7 @@ void CSMTools::ReferenceableCheckStage::lockpickCheck(
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
if (baseRecord.isDeleted()) if (baseRecord.isDeleted())
{
return; return;
}
const ESM::Lockpick& lockpick = (dynamic_cast<const CSMWorld::Record<ESM::Lockpick>& >(baseRecord)).get(); const ESM::Lockpick& lockpick = (dynamic_cast<const CSMWorld::Record<ESM::Lockpick>& >(baseRecord)).get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Lockpick, lockpick.mId); CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Lockpick, lockpick.mId);
@ -619,9 +596,7 @@ void CSMTools::ReferenceableCheckStage::miscCheck(
const CSMWorld::RecordBase& baseRecord = records.getRecord(stage); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
if (baseRecord.isDeleted()) if (baseRecord.isDeleted())
{
return; return;
}
const ESM::Miscellaneous& miscellaneous = (dynamic_cast<const CSMWorld::Record<ESM::Miscellaneous>& >(baseRecord)).get(); const ESM::Miscellaneous& miscellaneous = (dynamic_cast<const CSMWorld::Record<ESM::Miscellaneous>& >(baseRecord)).get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Miscellaneous, miscellaneous.mId); 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(); const ESM::NPC& npc = (dynamic_cast<const CSMWorld::Record<ESM::NPC>& >(baseRecord)).get();
CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Npc, npc.mId); CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Npc, npc.mId);
short level(npc.mNpdt52.mLevel); short level(npc.mNpdt.mLevel);
char disposition(npc.mNpdt52.mDisposition); char disposition(npc.mNpdt.mDisposition);
char reputation(npc.mNpdt52.mReputation); char reputation(npc.mNpdt.mReputation);
char rank(npc.mNpdt52.mRank); char rank(npc.mNpdt.mRank);
//Don't know what unknown is for //Don't know what unknown is for
int gold(npc.mNpdt52.mGold); int gold(npc.mNpdt.mGold);
//Detect if player is present //Detect if player is present
if (Misc::StringUtils::ciEqual(npc.mId, "player")) //Happy now, scrawl? if (Misc::StringUtils::ciEqual(npc.mId, "player")) //Happy now, scrawl?
@ -663,36 +638,36 @@ void CSMTools::ReferenceableCheckStage::npcCheck (
return; return;
} }
level = npc.mNpdt12.mLevel; level = npc.mNpdt.mLevel;
disposition = npc.mNpdt12.mDisposition; disposition = npc.mNpdt.mDisposition;
reputation = npc.mNpdt12.mReputation; reputation = npc.mNpdt.mReputation;
rank = npc.mNpdt12.mRank; rank = npc.mNpdt.mRank;
gold = npc.mNpdt12.mGold; gold = npc.mNpdt.mGold;
} }
else else
{ {
if (npc.mNpdt52.mAgility == 0) if (npc.mNpdt.mAgility == 0)
messages.push_back (std::make_pair (id, npc.mId + " agility has zero value")); 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")); 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")); 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")); 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")); 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")); 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")); 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")); 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")); messages.push_back (std::make_pair (id, npc.mId + " has any empty name"));
if (npc.mClass.empty()) if (npc.mClass.empty())
{ messages.push_back (std::make_pair (id, npc.mId + " has an empty class"));
messages.push_back (std::make_pair (id, npc.mId + " has any empty class"));
}
else if (mClasses.searchId (npc.mClass) == -1) else if (mClasses.searchId (npc.mClass) == -1)
{
messages.push_back (std::make_pair (id, npc.mId + " has invalid class")); messages.push_back (std::make_pair (id, npc.mId + " has invalid class"));
}
if (npc.mRace.empty()) if (npc.mRace.empty())
{ messages.push_back (std::make_pair (id, npc.mId + " has an empty race"));
messages.push_back (std::make_pair (id, npc.mId + " has any empty race"));
}
else if (mRaces.searchId (npc.mRace) == -1) else if (mRaces.searchId (npc.mRace) == -1)
{
messages.push_back (std::make_pair (id, npc.mId + " has invalid race")); messages.push_back (std::make_pair (id, npc.mId + " has invalid race"));
}
if (disposition < 0) if (disposition < 0)
messages.push_back (std::make_pair (id, npc.mId + " has negative disposition")); messages.push_back (std::make_pair (id, npc.mId + " has negative disposition"));
@ -823,7 +790,7 @@ void CSMTools::ReferenceableCheckStage::weaponCheck(
{ {
//checking of health //checking of health
if (weapon.mData.mHealth <= 0) 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) if (weapon.mData.mReach < 0)
messages.push_back (std::make_pair (id, weapon.mId + " has negative reach")); 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); const CSMWorld::RecordBase& baseRecord = records.getRecord(stage);
if (baseRecord.isDeleted()) if (baseRecord.isDeleted())
{
return; return;
}
const ESM::Probe& probe = (dynamic_cast<const CSMWorld::Record<ESM::Probe>& >(baseRecord)).get(); const ESM::Probe& probe = (dynamic_cast<const CSMWorld::Record<ESM::Probe>& >(baseRecord)).get();
CSMWorld::UniversalId id(CSMWorld::UniversalId::Type_Probe, probe.mId); 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); CSMWorld::UniversalId id (CSMWorld::UniversalId::Type_Sound, sound.mId);
if (sound.mData.mMinRange>sound.mData.mMaxRange) 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 /// \todo check, if the sound file exists
} }

@ -61,12 +61,7 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
connect (&mVerifier, SIGNAL (reportMessage (const CSMDoc::Message&, int)), connect (&mVerifier, SIGNAL (reportMessage (const CSMDoc::Message&, int)),
this, SLOT (verifierMessage (const CSMDoc::Message&, int))); this, SLOT (verifierMessage (const CSMDoc::Message&, int)));
std::vector<std::string> mandatoryIds; // I want C++11, damn it! std::vector<std::string> mandatoryIds {"Day", "DaysPassed", "GameHour", "Month", "PCRace"};
mandatoryIds.push_back ("Day");
mandatoryIds.push_back ("DaysPassed");
mandatoryIds.push_back ("GameHour");
mandatoryIds.push_back ("Month");
mandatoryIds.push_back ("PCRace");
mVerifierOperation->appendStage (new MandatoryIdStage (mData.getGlobals(), mVerifierOperation->appendStage (new MandatoryIdStage (mData.getGlobals(),
CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds)); CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Globals), mandatoryIds));

@ -66,7 +66,7 @@ namespace CSMWorld
{ ColumnId_SleepForbidden, "Sleep Forbidden" }, { ColumnId_SleepForbidden, "Sleep Forbidden" },
{ ColumnId_InteriorWater, "Interior Water" }, { ColumnId_InteriorWater, "Interior Water" },
{ ColumnId_InteriorSky, "Interior Sky" }, { ColumnId_InteriorSky, "Interior Sky" },
{ ColumnId_Model, "Model" }, { ColumnId_Model, "Model/Animation" },
{ ColumnId_Script, "Script" }, { ColumnId_Script, "Script" },
{ ColumnId_Icon, "Icon" }, { ColumnId_Icon, "Icon" },
{ ColumnId_Weight, "Weight" }, { ColumnId_Weight, "Weight" },

@ -962,6 +962,29 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base
return mReader->getRecordCount(); 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) bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
{ {
if (!mReader) if (!mReader)
@ -983,6 +1006,9 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
mReader = 0; mReader = 0;
mDialogue = 0; mDialogue = 0;
loadFallbackEntries();
return true; return true;
} }

@ -144,6 +144,8 @@ namespace CSMWorld
static int count (RecordBase::State state, const CollectionBase& collection); static int count (RecordBase::State state, const CollectionBase& collection);
void loadFallbackEntries();
public: public:
Data (ToUTF8::FromType encoding, bool fsStrict, const Files::PathContainer& dataPaths, 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(); ESM::NPC npc = record.get();
// store the whole struct // store the whole struct
npc.mNpdt52 = npc.mNpdt =
static_cast<const NestedTableWrapper<std::vector<ESM::NPC::NPDTstruct52> > &>(nestedTable).mNestedTable.at(0); static_cast<const NestedTableWrapper<std::vector<ESM::NPC::NPDTstruct52> > &>(nestedTable).mNestedTable.at(0);
record.setModified (npc); record.setModified (npc);
@ -928,7 +928,7 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::NpcAttributesRefIdAdapter::nestedTab
// return the whole struct // return the whole struct
std::vector<ESM::NPC::NPDTstruct52> wrap; std::vector<ESM::NPC::NPDTstruct52> wrap;
wrap.push_back(record.get().mNpdt52); wrap.push_back(record.get().mNpdt);
// deleted by dtor of NestedTableStoring // deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<ESM::NPC::NPDTstruct52> >(wrap); return new NestedTableWrapper<std::vector<ESM::NPC::NPDTstruct52> >(wrap);
} }
@ -939,7 +939,7 @@ QVariant CSMWorld::NpcAttributesRefIdAdapter::getNestedData (const RefIdColumn *
const Record<ESM::NPC>& record = const Record<ESM::NPC>& record =
static_cast<const Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); 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) if (subColIndex == 0)
return subRowIndex; return subRowIndex;
@ -966,7 +966,7 @@ void CSMWorld::NpcAttributesRefIdAdapter::setNestedData (const RefIdColumn *colu
Record<ESM::NPC>& record = Record<ESM::NPC>& record =
static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Npc))); static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Npc)));
ESM::NPC npc = record.get(); ESM::NPC npc = record.get();
ESM::NPC::NPDTstruct52& npcStruct = npc.mNpdt52; ESM::NPC::NPDTstruct52& npcStruct = npc.mNpdt;
if (subColIndex == 1) if (subColIndex == 1)
switch(subRowIndex) switch(subRowIndex)
@ -1021,7 +1021,7 @@ void CSMWorld::NpcSkillsRefIdAdapter::setNestedTable (const RefIdColumn* column,
ESM::NPC npc = record.get(); ESM::NPC npc = record.get();
// store the whole struct // store the whole struct
npc.mNpdt52 = npc.mNpdt =
static_cast<const NestedTableWrapper<std::vector<ESM::NPC::NPDTstruct52> > &>(nestedTable).mNestedTable.at(0); static_cast<const NestedTableWrapper<std::vector<ESM::NPC::NPDTstruct52> > &>(nestedTable).mNestedTable.at(0);
record.setModified (npc); record.setModified (npc);
@ -1035,7 +1035,7 @@ CSMWorld::NestedTableWrapperBase* CSMWorld::NpcSkillsRefIdAdapter::nestedTable (
// return the whole struct // return the whole struct
std::vector<ESM::NPC::NPDTstruct52> wrap; std::vector<ESM::NPC::NPDTstruct52> wrap;
wrap.push_back(record.get().mNpdt52); wrap.push_back(record.get().mNpdt);
// deleted by dtor of NestedTableStoring // deleted by dtor of NestedTableStoring
return new NestedTableWrapper<std::vector<ESM::NPC::NPDTstruct52> >(wrap); 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 = const Record<ESM::NPC>& record =
static_cast<const Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (index, UniversalId::Type_Npc))); 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) if (subRowIndex < 0 || subRowIndex >= ESM::Skill::Length)
throw std::runtime_error ("index out of range"); throw std::runtime_error ("index out of range");
@ -1065,7 +1065,7 @@ void CSMWorld::NpcSkillsRefIdAdapter::setNestedData (const RefIdColumn *column,
Record<ESM::NPC>& record = Record<ESM::NPC>& record =
static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Npc))); static_cast<Record<ESM::NPC>&> (data.getRecord (RefIdData::LocalIndex (row, UniversalId::Type_Npc)));
ESM::NPC npc = record.get(); ESM::NPC npc = record.get();
ESM::NPC::NPDTstruct52& npcStruct = npc.mNpdt52; ESM::NPC::NPDTstruct52& npcStruct = npc.mNpdt;
if (subRowIndex < 0 || subRowIndex >= ESM::Skill::Length) if (subRowIndex < 0 || subRowIndex >= ESM::Skill::Length)
throw std::runtime_error ("index out of range"); throw std::runtime_error ("index out of range");
@ -1130,30 +1130,30 @@ QVariant CSMWorld::NpcMiscRefIdAdapter::getNestedData (const RefIdColumn *column
if (autoCalc) if (autoCalc)
switch (subColIndex) 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 1: return QVariant(QVariant::UserType);
case 2: return QVariant(QVariant::UserType); case 2: return QVariant(QVariant::UserType);
case 3: return QVariant(QVariant::UserType); case 3: return QVariant(QVariant::UserType);
case 4: return QVariant(QVariant::UserType); case 4: return QVariant(QVariant::UserType);
case 5: return static_cast<int>(record.get().mNpdt12.mDisposition); case 5: return static_cast<int>(record.get().mNpdt.mDisposition);
case 6: return static_cast<int>(record.get().mNpdt12.mReputation); case 6: return static_cast<int>(record.get().mNpdt.mReputation);
case 7: return static_cast<int>(record.get().mNpdt12.mRank); case 7: return static_cast<int>(record.get().mNpdt.mRank);
case 8: return record.get().mNpdt12.mGold; case 8: return record.get().mNpdt.mGold;
case 9: return record.get().mPersistent == true; case 9: return record.get().mPersistent == true;
default: return QVariant(); // throw an exception here? default: return QVariant(); // throw an exception here?
} }
else else
switch (subColIndex) switch (subColIndex)
{ {
case 0: return static_cast<int>(record.get().mNpdt52.mLevel); case 0: return static_cast<int>(record.get().mNpdt.mLevel);
case 1: return static_cast<int>(record.get().mNpdt52.mFactionID); case 1: return static_cast<int>(record.get().mNpdt.mFactionID);
case 2: return static_cast<int>(record.get().mNpdt52.mHealth); case 2: return static_cast<int>(record.get().mNpdt.mHealth);
case 3: return static_cast<int>(record.get().mNpdt52.mMana); case 3: return static_cast<int>(record.get().mNpdt.mMana);
case 4: return static_cast<int>(record.get().mNpdt52.mFatigue); case 4: return static_cast<int>(record.get().mNpdt.mFatigue);
case 5: return static_cast<int>(record.get().mNpdt52.mDisposition); case 5: return static_cast<int>(record.get().mNpdt.mDisposition);
case 6: return static_cast<int>(record.get().mNpdt52.mReputation); case 6: return static_cast<int>(record.get().mNpdt.mReputation);
case 7: return static_cast<int>(record.get().mNpdt52.mRank); case 7: return static_cast<int>(record.get().mNpdt.mRank);
case 8: return record.get().mNpdt52.mGold; case 8: return record.get().mNpdt.mGold;
case 9: return record.get().mPersistent == true; case 9: return record.get().mPersistent == true;
default: return QVariant(); // throw an exception here? default: return QVariant(); // throw an exception here?
} }
@ -1171,30 +1171,30 @@ void CSMWorld::NpcMiscRefIdAdapter::setNestedData (const RefIdColumn *column,
if (autoCalc) if (autoCalc)
switch(subColIndex) 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 1: return;
case 2: return; case 2: return;
case 3: return; case 3: return;
case 4: return; case 4: return;
case 5: npc.mNpdt12.mDisposition = static_cast<signed char>(value.toInt()); break; case 5: npc.mNpdt.mDisposition = static_cast<signed char>(value.toInt()); break;
case 6: npc.mNpdt12.mReputation = static_cast<signed char>(value.toInt()); break; case 6: npc.mNpdt.mReputation = static_cast<signed char>(value.toInt()); break;
case 7: npc.mNpdt12.mRank = static_cast<signed char>(value.toInt()); break; case 7: npc.mNpdt.mRank = static_cast<signed char>(value.toInt()); break;
case 8: npc.mNpdt12.mGold = value.toInt(); break; case 8: npc.mNpdt.mGold = value.toInt(); break;
case 9: npc.mPersistent = value.toBool(); break; case 9: npc.mPersistent = value.toBool(); break;
default: return; // throw an exception here? default: return; // throw an exception here?
} }
else else
switch(subColIndex) switch(subColIndex)
{ {
case 0: npc.mNpdt52.mLevel = static_cast<short>(value.toInt()); break; case 0: npc.mNpdt.mLevel = static_cast<short>(value.toInt()); break;
case 1: npc.mNpdt52.mFactionID = static_cast<char>(value.toInt()); break; case 1: npc.mNpdt.mFactionID = static_cast<char>(value.toInt()); break;
case 2: npc.mNpdt52.mHealth = static_cast<unsigned short>(value.toInt()); break; case 2: npc.mNpdt.mHealth = static_cast<unsigned short>(value.toInt()); break;
case 3: npc.mNpdt52.mMana = static_cast<unsigned short>(value.toInt()); break; case 3: npc.mNpdt.mMana = static_cast<unsigned short>(value.toInt()); break;
case 4: npc.mNpdt52.mFatigue = static_cast<unsigned short>(value.toInt()); break; case 4: npc.mNpdt.mFatigue = static_cast<unsigned short>(value.toInt()); break;
case 5: npc.mNpdt52.mDisposition = static_cast<signed char>(value.toInt()); break; case 5: npc.mNpdt.mDisposition = static_cast<signed char>(value.toInt()); break;
case 6: npc.mNpdt52.mReputation = static_cast<signed char>(value.toInt()); break; case 6: npc.mNpdt.mReputation = static_cast<signed char>(value.toInt()); break;
case 7: npc.mNpdt52.mRank = static_cast<signed char>(value.toInt()); break; case 7: npc.mNpdt.mRank = static_cast<signed char>(value.toInt()); break;
case 8: npc.mNpdt52.mGold = value.toInt(); break; case 8: npc.mNpdt.mGold = value.toInt(); break;
case 9: npc.mPersistent = value.toBool(); break; case 9: npc.mPersistent = value.toBool(); break;
default: return; // throw an exception here? default: return; // throw an exception here?
} }

@ -64,21 +64,21 @@ namespace
static const TypeData sIdArg[] = static const TypeData sIdArg[] =
{ {
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable", ":./globvar.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_Gmst, "Game Setting", ":./gmst.png" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Skill, "Skill", ":./skill.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_Class, "Class", ":./class.png" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Faction, "Faction", ":./faction.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_Race, "Race", ":./race.png" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Sound, "Sound", ":./sound.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_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_Birthsign, "Birthsign", ":./birthsign.png" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Spell, "Spell", ":./spell.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_Topic, "Topic", ":./dialogue-topics.png" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Journal, "Journal", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Journal, "Journal", ":./journal-topics.png" },
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_TopicInfo, "TopicInfo", 0 }, { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_TopicInfo, "TopicInfo", ":./dialogue-topic-infos.png" },
{ CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_JournalInfo, "JournalInfo", 0 }, { 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, "Cell", ":./cell.png" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Cell_Missing, "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 }, { 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_Door, "Door", ":./door.png" },
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Ingredient, "Ingredient", ":./ingredient.png" }, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Ingredient, "Ingredient", ":./ingredient.png" },
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_CreatureLevelledList, { 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, { CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_ItemLevelledList,
"Item Levelled List", ":./leveled-item.png" }, "Item Levelled List", ":./leveled-item.png" },
{ CSMWorld::UniversalId::Class_RefRecord, CSMWorld::UniversalId::Type_Light, "Light", ":./light.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_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_Scene, "Scene", 0 },
{ CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Preview, "Preview", 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_Enchantment, "Enchantment", ":./enchantment.png" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_BodyPart, "Body Part", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_BodyPart, "Body Part", ":./body-part.png" },
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Mesh, "Mesh", 0 }, { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Mesh, "Mesh", ":resources-mesh"},
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Icon, "Icon", 0 }, { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Icon, "Icon", ":resources-icon"},
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Music, "Music", 0 }, { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Music, "Music", ":resources-music" },
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_SoundRes, "Sound File", 0 }, { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_SoundRes, "Sound File", ":resources-sound" },
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Texture, "Texture", 0 }, { CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Texture, "Texture", ":resources-texture"},
{ CSMWorld::UniversalId::Class_Resource, CSMWorld::UniversalId::Type_Video, "Video", 0 }, { 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_DebugProfile, "Debug Profile", 0 },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_SoundGen, "Sound Generator", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_SoundGen, "Sound Generator", ":./sound-generator.png" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_MagicEffect, "Magic Effect", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_MagicEffect, "Magic Effect", ":./magic-effect.png" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Land, "Land", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Land, "Land", ":./land-heightmap.png" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_LandTexture, "LandTexture", 0 }, { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_LandTexture, "LandTexture", ":./land-texture.png" },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Pathgrid, "Pathgrid", 0 }, { 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_StartScript, "Start Script", 0 },
{ CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_MetaData, "Meta Data", 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) 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), parent), mSubMode (0), mSubModeId ("move"), mSelectionMode (0), mDragMode (DragMode_None),
mDragAxis (-1), mLocked (false), mUnitScaleDist(1) 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 = new CSVWidget::SceneToolMode (toolbar, "Edit Sub-Mode");
mSubMode->addButton (new InstanceMoveMode (this), "move"); mSubMode->addButton (new InstanceMoveMode (this), "move");
mSubMode->addButton (":placeholder", "rotate", mSubMode->addButton (":scenetoolbar/transform-rotate", "rotate",
"Rotate selected instances" "Rotate selected instances"
"<ul><li>Use {scene-edit-primary} to rotate instances freely</li>" "<ul><li>Use {scene-edit-primary} to rotate instances freely</li>"
"<li>Use {scene-edit-secondary} to rotate instances within the grid</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>" "<li>The center of the view acts as the axis of rotation</li>"
"</ul>" "</ul>"
"<font color=Red>Grid rotate not implemented yet</font color>"); "<font color=Red>Grid rotate not implemented yet</font color>");
mSubMode->addButton (":placeholder", "scale", mSubMode->addButton (":scenetoolbar/transform-scale", "scale",
"Scale selected instances" "Scale selected instances"
"<ul><li>Use {scene-edit-primary} to scale instances freely</li>" "<ul><li>Use {scene-edit-primary} to scale instances freely</li>"
"<li>Use {scene-edit-secondary} to scale instances along the grid</li>" "<li>Use {scene-edit-secondary} to scale instances along the grid</li>"

@ -2,7 +2,7 @@
#include "instancemovemode.hpp" #include "instancemovemode.hpp"
CSVRender::InstanceMoveMode::InstanceMoveMode (QWidget *parent) CSVRender::InstanceMoveMode::InstanceMoveMode (QWidget *parent)
: ModeButton (QIcon (QPixmap (":placeholder")), : ModeButton (QIcon (QPixmap (":scenetoolbar/transform-move")),
"Move selected instances" "Move selected instances"
"<ul><li>Use {scene-edit-primary} to move instances around freely</li>" "<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>" "<li>Use {scene-edit-secondary} to move instances around within the grid</li>"

@ -13,7 +13,7 @@ namespace CSVRender
, mWorldspaceWidget(worldspaceWidget) , mWorldspaceWidget(worldspaceWidget)
, mInteractionMask(interactionMask) , mInteractionMask(interactionMask)
{ {
addButton(":placeholder", "cube-centre", addButton(":scenetoolbar/selection-mode-cube", "cube-centre",
"Centred cube" "Centred cube"
"<ul><li>Drag with {scene-select-primary} (make instances the selection) or {scene-select-secondary} " "<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>" "(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>" "starting on an instance will have the same effect</li>"
"</ul>" "</ul>"
"<font color=Red>Not implemented yet</font color>"); "<font color=Red>Not implemented yet</font color>");
addButton(":placeholder", "cube-corner", addButton(":scenetoolbar/selection-mode-cube-corner", "cube-corner",
"Cube corner to corner" "Cube corner to corner"
"<ul><li>Drag with {scene-select-primary} (make instances the selection) or {scene-select-secondary} " "<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>" "(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>" "starting on an instance will have the same effect</li>"
"</ul>" "</ul>"
"<font color=Red>Not implemented yet</font color>"); "<font color=Red>Not implemented yet</font color>");
addButton(":placeholder", "sphere", addButton(":scenetoolbar/selection-mode-cube-sphere", "sphere",
"Centred sphere" "Centred sphere"
"<ul><li>Drag with {scene-select-primary} (make instances the selection) or {scene-select-secondary} " "<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>" "(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); setSelectionMode (QAbstractItemView::ExtendedSelection);
mProxyModel = new QSortFilterProxyModel (this); mProxyModel = new QSortFilterProxyModel (this);
mProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
mProxyModel->setSourceModel (mModel); mProxyModel->setSourceModel (mModel);
mProxyModel->setSortRole(Qt::UserRole); mProxyModel->setSortRole(Qt::UserRole);

@ -57,12 +57,12 @@ CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id,
// left section // left section
mPrevButton = new QToolButton (this); mPrevButton = new QToolButton (this);
mPrevButton->setIcon(QIcon(":/go-previous.png")); mPrevButton->setIcon(QIcon(":record-previous"));
mPrevButton->setToolTip ("Switch to previous record"); mPrevButton->setToolTip ("Switch to previous record");
buttonsLayout->addWidget (mPrevButton, 0); buttonsLayout->addWidget (mPrevButton, 0);
mNextButton = new QToolButton (this); mNextButton = new QToolButton (this);
mNextButton->setIcon(QIcon(":/go-next.png")); mNextButton->setIcon(QIcon(":/record-next"));
mNextButton->setToolTip ("Switch to next record"); mNextButton->setToolTip ("Switch to next record");
buttonsLayout->addWidget (mNextButton, 1); buttonsLayout->addWidget (mNextButton, 1);
@ -72,7 +72,7 @@ CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id,
if (mTable.getFeatures() & CSMWorld::IdTable::Feature_Preview) if (mTable.getFeatures() & CSMWorld::IdTable::Feature_Preview)
{ {
QToolButton* previewButton = new QToolButton (this); QToolButton* previewButton = new QToolButton (this);
previewButton->setIcon(QIcon(":/edit-preview.png")); previewButton->setIcon(QIcon(":edit-preview"));
previewButton->setToolTip ("Open a preview of this record"); previewButton->setToolTip ("Open a preview of this record");
buttonsLayout->addWidget(previewButton); buttonsLayout->addWidget(previewButton);
connect (previewButton, SIGNAL(clicked()), this, SIGNAL (showPreview())); connect (previewButton, SIGNAL(clicked()), this, SIGNAL (showPreview()));
@ -89,22 +89,22 @@ CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id,
// right section // right section
mCloneButton = new QToolButton (this); mCloneButton = new QToolButton (this);
mCloneButton->setIcon(QIcon(":/edit-clone.png")); mCloneButton->setIcon(QIcon(":edit-clone"));
mCloneButton->setToolTip ("Clone record"); mCloneButton->setToolTip ("Clone record");
buttonsLayout->addWidget(mCloneButton); buttonsLayout->addWidget(mCloneButton);
mAddButton = new QToolButton (this); mAddButton = new QToolButton (this);
mAddButton->setIcon(QIcon(":/add.png")); mAddButton->setIcon(QIcon(":edit-add"));
mAddButton->setToolTip ("Add new record"); mAddButton->setToolTip ("Add new record");
buttonsLayout->addWidget(mAddButton); buttonsLayout->addWidget(mAddButton);
mDeleteButton = new QToolButton (this); mDeleteButton = new QToolButton (this);
mDeleteButton->setIcon(QIcon(":/edit-delete.png")); mDeleteButton->setIcon(QIcon(":edit-delete"));
mDeleteButton->setToolTip ("Delete record"); mDeleteButton->setToolTip ("Delete record");
buttonsLayout->addWidget(mDeleteButton); buttonsLayout->addWidget(mDeleteButton);
mRevertButton = new QToolButton (this); mRevertButton = new QToolButton (this);
mRevertButton->setIcon(QIcon(":/edit-undo.png")); mRevertButton->setIcon(QIcon(":edit-undo"));
mRevertButton->setToolTip ("Revert record"); mRevertButton->setToolTip ("Revert record");
buttonsLayout->addWidget(mRevertButton); buttonsLayout->addWidget(mRevertButton);

@ -27,7 +27,7 @@ CSVWorld::RecordStatusDelegateFactory::RecordStatusDelegateFactory()
static const char *sIcons[] = 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) for (int i=0; sIcons[i]; ++i)

@ -764,10 +764,8 @@ std::vector< CSMWorld::UniversalId > CSVWorld::Table::getDraggedRecords() const
QModelIndexList selectedRows = selectionModel()->selectedRows(); QModelIndexList selectedRows = selectionModel()->selectedRows();
std::vector<CSMWorld::UniversalId> idToDrag; 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())); idToDrag.push_back (getUniversalId (it.row()));
}
return idToDrag; return idToDrag;
} }

@ -11,6 +11,7 @@
#include "Cell.hpp" #include "Cell.hpp"
#include "CellController.hpp" #include "CellController.hpp"
#include "Player.hpp" #include "Player.hpp"
#include "Players.hpp"
using namespace std; using namespace std;
@ -32,6 +33,9 @@ void Actor::Init(LuaState &lua)
"getCell", &NetActor::getCell, "getCell", &NetActor::getCell,
"getInventory", &NetActor::getInventory, "getInventory", &NetActor::getInventory,
"followPlayer", &Actor::followPlayer,
"followActor", &Actor::followActor,
"refId", sol::property(&Actor::getRefId, &Actor::setRefId), "refId", sol::property(&Actor::getRefId, &Actor::setRefId),
"refNumIndex", sol::property(&Actor::getRefNumIndex, &Actor::setRefNumIndex), "refNumIndex", sol::property(&Actor::getRefNumIndex, &Actor::setRefNumIndex),
"mpNum", sol::property(&Actor::getMpNum, &Actor::setMpNum) "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 std::string Actor::getRefId() const
{ {
return actor->refId; return actor->refId;
@ -141,6 +171,7 @@ void ActorController::sendActors(std::shared_ptr<Player> player, std::vector<std
bool skillsChanged = false; bool skillsChanged = false;
bool baseInfoChanged = false;*/ bool baseInfoChanged = false;*/
bool equipmentChanged = false; bool equipmentChanged = false;
bool aiChanged = false;
bool changedCell = false; bool changedCell = false;
actorList.baseActors.clear(); actorList.baseActors.clear();
@ -152,6 +183,8 @@ void ActorController::sendActors(std::shared_ptr<Player> player, std::vector<std
positionChanged = true; positionChanged = true;
if (actor->statsChanged) if (actor->statsChanged)
statsChanged = true; statsChanged = true;
if (actor->aiChanged)
aiChanged = true;
/*if (actor->attributesChanged) /*if (actor->attributesChanged)
attributesChanged = true; attributesChanged = true;
if (actor->skillsChanged) if (actor->skillsChanged)
@ -223,6 +256,15 @@ void ActorController::sendActors(std::shared_ptr<Player> player, std::vector<std
if (sendToAll) if (sendToAll)
serverCell->sendToLoaded(packet, &actorList); 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) if (changedCell)
{ {
auto packet = actorCtrl->GetPacket(ID_ACTOR_CELL_CHANGE); auto packet = actorCtrl->GetPacket(ID_ACTOR_CELL_CHANGE);

@ -25,6 +25,10 @@ public:
void setRefNumIndex(unsigned refNumIndex); void setRefNumIndex(unsigned refNumIndex);
unsigned getMpNum() const; unsigned getMpNum() const;
void setMpNum(unsigned mpNum); void setMpNum(unsigned mpNum);
void followPlayer(int pid);
void followActor(unsigned int refNumIndex, unsigned int mpNum);
bool doesHavePosition() const; // ???? bool doesHavePosition() const; // ????
bool doesHaveStatsDynamic() const; // ???? bool doesHaveStatsDynamic() const; // ????

@ -70,7 +70,7 @@ public:
bool isPlayer() const { return isActorPlayer; } bool isPlayer() const { return isActorPlayer; }
Player *toPlayer(); Player *toPlayer();
protected: protected:
bool baseInfoChanged, shapeshiftChanged, levelChanged, statsChanged, positionChanged, momentumChanged, attributesChanged, skillsChanged; bool baseInfoChanged, shapeshiftChanged, levelChanged, statsChanged, positionChanged, momentumChanged, attributesChanged, skillsChanged, aiChanged;
mwmp::BasePlayer *basePlayer; mwmp::BasePlayer *basePlayer;
mwmp::BaseNetCreature *netCreature; mwmp::BaseNetCreature *netCreature;

@ -327,40 +327,40 @@ namespace MWClass
int gold=0; int gold=0;
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) 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) 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::Strength, ref->mBase->mNpdt.mStrength);
data->mNpcStats.setAttribute(ESM::Attribute::Intelligence, ref->mBase->mNpdt52.mIntelligence); data->mNpcStats.setAttribute(ESM::Attribute::Intelligence, ref->mBase->mNpdt.mIntelligence);
data->mNpcStats.setAttribute(ESM::Attribute::Willpower, ref->mBase->mNpdt52.mWillpower); data->mNpcStats.setAttribute(ESM::Attribute::Willpower, ref->mBase->mNpdt.mWillpower);
data->mNpcStats.setAttribute(ESM::Attribute::Agility, ref->mBase->mNpdt52.mAgility); data->mNpcStats.setAttribute(ESM::Attribute::Agility, ref->mBase->mNpdt.mAgility);
data->mNpcStats.setAttribute(ESM::Attribute::Speed, ref->mBase->mNpdt52.mSpeed); data->mNpcStats.setAttribute(ESM::Attribute::Speed, ref->mBase->mNpdt.mSpeed);
data->mNpcStats.setAttribute(ESM::Attribute::Endurance, ref->mBase->mNpdt52.mEndurance); data->mNpcStats.setAttribute(ESM::Attribute::Endurance, ref->mBase->mNpdt.mEndurance);
data->mNpcStats.setAttribute(ESM::Attribute::Personality, ref->mBase->mNpdt52.mPersonality); data->mNpcStats.setAttribute(ESM::Attribute::Personality, ref->mBase->mNpdt.mPersonality);
data->mNpcStats.setAttribute(ESM::Attribute::Luck, ref->mBase->mNpdt52.mLuck); data->mNpcStats.setAttribute(ESM::Attribute::Luck, ref->mBase->mNpdt.mLuck);
data->mNpcStats.setHealth (ref->mBase->mNpdt52.mHealth); data->mNpcStats.setHealth (ref->mBase->mNpdt.mHealth);
data->mNpcStats.setMagicka (ref->mBase->mNpdt52.mMana); data->mNpcStats.setMagicka (ref->mBase->mNpdt.mMana);
data->mNpcStats.setFatigue (ref->mBase->mNpdt52.mFatigue); data->mNpcStats.setFatigue (ref->mBase->mNpdt.mFatigue);
data->mNpcStats.setLevel(ref->mBase->mNpdt52.mLevel); data->mNpcStats.setLevel(ref->mBase->mNpdt.mLevel);
data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt52.mDisposition); data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt.mDisposition);
data->mNpcStats.setReputation(ref->mBase->mNpdt52.mReputation); data->mNpcStats.setReputation(ref->mBase->mNpdt.mReputation);
data->mNpcStats.setNeedRecalcDynamicStats(false); data->mNpcStats.setNeedRecalcDynamicStats(false);
} }
else else
{ {
gold = ref->mBase->mNpdt12.mGold; gold = ref->mBase->mNpdt.mGold;
for (int i=0; i<3; ++i) for (int i=0; i<3; ++i)
data->mNpcStats.setDynamic (i, 10); data->mNpcStats.setDynamic (i, 10);
data->mNpcStats.setLevel(ref->mBase->mNpdt12.mLevel); data->mNpcStats.setLevel(ref->mBase->mNpdt.mLevel);
data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt12.mDisposition); data->mNpcStats.setBaseDisposition(ref->mBase->mNpdt.mDisposition);
data->mNpcStats.setReputation(ref->mBase->mNpdt12.mReputation); data->mNpcStats.setReputation(ref->mBase->mNpdt.mReputation);
autoCalculateAttributes(ref->mBase, data->mNpcStats); autoCalculateAttributes(ref->mBase, data->mNpcStats);
autoCalculateSkills(ref->mBase, data->mNpcStats, ptr); autoCalculateSkills(ref->mBase, data->mNpcStats, ptr);
@ -1476,10 +1476,7 @@ namespace MWClass
int Npc::getBaseGold(const MWWorld::ConstPtr& ptr) const int Npc::getBaseGold(const MWWorld::ConstPtr& ptr) const
{ {
const MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>(); const MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
if(ref->mBase->mNpdtType != ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) return ref->mBase->mNpdt.mGold;
return ref->mBase->mNpdt52.mGold;
else
return ref->mBase->mNpdt12.mGold;
} }
bool Npc::isClass(const MWWorld::ConstPtr& ptr, const std::string &className) const bool Npc::isClass(const MWWorld::ConstPtr& ptr, const std::string &className) const

@ -426,7 +426,18 @@ namespace MWGui
} }
else 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; mPtr = object;
} }
// User clicked on an object. Restore focus to the console command line. // 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; const ESM::NPC *player = ptr.get<ESM::NPC>()->mBase;
// reset // reset
creatureStats.setLevel(player->mNpdt52.mLevel); creatureStats.setLevel(player->mNpdt.mLevel);
creatureStats.getSpells().clear(); creatureStats.getSpells().clear();
creatureStats.modifyMagicEffects(MagicEffects()); creatureStats.modifyMagicEffects(MagicEffects());
for (int i=0; i<27; ++i) 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::Strength, player->mNpdt.mStrength);
creatureStats.setAttribute(ESM::Attribute::Intelligence, player->mNpdt52.mIntelligence); creatureStats.setAttribute(ESM::Attribute::Intelligence, player->mNpdt.mIntelligence);
creatureStats.setAttribute(ESM::Attribute::Willpower, player->mNpdt52.mWillpower); creatureStats.setAttribute(ESM::Attribute::Willpower, player->mNpdt.mWillpower);
creatureStats.setAttribute(ESM::Attribute::Agility, player->mNpdt52.mAgility); creatureStats.setAttribute(ESM::Attribute::Agility, player->mNpdt.mAgility);
creatureStats.setAttribute(ESM::Attribute::Speed, player->mNpdt52.mSpeed); creatureStats.setAttribute(ESM::Attribute::Speed, player->mNpdt.mSpeed);
creatureStats.setAttribute(ESM::Attribute::Endurance, player->mNpdt52.mEndurance); creatureStats.setAttribute(ESM::Attribute::Endurance, player->mNpdt.mEndurance);
creatureStats.setAttribute(ESM::Attribute::Personality, player->mNpdt52.mPersonality); creatureStats.setAttribute(ESM::Attribute::Personality, player->mNpdt.mPersonality);
creatureStats.setAttribute(ESM::Attribute::Luck, player->mNpdt52.mLuck); creatureStats.setAttribute(ESM::Attribute::Luck, player->mNpdt.mLuck);
const MWWorld::ESMStore &esmStore = const MWWorld::ESMStore &esmStore =
MWBase::Environment::get().getWorld()->getStore(); 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) void Cell::readAttack(ActorList& actorList)
{ {
for (const auto &baseActor : actorList.baseActors) for (const auto &baseActor : actorList.baseActors)

@ -24,6 +24,7 @@ namespace mwmp
void readStatsDynamic(ActorList& actorList); void readStatsDynamic(ActorList& actorList);
void readEquipment(ActorList& actorList); void readEquipment(ActorList& actorList);
void readSpeech(ActorList& actorList); void readSpeech(ActorList& actorList);
void readAI(ActorList& actorList);
void readAttack(ActorList& actorList); void readAttack(ActorList& actorList);
void readCellChange(ActorList& actorList); void readCellChange(ActorList& actorList);

@ -154,6 +154,17 @@ void CellController::readSpeech(ActorList& actorList)
cellsInitialized[mapIndex]->readSpeech(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) void CellController::readAttack(ActorList& actorList)
{ {
std::string mapIndex = actorList.cell.getDescription(); std::string mapIndex = actorList.cell.getDescription();

@ -27,6 +27,7 @@ namespace mwmp
void readStatsDynamic(mwmp::ActorList& actorList); void readStatsDynamic(mwmp::ActorList& actorList);
void readEquipment(mwmp::ActorList& actorList); void readEquipment(mwmp::ActorList& actorList);
void readSpeech(mwmp::ActorList& actorList); void readSpeech(mwmp::ActorList& actorList);
void readAI(mwmp::ActorList& actorList);
void readAttack(mwmp::ActorList& actorList); void readAttack(mwmp::ActorList& actorList);
void readCellChange(mwmp::ActorList& actorList); void readCellChange(mwmp::ActorList& actorList);

@ -6,6 +6,7 @@
#include "../mwdialogue/dialoguemanagerimp.hpp" #include "../mwdialogue/dialoguemanagerimp.hpp"
#include "../mwmechanics/aifollow.hpp"
#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/mechanicsmanagerimp.hpp" #include "../mwmechanics/mechanicsmanagerimp.hpp"
#include "../mwmechanics/movement.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() void DedicatedActor::playAnimation()
{ {
if (!animation.groupname.empty()) if (!animation.groupname.empty())

@ -22,6 +22,7 @@ namespace mwmp
void setAnimFlags(); void setAnimFlags();
void setStatsDynamic(); void setStatsDynamic();
void setEquipment(); void setEquipment();
void setAI();
void playAnimation(); void playAnimation();
void playSound(); void playSound();

@ -17,7 +17,7 @@ namespace mwmp
virtual void Do(ActorPacket &packet, ActorList &actorList) 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) MWState::QuickSaveManager::QuickSaveManager(std::string &saveName, unsigned int maxSaves)
: mSaveName(saveName) : mSaveName(saveName)
, mMaxSaves(maxSaves) , mMaxSaves(maxSaves)
, mOldestSlotVisited(NULL)
, mSlotsVisited(0) , mSlotsVisited(0)
, mOldestSlotVisited(nullptr)
{ {
} }

@ -141,6 +141,7 @@ void ESMStore::setUp()
mMagicEffects.setUp(); mMagicEffects.setUp();
mAttributes.setUp(); mAttributes.setUp();
mDialogs.setUp(); mDialogs.setUp();
mStatics.setUp();
} }
int ESMStore::countSavedGameRecords() const 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 <> template <>
inline RecordId Store<ESM::Dialogue>::load(ESM::ESMReader &esm) { inline RecordId Store<ESM::Dialogue>::load(ESM::ESMReader &esm) {
// The original letter case of a dialogue ID is saved, because it's printed // 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) TEST(EsmFixedString, DISABLED_is_pod)
{ {
/* TODO: enable in C++11 ASSERT_TRUE(std::is_pod<ESM::NAME>::value);
* ASSERT_TRUE(std::is_pod<ESM::NAME>::value); ASSERT_TRUE(std::is_pod<ESM::NAME32>::value);
* ASSERT_TRUE(std::is_pod<ESM::NAME32>::value); ASSERT_TRUE(std::is_pod<ESM::NAME64>::value);
* ASSERT_TRUE(std::is_pod<ESM::NAME64>::value); ASSERT_TRUE(std::is_pod<ESM::NAME256>::value);
* ASSERT_TRUE(std::is_pod<ESM::NAME256>::value);
*/
} }

@ -512,7 +512,9 @@ void ContentSelectorModel::ContentModel::sortFiles()
//dependencies appear. //dependencies appear.
for (int j = i + 1; j < fileCount; j++) 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); mFiles.move(j, i);

@ -62,12 +62,23 @@ namespace ESM
if (esm.getSubSize() == 52) if (esm.getSubSize() == 52)
{ {
mNpdtType = NPC_DEFAULT; mNpdtType = NPC_DEFAULT;
esm.getExact(&mNpdt52, 52); esm.getExact(&mNpdt, 52);
} }
else if (esm.getSubSize() == 12) else if (esm.getSubSize() == 12)
{ {
//Reading into temporary NPDTstruct12 object
NPDTstruct12 npdt12;
mNpdtType = NPC_WITH_AUTOCALCULATED_STATS; 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 else
esm.fail("NPC_NPDT must be 12 or 52 bytes long"); esm.fail("NPC_NPDT must be 12 or 52 bytes long");
@ -135,9 +146,19 @@ namespace ESM
esm.writeHNOCString("SCRI", mScript); esm.writeHNOCString("SCRI", mScript);
if (mNpdtType == NPC_DEFAULT) if (mNpdtType == NPC_DEFAULT)
esm.writeHNT("NPDT", mNpdt52, 52); {
esm.writeHNT("NPDT", mNpdt, 52);
}
else if (mNpdtType == NPC_WITH_AUTOCALCULATED_STATS) 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); esm.writeHNT("FLAG", mFlags);
@ -171,25 +192,7 @@ namespace ESM
void NPC::blank() void NPC::blank()
{ {
mNpdtType = NPC_DEFAULT; mNpdtType = NPC_DEFAULT;
mNpdt52.mLevel = 0; blankNpdt();
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;
mFlags = 0; mFlags = 0;
mInventory.mList.clear(); mInventory.mList.clear();
mSpells.mList.clear(); mSpells.mList.clear();
@ -207,14 +210,27 @@ namespace ESM
mHead.clear(); 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 int NPC::getFactionRank() const
{ {
if (mFaction.empty()) if (mFaction.empty())
return -1; return -1;
else if (mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS) else
return mNpdt12.mRank; return mNpdt.mRank;
else // NPC_DEFAULT
return mNpdt52.mRank;
} }
const std::vector<Transport::Dest>& NPC::getTransport() const const std::vector<Transport::Dest>& NPC::getTransport() const

@ -95,6 +95,8 @@ struct NPC
int mGold; int mGold;
}; // 52 bytes }; // 52 bytes
//Structure for autocalculated characters.
// This is only used for load and save operations.
struct NPDTstruct12 struct NPDTstruct12
{ {
short mLevel; short mLevel;
@ -106,8 +108,9 @@ struct NPC
#pragma pack(pop) #pragma pack(pop)
unsigned char mNpdtType; unsigned char mNpdtType;
NPDTstruct52 mNpdt52; //Worth noting when saving the struct:
NPDTstruct12 mNpdt12; //for autocalculated characters // Although we might read a NPDTstruct12 in, we use NPDTstruct52 internally
NPDTstruct52 mNpdt;
int getFactionRank() const; /// wrapper for mNpdt*, -1 = no rank int getFactionRank() const; /// wrapper for mNpdt*, -1 = no rank
@ -141,6 +144,9 @@ struct NPC
void blank(); void blank();
///< Set record to default state (does not touch the ID). ///< Set record to default state (does not touch the ID).
/// Resets the mNpdt object
void blankNpdt();
}; };
} }
#endif #endif

@ -26,13 +26,23 @@ struct Static
/// Return a string descriptor for this record type. Currently used for debugging / error logs only. /// Return a string descriptor for this record type. Currently used for debugging / error logs only.
static std::string getRecordType() { return "Static"; } static std::string getRecordType() { return "Static"; }
std::string mId, mModel; std::string mId, mModel;
void load(ESMReader &esm, bool &isDeleted); void load(ESMReader &esm, bool &isDeleted);
void save(ESMWriter &esm, bool isDeleted = false) const; void save(ESMWriter &esm, bool isDeleted = false) const;
void blank(); void blank();
///< Set record to default state (does not touch the ID). ///< 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 #endif

@ -25,6 +25,11 @@ namespace mwmp
isFlying = false; isFlying = false;
} }
enum class AIAction : uint8_t
{
Follow = 0
};
std::string refId; std::string refId;
unsigned refNumIndex; unsigned refNumIndex;
unsigned mpNum; unsigned mpNum;
@ -33,6 +38,10 @@ namespace mwmp
Animation animation; Animation animation;
bool hasAiTarget;
Target aiTarget;
AIAction aiAction;
bool hasPositionData; bool hasPositionData;
bool hasStatsDynamicData; bool hasStatsDynamicData;
}; };

@ -11,5 +11,22 @@ PacketActorAI::PacketActorAI(RakNet::RakPeerInterface *peer) : ActorPacket(peer)
void PacketActorAI::Actor(BaseActor &actor, bool send) 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);
}
}
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 820 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 615 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 364 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 787 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 986 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 655 B

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save