Basic RefData and CellRef change tracking

Wrapped item charge handling in getItemHealth function
This commit is contained in:
scrawl 2014-05-25 14:13:07 +02:00
parent a05c8fd3ce
commit 039398c8ae
79 changed files with 720 additions and 407 deletions

View file

@ -57,7 +57,7 @@ add_openmw_dir (mwworld
cells localscripts customdata weather inventorystore ptr actionopen actionread cells localscripts customdata weather inventorystore ptr actionopen actionread
actionequip timestamp actionalchemy cellstore actionapply actioneat actionequip timestamp actionalchemy cellstore actionapply actioneat
esmstore store recordcmp fallback actionrepair actionsoulgem livecellref actiondoor esmstore store recordcmp fallback actionrepair actionsoulgem livecellref actiondoor
contentloader esmloader omwloader actiontrap cellreflist projectilemanager contentloader esmloader omwloader actiontrap cellreflist projectilemanager cellref
) )
add_openmw_dir (mwclass add_openmw_dir (mwclass

View file

@ -97,8 +97,8 @@ namespace MWClass
std::string text; std::string text;
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) if (MWBase::Environment::get().getWindowManager()->getFullHelp())
{ {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.text = text; info.text = text;

View file

@ -127,8 +127,8 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.text = text; info.text = text;

View file

@ -168,10 +168,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Armor> *ref = MWWorld::LiveCellRef<ESM::Armor> *ref =
ptr.get<ESM::Armor>(); ptr.get<ESM::Armor>();
if (ptr.getCellRef().mCharge == -1) return ref->mBase->mData.mValue * (static_cast<float>(getItemHealth(ptr)) / getItemMaxHealth(ptr));
return ref->mBase->mData.mValue;
else
return ref->mBase->mData.mValue * (static_cast<float>(ptr.getCellRef().mCharge) / getItemMaxHealth(ptr));
} }
void Armor::registerSelf() void Armor::registerSelf()
@ -242,7 +239,7 @@ namespace MWClass
text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->mBase->mData.mArmor); text += "\n#{sArmorRating}: " + MWGui::ToolTips::toString(ref->mBase->mData.mArmor);
int remainingHealth = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mHealth; int remainingHealth = getItemHealth(ptr);
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(remainingHealth) + "/" text += "\n#{sCondition}: " + MWGui::ToolTips::toString(remainingHealth) + "/"
+ MWGui::ToolTips::toString(ref->mBase->mData.mHealth); + MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
@ -250,14 +247,14 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.enchant = ref->mBase->mEnchant; info.enchant = ref->mBase->mEnchant;
if (!info.enchant.empty()) if (!info.enchant.empty())
info.remainingEnchantCharge = ptr.getCellRef().mEnchantmentCharge; info.remainingEnchantCharge = ptr.getCellRef().getEnchantmentCharge();
info.text = text; info.text = text;
@ -290,7 +287,7 @@ namespace MWClass
{ {
MWWorld::InventoryStore& invStore = npc.getClass().getInventoryStore(npc); MWWorld::InventoryStore& invStore = npc.getClass().getInventoryStore(npc);
if (ptr.getCellRef().mCharge == 0) if (ptr.getCellRef().getCharge() == 0)
return std::make_pair(0, "#{sInventoryMessage1}"); return std::make_pair(0, "#{sInventoryMessage1}");
// slots that this item can be equipped in // slots that this item can be equipped in

View file

@ -139,8 +139,8 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }

View file

@ -193,14 +193,14 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
info.enchant = ref->mBase->mEnchant; info.enchant = ref->mBase->mEnchant;
if (!info.enchant.empty()) if (!info.enchant.empty())
info.remainingEnchantCharge = ptr.getCellRef().mEnchantmentCharge; info.remainingEnchantCharge = ptr.getCellRef().getEnchantmentCharge();
info.text = text; info.text = text;

View file

@ -53,7 +53,7 @@ namespace MWClass
ptr.get<ESM::Container>(); ptr.get<ESM::Container>();
data->mContainerStore.fill( data->mContainerStore.fill(
ref->mBase->mInventory, ptr.getCellRef().mOwner, ptr.getCellRef().mFaction, MWBase::Environment::get().getWorld()->getStore()); ref->mBase->mInventory, ptr.getCellRef().getOwner(), ptr.getCellRef().getFaction(), MWBase::Environment::get().getWorld()->getStore());
// store // store
ptr.getRefData().setCustomData (data.release()); ptr.getRefData().setCustomData (data.release());
@ -75,7 +75,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Container> *ref = ptr.get<ESM::Container>(); MWWorld::LiveCellRef<ESM::Container> *ref = ptr.get<ESM::Container>();
const ESM::InventoryList& list = ref->mBase->mInventory; const ESM::InventoryList& list = ref->mBase->mInventory;
MWWorld::ContainerStore& store = getContainerStore(ptr); MWWorld::ContainerStore& store = getContainerStore(ptr);
store.restock(list, ptr, ptr.getCellRef().mOwner, ptr.getCellRef().mFaction); store.restock(list, ptr, ptr.getCellRef().getOwner(), ptr.getCellRef().getFaction());
} }
void Container::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const void Container::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -129,16 +129,16 @@ namespace MWClass
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
MWWorld::InventoryStore& invStore = player.getClass().getInventoryStore(player); MWWorld::InventoryStore& invStore = player.getClass().getInventoryStore(player);
bool needKey = ptr.getCellRef().mLockLevel > 0; bool needKey = ptr.getCellRef().getLockLevel() > 0;
bool hasKey = false; bool hasKey = false;
std::string keyName; std::string keyName;
// make key id lowercase // make key id lowercase
std::string keyId = ptr.getCellRef().mKey; std::string keyId = ptr.getCellRef().getKey();
Misc::StringUtils::toLower(keyId); Misc::StringUtils::toLower(keyId);
for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it) for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it)
{ {
std::string refId = it->getCellRef().mRefID; std::string refId = it->getCellRef().getRefId();
Misc::StringUtils::toLower(refId); Misc::StringUtils::toLower(refId);
if (refId == keyId) if (refId == keyId)
{ {
@ -152,13 +152,13 @@ namespace MWClass
MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}"); MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}");
unlock(ptr); unlock(ptr);
// using a key disarms the trap // using a key disarms the trap
ptr.getCellRef().mTrap = ""; ptr.getCellRef().setTrap("");
} }
if (!needKey || hasKey) if (!needKey || hasKey)
{ {
if(ptr.getCellRef().mTrap.empty()) if(ptr.getCellRef().getTrap().empty())
{ {
boost::shared_ptr<MWWorld::Action> action (new MWWorld::ActionOpen(ptr)); boost::shared_ptr<MWWorld::Action> action (new MWWorld::ActionOpen(ptr));
return action; return action;
@ -166,7 +166,7 @@ namespace MWClass
else else
{ {
// Activate trap // Activate trap
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTrap(actor, ptr.getCellRef().mTrap, ptr)); boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTrap(actor, ptr.getCellRef().getTrap(), ptr));
action->setSound(trapActivationSound); action->setSound(trapActivationSound);
return action; return action;
} }
@ -227,16 +227,16 @@ namespace MWClass
info.caption = ref->mBase->mName; info.caption = ref->mBase->mName;
std::string text; std::string text;
if (ref->mRef.mLockLevel > 0) if (ptr.getCellRef().getLockLevel() > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel); text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ptr.getCellRef().getLockLevel());
else if (ref->mRef.mLockLevel < 0) else if (ptr.getCellRef().getLockLevel() < 0)
text += "\n#{sUnlocked}"; text += "\n#{sUnlocked}";
if (ref->mRef.mTrap != "") if (ptr.getCellRef().getTrap() != "")
text += "\n#{sTrapped}"; text += "\n#{sTrapped}";
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
@ -261,14 +261,14 @@ namespace MWClass
void Container::lock (const MWWorld::Ptr& ptr, int lockLevel) const void Container::lock (const MWWorld::Ptr& ptr, int lockLevel) const
{ {
if(lockLevel!=0) if(lockLevel!=0)
ptr.getCellRef().mLockLevel = abs(lockLevel); //Changes lock to locklevel, in positive ptr.getCellRef().setLockLevel(abs(lockLevel)); //Changes lock to locklevel, in positive
else else
ptr.getCellRef().mLockLevel = abs(ptr.getCellRef().mLockLevel); //No locklevel given, just flip the oriional one ptr.getCellRef().setLockLevel(abs(ptr.getCellRef().getLockLevel())); //No locklevel given, just flip the original one
} }
void Container::unlock (const MWWorld::Ptr& ptr) const void Container::unlock (const MWWorld::Ptr& ptr) const
{ {
ptr.getCellRef().mLockLevel = -abs(ptr.getCellRef().mLockLevel); //Makes lockLevel negative ptr.getCellRef().setLockLevel(-abs(ptr.getCellRef().getLockLevel())); //Makes lockLevel negative
} }

View file

@ -291,20 +291,24 @@ namespace MWClass
weaponDamage *= 0.5f + (stats.getAttribute(ESM::Attribute::Luck).getModified() / 100.0f); weaponDamage *= 0.5f + (stats.getAttribute(ESM::Attribute::Luck).getModified() / 100.0f);
if(weaphashealth) if(weaphashealth)
{ {
int weapmaxhealth = weapon.get<ESM::Weapon>()->mBase->mData.mHealth; int weapmaxhealth = weapon.getClass().getItemMaxHealth(weapon);
if(weapon.getCellRef().mCharge == -1) int weaphealth = weapon.getClass().getItemHealth(weapon);
weapon.getCellRef().mCharge = weapmaxhealth; weaponDamage *= float(weaphealth) / weapmaxhealth;
weaponDamage *= float(weapon.getCellRef().mCharge) / weapmaxhealth;
if (!MWBase::Environment::get().getWorld()->getGodModeState())
{
// Reduce weapon charge by at least one, but cap at 0
weaphealth -= std::min(std::max(1,
(int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), weaphealth);
weapon.getCellRef().setCharge(weaphealth);
}
// Weapon broken? unequip it
if (weapon.getCellRef().getCharge() == 0)
weapon = *getInventoryStore(ptr).unequipItem(weapon, ptr);
} }
if (!MWBase::Environment::get().getWorld()->getGodModeState())
weapon.getCellRef().mCharge -= std::min(std::max(1,
(int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), weapon.getCellRef().mCharge);
// Weapon broken? unequip it
if (weapon.getCellRef().mCharge == 0)
weapon = *getInventoryStore(ptr).unequipItem(weapon, ptr);
damage += weaponDamage; damage += weaponDamage;
} }
@ -825,14 +829,14 @@ namespace MWClass
{ {
// Note we do not respawn moved references in the cell they were moved to. Instead they are respawned in the original cell. // Note we do not respawn moved references in the cell they were moved to. Instead they are respawned in the original cell.
// This also means we cannot respawn dynamically placed references with no content file connection. // This also means we cannot respawn dynamically placed references with no content file connection.
if (ptr.getCellRef().mRefNum.mContentFile != -1) if (ptr.getCellRef().getRefNum().mContentFile != -1)
{ {
if (ptr.getRefData().getCount() == 0) if (ptr.getRefData().getCount() == 0)
ptr.getRefData().setCount(1); ptr.getRefData().setCount(1);
// Reset to original position // Reset to original position
ESM::Position& pos = ptr.getRefData().getPosition(); ESM::Position& pos = ptr.getRefData().getPosition();
pos = ptr.getCellRef().mPos; pos = ptr.getCellRef().getPosition();
ptr.getRefData().setCustomData(NULL); ptr.getRefData().setCustomData(NULL);
} }
@ -844,7 +848,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>(); MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
const ESM::InventoryList& list = ref->mBase->mInventory; const ESM::InventoryList& list = ref->mBase->mInventory;
MWWorld::ContainerStore& store = getContainerStore(ptr); MWWorld::ContainerStore& store = getContainerStore(ptr);
store.restock(list, ptr, ptr.getCellRef().mRefID, ptr.getCellRef().mFaction); store.restock(list, ptr, ptr.getCellRef().getRefId(), ptr.getCellRef().getFaction());
} }
const ESM::GameSetting* Creature::fMinWalkSpeedCreature; const ESM::GameSetting* Creature::fMinWalkSpeedCreature;

View file

@ -73,8 +73,8 @@ namespace MWClass
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
MWWorld::ManualRef ref(store, id); MWWorld::ManualRef ref(store, id);
ref.getPtr().getCellRef().mPos = ptr.getCellRef().mPos; ref.getPtr().getCellRef().setPosition(ptr.getCellRef().getPosition());
MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(), ptr.getCell() , ptr.getCellRef().mPos); MWWorld::Ptr placed = MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(), ptr.getCell() , ptr.getCellRef().getPosition());
customData.mSpawnActorId = placed.getClass().getCreatureStats(placed).getActorId(); customData.mSpawnActorId = placed.getClass().getCreatureStats(placed).getActorId();
customData.mSpawn = false; customData.mSpawn = false;
} }

View file

@ -83,8 +83,8 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Door> *ref = MWWorld::LiveCellRef<ESM::Door> *ref =
ptr.get<ESM::Door>(); ptr.get<ESM::Door>();
if (ref->mRef.mTeleport && !ref->mRef.mDestCell.empty()) // TODO doors that lead to exteriors if (ptr.getCellRef().getTeleport() && !ptr.getCellRef().getDestCell().empty()) // TODO doors that lead to exteriors
return ref->mRef.mDestCell; return ptr.getCellRef().getDestCell();
return ref->mBase->mName; return ref->mBase->mName;
} }
@ -101,16 +101,16 @@ namespace MWClass
MWWorld::ContainerStore &invStore = actor.getClass().getContainerStore(actor); MWWorld::ContainerStore &invStore = actor.getClass().getContainerStore(actor);
bool needKey = ptr.getCellRef().mLockLevel > 0; bool needKey = ptr.getCellRef().getLockLevel() > 0;
bool hasKey = false; bool hasKey = false;
std::string keyName; std::string keyName;
// make key id lowercase // make key id lowercase
std::string keyId = ptr.getCellRef().mKey; std::string keyId = ptr.getCellRef().getKey();
Misc::StringUtils::toLower(keyId); Misc::StringUtils::toLower(keyId);
for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it) for (MWWorld::ContainerStoreIterator it = invStore.begin(); it != invStore.end(); ++it)
{ {
std::string refId = it->getCellRef().mRefID; std::string refId = it->getCellRef().getRefId();
Misc::StringUtils::toLower(refId); Misc::StringUtils::toLower(refId);
if (refId == keyId) if (refId == keyId)
{ {
@ -125,22 +125,22 @@ namespace MWClass
MWBase::Environment::get().getWindowManager()->messageBox(keyName + " #{sKeyUsed}"); MWBase::Environment::get().getWindowManager()->messageBox(keyName + " #{sKeyUsed}");
unlock(ptr); //Call the function here. because that makes sense. unlock(ptr); //Call the function here. because that makes sense.
// using a key disarms the trap // using a key disarms the trap
ptr.getCellRef().mTrap = ""; ptr.getCellRef().getTrap() = "";
} }
if (!needKey || hasKey) if (!needKey || hasKey)
{ {
if(!ptr.getCellRef().mTrap.empty()) if(!ptr.getCellRef().getTrap().empty())
{ {
// Trap activation // Trap activation
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTrap(actor, ptr.getCellRef().mTrap, ptr)); boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTrap(actor, ptr.getCellRef().getTrap(), ptr));
action->setSound(trapActivationSound); action->setSound(trapActivationSound);
return action; return action;
} }
if (ref->mRef.mTeleport) if (ptr.getCellRef().getTeleport())
{ {
boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport (ref->mRef.mDestCell, ref->mRef.mDoorDest)); boost::shared_ptr<MWWorld::Action> action(new MWWorld::ActionTeleport (ptr.getCellRef().getDestCell(), ptr.getCellRef().getDoorDest()));
action->setSound(openSound); action->setSound(openSound);
@ -191,14 +191,14 @@ namespace MWClass
void Door::lock (const MWWorld::Ptr& ptr, int lockLevel) const void Door::lock (const MWWorld::Ptr& ptr, int lockLevel) const
{ {
if(lockLevel!=0) if(lockLevel!=0)
ptr.getCellRef().mLockLevel = abs(lockLevel); //Changes lock to locklevel, in positive ptr.getCellRef().setLockLevel(abs(lockLevel)); //Changes lock to locklevel, in positive
else else
ptr.getCellRef().mLockLevel = abs(ptr.getCellRef().mLockLevel); //No locklevel given, just flip the origional one ptr.getCellRef().setLockLevel(abs(ptr.getCellRef().getLockLevel())); //No locklevel given, just flip the origional one
} }
void Door::unlock (const MWWorld::Ptr& ptr) const void Door::unlock (const MWWorld::Ptr& ptr) const
{ {
ptr.getCellRef().mLockLevel = -abs(ptr.getCellRef().mLockLevel); //Makes lockLevel negative ptr.getCellRef().setLockLevel(-abs(ptr.getCellRef().getLockLevel())); //Makes lockLevel negative
} }
std::string Door::getScript (const MWWorld::Ptr& ptr) const std::string Door::getScript (const MWWorld::Ptr& ptr) const
@ -234,17 +234,17 @@ namespace MWClass
std::string text; std::string text;
if (ref->mRef.mTeleport) if (ptr.getCellRef().getTeleport())
{ {
text += "\n#{sTo}"; text += "\n#{sTo}";
text += "\n" + getDestination(*ref); text += "\n" + getDestination(*ref);
} }
if (ref->mRef.mLockLevel > 0) if (ptr.getCellRef().getLockLevel() > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel); text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ptr.getCellRef().getLockLevel());
else if (ref->mRef.mLockLevel < 0) else if (ptr.getCellRef().getLockLevel() < 0)
text += "\n#{sUnlocked}"; text += "\n#{sUnlocked}";
if (ref->mRef.mTrap != "") if (ptr.getCellRef().getTrap() != "")
text += "\n#{sTrapped}"; text += "\n#{sTrapped}";
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) if (MWBase::Environment::get().getWindowManager()->getFullHelp())
@ -260,16 +260,16 @@ namespace MWClass
const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
std::string dest; std::string dest;
if (door.mRef.mDestCell != "") if (door.mRef.getDestCell() != "")
{ {
// door leads to an interior, use interior name as tooltip // door leads to an interior, use interior name as tooltip
dest = door.mRef.mDestCell; dest = door.mRef.getDestCell();
} }
else else
{ {
// door leads to exterior, use cell name (if any), otherwise translated region name // door leads to exterior, use cell name (if any), otherwise translated region name
int x,y; int x,y;
MWBase::Environment::get().getWorld()->positionToIndex (door.mRef.mDoorDest.pos[0], door.mRef.mDoorDest.pos[1], x, y); MWBase::Environment::get().getWorld()->positionToIndex (door.mRef.getDoorDest().pos[0], door.mRef.getDoorDest().pos[1], x, y);
const ESM::Cell* cell = store.get<ESM::Cell>().find(x,y); const ESM::Cell* cell = store.get<ESM::Cell>().find(x,y);
if (cell->mName != "") if (cell->mName != "")
dest = cell->mName; dest = cell->mName;

View file

@ -147,8 +147,8 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }

View file

@ -187,8 +187,8 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }

View file

@ -86,10 +86,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Lockpick> *ref = MWWorld::LiveCellRef<ESM::Lockpick> *ref =
ptr.get<ESM::Lockpick>(); ptr.get<ESM::Lockpick>();
if (ptr.getCellRef().mCharge == -1) return ref->mBase->mData.mValue * (static_cast<float>(getItemHealth(ptr)) / getItemMaxHealth(ptr));
return ref->mBase->mData.mValue;
else
return ref->mBase->mData.mValue * (static_cast<float>(ptr.getCellRef().mCharge) / getItemMaxHealth(ptr));
} }
void Lockpick::registerSelf() void Lockpick::registerSelf()
@ -136,7 +133,7 @@ namespace MWClass
std::string text; std::string text;
int remainingUses = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mUses; int remainingUses = getItemHealth(ptr);
text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses); text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
@ -144,8 +141,8 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }

View file

@ -28,11 +28,11 @@ namespace
{ {
bool isGold (const MWWorld::Ptr& ptr) bool isGold (const MWWorld::Ptr& ptr)
{ {
return Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_001") return Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_001")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_005") || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_005")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_010") || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_010")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_025") || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_025")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_100"); || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_100");
} }
} }
@ -94,12 +94,12 @@ namespace MWClass
ptr.get<ESM::Miscellaneous>(); ptr.get<ESM::Miscellaneous>();
int value = ref->mBase->mData.mValue; int value = ref->mBase->mData.mValue;
if (ptr.getCellRef().mGoldValue > 1 && ptr.getRefData().getCount() == 1) if (ptr.getCellRef().getGoldValue() > 1 && ptr.getRefData().getCount() == 1)
value = ptr.getCellRef().mGoldValue; value = ptr.getCellRef().getGoldValue();
if (ptr.getCellRef().mSoul != "") if (ptr.getCellRef().getSoul() != "")
{ {
const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get<ESM::Creature>().find(ref->mRef.mSoul); const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get<ESM::Creature>().find(ref->mRef.getSoul());
value *= creature->mData.mSoul; value *= creature->mData.mSoul;
} }
@ -167,9 +167,9 @@ namespace MWClass
info.caption = ref->mBase->mName + countString; info.caption = ref->mBase->mName + countString;
info.icon = ref->mBase->mIcon; info.icon = ref->mBase->mIcon;
if (ref->mRef.mSoul != "") if (ref->mRef.getSoul() != "")
{ {
const ESM::Creature *creature = store.get<ESM::Creature>().find(ref->mRef.mSoul); const ESM::Creature *creature = store.get<ESM::Creature>().find(ref->mRef.getSoul());
info.caption += " (" + creature->mName + ")"; info.caption += " (" + creature->mName + ")";
} }
@ -182,8 +182,8 @@ namespace MWClass
} }
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
@ -219,7 +219,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
newRef.getPtr().get<ESM::Miscellaneous>(); newRef.getPtr().get<ESM::Miscellaneous>();
newPtr = MWWorld::Ptr(&cell.get<ESM::Miscellaneous>().insert(*ref), &cell); newPtr = MWWorld::Ptr(&cell.get<ESM::Miscellaneous>().insert(*ref), &cell);
newPtr.getCellRef().mGoldValue = goldAmount; newPtr.getCellRef().setGoldValue(goldAmount);
newPtr.getRefData().setCount(1); newPtr.getRefData().setCount(1);
} else { } else {
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
@ -231,7 +231,7 @@ namespace MWClass
boost::shared_ptr<MWWorld::Action> Miscellaneous::use (const MWWorld::Ptr& ptr) const boost::shared_ptr<MWWorld::Action> Miscellaneous::use (const MWWorld::Ptr& ptr) const
{ {
if (ptr.getCellRef().mSoul == "") if (ptr.getCellRef().getSoul().empty())
return boost::shared_ptr<MWWorld::Action>(new MWWorld::NullAction()); return boost::shared_ptr<MWWorld::Action>(new MWWorld::NullAction());
else else
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionSoulgem(ptr)); return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionSoulgem(ptr));
@ -242,12 +242,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Miscellaneous> *ref = MWWorld::LiveCellRef<ESM::Miscellaneous> *ref =
item.get<ESM::Miscellaneous>(); item.get<ESM::Miscellaneous>();
return !ref->mBase->mData.mIsKey && (npcServices & ESM::NPC::Misc) return !ref->mBase->mData.mIsKey && (npcServices & ESM::NPC::Misc) && !isGold(item);
&& !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_001")
&& !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_005")
&& !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_010")
&& !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_025")
&& !Misc::StringUtils::ciEqual(item.getCellRef().mRefID, "gold_100");
} }
float Miscellaneous::getWeight(const MWWorld::Ptr &ptr) const float Miscellaneous::getWeight(const MWWorld::Ptr &ptr) const

View file

@ -526,20 +526,24 @@ namespace MWClass
(stats.getAttribute(ESM::Attribute::Strength).getModified() * fDamageStrengthMult->getFloat() * 0.1); (stats.getAttribute(ESM::Attribute::Strength).getModified() * fDamageStrengthMult->getFloat() * 0.1);
if(weaphashealth) if(weaphashealth)
{ {
int weapmaxhealth = weapon.get<ESM::Weapon>()->mBase->mData.mHealth; int weapmaxhealth = weapon.getClass().getItemMaxHealth(weapon);
if(weapon.getCellRef().mCharge == -1) int weaphealth = weapon.getClass().getItemHealth(weapon);
weapon.getCellRef().mCharge = weapmaxhealth;
damage *= float(weapon.getCellRef().mCharge) / weapmaxhealth; damage *= float(weaphealth) / weapmaxhealth;
if (!MWBase::Environment::get().getWorld()->getGodModeState())
{
// Reduce weapon charge by at least one, but cap at 0
weaphealth -= std::min(std::max(1,
(int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), weaphealth);
weapon.getCellRef().setCharge(weaphealth);
}
// Weapon broken? unequip it
if (weaphealth == 0)
weapon = *inv.unequipItem(weapon, ptr);
} }
if (!MWBase::Environment::get().getWorld()->getGodModeState())
weapon.getCellRef().mCharge -= std::min(std::max(1,
(int)(damage * gmst.find("fWeaponDamageMult")->getFloat())), weapon.getCellRef().mCharge);
// Weapon broken? unequip it
if (weapon.getCellRef().mCharge == 0)
weapon = *inv.unequipItem(weapon, ptr);
} }
healthdmg = true; healthdmg = true;
} }
@ -705,14 +709,13 @@ namespace MWClass
MWWorld::Ptr armor = ((armorslot != inv.end()) ? *armorslot : MWWorld::Ptr()); MWWorld::Ptr armor = ((armorslot != inv.end()) ? *armorslot : MWWorld::Ptr());
if(!armor.isEmpty() && armor.getTypeName() == typeid(ESM::Armor).name()) if(!armor.isEmpty() && armor.getTypeName() == typeid(ESM::Armor).name())
{ {
ESM::CellRef &armorref = armor.getCellRef(); int armorhealth = armor.getClass().getItemHealth(armor);
if(armorref.mCharge == -1) armorhealth -= std::min(std::max(1, (int)damagediff),
armorref.mCharge = armor.get<ESM::Armor>()->mBase->mData.mHealth; armorhealth);
armorref.mCharge -= std::min(std::max(1, (int)damagediff), armor.getCellRef().setCharge(armorhealth);
armorref.mCharge);
// Armor broken? unequip it // Armor broken? unequip it
if (armorref.mCharge == 0) if (armorhealth == 0)
inv.unequipItem(armor, ptr); inv.unequipItem(armor, ptr);
if (ptr.getRefData().getHandle() == "player") if (ptr.getRefData().getHandle() == "player")
@ -1316,14 +1319,14 @@ namespace MWClass
{ {
// Note we do not respawn moved references in the cell they were moved to. Instead they are respawned in the original cell. // Note we do not respawn moved references in the cell they were moved to. Instead they are respawned in the original cell.
// This also means we cannot respawn dynamically placed references with no content file connection. // This also means we cannot respawn dynamically placed references with no content file connection.
if (ptr.getCellRef().mRefNum.mContentFile != -1) if (ptr.getCellRef().getRefNum().mContentFile != -1)
{ {
if (ptr.getRefData().getCount() == 0) if (ptr.getRefData().getCount() == 0)
ptr.getRefData().setCount(1); ptr.getRefData().setCount(1);
// Reset to original position // Reset to original position
ESM::Position& pos = ptr.getRefData().getPosition(); ESM::Position& pos = ptr.getRefData().getPosition();
pos = ptr.getCellRef().mPos; pos = ptr.getCellRef().getPosition();
ptr.getRefData().setCustomData(NULL); ptr.getRefData().setCustomData(NULL);
} }
@ -1335,7 +1338,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>(); MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
const ESM::InventoryList& list = ref->mBase->mInventory; const ESM::InventoryList& list = ref->mBase->mInventory;
MWWorld::ContainerStore& store = getContainerStore(ptr); MWWorld::ContainerStore& store = getContainerStore(ptr);
store.restock(list, ptr, ptr.getCellRef().mRefID, ptr.getCellRef().mFaction); store.restock(list, ptr, ptr.getCellRef().getRefId(), ptr.getCellRef().getFaction());
} }
const ESM::GameSetting *Npc::fMinWalkSpeed; const ESM::GameSetting *Npc::fMinWalkSpeed;

View file

@ -151,8 +151,8 @@ namespace MWClass
info.isPotion = true; info.isPotion = true;
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }

View file

@ -85,10 +85,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Probe> *ref = MWWorld::LiveCellRef<ESM::Probe> *ref =
ptr.get<ESM::Probe>(); ptr.get<ESM::Probe>();
if (ptr.getCellRef().mCharge == -1) return ref->mBase->mData.mValue * (static_cast<float>(getItemHealth(ptr)) / getItemMaxHealth(ptr));
return ref->mBase->mData.mValue;
else
return ref->mBase->mData.mValue * (static_cast<float>(ptr.getCellRef().mCharge) / getItemMaxHealth(ptr));
} }
void Probe::registerSelf() void Probe::registerSelf()
@ -135,7 +132,7 @@ namespace MWClass
std::string text; std::string text;
int remainingUses = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mUses; int remainingUses = getItemHealth(ptr);
text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses); text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
@ -143,8 +140,8 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }

View file

@ -76,10 +76,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Repair> *ref = MWWorld::LiveCellRef<ESM::Repair> *ref =
ptr.get<ESM::Repair>(); ptr.get<ESM::Repair>();
if (ptr.getCellRef().mCharge == -1) return ref->mBase->mData.mValue * (static_cast<float>(getItemHealth(ptr)) / getItemMaxHealth(ptr));
return ref->mBase->mData.mValue;
else
return ref->mBase->mData.mValue * (static_cast<float>(ptr.getCellRef().mCharge) / getItemMaxHealth(ptr));
} }
void Repair::registerSelf() void Repair::registerSelf()
@ -139,7 +136,7 @@ namespace MWClass
std::string text; std::string text;
int remainingUses = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mUses; int remainingUses = getItemHealth(ptr);
text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses); text += "\n#{sUses}: " + MWGui::ToolTips::toString(remainingUses);
text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality); text += "\n#{sQuality}: " + MWGui::ToolTips::toString(ref->mBase->mData.mQuality);
@ -147,8 +144,8 @@ namespace MWClass
text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}"); text += MWGui::ToolTips::getValueString(getValue(ptr), "#{sValue}");
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }

View file

@ -154,10 +154,7 @@ namespace MWClass
MWWorld::LiveCellRef<ESM::Weapon> *ref = MWWorld::LiveCellRef<ESM::Weapon> *ref =
ptr.get<ESM::Weapon>(); ptr.get<ESM::Weapon>();
if (ptr.getCellRef().mCharge == -1) return ref->mBase->mData.mValue * (static_cast<float>(getItemHealth(ptr)) / getItemMaxHealth(ptr));
return ref->mBase->mData.mValue;
else
return ref->mBase->mData.mValue * (static_cast<float>(ptr.getCellRef().mCharge) / getItemMaxHealth(ptr));
} }
void Weapon::registerSelf() void Weapon::registerSelf()
@ -340,7 +337,7 @@ namespace MWClass
if (ref->mBase->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity if (ref->mBase->mData.mType < 11) // thrown weapons and arrows/bolts don't have health, only quantity
{ {
int remainingHealth = (ptr.getCellRef().mCharge != -1) ? ptr.getCellRef().mCharge : ref->mBase->mData.mHealth; int remainingHealth = getItemHealth(ptr);
text += "\n#{sCondition}: " + MWGui::ToolTips::toString(remainingHealth) + "/" text += "\n#{sCondition}: " + MWGui::ToolTips::toString(remainingHealth) + "/"
+ MWGui::ToolTips::toString(ref->mBase->mData.mHealth); + MWGui::ToolTips::toString(ref->mBase->mData.mHealth);
} }
@ -351,11 +348,11 @@ namespace MWClass
info.enchant = ref->mBase->mEnchant; info.enchant = ref->mBase->mEnchant;
if (!info.enchant.empty()) if (!info.enchant.empty())
info.remainingEnchantCharge = ptr.getCellRef().mEnchantmentCharge; info.remainingEnchantCharge = ptr.getCellRef().getEnchantmentCharge();
if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { if (MWBase::Environment::get().getWindowManager()->getFullHelp()) {
text += MWGui::ToolTips::getMiscString(ref->mRef.mOwner, "Owner"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getOwner(), "Owner");
text += MWGui::ToolTips::getMiscString(ref->mRef.mFaction, "Faction"); text += MWGui::ToolTips::getMiscString(ptr.getCellRef().getFaction(), "Faction");
text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script"); text += MWGui::ToolTips::getMiscString(ref->mBase->mScript, "Script");
} }
@ -388,7 +385,7 @@ namespace MWClass
std::pair<int, std::string> Weapon::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const std::pair<int, std::string> Weapon::canBeEquipped(const MWWorld::Ptr &ptr, const MWWorld::Ptr &npc) const
{ {
if (ptr.getCellRef().mCharge == 0) if (ptr.getCellRef().getCharge() == 0)
return std::make_pair(0, "#{sInventoryMessage1}"); return std::make_pair(0, "#{sInventoryMessage1}");
std::pair<std::vector<int>, bool> slots_ = ptr.getClass().getEquipmentSlots(ptr); std::pair<std::vector<int>, bool> slots_ = ptr.getClass().getEquipmentSlots(ptr);

View file

@ -413,7 +413,7 @@ namespace MWGui
} }
else else
{ {
setTitle("#{sConsoleTitle} (" + object.getCellRef().mRefID + ")"); setTitle("#{sConsoleTitle} (" + object.getCellRef().getRefId() + ")");
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.

View file

@ -306,7 +306,7 @@ namespace MWGui
for (int i=0; i<2; ++i) for (int i=0; i<2; ++i)
{ {
MWWorld::Ptr item = (i == 0) ? mEnchanting.getOldItem() : mEnchanting.getGem(); MWWorld::Ptr item = (i == 0) ? mEnchanting.getOldItem() : mEnchanting.getGem();
if (Misc::StringUtils::ciEqual(item.getCellRef().mOwner, mPtr.getCellRef().mRefID)) if (Misc::StringUtils::ciEqual(item.getCellRef().getOwner(), mPtr.getCellRef().getRefId()))
{ {
std::string msg = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage49")->getString(); std::string msg = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sNotifyMessage49")->getString();
if (msg.find("%s") != std::string::npos) if (msg.find("%s") != std::string::npos)

View file

@ -40,7 +40,7 @@ namespace MWGui
else else
dropped = world->dropObjectOnGround(world->getPlayerPtr(), item.mBase, count); dropped = world->dropObjectOnGround(world->getPlayerPtr(), item.mBase, count);
if (setNewOwner) if (setNewOwner)
dropped.getCellRef().mOwner = ""; dropped.getCellRef().setOwner("");
return dropped; return dropped;
} }

View file

@ -67,7 +67,7 @@ MWWorld::Ptr InventoryItemModel::moveItem(const ItemStack &item, size_t count, I
if (mActor.getClass().isActor() && mActor.getClass().getCreatureStats(mActor).isDead() if (mActor.getClass().isActor() && mActor.getClass().getCreatureStats(mActor).isDead()
// Make sure that the item is actually owned by the dead actor // Make sure that the item is actually owned by the dead actor
// Prevents a potential exploit for resetting the owner of any item, by placing the item in a corpse // Prevents a potential exploit for resetting the owner of any item, by placing the item in a corpse
&& Misc::StringUtils::ciEqual(item.mBase.getCellRef().mOwner, mActor.getCellRef().mRefID)) && Misc::StringUtils::ciEqual(item.mBase.getCellRef().getOwner(), mActor.getCellRef().getRefId()))
setNewOwner = true; setNewOwner = true;
MWWorld::Ptr ret = otherModel->copyItem(item, count, setNewOwner); MWWorld::Ptr ret = otherModel->copyItem(item, count, setNewOwner);
@ -87,7 +87,7 @@ void InventoryItemModel::update()
// NOTE: Don't show WerewolfRobe objects in the inventory, or allow them to be taken. // NOTE: Don't show WerewolfRobe objects in the inventory, or allow them to be taken.
// Vanilla likely uses a hack like this since there's no other way to prevent it from // Vanilla likely uses a hack like this since there's no other way to prevent it from
// being shown or taken. // being shown or taken.
if(item.getCellRef().mRefID == "werewolfrobe") if(item.getCellRef().getRefId() == "werewolfrobe")
continue; continue;
ItemStack newItem (item, this, item.getRefData().getCount()); ItemStack newItem (item, this, item.getRefData().getCount());

View file

@ -168,8 +168,8 @@ namespace MWGui
int count = item.mCount; int count = item.mCount;
// Bound items may not be moved // Bound items may not be moved
if (item.mBase.getCellRef().mRefID.size() > 6 if (item.mBase.getCellRef().getRefId().size() > 6
&& item.mBase.getCellRef().mRefID.substr(0,6) == "bound_") && item.mBase.getCellRef().getRefId().substr(0,6) == "bound_")
{ {
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0); MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog12}"); MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog12}");
@ -454,7 +454,7 @@ namespace MWGui
// NOTE: Don't allow users to select WerewolfRobe objects in the inventory. Vanilla // NOTE: Don't allow users to select WerewolfRobe objects in the inventory. Vanilla
// likely uses a hack like this since there's no other way to prevent it from being // likely uses a hack like this since there's no other way to prevent it from being
// taken. // taken.
if(item.getCellRef().mRefID == "werewolfrobe") if(item.getCellRef().getRefId() == "werewolfrobe")
return MWWorld::Ptr(); return MWWorld::Ptr();
return item; return item;
} }

View file

@ -47,7 +47,7 @@ void MerchantRepair::startRepair(const MWWorld::Ptr &actor)
if (iter->getClass().hasItemHealth(*iter)) if (iter->getClass().hasItemHealth(*iter))
{ {
int maxDurability = iter->getClass().getItemMaxHealth(*iter); int maxDurability = iter->getClass().getItemMaxHealth(*iter);
int durability = (iter->getCellRef().mCharge == -1) ? maxDurability : iter->getCellRef().mCharge; int durability = iter->getClass().getItemHealth(*iter);
if (maxDurability == durability) if (maxDurability == durability)
continue; continue;
@ -114,7 +114,7 @@ void MerchantRepair::onRepairButtonClick(MyGUI::Widget *sender)
{ {
// repair // repair
MWWorld::Ptr item = *sender->getUserData<MWWorld::Ptr>(); MWWorld::Ptr item = *sender->getUserData<MWWorld::Ptr>();
item.getCellRef().mCharge = item.getClass().getItemMaxHealth(item); item.getCellRef().setCharge(item.getClass().getItemMaxHealth(item));
MWBase::Environment::get().getSoundManager()->playSound("Repair",1,1); MWBase::Environment::get().getSoundManager()->playSound("Repair",1,1);

View file

@ -42,8 +42,8 @@ namespace MWGui
const ItemStack& item = mSourceModel->getItem(i); const ItemStack& item = mSourceModel->getItem(i);
// Bound items may not be stolen // Bound items may not be stolen
if (item.mBase.getCellRef().mRefID.size() > 6 if (item.mBase.getCellRef().getRefId().size() > 6
&& item.mBase.getCellRef().mRefID.substr(0,6) == "bound_") && item.mBase.getCellRef().getRefId().substr(0,6) == "bound_")
{ {
continue; continue;
} }

View file

@ -274,11 +274,11 @@ namespace MWGui
if (item.getRefData ().getCount() < 1) if (item.getRefData ().getCount() < 1)
{ {
// Try searching for a compatible replacement // Try searching for a compatible replacement
std::string id = item.getCellRef().mRefID; std::string id = item.getCellRef().getRefId();
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
{ {
if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, id)) if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), id))
{ {
item = *it; item = *it;
button->getChildAt(0)->setUserData(item); button->getChildAt(0)->setUserData(item);
@ -408,7 +408,7 @@ namespace MWGui
case Type_MagicItem: case Type_MagicItem:
{ {
MWWorld::Ptr item = *button->getChildAt(0)->getUserData<MWWorld::Ptr>(); MWWorld::Ptr item = *button->getChildAt(0)->getUserData<MWWorld::Ptr>();
key.mId = item.getCellRef().mRefID; key.mId = item.getCellRef().getRefId();
break; break;
} }
case Type_Magic: case Type_Magic:
@ -458,11 +458,12 @@ namespace MWGui
MWWorld::Ptr item; MWWorld::Ptr item;
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
{ {
if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, id)) if (Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), id))
{ {
if (item.isEmpty() || if (item.isEmpty() ||
// Prefer the stack with the lowest remaining uses // Prefer the stack with the lowest remaining uses
(it->getCellRef().mCharge != -1 && (item.getCellRef().mCharge == -1 || it->getCellRef().mCharge < item.getCellRef().mCharge) )) !item.getClass().hasItemHealth(*it) ||
it->getClass().getItemHealth(*it) < item.getClass().getItemHealth(item))
{ {
item = *it; item = *it;
} }

View file

@ -56,7 +56,7 @@ void Recharge::updateView()
{ {
MWWorld::Ptr gem = *mGemIcon->getUserData<MWWorld::Ptr>(); MWWorld::Ptr gem = *mGemIcon->getUserData<MWWorld::Ptr>();
std::string soul = gem.getCellRef().mSoul; std::string soul = gem.getCellRef().getSoul();
const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get<ESM::Creature>().find(soul); const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get<ESM::Creature>().find(soul);
mChargeLabel->setCaptionWithReplacing("#{sCharges} " + boost::lexical_cast<std::string>(creature->mData.mSoul)); mChargeLabel->setCaptionWithReplacing("#{sCharges} " + boost::lexical_cast<std::string>(creature->mData.mSoul));
@ -93,8 +93,8 @@ void Recharge::updateView()
if (enchantmentName.empty()) if (enchantmentName.empty())
continue; continue;
const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(enchantmentName); const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(enchantmentName);
if (iter->getCellRef().mEnchantmentCharge >= enchantment->mData.mCharge if (iter->getCellRef().getEnchantmentCharge() >= enchantment->mData.mCharge
|| iter->getCellRef().mEnchantmentCharge == -1) || iter->getCellRef().getEnchantmentCharge() == -1)
continue; continue;
MyGUI::TextBox* text = mView->createWidget<MyGUI::TextBox> ( MyGUI::TextBox* text = mView->createWidget<MyGUI::TextBox> (
@ -118,7 +118,7 @@ void Recharge::updateView()
Widgets::MWDynamicStatPtr chargeWidget = mView->createWidget<Widgets::MWDynamicStat> Widgets::MWDynamicStatPtr chargeWidget = mView->createWidget<Widgets::MWDynamicStat>
("MW_ChargeBar", MyGUI::IntCoord(72, currentY+2, 199, 20), MyGUI::Align::Default); ("MW_ChargeBar", MyGUI::IntCoord(72, currentY+2, 199, 20), MyGUI::Align::Default);
chargeWidget->setValue(iter->getCellRef().mEnchantmentCharge, enchantment->mData.mCharge); chargeWidget->setValue(iter->getCellRef().getEnchantmentCharge(), enchantment->mData.mCharge);
chargeWidget->setNeedMouseFocus(false); chargeWidget->setNeedMouseFocus(false);
currentY += 32 + 4; currentY += 32 + 4;
@ -159,15 +159,15 @@ void Recharge::onItemClicked(MyGUI::Widget *sender)
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99] int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
if (roll < x) if (roll < x)
{ {
std::string soul = gem.getCellRef().mSoul; std::string soul = gem.getCellRef().getSoul();
const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get<ESM::Creature>().find(soul); const ESM::Creature *creature = MWBase::Environment::get().getWorld()->getStore().get<ESM::Creature>().find(soul);
float restored = creature->mData.mSoul * (roll / x); float restored = creature->mData.mSoul * (roll / x);
const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find( const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(
item.getClass().getEnchantment(item)); item.getClass().getEnchantment(item));
item.getCellRef().mEnchantmentCharge = item.getCellRef().setEnchantmentCharge(
std::min(item.getCellRef().mEnchantmentCharge + restored, static_cast<float>(enchantment->mData.mCharge)); std::min(item.getCellRef().getEnchantmentCharge() + restored, static_cast<float>(enchantment->mData.mCharge)));
player.getClass().skillUsageSucceeded (player, ESM::Skill::Enchant, 0); player.getClass().skillUsageSucceeded (player, ESM::Skill::Enchant, 0);
} }

View file

@ -56,7 +56,7 @@ void Repair::updateRepairView()
MWWorld::LiveCellRef<ESM::Repair> *ref = MWWorld::LiveCellRef<ESM::Repair> *ref =
mRepair.getTool().get<ESM::Repair>(); mRepair.getTool().get<ESM::Repair>();
int uses = (mRepair.getTool().getCellRef().mCharge != -1) ? mRepair.getTool().getCellRef().mCharge : ref->mBase->mData.mUses; int uses = mRepair.getTool().getClass().getItemHealth(mRepair.getTool());
float quality = ref->mBase->mData.mQuality; float quality = ref->mBase->mData.mQuality;
@ -98,7 +98,7 @@ void Repair::updateRepairView()
if (iter->getClass().hasItemHealth(*iter)) if (iter->getClass().hasItemHealth(*iter))
{ {
int maxDurability = iter->getClass().getItemMaxHealth(*iter); int maxDurability = iter->getClass().getItemMaxHealth(*iter);
int durability = (iter->getCellRef().mCharge == -1) ? maxDurability : iter->getCellRef().mCharge; int durability = iter->getClass().getItemHealth(*iter);
if (maxDurability == durability) if (maxDurability == durability)
continue; continue;

View file

@ -114,7 +114,7 @@ namespace MWGui
if ((mFilter & Filter_OnlyEnchanted) && !(item.mFlags & ItemStack::Flag_Enchanted)) if ((mFilter & Filter_OnlyEnchanted) && !(item.mFlags & ItemStack::Flag_Enchanted))
return false; return false;
if ((mFilter & Filter_OnlyChargedSoulstones) && (base.getTypeName() != typeid(ESM::Miscellaneous).name() if ((mFilter & Filter_OnlyChargedSoulstones) && (base.getTypeName() != typeid(ESM::Miscellaneous).name()
|| base.getCellRef().mSoul == "")) || base.getCellRef().getSoul() == ""))
return false; return false;
if ((mFilter & Filter_OnlyEnchantable) && (item.mFlags & ItemStack::Flag_Enchanted if ((mFilter & Filter_OnlyEnchantable) && (item.mFlags & ItemStack::Flag_Enchanted
|| (base.getTypeName() != typeid(ESM::Armor).name() || (base.getTypeName() != typeid(ESM::Armor).name()

View file

@ -238,7 +238,7 @@ namespace MWGui
int castCost = std::max(1.f, enchantCost - (enchantCost / 100) * (eSkill - 10)); int castCost = std::max(1.f, enchantCost - (enchantCost / 100) * (eSkill - 10));
std::string cost = boost::lexical_cast<std::string>(castCost); std::string cost = boost::lexical_cast<std::string>(castCost);
int currentCharge = int(item.getCellRef().mEnchantmentCharge); int currentCharge = int(item.getCellRef().getEnchantmentCharge());
if (currentCharge == -1) if (currentCharge == -1)
currentCharge = enchant->mData.mCharge; currentCharge = enchant->mData.mCharge;
std::string charge = boost::lexical_cast<std::string>(currentCharge); std::string charge = boost::lexical_cast<std::string>(currentCharge);

View file

@ -97,7 +97,7 @@ namespace MWGui
setCoord(0, 0, 300, 300); setCoord(0, 0, 300, 300);
mDynamicToolTipBox->setVisible(true); mDynamicToolTipBox->setVisible(true);
ToolTipInfo info; ToolTipInfo info;
info.caption=mFocusObject.getCellRef().mRefID; info.caption=mFocusObject.getCellRef().getRefId();
info.icon=""; info.icon="";
tooltipSize = createToolTip(info); tooltipSize = createToolTip(info);
} }

View file

@ -148,14 +148,14 @@ namespace MWGui
if(!mMerchant.isEmpty()) if(!mMerchant.isEmpty())
{ {
MWWorld::Ptr base = item.mBase; MWWorld::Ptr base = item.mBase;
if(Misc::StringUtils::ciEqual(base.getCellRef().mRefID, MWWorld::ContainerStore::sGoldId)) if(Misc::StringUtils::ciEqual(base.getCellRef().getRefId(), MWWorld::ContainerStore::sGoldId))
continue; continue;
if(!base.getClass().canSell(base, services)) if(!base.getClass().canSell(base, services))
continue; continue;
// Bound items may not be bought // Bound items may not be bought
if (item.mBase.getCellRef().mRefID.size() > 6 if (item.mBase.getCellRef().getRefId().size() > 6
&& item.mBase.getCellRef().mRefID.substr(0,6) == "bound_") && item.mBase.getCellRef().getRefId().substr(0,6) == "bound_")
{ {
continue; continue;
} }

View file

@ -277,7 +277,7 @@ namespace MWGui
// check if the player is attempting to sell back an item stolen from this actor // check if the player is attempting to sell back an item stolen from this actor
for (std::vector<ItemStack>::iterator it = merchantBought.begin(); it != merchantBought.end(); ++it) for (std::vector<ItemStack>::iterator it = merchantBought.begin(); it != merchantBought.end(); ++it)
{ {
if (Misc::StringUtils::ciEqual(it->mBase.getCellRef().mOwner, mPtr.getCellRef().mRefID)) if (Misc::StringUtils::ciEqual(it->mBase.getCellRef().getOwner(), mPtr.getCellRef().getRefId()))
{ {
std::string msg = gmst.find("sNotifyMessage49")->getString(); std::string msg = gmst.find("sNotifyMessage49")->getString();
if (msg.find("%s") != std::string::npos) if (msg.find("%s") != std::string::npos)

View file

@ -1029,16 +1029,16 @@ namespace MWGui
const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>() const ESM::Enchantment* ench = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>()
.find(item.getClass().getEnchantment(item)); .find(item.getClass().getEnchantment(item));
int chargePercent = (item.getCellRef().mEnchantmentCharge == -1) ? 100 int chargePercent = (item.getCellRef().getEnchantmentCharge() == -1) ? 100
: (item.getCellRef().mEnchantmentCharge / static_cast<float>(ench->mData.mCharge) * 100); : (item.getCellRef().getEnchantmentCharge() / static_cast<float>(ench->mData.mCharge) * 100);
mHud->setSelectedEnchantItem(item, chargePercent); mHud->setSelectedEnchantItem(item, chargePercent);
mSpellWindow->setTitle(item.getClass().getName(item)); mSpellWindow->setTitle(item.getClass().getName(item));
} }
void WindowManager::setSelectedWeapon(const MWWorld::Ptr& item) void WindowManager::setSelectedWeapon(const MWWorld::Ptr& item)
{ {
int durabilityPercent = (item.getCellRef().mCharge == -1) ? 100 int durabilityPercent =
: (item.getCellRef().mCharge / static_cast<float>(item.getClass().getItemMaxHealth(item)) * 100); (item.getClass().getItemHealth(item) / static_cast<float>(item.getClass().getItemMaxHealth(item)) * 100);
mHud->setSelectedWeapon(item, durabilityPercent); mHud->setSelectedWeapon(item, durabilityPercent);
mInventoryWindow->setTitle(item.getClass().getName(item)); mInventoryWindow->setTitle(item.getClass().getName(item));
} }

View file

@ -62,17 +62,17 @@ bool disintegrateSlot (MWWorld::Ptr ptr, int slot, float disintegrate)
{ {
if (!item->getClass().hasItemHealth(*item)) if (!item->getClass().hasItemHealth(*item))
return false; return false;
if (item->getCellRef().mCharge == -1) int charge = item->getClass().getItemHealth(*item);
item->getCellRef().mCharge = item->getClass().getItemMaxHealth(*item);
if (item->getCellRef().mCharge == 0) if (charge == 0)
return false; return false;
item->getCellRef().mCharge -= charge -=
std::min(disintegrate, std::min(disintegrate,
static_cast<float>(item->getCellRef().mCharge)); static_cast<float>(charge));
item->getCellRef().setCharge(charge);
if (item->getCellRef().mCharge == 0) if (charge == 0)
{ {
// Will unequip the broken item and try to find a replacement // Will unequip the broken item and try to find a replacement
if (ptr.getRefData().getHandle() != "player") if (ptr.getRefData().getHandle() != "player")
@ -147,13 +147,13 @@ namespace MWMechanics
for (MWWorld::ContainerStoreIterator it = container.begin(MWWorld::ContainerStore::Type_Miscellaneous); for (MWWorld::ContainerStoreIterator it = container.begin(MWWorld::ContainerStore::Type_Miscellaneous);
it != container.end(); ++it) it != container.end(); ++it)
{ {
const std::string& id = it->getCellRef().mRefID; const std::string& id = it->getCellRef().getRefId();
if (id.size() >= soulgemFilter.size() if (id.size() >= soulgemFilter.size()
&& id.substr(0,soulgemFilter.size()) == soulgemFilter) && id.substr(0,soulgemFilter.size()) == soulgemFilter)
{ {
float thisGemCapacity = it->get<ESM::Miscellaneous>()->mBase->mData.mValue * fSoulgemMult; float thisGemCapacity = it->get<ESM::Miscellaneous>()->mBase->mData.mValue * fSoulgemMult;
if (thisGemCapacity >= creatureSoulValue && thisGemCapacity < gemCapacity if (thisGemCapacity >= creatureSoulValue && thisGemCapacity < gemCapacity
&& it->getCellRef().mSoul.empty()) && it->getCellRef().getSoul().empty())
{ {
gem = it; gem = it;
gemCapacity = thisGemCapacity; gemCapacity = thisGemCapacity;
@ -166,7 +166,7 @@ namespace MWMechanics
// Set the soul on just one of the gems, not the whole stack // Set the soul on just one of the gems, not the whole stack
gem->getContainerStore()->unstack(*gem, caster); gem->getContainerStore()->unstack(*gem, caster);
gem->getCellRef().mSoul = mCreature.getCellRef().mRefID; gem->getCellRef().setSoul(mCreature.getCellRef().getRefId());
if (caster.getRefData().getHandle() == "player") if (caster.getRefData().getHandle() == "player")
MWBase::Environment::get().getWindowManager()->messageBox("#{sSoultrapSuccess}"); MWBase::Environment::get().getWindowManager()->messageBox("#{sSoultrapSuccess}");
@ -546,7 +546,7 @@ namespace MWMechanics
{ {
MWWorld::CellStore* store = ptr.getCell(); MWWorld::CellStore* store = ptr.getCell();
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), creatureID, 1); MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), creatureID, 1);
ref.getPtr().getCellRef().mPos = ipos; ref.getPtr().getCellRef().setPosition(ipos);
MWMechanics::CreatureStats& summonedCreatureStats = ref.getPtr().getClass().getCreatureStats(ref.getPtr()); MWMechanics::CreatureStats& summonedCreatureStats = ref.getPtr().getClass().getCreatureStats(ref.getPtr());
@ -1142,7 +1142,7 @@ namespace MWMechanics
if(!stats.isDead() && stats.getAiSequence().getTypeId() == AiPackage::TypeIdFollow) if(!stats.isDead() && stats.getAiSequence().getTypeId() == AiPackage::TypeIdFollow)
{ {
MWMechanics::AiFollow* package = static_cast<MWMechanics::AiFollow*>(stats.getAiSequence().getActivePackage()); MWMechanics::AiFollow* package = static_cast<MWMechanics::AiFollow*>(stats.getAiSequence().getActivePackage());
if(package->getFollowedActor() == actor.getCellRef().mRefID) if(package->getFollowedActor() == actor.getCellRef().getRefId())
list.push_front(iter->first); list.push_front(iter->first);
} }
} }

View file

@ -73,11 +73,6 @@ bool MWMechanics::AiAvoidDoor::execute (const MWWorld::Ptr& actor,float duration
return false; return false;
} }
std::string MWMechanics::AiAvoidDoor::getAvoidedDoor()
{
return mDoorPtr.getCellRef().mRefID;
}
MWMechanics::AiAvoidDoor *MWMechanics::AiAvoidDoor::clone() const MWMechanics::AiAvoidDoor *MWMechanics::AiAvoidDoor::clone() const
{ {
return new AiAvoidDoor(*this); return new AiAvoidDoor(*this);

View file

@ -24,9 +24,6 @@ namespace MWMechanics
virtual int getTypeId() const; virtual int getTypeId() const;
/// Returns the door being avoided
std::string getAvoidedDoor();
private: private:
float mDuration; float mDuration;
MWWorld::Ptr mDoorPtr; MWWorld::Ptr mDoorPtr;

View file

@ -517,7 +517,7 @@ namespace MWMechanics
{ {
MWWorld::LiveCellRef<ESM::Door>& ref = *mDoorIter; MWWorld::LiveCellRef<ESM::Door>& ref = *mDoorIter;
float minSqr = 1.3*1.3*MIN_DIST_TO_DOOR_SQUARED; // for legibility float minSqr = 1.3*1.3*MIN_DIST_TO_DOOR_SQUARED; // for legibility
if(vActorPos.squaredDistance(Ogre::Vector3(ref.mRef.mPos.pos)) < minSqr && if(vActorPos.squaredDistance(Ogre::Vector3(ref.mRef.getPosition().pos)) < minSqr &&
ref.mData.getLocalRotation().rot[2] < 0.4f) // even small opening ref.mData.getLocalRotation().rot[2] < 0.4f) // even small opening
{ {
//std::cout<<"closed door id \""<<ref.mRef.mRefID<<"\""<<std::endl; //std::cout<<"closed door id \""<<ref.mRef.mRefID<<"\""<<std::endl;
@ -552,7 +552,7 @@ namespace MWMechanics
float minSqr = 1.6 * 1.6 * MIN_DIST_TO_DOOR_SQUARED; // for legibility float minSqr = 1.6 * 1.6 * MIN_DIST_TO_DOOR_SQUARED; // for legibility
// TODO: add reaction to checking open doors // TODO: add reaction to checking open doors
if(mBackOffDoor && if(mBackOffDoor &&
vActorPos.squaredDistance(Ogre::Vector3(ref.mRef.mPos.pos)) < minSqr) vActorPos.squaredDistance(Ogre::Vector3(ref.mRef.getPosition().pos)) < minSqr)
{ {
mMovement.mPosition[1] = -0.2; // back off, but slowly mMovement.mPosition[1] = -0.2; // back off, but slowly
} }

View file

@ -99,7 +99,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po
MWWorld::Ptr door = getNearbyDoor(actor); MWWorld::Ptr door = getNearbyDoor(actor);
if(door != MWWorld::Ptr()) // NOTE: checks interior cells only if(door != MWWorld::Ptr()) // NOTE: checks interior cells only
{ {
if(door.getCellRef().mTrap.empty() && mLastDoorChecked != door) { //Open the door if untrapped if(door.getCellRef().getTrap().empty() && mLastDoorChecked != door) { //Open the door if untrapped
door.getClass().activate(door, actor).get()->execute(actor); door.getClass().activate(door, actor).get()->execute(actor);
mLastDoorChecked = door; mLastDoorChecked = door;
} }

View file

@ -102,10 +102,11 @@ namespace MWMechanics
if (roll < x) if (roll < x)
{ {
// Reduce shield durability by incoming damage // Reduce shield durability by incoming damage
if (shield->getCellRef().mCharge == -1) int shieldhealth = shield->getClass().getItemHealth(*shield);
shield->getCellRef().mCharge = shield->getClass().getItemMaxHealth(*shield);
shield->getCellRef().mCharge -= std::min(shield->getCellRef().mCharge, int(damage)); shieldhealth -= std::min(shieldhealth, int(damage));
if (!shield->getCellRef().mCharge) shield->getCellRef().setCharge(shieldhealth);
if (shieldhealth == 0)
inv.unequipItem(*shield, blocker); inv.unequipItem(*shield, blocker);
// Reduce blocker fatigue // Reduce blocker fatigue

View file

@ -234,9 +234,9 @@ namespace MWMechanics
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
if(soulEmpty()) if(soulEmpty())
return 0; return 0;
if(mSoulGemPtr.getCellRef().mSoul=="") if(mSoulGemPtr.getCellRef().getSoul()=="")
return 0; return 0;
const ESM::Creature* soul = store.get<ESM::Creature>().find(mSoulGemPtr.getCellRef().mSoul); const ESM::Creature* soul = store.get<ESM::Creature>().find(mSoulGemPtr.getCellRef().getSoul());
return soul->mData.mSoul; return soul->mData.mSoul;
} }

View file

@ -24,10 +24,10 @@ namespace
/// @return is \a ptr allowed to take/use \a item or is it a crime? /// @return is \a ptr allowed to take/use \a item or is it a crime?
bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, MWWorld::Ptr& victim) bool isAllowedToUse (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, MWWorld::Ptr& victim)
{ {
const std::string& owner = item.getCellRef().mOwner; const std::string& owner = item.getCellRef().getOwner();
bool isOwned = !owner.empty() && owner != "player"; bool isOwned = !owner.empty() && owner != "player";
const std::string& faction = item.getCellRef().mFaction; const std::string& faction = item.getCellRef().getFaction();
bool isFactionOwned = false; bool isFactionOwned = false;
if (!faction.empty() && ptr.getClass().isNpc()) if (!faction.empty() && ptr.getClass().isNpc())
{ {
@ -36,8 +36,8 @@ namespace
isFactionOwned = true; isFactionOwned = true;
} }
if (!item.getCellRef().mOwner.empty()) if (!item.getCellRef().getOwner().empty())
victim = MWBase::Environment::get().getWorld()->searchPtr(item.getCellRef().mOwner, true); victim = MWBase::Environment::get().getWorld()->searchPtr(item.getCellRef().getOwner(), true);
return (!isOwned && !isFactionOwned); return (!isOwned && !isFactionOwned);
} }

View file

@ -50,7 +50,7 @@ namespace MWMechanics
for (; it != refList.end(); ++it) for (; it != refList.end(); ++it)
{ {
MWWorld::LiveCellRef<ESM::Door>& ref = *it; MWWorld::LiveCellRef<ESM::Door>& ref = *it;
if(pos.squaredDistance(Ogre::Vector3(ref.mRef.mPos.pos)) < minSqr) if(pos.squaredDistance(Ogre::Vector3(ref.mData.getPosition().pos)) < minSqr)
if((closed && ref.mData.getLocalRotation().rot[2] == 0) || if((closed && ref.mData.getLocalRotation().rot[2] == 0) ||
(!closed && ref.mData.getLocalRotation().rot[2] >= 1)) (!closed && ref.mData.getLocalRotation().rot[2] >= 1))
{ {

View file

@ -28,8 +28,8 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair)
player.getClass().getContainerStore(player).unstack(mTool, player); player.getClass().getContainerStore(player).unstack(mTool, player);
// reduce number of uses left // reduce number of uses left
int uses = (mTool.getCellRef().mCharge != -1) ? mTool.getCellRef().mCharge : ref->mBase->mData.mUses; int uses = mTool.getClass().getItemHealth(mTool);
mTool.getCellRef().mCharge = uses-1; mTool.getCellRef().setCharge(uses-1);
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
MWMechanics::NpcStats& npcStats = player.getClass().getNpcStats(player); MWMechanics::NpcStats& npcStats = player.getClass().getNpcStats(player);
@ -53,9 +53,9 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair)
y = std::max(1, y); y = std::max(1, y);
// repair by 'y' points // repair by 'y' points
itemToRepair.getCellRef().mCharge += y; int charge = itemToRepair.getClass().getItemHealth(itemToRepair);
itemToRepair.getCellRef().mCharge = std::min(itemToRepair.getCellRef().mCharge, charge = std::min(charge + y, itemToRepair.getClass().getItemMaxHealth(itemToRepair));
itemToRepair.getClass().getItemMaxHealth(itemToRepair)); itemToRepair.getCellRef().setCharge(charge);
// set the OnPCRepair variable on the item's script // set the OnPCRepair variable on the item's script
std::string script = itemToRepair.getClass().getScript(itemToRepair); std::string script = itemToRepair.getClass().getScript(itemToRepair);
@ -75,7 +75,7 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair)
} }
// tool used up? // tool used up?
if (mTool.getCellRef().mCharge == 0) if (mTool.getCellRef().getCharge() == 0)
{ {
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
MWWorld::ContainerStore& store = player.getClass().getContainerStore(player); MWWorld::ContainerStore& store = player.getClass().getContainerStore(player);
@ -91,7 +91,7 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair)
for (MWWorld::ContainerStoreIterator iter (store.begin()); for (MWWorld::ContainerStoreIterator iter (store.begin());
iter!=store.end(); ++iter) iter!=store.end(); ++iter)
{ {
if (Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, mTool.getCellRef().mRefID)) if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), mTool.getCellRef().getRefId()))
{ {
mTool = *iter; mTool = *iter;
break; break;

View file

@ -29,10 +29,10 @@ namespace MWMechanics
void Security::pickLock(const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick, void Security::pickLock(const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick,
std::string& resultMessage, std::string& resultSound) std::string& resultMessage, std::string& resultSound)
{ {
if (!(lock.getCellRef().mLockLevel > 0)) //If it's unlocked back out immediately if (!(lock.getCellRef().getLockLevel() > 0)) //If it's unlocked back out immediately
return; return;
int lockStrength = lock.getCellRef().mLockLevel; int lockStrength = lock.getCellRef().getLockLevel();
float pickQuality = lockpick.get<ESM::Lockpick>()->mBase->mData.mQuality; float pickQuality = lockpick.get<ESM::Lockpick>()->mBase->mData.mQuality;
@ -60,22 +60,22 @@ namespace MWMechanics
resultMessage = "#{sLockFail}"; resultMessage = "#{sLockFail}";
} }
if (lockpick.getCellRef().mCharge == -1) int uses = lockpick.getClass().getItemHealth(lockpick);
lockpick.getCellRef().mCharge = lockpick.get<ESM::Lockpick>()->mBase->mData.mUses; --uses;
--lockpick.getCellRef().mCharge; lockpick.getCellRef().setCharge(uses);
if (!lockpick.getCellRef().mCharge) if (!uses)
lockpick.getContainerStore()->remove(lockpick, 1, mActor); lockpick.getContainerStore()->remove(lockpick, 1, mActor);
} }
void Security::probeTrap(const MWWorld::Ptr &trap, const MWWorld::Ptr &probe, void Security::probeTrap(const MWWorld::Ptr &trap, const MWWorld::Ptr &probe,
std::string& resultMessage, std::string& resultSound) std::string& resultMessage, std::string& resultSound)
{ {
if (trap.getCellRef().mTrap == "") if (trap.getCellRef().getTrap() == "")
return; return;
float probeQuality = probe.get<ESM::Probe>()->mBase->mData.mQuality; float probeQuality = probe.get<ESM::Probe>()->mBase->mData.mQuality;
const ESM::Spell* trapSpell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(trap.getCellRef().mTrap); const ESM::Spell* trapSpell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(trap.getCellRef().getTrap());
float trapSpellPoints = trapSpell->mData.mCost; float trapSpellPoints = trapSpell->mData.mCost;
float fTrapCostMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fTrapCostMult")->getFloat(); float fTrapCostMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fTrapCostMult")->getFloat();
@ -93,7 +93,7 @@ namespace MWMechanics
int roll = static_cast<float> (std::rand()) / RAND_MAX * 100; int roll = static_cast<float> (std::rand()) / RAND_MAX * 100;
if (roll <= x) if (roll <= x)
{ {
trap.getCellRef().mTrap = ""; trap.getCellRef().setTrap("");
resultSound = "Disarm Trap"; resultSound = "Disarm Trap";
resultMessage = "#{sTrapSuccess}"; resultMessage = "#{sTrapSuccess}";
@ -103,10 +103,10 @@ namespace MWMechanics
resultMessage = "#{sTrapFail}"; resultMessage = "#{sTrapFail}";
} }
if (probe.getCellRef().mCharge == -1) int uses = probe.getClass().getItemHealth(probe);
probe.getCellRef().mCharge = probe.get<ESM::Probe>()->mBase->mData.mUses; --uses;
--probe.getCellRef().mCharge; probe.getCellRef().setCharge(uses);
if (!probe.getCellRef().mCharge) if (!uses)
probe.getContainerStore()->remove(probe, 1, mActor); probe.getContainerStore()->remove(probe, 1, mActor);
} }

View file

@ -470,21 +470,21 @@ namespace MWMechanics
{ {
if (effectId == ESM::MagicEffect::Lock) if (effectId == ESM::MagicEffect::Lock)
{ {
if (target.getCellRef().mLockLevel < magnitude) //If the door is not already locked to a higher value, lock it to spell magnitude if (target.getCellRef().getLockLevel() < magnitude) //If the door is not already locked to a higher value, lock it to spell magnitude
target.getCellRef().mLockLevel = magnitude; target.getCellRef().setLockLevel(magnitude);
} }
else if (effectId == ESM::MagicEffect::Open) else if (effectId == ESM::MagicEffect::Open)
{ {
if (target.getCellRef().mLockLevel <= magnitude) if (target.getCellRef().getLockLevel() <= magnitude)
{ {
//Door not already unlocked if (target.getCellRef().getLockLevel() > 0)
if (target.getCellRef().mLockLevel > 0)
{ {
//Door not already unlocked
MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock", 1.f, 1.f); MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock", 1.f, 1.f);
if (!caster.isEmpty() && caster.getClass().isActor()) if (!caster.isEmpty() && caster.getClass().isActor())
MWBase::Environment::get().getMechanicsManager()->objectOpened(caster, target); MWBase::Environment::get().getMechanicsManager()->objectOpened(caster, target);
} }
target.getCellRef().mLockLevel = -abs(target.getCellRef().mLockLevel); //unlocks the door target.getCellRef().setLockLevel(-abs(target.getCellRef().getLockLevel())); //unlocks the door
} }
else else
MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock Fail", 1.f, 1.f); MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock Fail", 1.f, 1.f);
@ -588,7 +588,7 @@ namespace MWMechanics
throw std::runtime_error("can't cast an item without an enchantment"); throw std::runtime_error("can't cast an item without an enchantment");
mSourceName = item.getClass().getName(item); mSourceName = item.getClass().getName(item);
mId = item.getCellRef().mRefID; mId = item.getCellRef().getRefId();
const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(enchantmentName); const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(enchantmentName);
@ -601,10 +601,10 @@ namespace MWMechanics
int eSkill = mCaster.getClass().getSkill(mCaster, ESM::Skill::Enchant); int eSkill = mCaster.getClass().getSkill(mCaster, ESM::Skill::Enchant);
const int castCost = std::max(1.f, enchantCost - (enchantCost / 100) * (eSkill - 10)); const int castCost = std::max(1.f, enchantCost - (enchantCost / 100) * (eSkill - 10));
if (item.getCellRef().mEnchantmentCharge == -1) if (item.getCellRef().getEnchantmentCharge() == -1)
item.getCellRef().mEnchantmentCharge = enchantment->mData.mCharge; item.getCellRef().setEnchantmentCharge(enchantment->mData.mCharge);
if (item.getCellRef().mEnchantmentCharge < castCost) if (item.getCellRef().getEnchantmentCharge() < castCost)
{ {
// TODO: Should there be a sound here? // TODO: Should there be a sound here?
if (mCaster.getRefData().getHandle() == "player") if (mCaster.getRefData().getHandle() == "player")
@ -612,7 +612,7 @@ namespace MWMechanics
return false; return false;
} }
// Reduce charge // Reduce charge
item.getCellRef().mEnchantmentCharge -= castCost; item.getCellRef().setEnchantmentCharge(item.getCellRef().getEnchantmentCharge() - castCost);
} }
if (enchantment->mData.mType == ESM::Enchantment::WhenUsed) if (enchantment->mData.mType == ESM::Enchantment::WhenUsed)

View file

@ -49,10 +49,10 @@ void Actors::insertBegin(const MWWorld::Ptr &ptr)
Ogre::SceneNode* insert = cellnode->createChildSceneNode(); Ogre::SceneNode* insert = cellnode->createChildSceneNode();
const float *f = ptr.getRefData().getPosition().pos; const float *f = ptr.getRefData().getPosition().pos;
insert->setPosition(f[0], f[1], f[2]); insert->setPosition(f[0], f[1], f[2]);
insert->setScale(ptr.getCellRef().mScale, ptr.getCellRef().mScale, ptr.getCellRef().mScale); insert->setScale(ptr.getCellRef().getScale(), ptr.getCellRef().getScale(), ptr.getCellRef().getScale());
// Convert MW rotation to a quaternion: // Convert MW rotation to a quaternion:
f = ptr.getCellRef().mPos.rot; f = ptr.getCellRef().getPosition().rot;
// Rotate around X axis // Rotate around X axis
Ogre::Quaternion xr(Ogre::Radian(-f[0]), Ogre::Vector3::UNIT_X); Ogre::Quaternion xr(Ogre::Radian(-f[0]), Ogre::Vector3::UNIT_X);

View file

@ -290,7 +290,7 @@ void Animation::addAnimSource(const std::string &model)
mAccumRoot = mNonAccumRoot->getParent(); mAccumRoot = mNonAccumRoot->getParent();
if(!mAccumRoot) if(!mAccumRoot)
{ {
std::cerr<< "Non-Accum root for "<<mPtr.getCellRef().mRefID<<" is skeleton root??" <<std::endl; std::cerr<< "Non-Accum root for "<<mPtr.getCellRef().getRefId()<<" is skeleton root??" <<std::endl;
mNonAccumRoot = NULL; mNonAccumRoot = NULL;
} }
} }
@ -301,7 +301,7 @@ void Animation::addAnimSource(const std::string &model)
mAccumRoot = mNonAccumRoot->getParent(); mAccumRoot = mNonAccumRoot->getParent();
if(!mAccumRoot) if(!mAccumRoot)
{ {
std::cerr<< "Non-Accum root for "<<mPtr.getCellRef().mRefID<<" is skeleton root??" <<std::endl; std::cerr<< "Non-Accum root for "<<mPtr.getCellRef().getRefId()<<" is skeleton root??" <<std::endl;
mNonAccumRoot = NULL; mNonAccumRoot = NULL;
} }
} }
@ -818,7 +818,7 @@ void Animation::play(const std::string &groupname, int priority, int groups, boo
} }
} }
if(iter == mAnimSources.rend()) if(iter == mAnimSources.rend())
std::cerr<< "Failed to find animation "<<groupname<<" for "<<mPtr.getCellRef().mRefID <<std::endl; std::cerr<< "Failed to find animation "<<groupname<<" for "<<mPtr.getCellRef().getRefId() <<std::endl;
resetActiveGroups(); resetActiveGroups();
} }

View file

@ -52,11 +52,11 @@ void Objects::insertBegin(const MWWorld::Ptr& ptr)
const float *f = ptr.getRefData().getPosition().pos; const float *f = ptr.getRefData().getPosition().pos;
insert->setPosition(f[0], f[1], f[2]); insert->setPosition(f[0], f[1], f[2]);
insert->setScale(ptr.getCellRef().mScale, ptr.getCellRef().mScale, ptr.getCellRef().mScale); insert->setScale(ptr.getCellRef().getScale(), ptr.getCellRef().getScale(), ptr.getCellRef().getScale());
// Convert MW rotation to a quaternion: // Convert MW rotation to a quaternion:
f = ptr.getCellRef().mPos.rot; f = ptr.getCellRef().getPosition().rot;
// Rotate around X axis // Rotate around X axis
Ogre::Quaternion xr(Ogre::Radian(-f[0]), Ogre::Vector3::UNIT_X); Ogre::Quaternion xr(Ogre::Radian(-f[0]), Ogre::Vector3::UNIT_X);

View file

@ -88,6 +88,11 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
if (!MWBase::Environment::get().getWorld()->getPlayerPtr().isInCell())
{
runtime.push (0);
return;
}
bool interior = bool interior =
!MWBase::Environment::get().getWorld()->getPlayerPtr().getCell()->getCell()->isExterior(); !MWBase::Environment::get().getWorld()->getPlayerPtr().getCell()->getCell()->isExterior();

View file

@ -121,7 +121,7 @@ namespace MWScript
std::string itemName; std::string itemName;
for (MWWorld::ContainerStoreIterator iter(store.begin()); iter != store.end(); ++iter) for (MWWorld::ContainerStoreIterator iter(store.begin()); iter != store.end(); ++iter)
if (::Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, item)) if (::Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), item))
itemName = iter->getClass().getName(*iter); itemName = iter->getClass().getName(*iter);
int numRemoved = store.remove(item, count, ptr); int numRemoved = store.remove(item, count, ptr);
@ -165,7 +165,7 @@ namespace MWScript
MWWorld::ContainerStoreIterator it = invStore.begin(); MWWorld::ContainerStoreIterator it = invStore.begin();
for (; it != invStore.end(); ++it) for (; it != invStore.end(); ++it)
{ {
if (::Misc::StringUtils::ciEqual(it->getCellRef().mRefID, item)) if (::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item))
break; break;
} }
if (it == invStore.end()) if (it == invStore.end())
@ -268,7 +268,7 @@ namespace MWScript
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot) for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot)
{ {
MWWorld::ContainerStoreIterator it = invStore.getSlot (slot); MWWorld::ContainerStoreIterator it = invStore.getSlot (slot);
if (it != invStore.end() && ::Misc::StringUtils::ciEqual(it->getCellRef().mRefID, item)) if (it != invStore.end() && ::Misc::StringUtils::ciEqual(it->getCellRef().getRefId(), item))
{ {
runtime.push(1); runtime.push(1);
return; return;
@ -295,7 +295,7 @@ namespace MWScript
it != invStore.end(); ++it) it != invStore.end(); ++it)
{ {
if (::Misc::StringUtils::ciEqual(it->getCellRef().mSoul, name)) if (::Misc::StringUtils::ciEqual(it->getCellRef().getSoul(), name))
{ {
runtime.push(1); runtime.push(1);
return; return;

View file

@ -131,7 +131,7 @@ namespace MWScript
{ {
MWWorld::Ptr ptr = R()(runtime); MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Integer lockLevel = ptr.getCellRef().mLockLevel; Interpreter::Type_Integer lockLevel = ptr.getCellRef().getLockLevel();
if(lockLevel==0) { //no lock level was ever set, set to 100 as default if(lockLevel==0) { //no lock level was ever set, set to 100 as default
lockLevel = 100; lockLevel = 100;
} }
@ -324,7 +324,7 @@ namespace MWScript
{ {
MWWorld::Ptr ptr = R()(runtime); MWWorld::Ptr ptr = R()(runtime);
runtime.push (ptr.getCellRef().mLockLevel > 0); runtime.push (ptr.getCellRef().getLockLevel() > 0);
} }
}; };
@ -369,7 +369,7 @@ namespace MWScript
store.get<ESM::Creature>().find(creature); // This line throws an exception if it can't find the creature store.get<ESM::Creature>().find(creature); // This line throws an exception if it can't find the creature
MWWorld::Ptr item = *ptr.getClass().getContainerStore(ptr).add(gem, 1, ptr); MWWorld::Ptr item = *ptr.getClass().getContainerStore(ptr).add(gem, 1, ptr);
item.getCellRef().mSoul = creature; item.getCellRef().setSoul(creature);
} }
}; };
@ -392,7 +392,7 @@ namespace MWScript
MWWorld::ContainerStore& store = ptr.getClass().getContainerStore (ptr); MWWorld::ContainerStore& store = ptr.getClass().getContainerStore (ptr);
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it) for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
{ {
if (::Misc::StringUtils::ciEqual(it->getCellRef().mSoul, soul)) if (::Misc::StringUtils::ciEqual(it->getCellRef().getSoul(), soul))
{ {
store.remove(*it, 1, ptr); store.remove(*it, 1, ptr);
return; return;
@ -430,7 +430,7 @@ namespace MWScript
int toRemove = amount; int toRemove = amount;
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter) for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
{ {
if (::Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, item)) if (::Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), item))
{ {
int removed = store.remove(*iter, toRemove, ptr); int removed = store.remove(*iter, toRemove, ptr);
MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter, removed); MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter, removed);
@ -462,7 +462,7 @@ namespace MWScript
for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter) for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter)
{ {
if (::Misc::StringUtils::ciEqual(iter->getCellRef().mSoul, soul)) if (::Misc::StringUtils::ciEqual(iter->getCellRef().getSoul(), soul))
{ {
MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter, 1); MWBase::Environment::get().getWorld()->dropObjectOnGround(ptr, *iter, 1);
store.remove(*iter, 1, ptr); store.remove(*iter, 1, ptr);
@ -659,10 +659,10 @@ namespace MWScript
const std::string script = ptr.getClass().getScript(ptr); const std::string script = ptr.getClass().getScript(ptr);
if(script.empty()) if(script.empty())
str<< ptr.getCellRef().mRefID<<" ("<<ptr.getRefData().getHandle()<<") does not have a script."; str<< ptr.getCellRef().getRefId()<<" ("<<ptr.getRefData().getHandle()<<") does not have a script.";
else else
{ {
str<< "Local variables for "<<ptr.getCellRef().mRefID<<" ("<<ptr.getRefData().getHandle()<<")"; str<< "Local variables for "<<ptr.getCellRef().getRefId()<<" ("<<ptr.getRefData().getHandle()<<")";
const Locals &locals = ptr.getRefData().getLocals(); const Locals &locals = ptr.getRefData().getLocals();
const Compiler::Locals &complocals = MWBase::Environment::get().getScriptManager()->getLocals(script); const Compiler::Locals &complocals = MWBase::Environment::get().getScriptManager()->getLocals(script);

View file

@ -47,7 +47,7 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
MWWorld::Ptr ptr = R()(runtime); MWWorld::Ptr ptr = R()(runtime);
runtime.push(ptr.getCellRef().mScale); runtime.push(ptr.getCellRef().getScale());
} }
}; };
@ -64,7 +64,7 @@ namespace MWScript
runtime.pop(); runtime.pop();
// add the parameter to the object's scale. // add the parameter to the object's scale.
MWBase::Environment::get().getWorld()->scaleObject(ptr,ptr.getCellRef().mScale + scale); MWBase::Environment::get().getWorld()->scaleObject(ptr,ptr.getCellRef().getScale() + scale);
} }
}; };
@ -117,15 +117,15 @@ namespace MWScript
if (axis == "x") if (axis == "x")
{ {
runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[0]).valueDegrees()); runtime.push(Ogre::Radian(ptr.getCellRef().getPosition().rot[0]).valueDegrees());
} }
else if (axis == "y") else if (axis == "y")
{ {
runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[1]).valueDegrees()); runtime.push(Ogre::Radian(ptr.getCellRef().getPosition().rot[1]).valueDegrees());
} }
else if (axis == "z") else if (axis == "z")
{ {
runtime.push(Ogre::Radian(ptr.getCellRef().mPos.rot[2]).valueDegrees()); runtime.push(Ogre::Radian(ptr.getCellRef().getPosition().rot[2]).valueDegrees());
} }
else else
throw std::runtime_error ("invalid rotation axis: " + axis); throw std::runtime_error ("invalid rotation axis: " + axis);
@ -247,15 +247,15 @@ namespace MWScript
if(axis == "x") if(axis == "x")
{ {
runtime.push(ptr.getCellRef().mPos.pos[0]); runtime.push(ptr.getCellRef().getPosition().pos[0]);
} }
else if(axis == "y") else if(axis == "y")
{ {
runtime.push(ptr.getCellRef().mPos.pos[1]); runtime.push(ptr.getCellRef().getPosition().pos[1]);
} }
else if(axis == "z") else if(axis == "z")
{ {
runtime.push(ptr.getCellRef().mPos.pos[2]); runtime.push(ptr.getCellRef().getPosition().pos[2]);
} }
else else
throw std::runtime_error ("invalid axis: " + axis); throw std::runtime_error ("invalid axis: " + axis);
@ -415,7 +415,7 @@ namespace MWScript
pos.rot[0] = pos.rot[1] = 0; pos.rot[0] = pos.rot[1] = 0;
pos.rot[2] = zRot; pos.rot[2] = zRot;
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID); MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID);
ref.getPtr().getCellRef().mPos = pos; ref.getPtr().getCellRef().setPosition(pos);
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),store,pos); MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),store,pos);
} }
else else
@ -456,7 +456,7 @@ namespace MWScript
pos.rot[0] = pos.rot[1] = 0; pos.rot[0] = pos.rot[1] = 0;
pos.rot[2] = zRot; pos.rot[2] = zRot;
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID); MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID);
ref.getPtr().getCellRef().mPos = pos; ref.getPtr().getCellRef().setPosition(pos);
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),store,pos); MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),store,pos);
} }
else else
@ -523,7 +523,7 @@ namespace MWScript
// create item // create item
MWWorld::CellStore* store = actor.getCell(); MWWorld::CellStore* store = actor.getCell();
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), itemID, count); MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), itemID, count);
ref.getPtr().getCellRef().mPos = ipos; ref.getPtr().getCellRef().setPosition(ipos);
MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),store,ipos); MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),store,ipos);
} }
@ -617,8 +617,8 @@ namespace MWScript
ptr.getRefData().getLocalRotation().rot[1] = 0; ptr.getRefData().getLocalRotation().rot[1] = 0;
ptr.getRefData().getLocalRotation().rot[2] = 0; ptr.getRefData().getLocalRotation().rot[2] = 0;
MWBase::Environment::get().getWorld()->rotateObject(ptr, 0,0,0,true); MWBase::Environment::get().getWorld()->rotateObject(ptr, 0,0,0,true);
MWBase::Environment::get().getWorld()->moveObject(ptr, ptr.getCellRef().mPos.pos[0], MWBase::Environment::get().getWorld()->moveObject(ptr, ptr.getCellRef().getPosition().pos[0],
ptr.getCellRef().mPos.pos[1], ptr.getCellRef().mPos.pos[2]); ptr.getCellRef().getPosition().pos[1], ptr.getCellRef().getPosition().pos[2]);
} }
}; };

View file

@ -11,7 +11,7 @@ namespace MWWorld
cast.mHitPosition = Ogre::Vector3(actor.getRefData().getPosition().pos); cast.mHitPosition = Ogre::Vector3(actor.getRefData().getPosition().pos);
cast.cast(mSpellId); cast.cast(mSpellId);
mTrapSource.getCellRef().mTrap = ""; mTrapSource.getCellRef().setTrap("");
} }
} }

View file

@ -0,0 +1,185 @@
#include "cellref.hpp"
#include <components/esm/objectstate.hpp>
namespace MWWorld
{
ESM::RefNum CellRef::getRefNum() const
{
return mCellRef.mRefNum;
}
std::string CellRef::getRefId() const
{
return mCellRef.mRefID;
}
bool CellRef::getTeleport() const
{
return mCellRef.mTeleport;
}
ESM::Position CellRef::getDoorDest() const
{
return mCellRef.mDoorDest;
}
std::string CellRef::getDestCell() const
{
return mCellRef.mDestCell;
}
float CellRef::getScale() const
{
return mCellRef.mScale;
}
void CellRef::setScale(float scale)
{
if (scale != mCellRef.mScale)
{
mChanged = true;
mCellRef.mScale = scale;
}
}
ESM::Position CellRef::getPosition() const
{
return mCellRef.mPos;
}
void CellRef::setPosition(const ESM::Position &position)
{
mChanged = true;
mCellRef.mPos = position;
}
float CellRef::getEnchantmentCharge() const
{
return mCellRef.mEnchantmentCharge;
}
void CellRef::setEnchantmentCharge(float charge)
{
if (charge != mCellRef.mEnchantmentCharge)
{
mChanged = true;
mCellRef.mEnchantmentCharge = charge;
}
}
int CellRef::getCharge() const
{
return mCellRef.mCharge;
}
void CellRef::setCharge(int charge)
{
if (charge != mCellRef.mCharge)
{
mChanged = true;
mCellRef.mCharge = charge;
}
}
std::string CellRef::getOwner() const
{
return mCellRef.mOwner;
}
void CellRef::setOwner(const std::string &owner)
{
if (owner != mCellRef.mOwner)
{
mChanged = true;
mCellRef.mOwner = owner;
}
}
std::string CellRef::getSoul() const
{
return mCellRef.mSoul;
}
void CellRef::setSoul(const std::string &soul)
{
if (soul != mCellRef.mSoul)
{
mChanged = true;
mCellRef.mSoul = soul;
}
}
std::string CellRef::getFaction() const
{
return mCellRef.mFaction;
}
void CellRef::setFaction(const std::string &faction)
{
if (faction != mCellRef.mFaction)
{
mChanged = true;
mCellRef.mFaction = faction;
}
}
int CellRef::getLockLevel() const
{
return mCellRef.mLockLevel;
}
void CellRef::setLockLevel(int lockLevel)
{
if (lockLevel != mCellRef.mLockLevel)
{
mChanged = true;
mCellRef.mLockLevel = lockLevel;
}
}
std::string CellRef::getKey() const
{
return mCellRef.mKey;
}
std::string CellRef::getTrap() const
{
return mCellRef.mTrap;
}
void CellRef::setTrap(const std::string& trap)
{
if (trap != mCellRef.mTrap)
{
mChanged = true;
mCellRef.mTrap = trap;
}
}
int CellRef::getGoldValue() const
{
return mCellRef.mGoldValue;
}
void CellRef::setGoldValue(int value)
{
if (value != mCellRef.mGoldValue)
{
mChanged = true;
mCellRef.mGoldValue = value;
}
}
void CellRef::writeState(ESM::ObjectState &state) const
{
state.mRef = mCellRef;
}
bool CellRef::hasChanged() const
{
return mChanged;
}
}

View file

@ -0,0 +1,99 @@
#ifndef OPENMW_MWWORLD_CELLREF_H
#define OPENMW_MWWORLD_CELLREF_H
#include <components/esm/cellref.hpp>
namespace ESM
{
class ObjectState;
}
namespace MWWorld
{
/// \brief Encapsulated variant of ESM::CellRef with change tracking
class CellRef
{
public:
CellRef (const ESM::CellRef& ref)
: mCellRef(ref)
{
mChanged = false;
}
// Note: Currently unused for items in containers
ESM::RefNum getRefNum() const;
// Id of object being referenced
std::string getRefId() const;
// For doors - true if this door teleports to somewhere else, false
// if it should open through animation.
bool getTeleport() const;
// Teleport location for the door, if this is a teleporting door.
ESM::Position getDoorDest() const;
// Destination cell for doors (optional)
std::string getDestCell() const;
// Scale applied to mesh
float getScale() const;
void setScale(float scale);
// Position and rotation of this object within the cell
ESM::Position getPosition() const;
void setPosition (const ESM::Position& position);
// Remaining enchantment charge. This could be -1 if the charge was not touched yet (i.e. full).
float getEnchantmentCharge() const;
void setEnchantmentCharge(float charge);
// For weapon or armor, this is the remaining item health.
// For tools (lockpicks, probes, repair hammer) it is the remaining uses.
int getCharge() const;
void setCharge(int charge);
// The NPC that owns this object (and will get angry if you steal it)
std::string getOwner() const;
void setOwner(const std::string& owner);
// ID of creature trapped in this soul gem
std::string getSoul() const;
void setSoul(const std::string& soul);
// The faction that owns this object (and will get angry if
// you take it and are not a faction member)
std::string getFaction() const;
void setFaction (const std::string& faction);
// Lock level for doors and containers
// Positive for a locked door. 0 for a door that was never locked.
// For an unlocked door, it is set to -(previous locklevel)
int getLockLevel() const;
void setLockLevel(int lockLevel);
// Key and trap ID names, if any
std::string getKey() const;
std::string getTrap() const;
void setTrap(const std::string& trap);
// This is 5 for Gold_005 references, 100 for Gold_100 and so on.
int getGoldValue() const;
void setGoldValue(int value);
// Write the content of this CellRef into the given ObjectState
void writeState (ESM::ObjectState& state) const;
// Has this CellRef changed since it was originally loaded?
bool hasChanged() const;
private:
bool mChanged;
ESM::CellRef mCellRef;
};
}
#endif

View file

@ -27,7 +27,7 @@ namespace MWWorld
LiveRef *find (const std::string& name) LiveRef *find (const std::string& name)
{ {
for (typename List::iterator iter (mList.begin()); iter!=mList.end(); ++iter) for (typename List::iterator iter (mList.begin()); iter!=mList.end(); ++iter)
if (iter->mData.getCount() > 0 && iter->mRef.mRefID == name) if (iter->mData.getCount() > 0 && iter->mRef.getRefId() == name)
return &*iter; return &*iter;
return 0; return 0;

View file

@ -72,8 +72,16 @@ namespace
iter (collection.mList.begin()); iter (collection.mList.begin());
iter!=collection.mList.end(); ++iter) iter!=collection.mList.end(); ++iter)
{ {
if (iter->mData.getCount()==0 && iter->mRef.mRefNum.mContentFile==-1) if (!iter->mData.hasChanged() && !iter->mRef.hasChanged() && iter->mRef.getRefNum().mContentFile != -1)
continue; // deleted reference that did not come from a content file -> ignore {
// Reference that came from a content file and has not been changed -> ignore
continue;
}
if (iter->mData.getCount()==0 && iter->mRef.getRefNum().mContentFile==-1)
{
// Deleted reference that did not come from a content file -> ignore
continue;
}
RecordType state; RecordType state;
iter->save (state); iter->save (state);
@ -117,7 +125,7 @@ namespace
{ {
for (typename MWWorld::CellRefList<T>::List::iterator iter (collection.mList.begin()); for (typename MWWorld::CellRefList<T>::List::iterator iter (collection.mList.begin());
iter!=collection.mList.end(); ++iter) iter!=collection.mList.end(); ++iter)
if (iter->mRef.mRefNum==state.mRef.mRefNum) if (iter->mRef.getRefNum()==state.mRef.mRefNum)
{ {
// overwrite existing reference // overwrite existing reference
iter->load (state); iter->load (state);

View file

@ -82,6 +82,14 @@ namespace MWWorld
return false; return false;
} }
int Class::getItemHealth(const Ptr &ptr) const
{
if (ptr.getCellRef().getCharge() == -1)
return getItemMaxHealth(ptr);
else
return ptr.getCellRef().getCharge();
}
int Class::getItemMaxHealth (const Ptr& ptr) const int Class::getItemMaxHealth (const Ptr& ptr) const
{ {
throw std::runtime_error ("class does not have item health"); throw std::runtime_error ("class does not have item health");

View file

@ -116,9 +116,12 @@ namespace MWWorld
virtual bool hasItemHealth (const Ptr& ptr) const; virtual bool hasItemHealth (const Ptr& ptr) const;
///< \return Item health data available? (default implementation: false) ///< \return Item health data available? (default implementation: false)
virtual int getItemHealth (const Ptr& ptr) const;
///< Return current item health or throw an exception if class does not have item health
virtual int getItemMaxHealth (const Ptr& ptr) const; virtual int getItemMaxHealth (const Ptr& ptr) const;
///< Return item max health or throw an exception, if class does not have item health ///< Return item max health or throw an exception, if class does not have item health
/// (default implementation: throw an exceoption) /// (default implementation: throw an exception)
virtual void hit(const Ptr& ptr, int type=-1) const; virtual void hit(const Ptr& ptr, int type=-1) const;
///< Execute a melee hit, using the current weapon. This will check the relevant skills ///< Execute a melee hit, using the current weapon. This will check the relevant skills

View file

@ -74,7 +74,6 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::getState (CellRefList<T
LiveCellRef<T> ref (record); LiveCellRef<T> ref (record);
ref.load (state); ref.load (state);
ref.mRef.mRefNum.mContentFile = -1;
collection.mList.push_back (ref); collection.mList.push_back (ref);
return ContainerStoreIterator (this, --collection.mList.end()); return ContainerStoreIterator (this, --collection.mList.end());
@ -127,7 +126,7 @@ int MWWorld::ContainerStore::count(const std::string &id)
{ {
int total=0; int total=0;
for (MWWorld::ContainerStoreIterator iter (begin()); iter!=end(); ++iter) for (MWWorld::ContainerStoreIterator iter (begin()); iter!=end(); ++iter)
if (Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, id)) if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), id))
total += iter->getRefData().getCount(); total += iter->getRefData().getCount();
return total; return total;
} }
@ -145,7 +144,7 @@ bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
const MWWorld::Class& cls1 = ptr1.getClass(); const MWWorld::Class& cls1 = ptr1.getClass();
const MWWorld::Class& cls2 = ptr2.getClass(); const MWWorld::Class& cls2 = ptr2.getClass();
if (!Misc::StringUtils::ciEqual(ptr1.getCellRef().mRefID, ptr2.getCellRef().mRefID)) if (!Misc::StringUtils::ciEqual(ptr1.getCellRef().getRefId(), ptr2.getCellRef().getRefId()))
return false; return false;
// If it has an enchantment, don't stack when some of the charge is already used // If it has an enchantment, don't stack when some of the charge is already used
@ -154,25 +153,24 @@ bool MWWorld::ContainerStore::stacks(const Ptr& ptr1, const Ptr& ptr2)
const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find( const ESM::Enchantment* enchantment = MWBase::Environment::get().getWorld()->getStore().get<ESM::Enchantment>().find(
ptr1.getClass().getEnchantment(ptr1)); ptr1.getClass().getEnchantment(ptr1));
float maxCharge = enchantment->mData.mCharge; float maxCharge = enchantment->mData.mCharge;
float enchantCharge1 = ptr1.getCellRef().mEnchantmentCharge == -1 ? maxCharge : ptr1.getCellRef().mEnchantmentCharge; float enchantCharge1 = ptr1.getCellRef().getEnchantmentCharge() == -1 ? maxCharge : ptr1.getCellRef().getEnchantmentCharge();
float enchantCharge2 = ptr2.getCellRef().mEnchantmentCharge == -1 ? maxCharge : ptr2.getCellRef().mEnchantmentCharge; float enchantCharge2 = ptr2.getCellRef().getEnchantmentCharge() == -1 ? maxCharge : ptr2.getCellRef().getEnchantmentCharge();
if (enchantCharge1 != maxCharge || enchantCharge2 != maxCharge) if (enchantCharge1 != maxCharge || enchantCharge2 != maxCharge)
return false; return false;
} }
return ptr1 != ptr2 // an item never stacks onto itself return ptr1 != ptr2 // an item never stacks onto itself
&& ptr1.getCellRef().mOwner == ptr2.getCellRef().mOwner && ptr1.getCellRef().getOwner() == ptr2.getCellRef().getOwner()
&& ptr1.getCellRef().mSoul == ptr2.getCellRef().mSoul && ptr1.getCellRef().getSoul() == ptr2.getCellRef().getSoul()
&& ptr1.getClass().getRemainingUsageTime(ptr1) == ptr2.getClass().getRemainingUsageTime(ptr2) && ptr1.getClass().getRemainingUsageTime(ptr1) == ptr2.getClass().getRemainingUsageTime(ptr2)
&& cls1.getScript(ptr1) == cls2.getScript(ptr2) && cls1.getScript(ptr1) == cls2.getScript(ptr2)
// item that is already partly used up never stacks // item that is already partly used up never stacks
&& (!cls1.hasItemHealth(ptr1) || ptr1.getCellRef().mCharge == -1 && (!cls1.hasItemHealth(ptr1) || (
|| cls1.getItemMaxHealth(ptr1) == ptr1.getCellRef().mCharge) cls1.getItemHealth(ptr1) == cls1.getItemMaxHealth(ptr1)
&& (!cls2.hasItemHealth(ptr2) || ptr2.getCellRef().mCharge == -1 && cls2.getItemHealth(ptr2) == cls2.getItemMaxHealth(ptr2)));
|| cls2.getItemMaxHealth(ptr2) == ptr2.getCellRef().mCharge);
} }
MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(const std::string &id, int count, const Ptr &actorPtr) MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add(const std::string &id, int count, const Ptr &actorPtr)
@ -195,19 +193,19 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr
{ {
// HACK: Set owner on the original item, then reset it after we have copied it // HACK: Set owner on the original item, then reset it after we have copied it
// If we set the owner on the copied item, it would not stack correctly... // If we set the owner on the copied item, it would not stack correctly...
std::string oldOwner = itemPtr.getCellRef().mOwner; std::string oldOwner = itemPtr.getCellRef().getOwner();
if (actorPtr == player) if (actorPtr == player)
{ {
// No point in setting owner to the player - NPCs will not respect this anyway // No point in setting owner to the player - NPCs will not respect this anyway
// Additionally, setting it to "player" would make those items not stack with items that don't have an owner // Additionally, setting it to "player" would make those items not stack with items that don't have an owner
itemPtr.getCellRef().mOwner = ""; itemPtr.getCellRef().setOwner("");
} }
else else
itemPtr.getCellRef().mOwner = actorPtr.getCellRef().mRefID; itemPtr.getCellRef().setOwner(actorPtr.getCellRef().getRefId());
it = addImp(itemPtr, count); it = addImp(itemPtr, count);
itemPtr.getCellRef().mOwner = oldOwner; itemPtr.getCellRef().setOwner(oldOwner);
} }
else else
{ {
@ -219,12 +217,14 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr
// we may have copied an item from the world, so reset a few things first // we may have copied an item from the world, so reset a few things first
item.getRefData().setBaseNode(NULL); // Especially important, otherwise scripts on the item could think that it's actually in a cell item.getRefData().setBaseNode(NULL); // Especially important, otherwise scripts on the item could think that it's actually in a cell
item.getCellRef().mPos.rot[0] = 0; ESM::Position pos;
item.getCellRef().mPos.rot[1] = 0; pos.rot[0] = 0;
item.getCellRef().mPos.rot[2] = 0; pos.rot[1] = 0;
item.getCellRef().mPos.pos[0] = 0; pos.rot[2] = 0;
item.getCellRef().mPos.pos[1] = 0; pos.pos[0] = 0;
item.getCellRef().mPos.pos[2] = 0; pos.pos[1] = 0;
pos.pos[2] = 0;
item.getCellRef().setPosition(pos);
std::string script = item.getClass().getScript(item); std::string script = item.getClass().getScript(item);
if(script != "") if(script != "")
@ -259,17 +259,17 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::addImp (const Ptr& ptr,
// gold needs special handling: when it is inserted into a container, the base object automatically becomes Gold_001 // gold needs special handling: when it is inserted into a container, the base object automatically becomes Gold_001
// this ensures that gold piles of different sizes stack with each other (also, several scripts rely on Gold_001 for detecting player gold) // this ensures that gold piles of different sizes stack with each other (also, several scripts rely on Gold_001 for detecting player gold)
if (Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_001") if (Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_001")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_005") || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_005")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_010") || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_010")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_025") || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_025")
|| Misc::StringUtils::ciEqual(ptr.getCellRef().mRefID, "gold_100")) || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), "gold_100"))
{ {
int realCount = count * ptr.getClass().getValue(ptr); int realCount = count * ptr.getClass().getValue(ptr);
for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter) for (MWWorld::ContainerStoreIterator iter (begin(type)); iter!=end(); ++iter)
{ {
if (Misc::StringUtils::ciEqual((*iter).getCellRef().mRefID, MWWorld::ContainerStore::sGoldId)) if (Misc::StringUtils::ciEqual((*iter).getCellRef().getRefId(), MWWorld::ContainerStore::sGoldId))
{ {
iter->getRefData().setCount(iter->getRefData().getCount() + realCount); iter->getRefData().setCount(iter->getRefData().getCount() + realCount);
flagAsModified(); flagAsModified();
@ -328,7 +328,7 @@ int MWWorld::ContainerStore::remove(const std::string& itemId, int count, const
int toRemove = count; int toRemove = count;
for (ContainerStoreIterator iter(begin()); iter != end() && toRemove > 0; ++iter) for (ContainerStoreIterator iter(begin()); iter != end() && toRemove > 0; ++iter)
if (Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, itemId)) if (Misc::StringUtils::ciEqual(iter->getCellRef().getRefId(), itemId))
toRemove -= remove(*iter, toRemove, actor); toRemove -= remove(*iter, toRemove, actor);
flagAsModified(); flagAsModified();
@ -408,8 +408,8 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::
} }
count = std::abs(count); count = std::abs(count);
ref.getPtr().getCellRef().mOwner = owner; ref.getPtr().getCellRef().setOwner(owner);
ref.getPtr().getCellRef().mFaction = faction; ref.getPtr().getCellRef().setFaction(faction);
addImp (ref.getPtr(), count); addImp (ref.getPtr(), count);
} }
} }

