mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 19:19:56 +00:00
Support eight possible blood types (feature #4958)
This commit is contained in:
parent
4d633fd3e6
commit
7814bd1b76
13 changed files with 75 additions and 127 deletions
|
@ -78,6 +78,7 @@
|
||||||
Feature #4859: Make water reflections more configurable
|
Feature #4859: Make water reflections more configurable
|
||||||
Feature #4887: Add openmw command option to set initial random seed
|
Feature #4887: Add openmw command option to set initial random seed
|
||||||
Feature #4890: Make Distant Terrain configurable
|
Feature #4890: Make Distant Terrain configurable
|
||||||
|
Feature #4958: Support eight blood types
|
||||||
Feature #4962: Add casting animations for magic items
|
Feature #4962: Add casting animations for magic items
|
||||||
Feature #4968: Scalable UI widget skins
|
Feature #4968: Scalable UI widget skins
|
||||||
Task #4686: Upgrade media decoder to a more current FFmpeg API
|
Task #4686: Upgrade media decoder to a more current FFmpeg API
|
||||||
|
|
|
@ -704,29 +704,25 @@ std::string creatureFlags(int flags)
|
||||||
{
|
{
|
||||||
std::string properties;
|
std::string properties;
|
||||||
if (flags == 0) properties += "[None] ";
|
if (flags == 0) properties += "[None] ";
|
||||||
if (flags & ESM::Creature::None) properties += "All ";
|
if (flags & ESM::Creature::Base) properties += "Base ";
|
||||||
if (flags & ESM::Creature::Walks) properties += "Walks ";
|
if (flags & ESM::Creature::Walks) properties += "Walks ";
|
||||||
if (flags & ESM::Creature::Swims) properties += "Swims ";
|
if (flags & ESM::Creature::Swims) properties += "Swims ";
|
||||||
if (flags & ESM::Creature::Flies) properties += "Flies ";
|
if (flags & ESM::Creature::Flies) properties += "Flies ";
|
||||||
if (flags & ESM::Creature::Bipedal) properties += "Bipedal ";
|
if (flags & ESM::Creature::Bipedal) properties += "Bipedal ";
|
||||||
if (flags & ESM::Creature::Respawn) properties += "Respawn ";
|
if (flags & ESM::Creature::Respawn) properties += "Respawn ";
|
||||||
if (flags & ESM::Creature::Weapon) properties += "Weapon ";
|
if (flags & ESM::Creature::Weapon) properties += "Weapon ";
|
||||||
if (flags & ESM::Creature::Skeleton) properties += "Skeleton ";
|
|
||||||
if (flags & ESM::Creature::Metal) properties += "Metal ";
|
|
||||||
if (flags & ESM::Creature::Essential) properties += "Essential ";
|
if (flags & ESM::Creature::Essential) properties += "Essential ";
|
||||||
int unused = (0xFFFFFFFF ^
|
int unused = (0xFF ^
|
||||||
(ESM::Creature::None|
|
(ESM::Creature::Base|
|
||||||
ESM::Creature::Walks|
|
ESM::Creature::Walks|
|
||||||
ESM::Creature::Swims|
|
ESM::Creature::Swims|
|
||||||
ESM::Creature::Flies|
|
ESM::Creature::Flies|
|
||||||
ESM::Creature::Bipedal|
|
ESM::Creature::Bipedal|
|
||||||
ESM::Creature::Respawn|
|
ESM::Creature::Respawn|
|
||||||
ESM::Creature::Weapon|
|
ESM::Creature::Weapon|
|
||||||
ESM::Creature::Skeleton|
|
|
||||||
ESM::Creature::Metal|
|
|
||||||
ESM::Creature::Essential));
|
ESM::Creature::Essential));
|
||||||
if (flags & unused) properties += "Invalid ";
|
if (flags & unused) properties += "Invalid ";
|
||||||
properties += str(boost::format("(0x%08X)") % flags);
|
properties += str(boost::format("(0x%02X)") % flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -828,33 +824,21 @@ std::string npcFlags(int flags)
|
||||||
{
|
{
|
||||||
std::string properties;
|
std::string properties;
|
||||||
if (flags == 0) properties += "[None] ";
|
if (flags == 0) properties += "[None] ";
|
||||||
// Mythicmods and the ESM component differ. Mythicmods says
|
if (flags & ESM::NPC::Base) properties += "Base ";
|
||||||
// 0x8=None and 0x10=AutoCalc, while our code previously defined
|
|
||||||
// 0x8 as AutoCalc. The former seems to be correct. All Bethesda
|
|
||||||
// records have bit 0x8 set. Previously, suspiciously large portion
|
|
||||||
// of females had autocalc turned off.
|
|
||||||
if (flags & 0x00000008) properties += "Unknown ";
|
|
||||||
if (flags & ESM::NPC::Autocalc) properties += "Autocalc ";
|
if (flags & ESM::NPC::Autocalc) properties += "Autocalc ";
|
||||||
if (flags & ESM::NPC::Female) properties += "Female ";
|
if (flags & ESM::NPC::Female) properties += "Female ";
|
||||||
if (flags & ESM::NPC::Respawn) properties += "Respawn ";
|
if (flags & ESM::NPC::Respawn) properties += "Respawn ";
|
||||||
if (flags & ESM::NPC::Essential) properties += "Essential ";
|
if (flags & ESM::NPC::Essential) properties += "Essential ";
|
||||||
// These two flags do not appear on any NPCs and may have been
|
|
||||||
// confused with the flags for creatures.
|
|
||||||
if (flags & ESM::NPC::Skeleton) properties += "Skeleton ";
|
|
||||||
if (flags & ESM::NPC::Metal) properties += "Metal ";
|
|
||||||
// Whether corpses persist is a bit that is unaccounted for,
|
// Whether corpses persist is a bit that is unaccounted for,
|
||||||
// however the only unknown bit occurs on ALL records, and
|
// however relatively few NPCs have this bit set.
|
||||||
// relatively few NPCs have this bit set.
|
int unused = (0xFF ^
|
||||||
int unused = (0xFFFFFFFF ^
|
(ESM::NPC::Base|
|
||||||
(0x00000008|
|
|
||||||
ESM::NPC::Autocalc|
|
ESM::NPC::Autocalc|
|
||||||
ESM::NPC::Female|
|
ESM::NPC::Female|
|
||||||
ESM::NPC::Respawn|
|
ESM::NPC::Respawn|
|
||||||
ESM::NPC::Essential|
|
ESM::NPC::Essential));
|
||||||
ESM::NPC::Skeleton|
|
|
||||||
ESM::NPC::Metal));
|
|
||||||
if (flags & unused) properties += "Invalid ";
|
if (flags & unused) properties += "Invalid ";
|
||||||
properties += str(boost::format("(0x%08X)") % flags);
|
properties += str(boost::format("(0x%02X)") % flags);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -618,7 +618,8 @@ void Record<ESM::Creature>::print()
|
||||||
std::cout << " Name: " << mData.mName << std::endl;
|
std::cout << " Name: " << mData.mName << std::endl;
|
||||||
std::cout << " Model: " << mData.mModel << std::endl;
|
std::cout << " Model: " << mData.mModel << std::endl;
|
||||||
std::cout << " Script: " << mData.mScript << std::endl;
|
std::cout << " Script: " << mData.mScript << std::endl;
|
||||||
std::cout << " Flags: " << creatureFlags(mData.mFlags) << std::endl;
|
std::cout << " Flags: " << creatureFlags((int)mData.mFlags) << std::endl;
|
||||||
|
std::cout << " Blood Type: " << mData.mBloodType+1 << std::endl;
|
||||||
std::cout << " Original: " << mData.mOriginal << std::endl;
|
std::cout << " Original: " << mData.mOriginal << std::endl;
|
||||||
std::cout << " Scale: " << mData.mScale << std::endl;
|
std::cout << " Scale: " << mData.mScale << std::endl;
|
||||||
|
|
||||||
|
@ -1022,7 +1023,9 @@ void Record<ESM::NPC>::print()
|
||||||
std::cout << " Script: " << mData.mScript << std::endl;
|
std::cout << " Script: " << mData.mScript << std::endl;
|
||||||
if (!mData.mFaction.empty())
|
if (!mData.mFaction.empty())
|
||||||
std::cout << " Faction: " << mData.mFaction << std::endl;
|
std::cout << " Faction: " << mData.mFaction << std::endl;
|
||||||
std::cout << " Flags: " << npcFlags(mData.mFlags) << std::endl;
|
std::cout << " Flags: " << npcFlags((int)mData.mFlags) << std::endl;
|
||||||
|
if (mData.mBloodType != 0)
|
||||||
|
std::cout << " Blood Type: " << mData.mBloodType+1 << std::endl;
|
||||||
|
|
||||||
if (mData.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
if (mData.mNpdtType == ESM::NPC::NPC_WITH_AUTOCALCULATED_STATS)
|
||||||
{
|
{
|
||||||
|
|
|
@ -230,9 +230,19 @@ MwIniImporter::MwIniImporter()
|
||||||
"Blood:Texture 0",
|
"Blood:Texture 0",
|
||||||
"Blood:Texture 1",
|
"Blood:Texture 1",
|
||||||
"Blood:Texture 2",
|
"Blood:Texture 2",
|
||||||
|
"Blood:Texture 3",
|
||||||
|
"Blood:Texture 4",
|
||||||
|
"Blood:Texture 5",
|
||||||
|
"Blood:Texture 6",
|
||||||
|
"Blood:Texture 7",
|
||||||
"Blood:Texture Name 0",
|
"Blood:Texture Name 0",
|
||||||
"Blood:Texture Name 1",
|
"Blood:Texture Name 1",
|
||||||
"Blood:Texture Name 2",
|
"Blood:Texture Name 2",
|
||||||
|
"Blood:Texture Name 3",
|
||||||
|
"Blood:Texture Name 4",
|
||||||
|
"Blood:Texture Name 5",
|
||||||
|
"Blood:Texture Name 6",
|
||||||
|
"Blood:Texture Name 7",
|
||||||
|
|
||||||
// movies
|
// movies
|
||||||
"Movies:Company Logo",
|
"Movies:Company Logo",
|
||||||
|
@ -624,17 +634,6 @@ MwIniImporter::MwIniImporter()
|
||||||
"Moons:Masser Fade Out Finish",
|
"Moons:Masser Fade Out Finish",
|
||||||
"Moons:Script Color",
|
"Moons:Script Color",
|
||||||
|
|
||||||
// blood
|
|
||||||
"Blood:Model 0",
|
|
||||||
"Blood:Model 1",
|
|
||||||
"Blood:Model 2",
|
|
||||||
"Blood:Texture 0",
|
|
||||||
"Blood:Texture 1",
|
|
||||||
"Blood:Texture 2",
|
|
||||||
"Blood:Texture Name 0",
|
|
||||||
"Blood:Texture Name 1",
|
|
||||||
"Blood:Texture Name 2",
|
|
||||||
|
|
||||||
// werewolf (Bloodmoon)
|
// werewolf (Bloodmoon)
|
||||||
"General:Werewolf FOV",
|
"General:Werewolf FOV",
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "columns.hpp"
|
#include "columns.hpp"
|
||||||
|
|
||||||
|
#include <components/fallback/fallback.hpp>
|
||||||
#include <components/misc/stringops.hpp>
|
#include <components/misc/stringops.hpp>
|
||||||
|
|
||||||
#include "universalid.hpp"
|
#include "universalid.hpp"
|
||||||
|
@ -573,11 +574,6 @@ namespace
|
||||||
"Book", "Scroll", 0
|
"Book", "Scroll", 0
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *sBloodType[] =
|
|
||||||
{
|
|
||||||
"Default (Red)", "Skeleton Blood (White)", "Metal Blood (Golden)", 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *sEmitterType[] =
|
static const char *sEmitterType[] =
|
||||||
{
|
{
|
||||||
"<None>", "Flickering", "Flickering (Slow)", "Pulsing", "Pulsing (Slow)", 0
|
"<None>", "Flickering", "Flickering (Slow)", "Pulsing", "Pulsing (Slow)", 0
|
||||||
|
@ -613,7 +609,6 @@ namespace
|
||||||
case CSMWorld::Columns::ColumnId_InfoCondFunc: return CSMWorld::ConstInfoSelectWrapper::FunctionEnumStrings;
|
case CSMWorld::Columns::ColumnId_InfoCondFunc: return CSMWorld::ConstInfoSelectWrapper::FunctionEnumStrings;
|
||||||
case CSMWorld::Columns::ColumnId_InfoCondComp: return CSMWorld::ConstInfoSelectWrapper::RelationEnumStrings;
|
case CSMWorld::Columns::ColumnId_InfoCondComp: return CSMWorld::ConstInfoSelectWrapper::RelationEnumStrings;
|
||||||
case CSMWorld::Columns::ColumnId_BookType: return sBookType;
|
case CSMWorld::Columns::ColumnId_BookType: return sBookType;
|
||||||
case CSMWorld::Columns::ColumnId_BloodType: return sBloodType;
|
|
||||||
case CSMWorld::Columns::ColumnId_EmitterType: return sEmitterType;
|
case CSMWorld::Columns::ColumnId_EmitterType: return sEmitterType;
|
||||||
|
|
||||||
default: return 0;
|
default: return 0;
|
||||||
|
@ -633,6 +628,15 @@ std::vector<std::pair<int,std::string>>CSMWorld::Columns::getEnums (ColumnId col
|
||||||
if (const char **table = getEnumNames (column))
|
if (const char **table = getEnumNames (column))
|
||||||
for (int i=0; table[i]; ++i)
|
for (int i=0; table[i]; ++i)
|
||||||
enums.emplace_back(i, table[i]);
|
enums.emplace_back(i, table[i]);
|
||||||
|
else if (column==ColumnId_BloodType)
|
||||||
|
{
|
||||||
|
for (int i=0; i<8; i++)
|
||||||
|
{
|
||||||
|
const std::string& bloodName = Fallback::Map::getString("Blood_Texture_Name_" + std::to_string(i));
|
||||||
|
if (!bloodName.empty())
|
||||||
|
enums.emplace_back(i, bloodName);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (column==ColumnId_RecordType)
|
else if (column==ColumnId_RecordType)
|
||||||
{
|
{
|
||||||
enums.emplace_back(UniversalId::Type_None, ""); // none
|
enums.emplace_back(UniversalId::Type_None, ""); // none
|
||||||
|
|
|
@ -491,17 +491,7 @@ QVariant CSMWorld::CreatureRefIdAdapter::getData (const RefIdColumn *column, con
|
||||||
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
||||||
|
|
||||||
if (column == mColumns.mBloodType)
|
if (column == mColumns.mBloodType)
|
||||||
{
|
return record.get().mBloodType;
|
||||||
int mask = ESM::Creature::Skeleton | ESM::Creature::Metal;
|
|
||||||
|
|
||||||
if ((record.get().mFlags & mask) == ESM::Creature::Skeleton)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if ((record.get().mFlags & mask) == ESM::Creature::Metal)
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||||
mColumns.mFlags.find (column);
|
mColumns.mFlags.find (column);
|
||||||
|
@ -527,16 +517,7 @@ void CSMWorld::CreatureRefIdAdapter::setData (const RefIdColumn *column, RefIdDa
|
||||||
else if (column==mColumns.mOriginal)
|
else if (column==mColumns.mOriginal)
|
||||||
creature.mOriginal = value.toString().toUtf8().constData();
|
creature.mOriginal = value.toString().toUtf8().constData();
|
||||||
else if (column == mColumns.mBloodType)
|
else if (column == mColumns.mBloodType)
|
||||||
{
|
creature.mBloodType = value.toInt();
|
||||||
int mask = ~(ESM::Creature::Skeleton | ESM::Creature::Metal);
|
|
||||||
|
|
||||||
if (value.toInt() == 1)
|
|
||||||
creature.mFlags = (creature.mFlags & mask) | ESM::Creature::Skeleton;
|
|
||||||
else if (value.toInt() == 2)
|
|
||||||
creature.mFlags = (creature.mFlags & mask) | ESM::Creature::Metal;
|
|
||||||
else
|
|
||||||
creature.mFlags = creature.mFlags & mask;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
std::map<const RefIdColumn *, unsigned int>::const_iterator iter =
|
||||||
|
@ -797,17 +778,7 @@ QVariant CSMWorld::NpcRefIdAdapter::getData (const RefIdColumn *column, const Re
|
||||||
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
return QVariant::fromValue(ColumnBase::TableEdit_Full);
|
||||||
|
|
||||||
if (column == mColumns.mBloodType)
|
if (column == mColumns.mBloodType)
|
||||||
{
|
return record.get().mBloodType;
|
||||||
int mask = ESM::NPC::Skeleton | ESM::NPC::Metal;
|
|
||||||
|
|
||||||
if ((record.get().mFlags & mask) == ESM::NPC::Skeleton)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if ((record.get().mFlags & mask) == ESM::NPC::Metal)
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (column == mColumns.mGender)
|
if (column == mColumns.mGender)
|
||||||
{
|
{
|
||||||
|
@ -846,16 +817,7 @@ void CSMWorld::NpcRefIdAdapter::setData (const RefIdColumn *column, RefIdData& d
|
||||||
else if (column==mColumns.mHead)
|
else if (column==mColumns.mHead)
|
||||||
npc.mHead = value.toString().toUtf8().constData();
|
npc.mHead = value.toString().toUtf8().constData();
|
||||||
else if (column == mColumns.mBloodType)
|
else if (column == mColumns.mBloodType)
|
||||||
{
|
npc.mBloodType = value.toInt();
|
||||||
int mask = ~(ESM::NPC::Skeleton | ESM::NPC::Metal);
|
|
||||||
|
|
||||||
if (value.toInt() == 1)
|
|
||||||
npc.mFlags = (npc.mFlags & mask) | ESM::NPC::Skeleton;
|
|
||||||
else if (value.toInt() == 2)
|
|
||||||
npc.mFlags = (npc.mFlags & mask) | ESM::NPC::Metal;
|
|
||||||
else
|
|
||||||
npc.mFlags = npc.mFlags & mask;
|
|
||||||
}
|
|
||||||
else if (column == mColumns.mGender)
|
else if (column == mColumns.mGender)
|
||||||
{
|
{
|
||||||
// Implemented this way to allow additional gender types in the future.
|
// Implemented this way to allow additional gender types in the future.
|
||||||
|
|
|
@ -766,13 +766,7 @@ namespace MWClass
|
||||||
|
|
||||||
int Creature::getBloodTexture(const MWWorld::ConstPtr &ptr) const
|
int Creature::getBloodTexture(const MWWorld::ConstPtr &ptr) const
|
||||||
{
|
{
|
||||||
int flags = ptr.get<ESM::Creature>()->mBase->mFlags;
|
return ptr.get<ESM::Creature>()->mBase->mBloodType;
|
||||||
|
|
||||||
if (flags & ESM::Creature::Skeleton)
|
|
||||||
return 1;
|
|
||||||
if (flags & ESM::Creature::Metal)
|
|
||||||
return 2;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Creature::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)
|
void Creature::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)
|
||||||
|
|
|
@ -1286,13 +1286,7 @@ namespace MWClass
|
||||||
|
|
||||||
int Npc::getBloodTexture(const MWWorld::ConstPtr &ptr) const
|
int Npc::getBloodTexture(const MWWorld::ConstPtr &ptr) const
|
||||||
{
|
{
|
||||||
const MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
|
return ptr.get<ESM::NPC>()->mBase->mBloodType;
|
||||||
|
|
||||||
if (ref->mBase->mFlags & ESM::NPC::Skeleton)
|
|
||||||
return 1;
|
|
||||||
if (ref->mBase->mFlags & ESM::NPC::Metal)
|
|
||||||
return 2;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Npc::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)
|
void Npc::readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)
|
||||||
|
|
|
@ -3585,7 +3585,11 @@ namespace MWWorld
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::string texture = Fallback::Map::getString("Blood_Texture_" + std::to_string(ptr.getClass().getBloodTexture(ptr)));
|
std::string texture = Fallback::Map::getString("Blood_Texture_" + std::to_string(ptr.getClass().getBloodTexture(ptr)));
|
||||||
|
if (texture.empty())
|
||||||
|
texture = Fallback::Map::getString("Blood_Texture_0");
|
||||||
|
|
||||||
std::string model = "meshes\\" + Fallback::Map::getString("Blood_Model_" + std::to_string(Misc::Rng::rollDice(3))); // [0, 2]
|
std::string model = "meshes\\" + Fallback::Map::getString("Blood_Model_" + std::to_string(Misc::Rng::rollDice(3))); // [0, 2]
|
||||||
|
|
||||||
mRendering->spawnEffect(model, texture, worldPosition, 1.0f, false);
|
mRendering->spawnEffect(model, texture, worldPosition, 1.0f, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,10 @@ namespace ESM {
|
||||||
hasNpdt = true;
|
hasNpdt = true;
|
||||||
break;
|
break;
|
||||||
case ESM::FourCC<'F','L','A','G'>::value:
|
case ESM::FourCC<'F','L','A','G'>::value:
|
||||||
esm.getHT(mFlags);
|
int flags;
|
||||||
|
esm.getHT(flags);
|
||||||
|
mFlags = flags & 0xFF;
|
||||||
|
mBloodType = ((flags >> 8) & 0xFF) >> 2;
|
||||||
hasFlags = true;
|
hasFlags = true;
|
||||||
break;
|
break;
|
||||||
case ESM::FourCC<'X','S','C','L'>::value:
|
case ESM::FourCC<'X','S','C','L'>::value:
|
||||||
|
@ -121,7 +124,7 @@ namespace ESM {
|
||||||
esm.writeHNOCString("FNAM", mName);
|
esm.writeHNOCString("FNAM", mName);
|
||||||
esm.writeHNOCString("SCRI", mScript);
|
esm.writeHNOCString("SCRI", mScript);
|
||||||
esm.writeHNT("NPDT", mData, 96);
|
esm.writeHNT("NPDT", mData, 96);
|
||||||
esm.writeHNT("FLAG", mFlags);
|
esm.writeHNT("FLAG", ((mBloodType << 10) + mFlags));
|
||||||
if (mScale != 1.0) {
|
if (mScale != 1.0) {
|
||||||
esm.writeHNT("XSCL", mScale);
|
esm.writeHNT("XSCL", mScale);
|
||||||
}
|
}
|
||||||
|
@ -144,6 +147,7 @@ namespace ESM {
|
||||||
mData.mCombat = mData.mMagic = mData.mStealth = 0;
|
mData.mCombat = mData.mMagic = mData.mStealth = 0;
|
||||||
for (int i=0; i<6; ++i) mData.mAttack[i] = 0;
|
for (int i=0; i<6; ++i) mData.mAttack[i] = 0;
|
||||||
mData.mGold = 0;
|
mData.mGold = 0;
|
||||||
|
mBloodType = 0;
|
||||||
mFlags = 0;
|
mFlags = 0;
|
||||||
mScale = 1.f;
|
mScale = 1.f;
|
||||||
mModel.clear();
|
mModel.clear();
|
||||||
|
|
|
@ -28,20 +28,14 @@ struct Creature
|
||||||
// Default is 0x48?
|
// Default is 0x48?
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
// Movement types
|
Bipedal = 0x01,
|
||||||
Bipedal = 0x001,
|
Respawn = 0x02,
|
||||||
Swims = 0x010,
|
Weapon = 0x04, // Has weapon and shield
|
||||||
Flies = 0x020, // Don't know what happens if several
|
Base = 0x08, // This flag is set for every actor in Bethesda ESMs
|
||||||
Walks = 0x040, // of these are set
|
Swims = 0x10,
|
||||||
|
Flies = 0x20, // Don't know what happens if several
|
||||||
Respawn = 0x002,
|
Walks = 0x40, // of these are set
|
||||||
Weapon = 0x004, // Has weapon and shield
|
Essential = 0x80
|
||||||
None = 0x008, // ?? This flag appears set for every creature in Morrowind.esm
|
|
||||||
Essential = 0x080,
|
|
||||||
|
|
||||||
// Blood types
|
|
||||||
Skeleton = 0x400,
|
|
||||||
Metal = 0x800
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Type
|
enum Type
|
||||||
|
@ -79,7 +73,8 @@ struct Creature
|
||||||
|
|
||||||
NPDTstruct mData;
|
NPDTstruct mData;
|
||||||
|
|
||||||
int mFlags;
|
int mBloodType;
|
||||||
|
unsigned char mFlags;
|
||||||
|
|
||||||
bool mPersistent;
|
bool mPersistent;
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,10 @@ namespace ESM
|
||||||
break;
|
break;
|
||||||
case ESM::FourCC<'F','L','A','G'>::value:
|
case ESM::FourCC<'F','L','A','G'>::value:
|
||||||
hasFlags = true;
|
hasFlags = true;
|
||||||
esm.getHT(mFlags);
|
int flags;
|
||||||
|
esm.getHT(flags);
|
||||||
|
mFlags = flags & 0xFF;
|
||||||
|
mBloodType = ((flags >> 8) & 0xFF) >> 2;
|
||||||
break;
|
break;
|
||||||
case ESM::FourCC<'N','P','C','S'>::value:
|
case ESM::FourCC<'N','P','C','S'>::value:
|
||||||
mSpells.add(esm);
|
mSpells.add(esm);
|
||||||
|
@ -160,7 +163,7 @@ namespace ESM
|
||||||
esm.writeHNT("NPDT", npdt12, 12);
|
esm.writeHNT("NPDT", npdt12, 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
esm.writeHNT("FLAG", mFlags);
|
esm.writeHNT("FLAG", ((mBloodType << 10) + mFlags));
|
||||||
|
|
||||||
mInventory.save(esm);
|
mInventory.save(esm);
|
||||||
mSpells.save(esm);
|
mSpells.save(esm);
|
||||||
|
@ -186,6 +189,7 @@ namespace ESM
|
||||||
{
|
{
|
||||||
mNpdtType = NPC_DEFAULT;
|
mNpdtType = NPC_DEFAULT;
|
||||||
blankNpdt();
|
blankNpdt();
|
||||||
|
mBloodType = 0;
|
||||||
mFlags = 0;
|
mFlags = 0;
|
||||||
mInventory.mList.clear();
|
mInventory.mList.clear();
|
||||||
mSpells.mList.clear();
|
mSpells.mList.clear();
|
||||||
|
|
|
@ -56,12 +56,11 @@ struct NPC
|
||||||
|
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
Female = 0x0001,
|
Female = 0x01,
|
||||||
Essential = 0x0002,
|
Essential = 0x02,
|
||||||
Respawn = 0x0004,
|
Respawn = 0x04,
|
||||||
Autocalc = 0x0010,
|
Base = 0x08,
|
||||||
Skeleton = 0x0400, // Skeleton blood effect (white)
|
Autocalc = 0x10
|
||||||
Metal = 0x0800 // Metal blood effect (golden?)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum NpcType
|
enum NpcType
|
||||||
|
@ -114,7 +113,8 @@ struct NPC
|
||||||
|
|
||||||
int getFactionRank() const; /// wrapper for mNpdt*, -1 = no rank
|
int getFactionRank() const; /// wrapper for mNpdt*, -1 = no rank
|
||||||
|
|
||||||
int mFlags;
|
int mBloodType;
|
||||||
|
unsigned char mFlags;
|
||||||
|
|
||||||
bool mPersistent;
|
bool mPersistent;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue