Merge remote-tracking branch 'scrawl/master'

deque
Marc Zinnschlag 11 years ago
commit 33c36bf0df

@ -102,7 +102,6 @@ set(LIBDIR ${CMAKE_SOURCE_DIR}/libs)
set(OENGINE_OGRE
${LIBDIR}/openengine/ogre/renderer.cpp
${LIBDIR}/openengine/ogre/fader.cpp
${LIBDIR}/openengine/ogre/lights.cpp
${LIBDIR}/openengine/ogre/selectionbuffer.cpp
${LIBDIR}/openengine/ogre/imagerotate.cpp

@ -33,7 +33,7 @@ add_openmw_dir (mwgui
merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks
keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview
tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers savegamedialog
recharge mode videowidget backgroundimage itemwidget
recharge mode videowidget backgroundimage itemwidget screenfader
)
add_openmw_dir (mwdialogue

@ -128,6 +128,7 @@ namespace MWBase
OffenseType type, int arg=0) = 0;
virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim,
OffenseType type, int arg=0) = 0;
virtual void actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker) = 0;
/// Utility to check if taking this item is illegal and calling commitCrime if so
virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count) = 0;
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so

@ -331,6 +331,15 @@ namespace MWBase
virtual void removeCurrentModal(MWGui::WindowModal* input) = 0;
virtual void pinWindow (MWGui::GuiWindow window) = 0;
/// Fade the screen in, over \a time seconds
virtual void fadeScreenIn(const float time) = 0;
/// Fade the screen out to black, over \a time seconds
virtual void fadeScreenOut(const float time) = 0;
/// Fade the screen to a specified percentage of black, over \a time seconds
virtual void fadeScreenTo(const int percent, const float time) = 0;
/// Darken the screen by \a factor (1.0 = no darkening). Works independently from screen fading.
virtual void setScreenFactor (float factor) = 0;
};
}

@ -17,11 +17,6 @@ namespace Ogre
namespace OEngine
{
namespace Render
{
class Fader;
}
namespace Physic
{
class PhysicEngine;
@ -113,9 +108,6 @@ namespace MWBase
virtual void readRecord (ESM::ESMReader& reader, int32_t type,
const std::map<int, int>& contentFileMap) = 0;
virtual OEngine::Render::Fader* getFader() = 0;
///< \todo remove this function. Rendering details should not be exposed.
virtual MWWorld::CellStore *getExterior (int x, int y) = 0;
virtual MWWorld::CellStore *getInterior (const std::string& name) = 0;
@ -271,8 +263,9 @@ namespace MWBase
/// use the "Head" node, or alternatively the "Bip01 Head" node as a basis.
virtual std::pair<MWWorld::Ptr,Ogre::Vector3> getHitContact(const MWWorld::Ptr &ptr, float distance) = 0;
virtual void adjustPosition (const MWWorld::Ptr& ptr) = 0;
virtual void adjustPosition (const MWWorld::Ptr& ptr, bool force) = 0;
///< Adjust position after load to be on ground. Must be called after model load.
/// @param force do this even if the ptr is flying
virtual void fixPosition (const MWWorld::Ptr& actor) = 0;
///< Attempt to fix position so that the Ptr is no longer inside collision geometry.

@ -157,15 +157,19 @@ namespace MWClass
float iWeight = gmst.find (typeGmst)->getInt();
if (iWeight * gmst.find ("fLightMaxMod")->getFloat()>=
ref->mBase->mData.mWeight)
float epsilon = 5e-4;
if (ref->mBase->mData.mWeight == 0)
return ESM::Skill::Unarmored;
if (ref->mBase->mData.mWeight <= iWeight * gmst.find ("fLightMaxMod")->getFloat() + epsilon)
return ESM::Skill::LightArmor;
if (iWeight * gmst.find ("fMedMaxMod")->getFloat()>=
ref->mBase->mData.mWeight)
if (ref->mBase->mData.mWeight <= iWeight * gmst.find ("fMedMaxMod")->getFloat() + epsilon)
return ESM::Skill::MediumArmor;
return ESM::Skill::HeavyArmor;
else
return ESM::Skill::HeavyArmor;
}
int Armor::getValue (const MWWorld::Ptr& ptr) const

@ -148,9 +148,9 @@ namespace MWClass
return ref->mBase->mId;
}
void Creature::adjustPosition(const MWWorld::Ptr& ptr) const
void Creature::adjustPosition(const MWWorld::Ptr& ptr, bool force) const
{
MWBase::Environment::get().getWorld()->adjustPosition(ptr);
MWBase::Environment::get().getWorld()->adjustPosition(ptr, force);
}
void Creature::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -255,23 +255,7 @@ namespace MWClass
if((::rand()/(RAND_MAX+1.0)) > hitchance/100.0f)
{
victim.getClass().onHit(victim, 0.0f, false, MWWorld::Ptr(), ptr, false);
// Weapon health is reduced by 1 even if the attack misses
const bool weaphashealth = !weapon.isEmpty() && weapon.getClass().hasItemHealth(weapon);
if(weaphashealth)
{
int weaphealth = weapon.getClass().getItemHealth(weapon);
if (!MWBase::Environment::get().getWorld()->getGodModeState())
{
weaphealth -= std::min(1, weaphealth);
weapon.getCellRef().setCharge(weaphealth);
}
// Weapon broken? unequip it
if (weapon.getCellRef().getCharge() == 0)
weapon = *getInventoryStore(ptr).unequipItem(weapon, ptr);
}
MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr);
return;
}
@ -298,7 +282,6 @@ namespace MWClass
if (!weapon.isEmpty())
{
const bool weaphashealth = weapon.getClass().hasItemHealth(weapon);
const unsigned char *attack = NULL;
if(type == ESM::Weapon::AT_Chop)
attack = weapon.get<ESM::Weapon>()->mBase->mData.mChop;
@ -309,26 +292,10 @@ namespace MWClass
if(attack)
{
damage = attack[0] + ((attack[1]-attack[0])*stats.getAttackStrength());
damage *= 0.5f + (stats.getAttribute(ESM::Attribute::Luck).getModified() / 100.0f);
if(weaphashealth)
{
int weapmaxhealth = weapon.getClass().getItemMaxHealth(weapon);
int weaphealth = weapon.getClass().getItemHealth(weapon);
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 (weapon.getCellRef().getCharge() == 0)
weapon = *getInventoryStore(ptr).unequipItem(weapon, ptr);
}
damage *= gmst.find("fDamageStrengthBase")->getFloat() +
(stats.getAttribute(ESM::Attribute::Strength).getModified() * gmst.find("fDamageStrengthMult")->getFloat() * 0.1);
MWMechanics::adjustWeaponDamage(damage, weapon);
MWMechanics::reduceWeaponCondition(damage, true, weapon, ptr);
}
// Apply "On hit" enchanted weapons
@ -366,16 +333,11 @@ namespace MWClass
getCreatureStats(ptr).setAttacked(true);
// Self defense
if ( ((!attacker.isEmpty() && attacker.getClass().getCreatureStats(attacker).getAiSequence().isInCombat(ptr))
|| attacker == MWBase::Environment::get().getWorld()->getPlayerPtr())
&& !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker)
&& (canWalk(ptr) || canFly(ptr) || canSwim(ptr)) // No retaliation for totally static creatures
if ((canWalk(ptr) || canFly(ptr) || canSwim(ptr)) // No retaliation for totally static creatures
// (they have no movement or attacks anyway)
)
&& !attacker.isEmpty())
{
// Attacker is in combat with us, but we are not in combat with the attacker yet. Time to fight back.
// Note: accidental or collateral damage attacks are ignored.
MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, attacker);
MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
}
if(!successful)

@ -49,7 +49,9 @@ namespace MWClass
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual void adjustPosition(const MWWorld::Ptr& ptr) const;
virtual void adjustPosition(const MWWorld::Ptr& ptr, bool force) const;
///< Adjust position to stand on ground. Must be called post model load
/// @param force do this even if the ptr is flying
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);

@ -403,9 +403,9 @@ namespace MWClass
return ref->mBase->mId;
}
void Npc::adjustPosition(const MWWorld::Ptr& ptr) const
void Npc::adjustPosition(const MWWorld::Ptr& ptr, bool force) const
{
MWBase::Environment::get().getWorld()->adjustPosition(ptr);
MWBase::Environment::get().getWorld()->adjustPosition(ptr, force);
}
void Npc::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
@ -529,24 +529,7 @@ namespace MWClass
if((::rand()/(RAND_MAX+1.0)) > hitchance/100.0f)
{
othercls.onHit(victim, 0.0f, false, weapon, ptr, false);
// Weapon health is reduced by 1 even if the attack misses
const bool weaphashealth = !weapon.isEmpty() && weapon.getClass().hasItemHealth(weapon);
if(weaphashealth)
{
int weaphealth = weapon.getClass().getItemHealth(weapon);
if (!MWBase::Environment::get().getWorld()->getGodModeState())
{
weaphealth -= std::min(1, weaphealth);
weapon.getCellRef().setCharge(weaphealth);
}
// Weapon broken? unequip it
if (weaphealth == 0)
weapon = *inv.unequipItem(weapon, ptr);
}
MWMechanics::reduceWeaponCondition(0.f, false, weapon, ptr);
return;
}
@ -555,7 +538,6 @@ namespace MWClass
MWMechanics::NpcStats &stats = getNpcStats(ptr);
if(!weapon.isEmpty())
{
const bool weaphashealth = weapon.getClass().hasItemHealth(weapon);
const unsigned char *attack = NULL;
if(type == ESM::Weapon::AT_Chop)
attack = weapon.get<ESM::Weapon>()->mBase->mData.mChop;
@ -568,27 +550,9 @@ namespace MWClass
damage = attack[0] + ((attack[1]-attack[0])*stats.getAttackStrength());
damage *= gmst.fDamageStrengthBase->getFloat() +
(stats.getAttribute(ESM::Attribute::Strength).getModified() * gmst.fDamageStrengthMult->getFloat() * 0.1);
if(weaphashealth)
{
int weapmaxhealth = weapon.getClass().getItemMaxHealth(weapon);
int weaphealth = weapon.getClass().getItemHealth(weapon);
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 * store.find("fWeaponDamageMult")->getFloat())), weaphealth);
weapon.getCellRef().setCharge(weaphealth);
}
// Weapon broken? unequip it
if (weaphealth == 0)
weapon = *inv.unequipItem(weapon, ptr);
}
}
MWMechanics::adjustWeaponDamage(damage, weapon);
MWMechanics::reduceWeaponCondition(damage, true, weapon, ptr);
healthdmg = true;
}
else
@ -675,26 +639,13 @@ namespace MWClass
// NOTE: 'object' and/or 'attacker' may be empty.
if (ptr != MWBase::Environment::get().getWorld()->getPlayerPtr())
{
// Attacking peaceful NPCs is a crime
if (!attacker.isEmpty() && !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker)
&& !MWBase::Environment::get().getMechanicsManager()->isAggressive(ptr, attacker))
MWBase::Environment::get().getMechanicsManager()->commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault);
if (!attacker.isEmpty() && attacker.getClass().getCreatureStats(attacker).getAiSequence().isInCombat(ptr)
&& !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker))
{
// Attacker is in combat with us, but we are not in combat with the attacker yet. Time to fight back.
// Note: accidental or collateral damage attacks are ignored.
MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, attacker);
}
}
bool wasDead = getCreatureStats(ptr).isDead();
getCreatureStats(ptr).setAttacked(true);
if (!attacker.isEmpty())
MWBase::Environment::get().getMechanicsManager()->actorAttacked(ptr, attacker);
if(!successful)
{
// TODO: Handle HitAttemptOnMe script function

@ -55,7 +55,9 @@ namespace MWClass
virtual void insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics) const;
virtual void adjustPosition(const MWWorld::Ptr& ptr) const;
virtual void adjustPosition(const MWWorld::Ptr& ptr, bool force) const;
///< Adjust position to stand on ground. Must be called post model load
/// @param force do this even if the ptr is flying
virtual std::string getName (const MWWorld::Ptr& ptr) const;
///< \return name (the one that is to be presented to the user; not the internal one);

@ -28,6 +28,16 @@
namespace MWGui
{
DragAndDrop::DragAndDrop()
: mDraggedWidget(NULL)
, mDraggedCount(0)
, mSourceModel(NULL)
, mSourceView(NULL)
, mSourceSortModel(NULL)
, mIsOnDragAndDrop(NULL)
{
}
void DragAndDrop::startDrag (int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, int count)
{
mItem = sourceModel->getItem(index);
@ -36,7 +46,6 @@ namespace MWGui
mSourceView = sourceView;
mSourceSortModel = sortModel;
mIsOnDragAndDrop = true;
mDragAndDropWidget->setVisible(true);
// If picking up an item that isn't from the player's inventory, the item gets added to player inventory backend
// immediately, even though it's still floating beneath the mouse cursor. A bit counterintuitive,
@ -73,8 +82,13 @@ namespace MWGui
mSourceSortModel->addDragItem(mItem.mBase, count);
}
ItemWidget* baseWidget = mDragAndDropWidget->createWidget<ItemWidget>
("MW_ItemIcon", MyGUI::IntCoord(0, 0, 42, 42), MyGUI::Align::Default);
ItemWidget* baseWidget = MyGUI::Gui::getInstance().createWidget<ItemWidget>("MW_ItemIcon", 0, 0, 42, 42, MyGUI::Align::Default, "DragAndDrop");
Controllers::ControllerFollowMouse* controller =
MyGUI::ControllerManager::getInstance().createItem(Controllers::ControllerFollowMouse::getClassTypeName())
->castType<Controllers::ControllerFollowMouse>();
MyGUI::ControllerManager::getInstance().addItem(baseWidget, controller);
mDraggedWidget = baseWidget;
baseWidget->setItem(mItem.mBase);
baseWidget->setNeedMouseFocus(false);
@ -99,8 +113,6 @@ namespace MWGui
std::string sound = mItem.mBase.getClass().getDownSoundId(mItem.mBase);
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
mDragAndDropWidget->setVisible(false);
// If item is dropped where it was taken from, we don't need to do anything -
// otherwise, do the transfer
if (targetModel != mSourceModel)

@ -33,13 +33,14 @@ namespace MWGui
public:
bool mIsOnDragAndDrop;
MyGUI::Widget* mDraggedWidget;
MyGUI::Widget* mDragAndDropWidget;
ItemModel* mSourceModel;
ItemView* mSourceView;
SortFilterItemModel* mSourceSortModel;
ItemStack mItem;
int mDraggedCount;
DragAndDrop();
void startDrag (int index, SortFilterItemModel* sortModel, ItemModel* sourceModel, ItemView* sourceView, int count);
void drop (ItemModel* targetModel, ItemView* targetView);

@ -1,5 +1,7 @@
#include "controllers.hpp"
#include <MyGUI_InputManager.h>
namespace MWGui
{
namespace Controllers
@ -50,5 +52,17 @@ namespace MWGui
{
}
// -------------------------------------------------------------
void ControllerFollowMouse::prepareItem(MyGUI::Widget *_widget)
{
}
bool ControllerFollowMouse::addTime(MyGUI::Widget *_widget, float _time)
{
_widget->setPosition(MyGUI::InputManager::getInstance().getMousePosition());
return true;
}
}
}

@ -40,6 +40,17 @@ namespace MWGui
bool mEnabled;
float mTimeLeft;
};
/// Automatically positions a widget below the mouse cursor.
class ControllerFollowMouse :
public MyGUI::ControllerItem
{
MYGUI_RTTI_DERIVED( ControllerFollowMouse )
private:
bool addTime(MyGUI::Widget* _widget, float _time);
void prepareItem(MyGUI::Widget* _widget);
};
}
}

@ -262,11 +262,32 @@ namespace MWGui
// in the cp437 encoding of the font. Fall back to similar available characters.
if (mEncoding == ToUTF8::CP437)
{
std::multimap<int, int> additional;
std::multimap<int, int> additional; // <cp437, unicode>
additional.insert(std::make_pair(39, 0x2019)); // apostrophe
additional.insert(std::make_pair(45, 0x2013)); // dash
additional.insert(std::make_pair(45, 0x2014)); // dash
additional.insert(std::make_pair(34, 0x201D)); // right double quotation mark
additional.insert(std::make_pair(34, 0x201C)); // left double quotation mark
additional.insert(std::make_pair(44, 0x201A));
additional.insert(std::make_pair(44, 0x201E));
additional.insert(std::make_pair(43, 0x2020));
additional.insert(std::make_pair(94, 0x02C6));
additional.insert(std::make_pair(37, 0x2030));
additional.insert(std::make_pair(83, 0x0160));
additional.insert(std::make_pair(60, 0x2039));
additional.insert(std::make_pair(79, 0x0152));
additional.insert(std::make_pair(90, 0x017D));
additional.insert(std::make_pair(39, 0x2019));
additional.insert(std::make_pair(126, 0x02DC));
additional.insert(std::make_pair(84, 0x2122));
additional.insert(std::make_pair(83, 0x0161));
additional.insert(std::make_pair(62, 0x203A));
additional.insert(std::make_pair(111, 0x0153));
additional.insert(std::make_pair(122, 0x017E));
additional.insert(std::make_pair(89, 0x0178));
additional.insert(std::make_pair(156, 0x00A2));
additional.insert(std::make_pair(46, 0x2026));
for (std::multimap<int, int>::iterator it = additional.begin(); it != additional.end(); ++it)
{
if (it->first != i)

@ -406,7 +406,7 @@ namespace MWGui
box->setTextAlign(mTextStyle.mTextAlign);
box->setTextColour(mTextStyle.mColour);
box->setFontName(mTextStyle.mFont);
box->setCaption(realText);
box->setCaption(MyGUI::TextIterator::toTagsString(realText));
box->setSize(box->getSize().width, box->getTextSize().height);
mHeight += box->getTextSize().height;

@ -59,7 +59,7 @@ namespace MWGui
};
HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
HUD::HUD(int fpsLevel, DragAndDrop* dragAndDrop)
: Layout("openmw_hud.layout")
, mHealth(NULL)
, mMagicka(NULL)
@ -97,7 +97,7 @@ namespace MWGui
, mWeaponSpellTimer(0.f)
, mDrowningFlashTheta(0.f)
{
setCoord(0,0, width, height);
mMainWidget->setSize(MyGUI::RenderManager::getInstance().getViewSize());
// Energy bars
getWidget(mHealthFrame, "HealthFrame");
@ -405,11 +405,6 @@ namespace MWGui
mDrowningFlashTheta += dt * Ogre::Math::TWO_PI;
}
void HUD::onResChange(int width, int height)
{
setCoord(0, 0, width, height);
}
void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent)
{
const ESM::Spell* spell =

@ -15,7 +15,7 @@ namespace MWGui
class HUD : public OEngine::GUI::Layout, public LocalMapBase
{
public:
HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop);
HUD(int fpsLevel, DragAndDrop* dragAndDrop);
virtual ~HUD();
void setValue (const std::string& id, const MWMechanics::DynamicStat<float>& value);
void setFPS(float fps);
@ -47,7 +47,6 @@ namespace MWGui
void setCrosshairVisible(bool visible);
void onFrame(float dt);
void onResChange(int width, int height);
void setCellName(const std::string& cellName);

@ -30,6 +30,8 @@ namespace MWGui
, mProgress(0)
, mVSyncWasEnabled(false)
{
mMainWidget->setSize(MyGUI::RenderManager::getInstance().getViewSize());
getWidget(mLoadingText, "LoadingText");
getWidget(mProgressBar, "ProgressBar");
@ -56,13 +58,6 @@ namespace MWGui
mBackgroundImage->setVisible(visible);
}
void LoadingScreen::onResChange(int w, int h)
{
setCoord(0,0,w,h);
mBackgroundImage->setCoord(MyGUI::IntCoord(0,0,w,h));
}
void LoadingScreen::loadingOn()
{
// Early-out if already on

@ -35,8 +35,6 @@ namespace MWGui
void setLoadingProgress (const std::string& stage, int depth, int current, int total);
void loadingDone();
void onResChange(int w, int h);
void updateWindow(Ogre::RenderWindow* rw) { mWindow = rw; }
private:

@ -0,0 +1,111 @@
#include "screenfader.hpp"
namespace MWGui
{
ScreenFader::ScreenFader()
: WindowBase("openmw_screen_fader.layout")
, mMode(FadingMode_In)
, mRemainingTime(0.f)
, mTargetTime(0.f)
, mTargetAlpha(0.f)
, mCurrentAlpha(0.f)
, mStartAlpha(0.f)
, mFactor(1.f)
{
mMainWidget->setSize(MyGUI::RenderManager::getInstance().getViewSize());
setVisible(false);
}
void ScreenFader::update(float dt)
{
if (mRemainingTime > 0)
{
if (mMode == FadingMode_In)
{
mCurrentAlpha -= dt/mTargetTime * (mStartAlpha-mTargetAlpha);
if (mCurrentAlpha < mTargetAlpha) mCurrentAlpha = mTargetAlpha;
}
else if (mMode == FadingMode_Out)
{
mCurrentAlpha += dt/mTargetTime * (mTargetAlpha-mStartAlpha);
if (mCurrentAlpha > mTargetAlpha) mCurrentAlpha = mTargetAlpha;
}
mRemainingTime -= dt;
}
if (1.f-((1.f-mCurrentAlpha) * mFactor) == 0.f)
mMainWidget->setVisible(false);
else
applyAlpha();
}
void ScreenFader::applyAlpha()
{
setVisible(true);
mMainWidget->setAlpha(1.f-((1.f-mCurrentAlpha) * mFactor));
}
void ScreenFader::fadeIn(float time)
{
if (time<0.f) return;
if (time==0.f)
{
mCurrentAlpha = 0.f;
applyAlpha();
return;
}
mStartAlpha = mCurrentAlpha;
mTargetAlpha = 0.f;
mMode = FadingMode_In;
mTargetTime = time;
mRemainingTime = time;
}
void ScreenFader::fadeOut(const float time)
{
if (time<0.f) return;
if (time==0.f)
{
mCurrentAlpha = 1.f;
applyAlpha();
return;
}
mStartAlpha = mCurrentAlpha;
mTargetAlpha = 1.f;
mMode = FadingMode_Out;
mTargetTime = time;
mRemainingTime = time;
}
void ScreenFader::fadeTo(const int percent, const float time)
{
if (time<0.f) return;
if (time==0.f)
{
mCurrentAlpha = percent/100.f;
applyAlpha();
return;
}
mStartAlpha = mCurrentAlpha;
mTargetAlpha = percent/100.f;
if (mTargetAlpha == mStartAlpha) return;
else if (mTargetAlpha > mStartAlpha) mMode = FadingMode_Out;
else mMode = FadingMode_In;
mTargetTime = time;
mRemainingTime = time;
}
void ScreenFader::setFactor(float factor)
{
mFactor = factor;
}
}

@ -0,0 +1,39 @@
#include "windowbase.hpp"
namespace MWGui
{
class ScreenFader : public WindowBase
{
public:
ScreenFader();
void update(float dt);
void fadeIn(const float time);
void fadeOut(const float time);
void fadeTo(const int percent, const float time);
void setFactor (float factor);
private:
enum FadingMode
{
FadingMode_In,
FadingMode_Out
};
void applyAlpha();
FadingMode mMode;
float mRemainingTime;
float mTargetTime;
float mTargetAlpha;
float mCurrentAlpha;
float mStartAlpha;
float mFactor;
};
}

@ -2,8 +2,6 @@
#include <boost/lexical_cast.hpp>
#include <openengine/ogre/fader.hpp>
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -171,7 +169,7 @@ namespace MWGui
MWBase::Environment::get().getMechanicsManager()->rest(false);
MWBase::Environment::get().getMechanicsManager()->rest(false);
MWBase::Environment::get().getWorld ()->getFader()->fadeOut(0.25);
MWBase::Environment::get().getWindowManager()->fadeScreenOut(0.25);
mFadeTimeRemaining = 0.5;
}
@ -183,6 +181,6 @@ namespace MWGui
mFadeTimeRemaining -= dt;
if (mFadeTimeRemaining <= 0)
MWBase::Environment::get().getWorld ()->getFader()->fadeIn(0.25);
MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.25);
}
}

@ -4,8 +4,6 @@
#include <OgreVector3.h>
#include <libs/openengine/ogre/fader.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
@ -156,7 +154,7 @@ namespace MWGui
MWMechanics::CreatureStats& npcStats = mPtr.getClass().getCreatureStats(mPtr);
npcStats.setGoldPool(npcStats.getGoldPool() + price);
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(1);
MWBase::Environment::get().getWindowManager()->fadeScreenOut(1);
ESM::Position pos = *_sender->getUserData<ESM::Position>();
std::string cellname = _sender->getUserString("Destination");
bool interior = _sender->getUserString("interior") == "y";
@ -179,8 +177,8 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Travel);
MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Dialogue);
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0);
MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(1);
MWBase::Environment::get().getWindowManager()->fadeScreenOut(0);
MWBase::Environment::get().getWindowManager()->fadeScreenIn(1);
}
void TravelWindow::onCancelButtonClicked(MyGUI::Widget* _sender)

@ -2,8 +2,6 @@
#include <boost/lexical_cast.hpp>
#include <libs/openengine/ogre/fader.hpp>
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
@ -128,7 +126,7 @@ namespace MWGui
MWBase::Environment::get().getStateManager()->quickSave("Autosave");
MWBase::World* world = MWBase::Environment::get().getWorld();
world->getFader ()->fadeOut(0.2);
MWBase::Environment::get().getWindowManager()->fadeScreenOut(0.2);
setVisible(false);
mProgressBar.setVisible (true);
@ -243,7 +241,7 @@ namespace MWGui
void WaitDialog::stopWaiting ()
{
MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(0.2);
MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.2);
mProgressBar.setVisible (false);
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_Rest);
MWBase::Environment::get().getWindowManager()->removeGuiMode (GM_RestBed);

@ -65,6 +65,7 @@
#include "videowidget.hpp"
#include "backgroundimage.hpp"
#include "itemwidget.hpp"
#include "screenfader.hpp"
namespace MWGui
{
@ -112,6 +113,7 @@ namespace MWGui
, mCompanionWindow(NULL)
, mVideoBackground(NULL)
, mVideoWidget(NULL)
, mScreenFader(NULL)
, mTranslationDataStorage (translationDataStorage)
, mCharGen(NULL)
, mInputBlocker(NULL)
@ -171,18 +173,14 @@ namespace MWGui
ItemWidget::registerComponents();
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Controllers::ControllerRepeatClick>("Controller");
MyGUI::FactoryManager::getInstance().registerFactory<MWGui::Controllers::ControllerFollowMouse>("Controller");
MyGUI::FactoryManager::getInstance().registerFactory<ResourceImageSetPointerFix>("Resource", "ResourceImageSetPointer");
MyGUI::ResourceManager::getInstance().load("core.xml");
MyGUI::LanguageManager::getInstance().eventRequestTag = MyGUI::newDelegate(this, &WindowManager::onRetrieveTag);
// Get size info from the Gui object
int w = MyGUI::RenderManager::getInstance().getViewSize().width;
int h = MyGUI::RenderManager::getInstance().getViewSize().height;
mLoadingScreen = new LoadingScreen(mRendering->getScene (), mRendering->getWindow ());
mLoadingScreen->onResChange (w,h);
//set up the hardware cursor manager
mCursorManager = new SFO::SDLCursorManager();
@ -192,7 +190,6 @@ namespace MWGui
MyGUI::InputManager::getInstance().eventChangeKeyFocus += MyGUI::newDelegate(this, &WindowManager::onKeyFocusChanged);
onCursorChange(MyGUI::PointerManager::getInstance().getDefaultPointer());
//SDL_ShowCursor(false);
mCursorManager->setEnabled(true);
@ -217,13 +214,7 @@ namespace MWGui
int w = MyGUI::RenderManager::getInstance().getViewSize().width;
int h = MyGUI::RenderManager::getInstance().getViewSize().height;
MyGUI::Widget* dragAndDropWidget = mGui->createWidgetT("Widget","",0,0,w,h,MyGUI::Align::Default,"DragAndDrop","DragAndDropWidget");
dragAndDropWidget->setVisible(false);
mDragAndDrop = new DragAndDrop();
mDragAndDrop->mIsOnDragAndDrop = false;
mDragAndDrop->mDraggedWidget = 0;
mDragAndDrop->mDragAndDropWidget = dragAndDropWidget;
mRecharge = new Recharge();
mMenu = new MainMenu(w,h);
@ -245,7 +236,7 @@ namespace MWGui
trackWindow(mDialogueWindow, "dialogue");
mContainerWindow = new ContainerWindow(mDragAndDrop);
trackWindow(mContainerWindow, "container");
mHud = new HUD(w,h, mShowFPSLevel, mDragAndDrop);
mHud = new HUD(mShowFPSLevel, mDragAndDrop);
mToolTips = new ToolTips();
mScrollWindow = new ScrollWindow();
mBookWindow = new BookWindow();
@ -267,8 +258,9 @@ namespace MWGui
mSoulgemDialog = new SoulgemDialog(mMessageBoxManager);
mCompanionWindow = new CompanionWindow(mDragAndDrop, mMessageBoxManager);
trackWindow(mCompanionWindow, "companion");
mScreenFader = new ScreenFader();
mInputBlocker = mGui->createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Default,"Overlay");
mInputBlocker = mGui->createWidget<MyGUI::Widget>("",0,0,w,h,MyGUI::Align::Stretch,"Overlay");
mHud->setVisible(mHudEnabled);
@ -357,6 +349,7 @@ namespace MWGui
delete mCursorManager;
delete mRecharge;
delete mCompanionWindow;
delete mScreenFader;
cleanupGarbage();
@ -858,6 +851,8 @@ namespace MWGui
mCompanionWindow->checkReferenceAvailable();
mConsole->checkReferenceAvailable();
mCompanionWindow->onFrame();
mScreenFader->update(frameDuration);
}
void WindowManager::changeCell(MWWorld::CellStore* cell)
@ -1019,7 +1014,6 @@ namespace MWGui
{
sizeVideo(x, y);
mGuiManager->windowResized();
mLoadingScreen->onResChange (x,y);
if (!mHud)
return; // UI not initialized yet
@ -1033,7 +1027,6 @@ namespace MWGui
it->first->setSize(size);
}
mHud->onResChange(x, y);
mConsole->onResChange(x, y);
mMenu->onResChange(x, y);
mSettingsWindow->center();
@ -1042,8 +1035,6 @@ namespace MWGui
mBookWindow->center();
mQuickKeysMenu->center();
mSpellBuyingWindow->center();
mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y));
mInputBlocker->setSize(MyGUI::IntSize(x,y));
}
void WindowManager::pushGuiMode(GuiMode mode)
@ -1688,4 +1679,24 @@ namespace MWGui
updateVisible();
}
void WindowManager::fadeScreenIn(const float time)
{
mScreenFader->fadeIn(time);
}
void WindowManager::fadeScreenOut(const float time)
{
mScreenFader->fadeOut(time);
}
void WindowManager::fadeScreenTo(const int percent, const float time)
{
mScreenFader->fadeTo(percent, time);
}
void WindowManager::setScreenFactor(float factor)
{
mScreenFader->setFactor(factor);
}
}

@ -86,6 +86,7 @@ namespace MWGui
class CompanionWindow;
class VideoWidget;
class WindowModal;
class ScreenFader;
class WindowManager : public MWBase::WindowManager
{
@ -324,6 +325,15 @@ namespace MWGui
virtual void pinWindow (MWGui::GuiWindow window);
/// Fade the screen in, over \a time seconds
virtual void fadeScreenIn(const float time);
/// Fade the screen out to black, over \a time seconds
virtual void fadeScreenOut(const float time);
/// Fade the screen to a specified percentage of black, over \a time seconds
virtual void fadeScreenTo(const int percent, const float time);
/// Darken the screen by \a factor (1.0 = no darkening). Works independently from screen fading.
virtual void setScreenFactor (float factor);
private:
bool mConsoleOnlyScripts;
@ -373,6 +383,7 @@ namespace MWGui
CompanionWindow* mCompanionWindow;
MyGUI::ImageBox* mVideoBackground;
VideoWidget* mVideoWidget;
ScreenFader* mScreenFader;
Translation::Storage& mTranslationDataStorage;
Cursor* mSoftwareCursor;

@ -805,16 +805,16 @@ namespace MWInput
if (MyGUI::InputManager::getInstance ().isModalAny())
return;
if((!MWBase::Environment::get().getWindowManager()->isGuiMode()
|| MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_Dialogue)
&& MWBase::Environment::get().getWindowManager ()->getJournalAllowed())
if(MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Journal
&& MWBase::Environment::get().getWindowManager ()->getJournalAllowed()
&& MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Console)
{
MWBase::Environment::get().getSoundManager()->playSound ("book open", 1.0, 1.0);
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Journal);
}
else if(MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_Journal)
else if(MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_Journal))
{
MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode();
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Journal);
}
}

@ -169,12 +169,12 @@ namespace MWMechanics
MWMechanics::CreatureStats& attackerStats = attacker.getClass().getCreatureStats(attacker);
const MWWorld::Class &othercls = victim.getClass();
if(!othercls.isActor()) // Can't hit non-actors
return;
MWMechanics::CreatureStats &otherstats = victim.getClass().getCreatureStats(victim);
if(otherstats.isDead()) // Can't hit dead actors
if(victim.isEmpty() || !victim.getClass().isActor() || victim.getClass().getCreatureStats(victim).isDead())
// Can't hit non-actors or dead actors
{
reduceWeaponCondition(0.f, false, weapon, attacker);
return;
}
if(attacker.getRefData().getHandle() == "player")
MWBase::Environment::get().getWindowManager()->setEnemy(victim);
@ -189,6 +189,7 @@ namespace MWMechanics
if((::rand()/(RAND_MAX+1.0)) > getHitChance(attacker, victim, skillValue)/100.0f)
{
victim.getClass().onHit(victim, 0.0f, false, projectile, attacker, false);
MWMechanics::reduceWeaponCondition(0.f, false, weapon, attacker);
return;
}
@ -209,6 +210,8 @@ namespace MWMechanics
damage *= fDamageStrengthBase +
(attackerStats.getAttribute(ESM::Attribute::Strength).getModified() * fDamageStrengthMult * 0.1);
adjustWeaponDamage(damage, weapon);
reduceWeaponCondition(damage, true, weapon, attacker);
if(attacker.getRefData().getHandle() == "player")
attacker.getClass().skillUsageSucceeded(attacker, weapskill, 0);
@ -295,4 +298,42 @@ namespace MWMechanics
}
}
void reduceWeaponCondition(float damage, bool hit, MWWorld::Ptr &weapon, const MWWorld::Ptr &attacker)
{
if (weapon.isEmpty())
return;
if (!hit)
damage = 0.f;
const bool weaphashealth = weapon.getClass().hasItemHealth(weapon);
if(weaphashealth)
{
int weaphealth = weapon.getClass().getItemHealth(weapon);
const float fWeaponDamageMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWeaponDamageMult")->getFloat();
float x = std::max(1.f, fWeaponDamageMult * damage);
weaphealth -= std::min(int(x), weaphealth);
weapon.getCellRef().setCharge(weaphealth);
// Weapon broken? unequip it
if (weaphealth == 0)
weapon = *attacker.getClass().getInventoryStore(attacker).unequipItem(weapon, attacker);
}
}
void adjustWeaponDamage(float &damage, const MWWorld::Ptr &weapon)
{
if (weapon.isEmpty())
return;
const bool weaphashealth = weapon.getClass().hasItemHealth(weapon);
if(weaphashealth)
{
int weaphealth = weapon.getClass().getItemHealth(weapon);
int weapmaxhealth = weapon.getClass().getItemMaxHealth(weapon);
damage *= (float(weaphealth) / weapmaxhealth);
}
}
}

@ -13,6 +13,7 @@ bool blockMeleeAttack (const MWWorld::Ptr& attacker, const MWWorld::Ptr& blocker
void resistNormalWeapon (const MWWorld::Ptr& actor, const MWWorld::Ptr& attacker, const MWWorld::Ptr& weapon, float& damage);
/// @note for a thrown weapon, \a weapon == \a projectile, for bows/crossbows, \a projectile is the arrow/bolt
/// @note \a victim may be empty (e.g. for a hit on terrain), a non-actor (environment objects) or an actor
void projectileHit (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, MWWorld::Ptr weapon, const MWWorld::Ptr& projectile,
const Ogre::Vector3& hitPosition);
@ -22,6 +23,15 @@ float getHitChance (const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim, in
/// Applies damage to attacker based on the victim's elemental shields.
void applyElementalShields(const MWWorld::Ptr& attacker, const MWWorld::Ptr& victim);
/// @param damage Unmitigated weapon damage of the attack
/// @param hit Was the attack successful?
/// @param weapon The weapon used.
/// @note if the weapon is unequipped as result of condition damage, a new Ptr will be assigned to \a weapon.
void reduceWeaponCondition (float damage, bool hit, MWWorld::Ptr& weapon, const MWWorld::Ptr& attacker);
/// Adjust weapon damage based on its condition. A used weapon will be less effective.
void adjustWeaponDamage (float& damage, const MWWorld::Ptr& weapon);
}
#endif

@ -973,6 +973,9 @@ namespace MWMechanics
if (!it->getClass().isNpc())
continue;
if (it->getClass().getCreatureStats(*it).getAiSequence().isInCombat(victim))
continue;
// Will the witness report the crime?
if (it->getClass().getCreatureStats(*it).getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm)
{
@ -1071,6 +1074,9 @@ namespace MWMechanics
if (*it != victim && type == OT_Assault)
aggression = iFightAttacking;
if (it->getClass().getCreatureStats(*it).getAiSequence().isInCombat(victim))
continue;
if (it->getClass().isClass(*it, "guard"))
{
// Mark as Alarmed for dialogue
@ -1100,6 +1106,35 @@ namespace MWMechanics
}
}
void MechanicsManager::actorAttacked(const MWWorld::Ptr &ptr, const MWWorld::Ptr &attacker)
{
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
return;
std::list<MWWorld::Ptr> followers = getActorsFollowing(attacker);
if (std::find(followers.begin(), followers.end(), ptr) != followers.end())
{
ptr.getClass().getCreatureStats(ptr).friendlyHit();
if (ptr.getClass().getCreatureStats(ptr).getFriendlyHits() < 4)
return;
}
// Attacking peaceful NPCs is a crime
if (ptr.getClass().isNpc() && !attacker.isEmpty() && !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker)
&& !isAggressive(ptr, attacker))
commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault);
if (!attacker.isEmpty() && (attacker.getClass().getCreatureStats(attacker).getAiSequence().isInCombat(ptr)
|| attacker == MWBase::Environment::get().getWorld()->getPlayerPtr())
&& !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat(attacker))
{
// Attacker is in combat with us, but we are not in combat with the attacker yet. Time to fight back.
// Note: accidental or collateral damage attacks are ignored.
startCombat(ptr, attacker);
}
}
bool MechanicsManager::awarenessCheck(const MWWorld::Ptr &ptr, const MWWorld::Ptr &observer)
{
if (observer.getClass().getCreatureStats(observer).isDead())

@ -119,6 +119,7 @@ namespace MWMechanics
OffenseType type, int arg=0);
virtual void reportCrime (const MWWorld::Ptr& ptr, const MWWorld::Ptr& victim,
OffenseType type, int arg=0);
virtual void actorAttacked (const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker);
/// Utility to check if taking this item is illegal and calling commitCrime if so
virtual void itemTaken (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item, int count);
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so

@ -72,7 +72,7 @@ namespace MWMechanics
return schoolSkillMap[school];
}
float getSpellSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool)
float getSpellSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool, bool cap)
{
CreatureStats& stats = actor.getClass().getCreatureStats(actor);
@ -123,14 +123,17 @@ namespace MWMechanics
if (MWBase::Environment::get().getWorld()->getGodModeState() && actor.getRefData().getHandle() == "player")
castChance = 100;
return std::max(0.f, std::min(100.f, castChance));
if (!cap)
return std::max(0.f, castChance);
else
return std::max(0.f, std::min(100.f, castChance));
}
float getSpellSuccessChance (const std::string& spellId, const MWWorld::Ptr& actor, int* effectiveSchool)
float getSpellSuccessChance (const std::string& spellId, const MWWorld::Ptr& actor, int* effectiveSchool, bool cap)
{
const ESM::Spell* spell =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(spellId);
return getSpellSuccessChance(spell, actor, effectiveSchool);
return getSpellSuccessChance(spell, actor, effectiveSchool, cap);
}
@ -184,6 +187,10 @@ namespace MWMechanics
float resisted = 0;
if (magicEffect->mData.mFlags & ESM::MagicEffect::Harmful)
{
// Effects with no resistance attribute belonging to them can not be resisted
if (ESM::MagicEffect::getResistanceEffect(effectId) == -1)
return 0.f;
float resistance = getEffectResistanceAttribute(effectId, magicEffects);
float willpower = stats.getAttribute(ESM::Attribute::Willpower).getModified();
@ -191,12 +198,13 @@ namespace MWMechanics
float x = (willpower + 0.1 * luck) * stats.getFatigueTerm();
// This makes spells that are easy to cast harder to resist and vice versa
float castChance = 100.f;
if (spell != NULL && !caster.isEmpty() && caster.getClass().isActor())
{
float castChance = getSpellSuccessChance(spell, caster);
if (castChance > 0)
x *= 50 / castChance;
castChance = getSpellSuccessChance(spell, caster, NULL, false); // Uncapped casting chance
}
if (castChance > 0)
x *= 50 / castChance;
float roll = static_cast<float>(std::rand()) / RAND_MAX * 100;
if (magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)
@ -230,6 +238,44 @@ namespace MWMechanics
return -(resistance-100) / 100.f;
}
/// Check if the given affect can be applied to the target. If \a castByPlayer, emits a message box on failure.
bool checkEffectTarget (int effectId, const MWWorld::Ptr& target, bool castByPlayer)
{
switch (effectId)
{
case ESM::MagicEffect::Levitate:
if (!MWBase::Environment::get().getWorld()->isLevitationEnabled())
{
if (castByPlayer)
MWBase::Environment::get().getWindowManager()->messageBox("#{sLevitateDisabled}");
return false;
}
break;
case ESM::MagicEffect::Soultrap:
if ((target.getClass().isActor() && target.getClass().isNpc())
|| (target.getTypeName() == typeid(ESM::Creature).name() && target.get<ESM::Creature>()->mBase->mData.mSoul == 0))
{
if (castByPlayer)
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicInvalidTarget}");
return false;
}
break;
case ESM::MagicEffect::AlmsiviIntervention:
case ESM::MagicEffect::DivineIntervention:
case ESM::MagicEffect::Mark:
case ESM::MagicEffect::Recall:
if (!MWBase::Environment::get().getWorld()->isTeleportingEnabled())
{
if (castByPlayer)
MWBase::Environment::get().getWindowManager()->messageBox("#{sTeleportDisabled}");
return false;
}
break;
}
return true;
}
CastSpell::CastSpell(const MWWorld::Ptr &caster, const MWWorld::Ptr &target)
: mCaster(caster)
, mTarget(target)
@ -318,23 +364,8 @@ namespace MWMechanics
MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find (
effectIt->mEffectID);
if (!MWBase::Environment::get().getWorld()->isLevitationEnabled() && effectIt->mEffectID == ESM::MagicEffect::Levitate)
{
if (castByPlayer)
MWBase::Environment::get().getWindowManager()->messageBox("#{sLevitateDisabled}");
continue;
}
if (!MWBase::Environment::get().getWorld()->isTeleportingEnabled() &&
(effectIt->mEffectID == ESM::MagicEffect::AlmsiviIntervention ||
effectIt->mEffectID == ESM::MagicEffect::DivineIntervention ||
effectIt->mEffectID == ESM::MagicEffect::Mark ||
effectIt->mEffectID == ESM::MagicEffect::Recall))
{
if (castByPlayer)
MWBase::Environment::get().getWindowManager()->messageBox("#{sTeleportDisabled}");
if (!checkEffectTarget(effectIt->mEffectID, target, castByPlayer))
continue;
}
// If player is healing someone, show the target's HP bar
if (castByPlayer && target != caster

@ -26,11 +26,12 @@ namespace MWMechanics
* @param spell spell to cast
* @param actor calculate spell success chance for this actor (depends on actor's skills)
* @param effectiveSchool the spell's effective school (relevant for skill progress) will be written here
* @attention actor has to be an NPC and not a creature!
* @return success chance from 0 to 100 (in percent)
* @param cap cap the result to 100%?
* @note actor can be an NPC or a creature
* @return success chance from 0 to 100 (in percent), if cap=false then chance above 100 may be returned.
*/
float getSpellSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool = NULL);
float getSpellSuccessChance (const std::string& spellId, const MWWorld::Ptr& actor, int* effectiveSchool = NULL);
float getSpellSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool = NULL, bool cap=true);
float getSpellSuccessChance (const std::string& spellId, const MWWorld::Ptr& actor, int* effectiveSchool = NULL, bool cap=true);
int getSpellSchool(const std::string& spellId, const MWWorld::Ptr& actor);
int getSpellSchool(const ESM::Spell* spell, const MWWorld::Ptr& actor);

@ -98,6 +98,7 @@ void LocalMap::saveFogOfWar(MWWorld::CellStore* cell)
return;
Ogre::Image image;
tex->load();
tex->convertToImage(image);
Ogre::DataStreamPtr encoded = image.encode("tga");
@ -137,6 +138,7 @@ void LocalMap::saveFogOfWar(MWWorld::CellStore* cell)
return;
Ogre::Image image;
tex->load();
tex->convertToImage(image);
fog->mFogTextures.push_back(ESM::FogTexture());
@ -581,6 +583,8 @@ void LocalMap::updatePlayer (const Ogre::Vector3& position, const Ogre::Quaterni
}
}
tex->load();
// copy to the texture
// NOTE: Could be optimized later. We actually only need to update the region that changed.
// Not a big deal at the moment, the FoW is only 32x32 anyway.

@ -212,11 +212,6 @@ MWRender::Actors& RenderingManager::getActors(){
return *mActors;
}
OEngine::Render::Fader* RenderingManager::getFader()
{
return mRendering.getFader();
}
MWRender::Camera* RenderingManager::getCamera() const
{
return mCamera;
@ -345,7 +340,7 @@ void RenderingManager::update (float duration, bool paused)
MWWorld::Ptr player = world->getPlayerPtr();
int blind = player.getClass().getCreatureStats(player).getMagicEffects().get(ESM::MagicEffect::Blind).mMagnitude;
mRendering.getFader()->setFactor(std::max(0.f, 1.f-(blind / 100.f)));
MWBase::Environment::get().getWindowManager()->setScreenFactor(std::max(0.f, 1.f-(blind / 100.f)));
setAmbientMode();
// player position

@ -4,8 +4,6 @@
#include "sky.hpp"
#include "debugging.hpp"
#include <openengine/ogre/fader.hpp>
#include <components/settings/settings.hpp>
#include <boost/filesystem.hpp>
@ -98,8 +96,6 @@ public:
void toggleLight();
bool toggleRenderMode(int mode);
OEngine::Render::Fader* getFader();
void removeCell (MWWorld::CellStore *store);
/// \todo this function should be removed later. Instead the rendering subsystems should track

@ -294,7 +294,12 @@ void SkyManager::create()
// Stars
mAtmosphereNight = mRootNode->createChildSceneNode();
NifOgre::ObjectScenePtr objects = NifOgre::Loader::createObjects(mAtmosphereNight, "meshes\\sky_night_01.nif");
NifOgre::ObjectScenePtr objects;
if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup("meshes\\sky_night_02.nif"))
objects = NifOgre::Loader::createObjects(mAtmosphereNight, "meshes\\sky_night_02.nif");
else
objects = NifOgre::Loader::createObjects(mAtmosphereNight, "meshes\\sky_night_01.nif");
for(size_t i = 0, matidx = 0;i < objects->mEntities.size();i++)
{
Entity* night1_ent = objects->mEntities[i];

@ -3,8 +3,6 @@
#include <cstdlib>
#include <libs/openengine/ogre/fader.hpp>
#include <components/compiler/extensions.hpp>
#include <components/compiler/opcodes.hpp>
#include <components/compiler/locals.hpp>
@ -248,7 +246,7 @@ namespace MWScript
Interpreter::Type_Float time = runtime[0].mFloat;
runtime.pop();
MWBase::Environment::get().getWorld()->getFader()->fadeIn(time);
MWBase::Environment::get().getWindowManager()->fadeScreenIn(time);
}
};
@ -261,7 +259,7 @@ namespace MWScript
Interpreter::Type_Float time = runtime[0].mFloat;
runtime.pop();
MWBase::Environment::get().getWorld()->getFader()->fadeOut(time);
MWBase::Environment::get().getWindowManager()->fadeScreenOut(time);
}
};
@ -277,7 +275,7 @@ namespace MWScript
Interpreter::Type_Float time = runtime[0].mFloat;
runtime.pop();
MWBase::Environment::get().getWorld()->getFader()->fadeTo(alpha, time);
MWBase::Environment::get().getWindowManager()->fadeScreenTo(alpha, time);
}
};

@ -637,8 +637,6 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0)
{
MWWorld::Ptr ptr = R()(runtime);
std::string factionID = "";
if(arg0 >0)
{
@ -647,6 +645,8 @@ namespace MWScript
}
else
{
MWWorld::Ptr ptr = R()(runtime);
if(ptr.getClass().getNpcStats(ptr).getFactionRanks().empty())
{
factionID = "";
@ -913,8 +913,6 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0)
{
MWWorld::Ptr ptr = R()(runtime);
std::string factionID = "";
if(arg0 >0 )
{
@ -923,6 +921,8 @@ namespace MWScript
}
else
{
MWWorld::Ptr ptr = R()(runtime);
if(ptr.getClass().getNpcStats(ptr).getFactionRanks().empty())
{
factionID = "";

@ -327,7 +327,7 @@ namespace MWScript
}
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,zRot);
ptr.getClass().adjustPosition(ptr);
ptr.getClass().adjustPosition(ptr, false);
}
else
{
@ -374,7 +374,7 @@ namespace MWScript
zRot = zRot/60.;
}
MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,zRot);
ptr.getClass().adjustPosition(ptr);
ptr.getClass().adjustPosition(ptr, false);
}
};

@ -322,7 +322,7 @@ namespace MWWorld
return std::make_pair (1, "");
}
void Class::adjustPosition(const MWWorld::Ptr& ptr) const
void Class::adjustPosition(const MWWorld::Ptr& ptr, bool force) const
{
}

@ -90,8 +90,9 @@ namespace MWWorld
///< \return name (the one that is to be presented to the user; not the internal one);
/// can return an empty string.
virtual void adjustPosition(const MWWorld::Ptr& ptr) const;
virtual void adjustPosition(const MWWorld::Ptr& ptr, bool force) const;
///< Adjust position to stand on ground. Must be called post model load
/// @param force do this even if the ptr is flying
virtual MWMechanics::CreatureStats& getCreatureStats (const Ptr& ptr) const;
///< Return creature stats or throw an exception, if class does not have creature stats

@ -247,29 +247,23 @@ namespace MWWorld
if (obstacle == caster)
continue;
if (obstacle.isEmpty())
MWWorld::ManualRef projectileRef(MWBase::Environment::get().getWorld()->getStore(), it->mId);
// Try to get a Ptr to the bow that was used. It might no longer exist.
MWWorld::Ptr bow = projectileRef.getPtr();
if (!caster.isEmpty())
{
// Terrain
}
else if (obstacle.getClass().isActor())
{
MWWorld::ManualRef projectileRef(MWBase::Environment::get().getWorld()->getStore(), it->mId);
// Try to get a Ptr to the bow that was used. It might no longer exist.
MWWorld::Ptr bow = projectileRef.getPtr();
if (!caster.isEmpty())
{
MWWorld::InventoryStore& inv = caster.getClass().getInventoryStore(caster);
MWWorld::ContainerStoreIterator invIt = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
if (invIt != inv.end() && Misc::StringUtils::ciEqual(invIt->getCellRef().getRefId(), it->mBowId))
bow = *invIt;
}
if (caster.isEmpty())
caster = obstacle;
MWMechanics::projectileHit(caster, obstacle, bow, projectileRef.getPtr(), pos + (newPos - pos) * cIt->first);
MWWorld::InventoryStore& inv = caster.getClass().getInventoryStore(caster);
MWWorld::ContainerStoreIterator invIt = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
if (invIt != inv.end() && Misc::StringUtils::ciEqual(invIt->getCellRef().getRefId(), it->mBowId))
bow = *invIt;
}
if (caster.isEmpty())
caster = obstacle;
MWMechanics::projectileHit(caster, obstacle, bow, projectileRef.getPtr(), pos + (newPos - pos) * cIt->first);
hit = true;
}
if (hit)

@ -4,8 +4,6 @@
#include <components/nif/niffile.hpp>
#include <libs/openengine/ogre/fader.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" /// FIXME
#include "../mwbase/soundmanager.hpp"
@ -86,7 +84,7 @@ namespace
updateObjectLocalRotation(ptr, mPhysics, mRendering);
MWBase::Environment::get().getWorld()->scaleObject (ptr, ptr.getCellRef().getScale());
ptr.getClass().adjustPosition (ptr);
ptr.getClass().adjustPosition (ptr, false);
}
catch (const std::exception& e)
{
@ -232,7 +230,7 @@ namespace MWWorld
float z = Ogre::Radian(pos.rot[2]).valueDegrees();
world->rotateObject(player, x, y, z);
player.getClass().adjustPosition(player);
player.getClass().adjustPosition(player, true);
}
MWBase::MechanicsManager *mechMgr =
@ -406,7 +404,7 @@ namespace MWWorld
void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)
{
Nif::NIFFile::CacheLock lock;
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0.5);
MWBase::Environment::get().getWindowManager()->fadeScreenOut(0.5);
Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
Loading::ScopedLoad load(loadingListener);
@ -431,8 +429,8 @@ namespace MWWorld
float z = Ogre::Radian(position.rot[2]).valueDegrees();
world->rotateObject(world->getPlayerPtr(), x, y, z);
world->getPlayerPtr().getClass().adjustPosition(world->getPlayerPtr());
world->getFader()->fadeIn(0.5f);
world->getPlayerPtr().getClass().adjustPosition(world->getPlayerPtr(), true);
MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.5);
return;
}
@ -480,7 +478,7 @@ namespace MWWorld
MWBase::Environment::get().getWorld()->adjustSky();
mCellChanged = true;
MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(0.5);
MWBase::Environment::get().getWindowManager()->fadeScreenIn(0.5);
}
void Scene::changeToExteriorCell (const ESM::Position& position)

@ -1151,7 +1151,7 @@ namespace MWWorld
}
}
void World::adjustPosition(const Ptr &ptr)
void World::adjustPosition(const Ptr &ptr, bool force)
{
ESM::Position pos (ptr.getRefData().getPosition());
@ -1170,7 +1170,7 @@ namespace MWWorld
ptr.getRefData().setPosition(pos);
if (!isFlying(ptr))
if (force || !isFlying(ptr))
{
Ogre::Vector3 traced = mPhysics->traceDown(ptr, 200);
if (traced.z < pos.pos[2])
@ -1555,11 +1555,6 @@ namespace MWWorld
mWeatherManager->modRegion(regionid, chances);
}
OEngine::Render::Fader* World::getFader()
{
return mRendering->getFader();
}
Ogre::Vector2 World::getNorthVector (CellStore* cell)
{
MWWorld::CellRefList<ESM::Static>& statics = cell->get<ESM::Static>();

@ -169,9 +169,6 @@ namespace MWWorld
virtual void readRecord (ESM::ESMReader& reader, int32_t type,
const std::map<int, int>& contentFileMap);
virtual OEngine::Render::Fader* getFader();
///< \todo remove this function. Rendering details should not be exposed.
virtual CellStore *getExterior (int x, int y);
virtual CellStore *getInterior (const std::string& name);
@ -260,8 +257,9 @@ namespace MWWorld
virtual Ptr searchPtrViaActorId (int actorId);
///< Search is limited to the active cells.
virtual void adjustPosition (const Ptr& ptr);
virtual void adjustPosition (const Ptr& ptr, bool force);
///< Adjust position after load to be on ground. Must be called after model load.
/// @param force do this even if the ptr is flying
virtual void fixPosition (const Ptr& actor);
///< Attempt to fix position so that the Ptr is no longer inside collision geometry.

@ -113,7 +113,7 @@ namespace Compiler
{
void registerExtensions (Extensions& extensions)
{
extensions.registerInstruction ("additem", "cl", opcodeAddItem, opcodeAddItemExplicit);
extensions.registerInstruction ("additem", "clX", opcodeAddItem, opcodeAddItemExplicit);
extensions.registerFunction ("getitemcount", 'l', "c", opcodeGetItemCount,
opcodeGetItemCountExplicit);
extensions.registerInstruction ("removeitem", "cl", opcodeRemoveItem,

@ -80,6 +80,7 @@ set(MYGUI_FILES
openmw_companion_window.layout
openmw_savegame_dialog.layout
openmw_recharge_dialog.layout
openmw_screen_fader.layout
DejaVuLGCSansMono.ttf
markers.png
../launcher/images/openmw.png

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Widget" layer="HUD" position="0 0 300 200" name="_Main">
<Widget type="Widget" layer="HUD" position="0 0 300 200" name="_Main" align="Stretch">
<!-- Energy bars -->
<Widget type="ProgressBar" skin="MW_EnergyBar_Yellow" position="13 131 65 12" align="Left Bottom" name="EnemyHealth">
<Property key="Visible" value="false"/>

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layer">
<Layer name="Render" overlapped="false" peek="false"/>
<Layer name="HUD" overlapped="false" peek="true"/>
<Layer name="Menu" overlapped="false" peek="false"/>
<Layer name="Windows" overlapped="true" peek="true"/>

@ -2,7 +2,7 @@
<MyGUI type="Layout">
<!-- The entire screen -->
<Widget type="Widget" layer="LoadingScreen" position="0 0 300 300" name="_Main">
<Widget type="Widget" layer="LoadingScreen" position="0 0 300 300" name="_Main" align="Stretch">
<Widget type="Widget" skin="HUD_Box" position="0 245 300 48" align="Bottom HCenter">

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="ImageBox" skin="ImageBox" layer="Render" position="0 0 300 200" name="_Main" align="Stretch">
<Property key="ImageTexture" value="black.png"/>
</Widget>
</MyGUI>

@ -1,136 +0,0 @@
#include "fader.hpp"
#include <OgreMaterial.h>
#include <OgreTechnique.h>
#include <OgreMaterialManager.h>
#include <OgreResourceGroupManager.h>
#include <OgreRectangle2D.h>
#include <OgreSceneManager.h>
#include <OgreSceneNode.h>
using namespace Ogre;
using namespace OEngine::Render;
Fader::Fader(Ogre::SceneManager* sceneMgr)
: mSceneMgr(sceneMgr)
, mMode(FadingMode_In)
, mRemainingTime(0.f)
, mTargetTime(0.f)
, mTargetAlpha(0.f)
, mCurrentAlpha(0.f)
, mStartAlpha(0.f)
, mFactor(1.f)
{
// Create the fading material
MaterialPtr material = MaterialManager::getSingleton().create("FadeInOutMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
Pass* pass = material->getTechnique(0)->getPass(0);
pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
pass->setDepthWriteEnabled (false);
mFadeTextureUnit = pass->createTextureUnitState("black.png");
mFadeTextureUnit->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue(0.f, 0.f, 0.f)); // always black colour
mRectangle = new Ogre::Rectangle2D(true);
mRectangle->setCorners(-1.0, 1.0, 1.0, -1.0);
mRectangle->setMaterial("FadeInOutMaterial");
mRectangle->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY-1);
// Use infinite AAB to always stay visible
Ogre::AxisAlignedBox aabInf;
aabInf.setInfinite();
mRectangle->setBoundingBox(aabInf);
// Attach background to the scene
Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
node->attachObject(mRectangle);
mRectangle->setVisible(false);
mRectangle->setVisibilityFlags (2048);
}
Fader::~Fader()
{
delete mRectangle;
}
void Fader::update(float dt)
{
if (mRemainingTime > 0)
{
if (mMode == FadingMode_In)
{
mCurrentAlpha -= dt/mTargetTime * (mStartAlpha-mTargetAlpha);
if (mCurrentAlpha < mTargetAlpha) mCurrentAlpha = mTargetAlpha;
}
else if (mMode == FadingMode_Out)
{
mCurrentAlpha += dt/mTargetTime * (mTargetAlpha-mStartAlpha);
if (mCurrentAlpha > mTargetAlpha) mCurrentAlpha = mTargetAlpha;
}
mRemainingTime -= dt;
}
if (1.f-((1.f-mCurrentAlpha) * mFactor) == 0.f)
mRectangle->setVisible(false);
else
applyAlpha();
}
void Fader::applyAlpha()
{
mRectangle->setVisible(true);
mFadeTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, 1.f-((1.f-mCurrentAlpha) * mFactor));
}
void Fader::fadeIn(float time)
{
if (time<0.f) return;
if (time==0.f)
{
mCurrentAlpha = 0.f;
applyAlpha();
return;
}
mStartAlpha = mCurrentAlpha;
mTargetAlpha = 0.f;
mMode = FadingMode_In;
mTargetTime = time;
mRemainingTime = time;
}
void Fader::fadeOut(const float time)
{
if (time<0.f) return;
if (time==0.f)
{
mCurrentAlpha = 1.f;
applyAlpha();
return;
}
mStartAlpha = mCurrentAlpha;
mTargetAlpha = 1.f;
mMode = FadingMode_Out;
mTargetTime = time;
mRemainingTime = time;
}
void Fader::fadeTo(const int percent, const float time)
{
if (time<0.f) return;
if (time==0.f)
{
mCurrentAlpha = percent/100.f;
applyAlpha();
return;
}
mStartAlpha = mCurrentAlpha;
mTargetAlpha = percent/100.f;
if (mTargetAlpha == mStartAlpha) return;
else if (mTargetAlpha > mStartAlpha) mMode = FadingMode_Out;
else mMode = FadingMode_In;
mTargetTime = time;
mRemainingTime = time;
}

@ -1,59 +0,0 @@
#ifndef OENGINE_OGRE_FADE_H
#define OENGINE_OGRE_FADE_H
/*
A class that handles fading in the screen from black or fading it out to black.
To achieve this, it uses a full-screen Rectangle2d
*/
namespace Ogre
{
class TextureUnitState;
class Rectangle2D;
class SceneManager;
}
namespace OEngine {
namespace Render
{
class Fader
{
public:
Fader(Ogre::SceneManager* sceneMgr);
~Fader();
void update(float dt);
void fadeIn(const float time);
void fadeOut(const float time);
void fadeTo(const int percent, const float time);
void setFactor (float factor) { mFactor = factor; }
private:
enum FadingMode
{
FadingMode_In,
FadingMode_Out
};
void applyAlpha();
Ogre::TextureUnitState* mFadeTextureUnit;
Ogre::Rectangle2D* mRectangle;
FadingMode mMode;
float mRemainingTime;
float mTargetTime;
float mTargetAlpha;
float mCurrentAlpha;
float mStartAlpha;
float mFactor;
Ogre::SceneManager* mSceneMgr;
};
}}
#endif

@ -1,5 +1,4 @@
#include "renderer.hpp"
#include "fader.hpp"
#include <SDL.h>
@ -27,9 +26,6 @@ using namespace OEngine::Render;
void OgreRenderer::cleanup()
{
delete mFader;
mFader = NULL;
if (mWindow)
Ogre::Root::getSingleton().destroyRenderTarget(mWindow);
mWindow = NULL;
@ -46,7 +42,6 @@ void OgreRenderer::cleanup()
void OgreRenderer::update(float dt)
{
mFader->update(dt);
}
void OgreRenderer::screenshot(const std::string &file)
@ -161,8 +156,6 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings&
mScene = mRoot->createSceneManager(ST_GENERIC);
mFader = new Fader(mScene);
mCamera = mScene->createCamera("cam");
// Create one viewport, entire window

@ -43,8 +43,6 @@ namespace OEngine
std::string icon;
};
class Fader;
class WindowSizeListener
{
public:
@ -62,8 +60,6 @@ namespace OEngine
OgreInit::OgreInit* mOgreInit;
Fader* mFader;
WindowSizeListener* mWindowListener;
int mWindowWidth;
@ -79,7 +75,6 @@ namespace OEngine
, mCamera(NULL)
, mView(NULL)
, mOgreInit(NULL)
, mFader(NULL)
, mWindowListener(NULL)
, mWindowWidth(0)
, mWindowHeight(0)
@ -131,9 +126,6 @@ namespace OEngine
/// Get the scene manager
Ogre::SceneManager *getScene() { return mScene; }
/// Get the screen colour fader
Fader *getFader() { return mFader; }
/// Camera
Ogre::Camera *getCamera() { return mCamera; }

Loading…
Cancel
Save