View file

@ -206,7 +206,7 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
// Only autoEquip if we are the original owner of the item. // Only autoEquip if we are the original owner of the item.
// This stops merchants from auto equipping anything you sell to them. // This stops merchants from auto equipping anything you sell to them.
// ...unless this is a companion, he should always equip items given to him. // ...unless this is a companion, he should always equip items given to him.
if (!Misc::StringUtils::ciEqual(test.getCellRef().mOwner, actor.getCellRef().mRefID) && if (!Misc::StringUtils::ciEqual(test.getCellRef().getOwner(), actor.getCellRef().getRefId()) &&
(actor.getClass().getScript(actor).empty() || (actor.getClass().getScript(actor).empty() ||
!actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion"))) !actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion")))
continue; continue;
@ -337,7 +337,7 @@ void MWWorld::InventoryStore::updateMagicEffects(const Ptr& actor)
std::vector<EffectParams> params; std::vector<EffectParams> params;
bool existed = (mPermanentMagicEffectMagnitudes.find((**iter).getCellRef().mRefID) != mPermanentMagicEffectMagnitudes.end()); bool existed = (mPermanentMagicEffectMagnitudes.find((**iter).getCellRef().getRefId()) != mPermanentMagicEffectMagnitudes.end());
if (!existed) if (!existed)
{ {
// Roll some dice, one for each effect // Roll some dice, one for each effect
@ -358,10 +358,10 @@ void MWWorld::InventoryStore::updateMagicEffects(const Ptr& actor)
// Consider equipping the same item twice (e.g. a ring) // Consider equipping the same item twice (e.g. a ring)
// However, permanent enchantments with a random magnitude are kind of an exploit anyway, // However, permanent enchantments with a random magnitude are kind of an exploit anyway,
// so it doesn't really matter if both items will get the same magnitude. *Extreme* edge case. // so it doesn't really matter if both items will get the same magnitude. *Extreme* edge case.
mPermanentMagicEffectMagnitudes[(**iter).getCellRef().mRefID] = params; mPermanentMagicEffectMagnitudes[(**iter).getCellRef().getRefId()] = params;
} }
else else
params = mPermanentMagicEffectMagnitudes[(**iter).getCellRef().mRefID]; params = mPermanentMagicEffectMagnitudes[(**iter).getCellRef().getRefId()];
int i=0; int i=0;
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt (enchantment.mEffects.mList.begin()); for (std::vector<ESM::ENAMstruct>::const_iterator effectIt (enchantment.mEffects.mList.begin());
@ -407,7 +407,7 @@ void MWWorld::InventoryStore::updateMagicEffects(const Ptr& actor)
{ {
if (*iter == end()) if (*iter == end())
continue; continue;
if ((**iter).getCellRef().mRefID == it->first) if ((**iter).getCellRef().getRefId() == it->first)
{ {
found = true; found = true;
} }
@ -589,14 +589,14 @@ void MWWorld::InventoryStore::visitEffectSources(MWMechanics::EffectSourceVisito
if (enchantment.mData.mType != ESM::Enchantment::ConstantEffect) if (enchantment.mData.mType != ESM::Enchantment::ConstantEffect)
continue; continue;
if (mPermanentMagicEffectMagnitudes.find((**iter).getCellRef().mRefID) == mPermanentMagicEffectMagnitudes.end()) if (mPermanentMagicEffectMagnitudes.find((**iter).getCellRef().getRefId()) == mPermanentMagicEffectMagnitudes.end())
continue; continue;
int i=0; int i=0;
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt (enchantment.mEffects.mList.begin()); for (std::vector<ESM::ENAMstruct>::const_iterator effectIt (enchantment.mEffects.mList.begin());
effectIt!=enchantment.mEffects.mList.end(); ++effectIt) effectIt!=enchantment.mEffects.mList.end(); ++effectIt)
{ {
const EffectParams& params = mPermanentMagicEffectMagnitudes[(**iter).getCellRef().mRefID][i]; const EffectParams& params = mPermanentMagicEffectMagnitudes[(**iter).getCellRef().getRefId()][i];
float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * params.mRandom; float magnitude = effectIt->mMagnMin + (effectIt->mMagnMax - effectIt->mMagnMin) * params.mRandom;
magnitude *= params.mMultiplier; magnitude *= params.mMultiplier;
visitor.visit(MWMechanics::EffectKey(*effectIt), (**iter).getClass().getName(**iter), -1, magnitude); visitor.visit(MWMechanics::EffectKey(*effectIt), (**iter).getClass().getName(**iter), -1, magnitude);
@ -626,15 +626,15 @@ void MWWorld::InventoryStore::rechargeItems(float duration)
{ {
for (TRechargingItems::iterator it = mRechargingItems.begin(); it != mRechargingItems.end(); ++it) for (TRechargingItems::iterator it = mRechargingItems.begin(); it != mRechargingItems.end(); ++it)
{ {
if (it->first->getCellRef().mEnchantmentCharge == -1 if (it->first->getCellRef().getEnchantmentCharge() == -1
|| it->first->getCellRef().mEnchantmentCharge == it->second) || it->first->getCellRef().getEnchantmentCharge() == it->second)
continue; continue;
static float fMagicItemRechargePerSecond = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find( static float fMagicItemRechargePerSecond = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find(
"fMagicItemRechargePerSecond")->getFloat(); "fMagicItemRechargePerSecond")->getFloat();
it->first->getCellRef().mEnchantmentCharge = std::min (it->first->getCellRef().mEnchantmentCharge + fMagicItemRechargePerSecond * duration, it->first->getCellRef().setEnchantmentCharge(std::min (it->first->getCellRef().getEnchantmentCharge() + fMagicItemRechargePerSecond * duration,
it->second); it->second));
} }
} }

View file

@ -11,7 +11,7 @@
#include "esmstore.hpp" #include "esmstore.hpp"
MWWorld::LiveCellRefBase::LiveCellRefBase(std::string type, const ESM::CellRef &cref) MWWorld::LiveCellRefBase::LiveCellRefBase(std::string type, const ESM::CellRef &cref)
: mClass(&Class::get(type)), mRef(cref), mData(mRef) : mClass(&Class::get(type)), mRef(cref), mData(cref)
{ {
} }
@ -41,7 +41,7 @@ void MWWorld::LiveCellRefBase::loadImp (const ESM::ObjectState& state)
void MWWorld::LiveCellRefBase::saveImp (ESM::ObjectState& state) const void MWWorld::LiveCellRefBase::saveImp (ESM::ObjectState& state) const
{ {
state.mRef = mRef; mRef.writeState(state);
/// \todo get rid of this cast once const-correct Ptr are available /// \todo get rid of this cast once const-correct Ptr are available
Ptr ptr (const_cast<LiveCellRefBase *> (this)); Ptr ptr (const_cast<LiveCellRefBase *> (this));

View file

@ -3,7 +3,7 @@
#include <typeinfo> #include <typeinfo>
#include <components/esm/cellref.hpp> #include "cellref.hpp"
#include "refdata.hpp" #include "refdata.hpp"
@ -26,7 +26,7 @@ namespace MWWorld
/** Information about this instance, such as 3D location and rotation /** Information about this instance, such as 3D location and rotation
* and individual type-dependent data. * and individual type-dependent data.
*/ */
ESM::CellRef mRef; MWWorld::CellRef mRef;
/** runtime-data */ /** runtime-data */
RefData mData; RefData mData;
@ -62,9 +62,9 @@ namespace MWWorld
/// \note Does not check if the RefId exists. /// \note Does not check if the RefId exists.
}; };
inline bool operator== (const LiveCellRefBase& cellRef, const ESM::CellRef::RefNum refNum) inline bool operator== (const LiveCellRefBase& cellRef, const ESM::RefNum refNum)
{ {
return cellRef.mRef.mRefNum==refNum; return cellRef.mRef.getRefNum()==refNum;
} }
/// A reference to one object (of any type) in a cell. /// A reference to one object (of any type) in a cell.

View file

@ -23,10 +23,20 @@ namespace MWWorld
{ {
const T* base = list.find(name); const T* base = list.find(name);
LiveCellRef<T> ref; ESM::CellRef cellRef;
ref.mBase = base; cellRef.mRefNum.mIndex = 0;
ref.mRef.mRefNum.mIndex = 0; cellRef.mRefNum.mContentFile = -1;
ref.mRef.mRefNum.mContentFile = -1; cellRef.mRefID = name;
cellRef.mScale = 1;
cellRef.mFactIndex = 0;
cellRef.mCharge = -1;
cellRef.mGoldValue = 1;
cellRef.mEnchantmentCharge = -1;
cellRef.mTeleport = false;
cellRef.mLockLevel = 0;
cellRef.mReferenceBlocked = 0;
LiveCellRef<T> ref(cellRef, base);
mRef = ref; mRef = ref;
mPtr = Ptr (&boost::any_cast<LiveCellRef<T>&> (mRef), 0); mPtr = Ptr (&boost::any_cast<LiveCellRef<T>&> (mRef), 0);
@ -67,19 +77,6 @@ namespace MWWorld
throw std::logic_error ("failed to create manual cell ref for " + lowerName + " (unknown type)"); throw std::logic_error ("failed to create manual cell ref for " + lowerName + " (unknown type)");
} }
// initialise
ESM::CellRef& cellRef = mPtr.getCellRef();
cellRef.mRefID = lowerName;
cellRef.mRefNum.mIndex = 0;
cellRef.mRefNum.mContentFile = -1;
cellRef.mScale = 1;
cellRef.mFactIndex = 0;
cellRef.mCharge = -1;
cellRef.mGoldValue = 1;
cellRef.mEnchantmentCharge = -1;
cellRef.mTeleport = false;
cellRef.mLockLevel = 0;
cellRef.mReferenceBlocked = 0;
mPtr.getRefData().setCount(count); mPtr.getRefData().setCount(count);
} }

View file

@ -656,7 +656,7 @@ namespace MWWorld
return false; return false;
} }
btVector3 btMin, btMax; btVector3 btMin, btMax;
float scale = ptr.getCellRef().mScale; float scale = ptr.getCellRef().getScale();
mEngine->getObjectAABB(model, scale, btMin, btMax); mEngine->getObjectAABB(model, scale, btMin, btMax);
min.x = btMin.x(); min.x = btMin.x();

View file

@ -39,8 +39,10 @@ namespace MWWorld
mCurrentCrimeId(-1), mCurrentCrimeId(-1),
mPaidCrimeId(-1) mPaidCrimeId(-1)
{ {
mPlayer.mBase = player; ESM::CellRef cellRef;
mPlayer.mRef.mRefID = "player"; cellRef.blank();
cellRef.mRefID = "player";
mPlayer = LiveCellRef<ESM::NPC>(cellRef, player);
float* playerPos = mPlayer.mData.getPosition().pos; float* playerPos = mPlayer.mData.getPosition().pos;
playerPos[0] = playerPos[1] = playerPos[2] = 0; playerPos[0] = playerPos[1] = playerPos[2] = 0;

View file

@ -102,11 +102,11 @@ namespace MWWorld
{ {
ProjectileState state; ProjectileState state;
state.mActorId = actor.getClass().getCreatureStats(actor).getActorId(); state.mActorId = actor.getClass().getCreatureStats(actor).getActorId();
state.mBowId = bow.getCellRef().mRefID; state.mBowId = bow.getCellRef().getRefId();
state.mVelocity = orient.yAxis() * speed; state.mVelocity = orient.yAxis() * speed;
state.mId = projectile.getCellRef().mRefID; state.mId = projectile.getCellRef().getRefId();
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), projectile.getCellRef().mRefID); MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), projectile.getCellRef().getRefId());
MWWorld::Ptr ptr = ref.getPtr(); MWWorld::Ptr ptr = ref.getPtr();
state.mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(pos, orient); state.mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(pos, orient);
@ -241,7 +241,7 @@ namespace MWWorld
{ {
MWWorld::InventoryStore& inv = caster.getClass().getInventoryStore(caster); MWWorld::InventoryStore& inv = caster.getClass().getInventoryStore(caster);
MWWorld::ContainerStoreIterator invIt = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); MWWorld::ContainerStoreIterator invIt = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
if (invIt != inv.end() && Misc::StringUtils::ciEqual(invIt->getCellRef().mRefID, it->mBowId)) if (invIt != inv.end() && Misc::StringUtils::ciEqual(invIt->getCellRef().getRefId(), it->mBowId))
bow = *invIt; bow = *invIt;
} }

View file

@ -22,7 +22,7 @@ MWWorld::LiveCellRefBase *MWWorld::Ptr::getBase() const
return mRef; return mRef;
} }
ESM::CellRef& MWWorld::Ptr::getCellRef() const MWWorld::CellRef& MWWorld::Ptr::getCellRef() const
{ {
assert(mRef); assert(mRef);

View file

@ -60,7 +60,7 @@ namespace MWWorld
MWWorld::LiveCellRefBase *getBase() const; MWWorld::LiveCellRefBase *getBase() const;
ESM::CellRef& getCellRef() const; MWWorld::CellRef& getCellRef() const;
RefData& getRefData() const; RefData& getRefData() const;

View file

@ -22,6 +22,7 @@ namespace MWWorld
mCount = refData.mCount; mCount = refData.mCount;
mPosition = refData.mPosition; mPosition = refData.mPosition;
mLocalRotation = refData.mLocalRotation; mLocalRotation = refData.mLocalRotation;
mChanged = refData.mChanged;
mCustomData = refData.mCustomData ? refData.mCustomData->clone() : 0; mCustomData = refData.mCustomData ? refData.mCustomData->clone() : 0;
} }
@ -35,7 +36,7 @@ namespace MWWorld
} }
RefData::RefData() RefData::RefData()
: mBaseNode(0), mHasLocals (false), mEnabled (true), mCount (1), mCustomData (0) : mBaseNode(0), mHasLocals (false), mEnabled (true), mCount (1), mCustomData (0), mChanged(false)
{ {
for (int i=0; i<3; ++i) for (int i=0; i<3; ++i)
{ {
@ -47,7 +48,8 @@ namespace MWWorld
RefData::RefData (const ESM::CellRef& cellRef) RefData::RefData (const ESM::CellRef& cellRef)
: mBaseNode(0), mHasLocals (false), mEnabled (true), mCount (1), mPosition (cellRef.mPos), : mBaseNode(0), mHasLocals (false), mEnabled (true), mCount (1), mPosition (cellRef.mPos),
mCustomData (0) mCustomData (0),
mChanged(false) // Loading from ESM/ESP files -> assume unchanged
{ {
mLocalRotation.rot[0]=0; mLocalRotation.rot[0]=0;
mLocalRotation.rot[1]=0; mLocalRotation.rot[1]=0;
@ -56,8 +58,9 @@ namespace MWWorld
RefData::RefData (const ESM::ObjectState& objectState) RefData::RefData (const ESM::ObjectState& objectState)
: mBaseNode (0), mHasLocals (false), mEnabled (objectState.mEnabled), : mBaseNode (0), mHasLocals (false), mEnabled (objectState.mEnabled),
mCount (objectState.mCount), mPosition (objectState.mPosition), mCustomData (0) mCount (objectState.mCount), mPosition (objectState.mPosition), mCustomData (0),
{ mChanged(true) // Loading from a savegame -> assume changed
{
for (int i=0; i<3; ++i) for (int i=0; i<3; ++i)
mLocalRotation.rot[i] = objectState.mLocalRotation[i]; mLocalRotation.rot[i] = objectState.mLocalRotation[i];
} }
@ -149,6 +152,7 @@ namespace MWWorld
{ {
mLocals.configure (script); mLocals.configure (script);
mHasLocals = true; mHasLocals = true;
mChanged = true;
} }
} }
@ -157,6 +161,8 @@ namespace MWWorld
if(count == 0) if(count == 0)
MWBase::Environment::get().getWorld()->removeRefScript(this); MWBase::Environment::get().getWorld()->removeRefScript(this);
mChanged = true;
mCount = count; mCount = count;
} }
@ -172,26 +178,31 @@ namespace MWWorld
void RefData::enable() void RefData::enable()
{ {
mChanged = !mEnabled;
mEnabled = true; mEnabled = true;
} }
void RefData::disable() void RefData::disable()
{ {
mChanged = mEnabled;
mEnabled = false; mEnabled = false;
} }
ESM::Position& RefData::getPosition() ESM::Position& RefData::getPosition()
{ {
mChanged = true;
return mPosition; return mPosition;
} }
LocalRotation& RefData::getLocalRotation() LocalRotation& RefData::getLocalRotation()
{ {
mChanged = true;
return mLocalRotation; return mLocalRotation;
} }
void RefData::setCustomData (CustomData *data) void RefData::setCustomData (CustomData *data)
{ {
mChanged = true; // We do not currently track CustomData, so assume anything with a CustomData is changed
delete mCustomData; delete mCustomData;
mCustomData = data; mCustomData = data;
} }
@ -200,4 +211,9 @@ namespace MWWorld
{ {
return mCustomData; return mCustomData;
} }
bool RefData::hasChanged() const
{
return mChanged;
}
} }

