Equipped torches and lights run out of fuel

actorid
Alex "rainChu" Haddad 11 years ago
parent cfc3093320
commit 30ee3c5cf6

@ -16,12 +16,27 @@
#include "../mwworld/inventorystore.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwworld/physicssystem.hpp"
#include "../mwworld/customdata.hpp"
#include "../mwgui/tooltips.hpp"
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
namespace
{
struct CustomData : public MWWorld::CustomData
{
float mTime;
///< Time remaining
virtual MWWorld::CustomData *clone() const
{
return new CustomData (*this);
}
};
}
namespace MWClass
{
void Light::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -182,6 +197,24 @@ namespace MWClass
return action;
}
void Light::setRemainingUsageTime (const MWWorld::Ptr& ptr, float duration) const
{
ensureCustomData(ptr);
float &timeCharge = dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mTime;
// TODO time it in vanilla, see if 1 second is really one unit.
timeCharge = duration;
}
float Light::getRemainingUsageTime (const MWWorld::Ptr& ptr) const
{
ensureCustomData(ptr);
ESM::CellRef &ref = ptr.getCellRef();
return dynamic_cast<CustomData&> (*ptr.getRefData().getCustomData()).mTime;
}
MWWorld::Ptr
Light::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{
@ -191,6 +224,20 @@ namespace MWClass
return MWWorld::Ptr(&cell.mLights.insert(*ref), &cell);
}
void Light::ensureCustomData (const MWWorld::Ptr& ptr) const
{
if (!ptr.getRefData().getCustomData())
{
MWWorld::LiveCellRef<ESM::Light> *ref = ptr.get<ESM::Light>();
CustomData *data = new CustomData;
data->mTime = ref->mBase->mData.mTime;
ptr.getRefData().setCustomData(data);
}
}
bool Light::canSell (const MWWorld::Ptr& item, int npcServices) const
{
return npcServices & ESM::NPC::Lights;

@ -10,6 +10,8 @@ namespace MWClass
virtual MWWorld::Ptr
copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const;
void ensureCustomData (const MWWorld::Ptr& ptr) const;
public:
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
@ -56,6 +58,12 @@ namespace MWClass
const;
///< Generate action for using via inventory menu
virtual void setRemainingUsageTime (const MWWorld::Ptr& ptr, float duration) const;
///< Sets the remaining duration of the object.
virtual float getRemainingUsageTime (const MWWorld::Ptr& ptr) const;
///< Returns the remaining duration of the object.
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
virtual float getWeight (const MWWorld::Ptr& ptr) const;

@ -42,7 +42,13 @@ namespace MWMechanics
void Actors::updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused)
{
if(!paused)
{
updateDrowning(ptr, duration);
// Only update the light of the player.
if(ptr.getRefData().getHandle()=="player")
updateEquippedLight(ptr, duration);
}
}
void Actors::adjustMagicEffects (const MWWorld::Ptr& creature)
@ -196,6 +202,32 @@ namespace MWMechanics
stats.setTimeToStartDrowning(20);
}
void Actors::updateEquippedLight (const MWWorld::Ptr& ptr, float duration)
{
//If holding a light...
MWWorld::InventoryStore &inventoryStore = MWWorld::Class::get(ptr).getInventoryStore(ptr);
MWWorld::ContainerStoreIterator heldIter =
inventoryStore.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
if(heldIter.getType() == MWWorld::ContainerStore::Type_Light)
{
// ... then use some "fuel" from the timer
float timeRemaining = heldIter->getClass().getRemainingUsageTime(*heldIter);
// If it's already -1, then it should be an infinite light.
// TODO see what happens for other negative values.
if(timeRemaining >= 0.0f)
{
timeRemaining -= duration;
if(timeRemaining > 0.0f)
heldIter->getClass().setRemainingUsageTime(*heldIter, timeRemaining);
else
heldIter->getRefData().setCount(0); // remove it
}
}
}
Actors::Actors() : mDuration (0) {}
void Actors::addActor (const MWWorld::Ptr& ptr)

@ -44,6 +44,8 @@ namespace MWMechanics
void updateDrowning (const MWWorld::Ptr& ptr, float duration);
void updateEquippedLight (const MWWorld::Ptr& ptr, float duration);
public:
Actors();

@ -132,6 +132,16 @@ namespace MWWorld
throw std::runtime_error ("class does not support unlocking");
}
void Class::setRemainingUsageTime (const Ptr& ptr, float duration) const
{
throw std::runtime_error ("class does not support time-based uses.");
}
float Class::getRemainingUsageTime (const Ptr& ptr) const
{
throw std::runtime_error ("class does not support time-based uses.");
}
std::string Class::getScript (const Ptr& ptr) const
{
return "";

@ -156,6 +156,14 @@ namespace MWWorld
virtual void unlock (const Ptr& ptr) const;
///< Unlock object (default implementation: throw an exception)
virtual void setRemainingUsageTime (const Ptr& ptr, float duration) const;
///< Sets the remaining duration of the object, such as an equippable light
/// source. (default implementation: throw an exception)
virtual float getRemainingUsageTime (const Ptr& ptr) const;
///< Returns the remaining duration of the object, such as an equippable light
/// source. (default implementation: throw an exception)
virtual std::string getScript (const Ptr& ptr) const;
///< Return name of the script attached to ptr (default implementation: return an empty
/// string).

Loading…
Cancel
Save