View file

@ -47,6 +47,8 @@ namespace MWWorld
void cleanup(); void cleanup();
bool mChanged;
public: public:
RefData(); RefData();
@ -108,6 +110,9 @@ namespace MWWorld
CustomData *getCustomData(); CustomData *getCustomData();
///< May return a 0-pointer. The ownership of the return data object is not transferred. ///< May return a 0-pointer. The ownership of the return data object is not transferred.
bool hasChanged() const;
///< Has this RefData changed since it was originally loaded?
}; };
} }

View file

@ -47,10 +47,10 @@ namespace
{ {
if (mRescale) if (mRescale)
{ {
if (ptr.getCellRef().mScale<0.5) if (ptr.getCellRef().getScale()<0.5)
ptr.getCellRef().mScale = 0.5; ptr.getCellRef().setScale(0.5);
else if (ptr.getCellRef().mScale>2) else if (ptr.getCellRef().getScale()>2)
ptr.getCellRef().mScale = 2; ptr.getCellRef().setScale(2);
} }
if (ptr.getRefData().getCount() && ptr.getRefData().isEnabled()) if (ptr.getRefData().getCount() && ptr.getRefData().isEnabled())
@ -65,7 +65,7 @@ namespace
float az = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[2]).valueDegrees(); float az = Ogre::Radian(ptr.getRefData().getLocalRotation().rot[2]).valueDegrees();
MWBase::Environment::get().getWorld()->localRotateObject (ptr, ax, ay, az); MWBase::Environment::get().getWorld()->localRotateObject (ptr, ax, ay, az);
MWBase::Environment::get().getWorld()->scaleObject (ptr, ptr.getCellRef().mScale); MWBase::Environment::get().getWorld()->scaleObject (ptr, ptr.getCellRef().getScale());
ptr.getClass().adjustPosition (ptr); ptr.getClass().adjustPosition (ptr);
} }
catch (const std::exception& e) catch (const std::exception& e)
@ -484,7 +484,7 @@ namespace MWWorld
mRendering.addObject(ptr); mRendering.addObject(ptr);
ptr.getClass().insertObject(ptr, *mPhysics); ptr.getClass().insertObject(ptr, *mPhysics);
MWBase::Environment::get().getWorld()->rotateObject(ptr, 0, 0, 0, true); MWBase::Environment::get().getWorld()->rotateObject(ptr, 0, 0, 0, true);
MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().mScale); MWBase::Environment::get().getWorld()->scaleObject(ptr, ptr.getCellRef().getScale());
} }
void Scene::removeObjectFromScene (const Ptr& ptr) void Scene::removeObjectFromScene (const Ptr& ptr)

View file

@ -1034,7 +1034,7 @@ namespace MWWorld
void World::scaleObject (const Ptr& ptr, float scale) void World::scaleObject (const Ptr& ptr, float scale)
{ {
ptr.getCellRef().mScale = scale; ptr.getCellRef().setScale(scale);
ptr.getClass().adjustScale(ptr,scale); ptr.getClass().adjustScale(ptr,scale);
if(ptr.getRefData().getBaseNode() == 0) if(ptr.getRefData().getBaseNode() == 0)
@ -1544,7 +1544,7 @@ namespace MWWorld
if (!ref.mData.isEnabled()) if (!ref.mData.isEnabled())
continue; continue;
if (ref.mRef.mTeleport) if (ref.mRef.getTeleport())
{ {
World::DoorMarker newMarker; World::DoorMarker newMarker;
newMarker.name = MWClass::Door::getDestination(ref); newMarker.name = MWClass::Door::getDestination(ref);
@ -1948,7 +1948,7 @@ namespace MWWorld
for (CellRefList<ESM::Container>::List::iterator container = refList.begin(); container != refList.end(); ++container) for (CellRefList<ESM::Container>::List::iterator container = refList.begin(); container != refList.end(); ++container)
{ {
MWWorld::Ptr ptr (&*container, *cellIt); MWWorld::Ptr ptr (&*container, *cellIt);
if (Misc::StringUtils::ciEqual(ptr.getCellRef().mOwner, npc.getCellRef().mRefID)) if (Misc::StringUtils::ciEqual(ptr.getCellRef().getOwner(), npc.getCellRef().getRefId()))
out.push_back(ptr); out.push_back(ptr);
} }
} }
@ -1976,7 +1976,7 @@ namespace MWWorld
(*cellIt)->forEach<ListHandlesFunctor>(functor); (*cellIt)->forEach<ListHandlesFunctor>(functor);
for (std::vector<std::string>::iterator it = functor.mHandles.begin(); it != functor.mHandles.end(); ++it) for (std::vector<std::string>::iterator it = functor.mHandles.begin(); it != functor.mHandles.end(); ++it)
if (Misc::StringUtils::ciEqual(searchPtrViaHandle(*it).getCellRef().mOwner, npc.getCellRef().mRefID)) if (Misc::StringUtils::ciEqual(searchPtrViaHandle(*it).getCellRef().getOwner(), npc.getCellRef().getRefId()))
out.push_back(searchPtrViaHandle(*it)); out.push_back(searchPtrViaHandle(*it));
} }
} }
@ -2032,34 +2032,34 @@ namespace MWWorld
} }
const DoorList &doors = cellStore->get<ESM::Door>().mList; const DoorList &doors = cellStore->get<ESM::Door>().mList;
for (DoorList::const_iterator it = doors.begin(); it != doors.end(); ++it) { for (DoorList::const_iterator it = doors.begin(); it != doors.end(); ++it) {
if (!it->mRef.mTeleport) { if (!it->mRef.getTeleport()) {
continue; continue;
} }
MWWorld::CellStore *source = 0; MWWorld::CellStore *source = 0;
// door to exterior // door to exterior
if (it->mRef.mDestCell.empty()) { if (it->mRef.getDestCell().empty()) {
int x, y; int x, y;
const float *pos = it->mRef.mDoorDest.pos; const float *pos = it->mRef.getDoorDest().pos;
positionToIndex(pos[0], pos[1], x, y); positionToIndex(pos[0], pos[1], x, y);
source = getExterior(x, y); source = getExterior(x, y);
} }
// door to interior // door to interior
else { else {
source = getInterior(it->mRef.mDestCell); source = getInterior(it->mRef.getDestCell());
} }
if (0 != source) { if (0 != source) {
// Find door leading to our current teleport door // Find door leading to our current teleport door
// and use it destination to position inside cell. // and use it destination to position inside cell.
const DoorList &doors = source->get<ESM::Door>().mList; const DoorList &doors = source->get<ESM::Door>().mList;
for (DoorList::const_iterator jt = doors.begin(); jt != doors.end(); ++jt) { for (DoorList::const_iterator jt = doors.begin(); jt != doors.end(); ++jt) {
if (it->mRef.mTeleport && if (it->mRef.getTeleport() &&
Misc::StringUtils::ciEqual(name, jt->mRef.mDestCell)) Misc::StringUtils::ciEqual(name, jt->mRef.getDestCell()))
{ {
/// \note Using _any_ door pointed to the interior, /// \note Using _any_ door pointed to the interior,
/// not the one pointed to current door. /// not the one pointed to current door.
pos = jt->mRef.mDoorDest; pos = jt->mRef.getDoorDest();
return true; return true;
} }
} }
@ -2322,9 +2322,9 @@ namespace MWWorld
for (CellRefList<ESM::Door>::List::iterator it = refList.begin(); it != refList.end(); ++it) for (CellRefList<ESM::Door>::List::iterator it = refList.begin(); it != refList.end(); ++it)
{ {
MWWorld::LiveCellRef<ESM::Door>& ref = *it; MWWorld::LiveCellRef<ESM::Door>& ref = *it;
if (ref.mRef.mTeleport && ref.mRef.mDestCell.empty()) if (ref.mRef.getTeleport() && ref.mRef.getDestCell().empty())
{ {
ESM::Position pos = ref.mRef.mDoorDest; ESM::Position pos = ref.mRef.getDoorDest();
result = Ogre::Vector3(pos.pos); result = Ogre::Vector3(pos.pos);
return true; return true;
} }
@ -2520,13 +2520,13 @@ namespace MWWorld
ContainerStore& store = ptr.getClass().getContainerStore(ptr); ContainerStore& store = ptr.getClass().getContainerStore(ptr);
for (ContainerStoreIterator it = store.begin(); it != store.end(); ++it) //Move all stolen stuff into chest for (ContainerStoreIterator it = store.begin(); it != store.end(); ++it) //Move all stolen stuff into chest
{ {
if (!it->getCellRef().mOwner.empty() && it->getCellRef().mOwner != "player") //Not owned by no one/player? if (!it->getCellRef().getOwner().empty() && it->getCellRef().getOwner() != "player") //Not owned by no one/player?
{ {
closestChest.getClass().getContainerStore(closestChest).add(*it, it->getRefData().getCount(), closestChest); closestChest.getClass().getContainerStore(closestChest).add(*it, it->getRefData().getCount(), closestChest);
store.remove(*it, it->getRefData().getCount(), ptr); store.remove(*it, it->getRefData().getCount(), ptr);
} }
} }
closestChest.getCellRef().mLockLevel = abs(closestChest.getCellRef().mLockLevel); closestChest.getClass().unlock(closestChest);
} }
} }
@ -2630,7 +2630,7 @@ namespace MWWorld
MWWorld::CellStore* cell = mPlayer->getPlayer().getCell(); MWWorld::CellStore* cell = mPlayer->getPlayer().getCell();
MWWorld::ManualRef ref(getStore(), selectedCreature, 1); MWWorld::ManualRef ref(getStore(), selectedCreature, 1);
ref.getPtr().getCellRef().mPos = ipos; ref.getPtr().getCellRef().setPosition(ipos);
safePlaceObject(ref.getPtr(), cell, ipos); safePlaceObject(ref.getPtr(), cell, ipos);
} }

View file

@ -168,7 +168,7 @@ void ESM::CellRef::blank()
} }
} }
bool ESM::operator== (const CellRef::RefNum& left, const CellRef::RefNum& right) bool ESM::operator== (const RefNum& left, const RefNum& right)
{ {
return left.mIndex==right.mIndex && left.mContentFile==right.mContentFile; return left.mIndex==right.mIndex && left.mContentFile==right.mContentFile;
} }

View file

@ -10,6 +10,13 @@ namespace ESM
class ESMWriter; class ESMWriter;
class ESMReader; class ESMReader;
struct RefNum
{
int mIndex;
int mContentFile; // -1 no content file
};
/* Cell reference. This represents ONE object (of many) inside the /* Cell reference. This represents ONE object (of many) inside the
cell. The cell references are not loaded as part of the normal cell. The cell references are not loaded as part of the normal
loading process, but are rather loaded later on demand when we are loading process, but are rather loaded later on demand when we are
@ -20,13 +27,10 @@ namespace ESM
{ {
public: public:
struct RefNum // Reference number
{ // Note: Currently unused for items in containers
int mIndex; RefNum mRefNum;
int mContentFile; // -1 no content file
};
RefNum mRefNum; // Reference number
std::string mRefID; // ID of object being referenced std::string mRefID; // ID of object being referenced
float mScale; // Scale applied to mesh float mScale; // Scale applied to mesh
@ -38,7 +42,7 @@ namespace ESM
// I have no idea, looks like a link to a global variable? // I have no idea, looks like a link to a global variable?
std::string mGlob; std::string mGlob;
// ID of creature trapped in this soul gem (?) // ID of creature trapped in this soul gem
std::string mSoul; std::string mSoul;
// The faction that owns this object (and will get angry if // The faction that owns this object (and will get angry if
@ -53,7 +57,7 @@ namespace ESM
// For tools (lockpicks, probes, repair hammer) it is the remaining uses. // For tools (lockpicks, probes, repair hammer) it is the remaining uses.
int mCharge; int mCharge;
// Remaining enchantment charge // Remaining enchantment charge. This could be -1 if the charge was not touched yet (i.e. full).
float mEnchantmentCharge; float mEnchantmentCharge;
// This is 5 for Gold_005 references, 100 for Gold_100 and so on. // This is 5 for Gold_005 references, 100 for Gold_100 and so on.
@ -94,7 +98,7 @@ namespace ESM
void blank(); void blank();
}; };
bool operator== (const CellRef::RefNum& left, const CellRef::RefNum& right); bool operator== (const RefNum& left, const RefNum& right);
} }
#endif #endif

View file

@ -16,7 +16,7 @@
namespace namespace
{ {
///< Translate 8bit/24bit code (stored in refNum.mIndex) into a proper refNum ///< Translate 8bit/24bit code (stored in refNum.mIndex) into a proper refNum
void adjustRefNum (ESM::CellRef::RefNum& refNum, ESM::ESMReader& reader) void adjustRefNum (ESM::RefNum& refNum, ESM::ESMReader& reader)
{ {
int local = (refNum.mIndex & 0xff000000) >> 24; int local = (refNum.mIndex & 0xff000000) >> 24;
@ -40,12 +40,12 @@ namespace ESM
unsigned int Cell::sRecordId = REC_CELL; unsigned int Cell::sRecordId = REC_CELL;
// Some overloaded compare operators. // Some overloaded compare operators.
bool operator== (const MovedCellRef& ref, const CellRef::RefNum& refNum) bool operator== (const MovedCellRef& ref, const RefNum& refNum)
{ {
return ref.mRefNum == refNum; return ref.mRefNum == refNum;
} }
bool operator== (const CellRef& ref, const CellRef::RefNum& refNum) bool operator== (const CellRef& ref, const RefNum& refNum)
{ {
return ref.mRefNum == refNum; return ref.mRefNum == refNum;
} }

View file

@ -28,7 +28,7 @@ class ESMWriter;
class MovedCellRef class MovedCellRef
{ {
public: public:
CellRef::RefNum mRefNum; RefNum mRefNum;
// Target cell (if exterior) // Target cell (if exterior)
int mTarget[2]; int mTarget[2];
@ -39,8 +39,8 @@ public:
}; };
/// Overloaded compare operator used to search inside a list of cell refs. /// Overloaded compare operator used to search inside a list of cell refs.
bool operator==(const MovedCellRef& ref, const CellRef::RefNum& refNum); bool operator==(const MovedCellRef& ref, const RefNum& refNum);
bool operator==(const CellRef& ref, const CellRef::RefNum& refNum); bool operator==(const CellRef& ref, const RefNum& refNum);
typedef std::list<MovedCellRef> MovedCellRefTracker; typedef std::list<MovedCellRef> MovedCellRefTracker;
typedef std::list<CellRef> CellRefTracker; typedef std::list<CellRef> CellRefTracker;