Merge remote-tracking branch 'scrawl/master'

This commit is contained in:
Marc Zinnschlag 2013-11-21 08:27:53 +01:00
commit 26361b35f2
19 changed files with 178 additions and 230 deletions

View file

@ -284,6 +284,9 @@ namespace MWBase
virtual void setKeyFocusWidget (MyGUI::Widget* widget) = 0; virtual void setKeyFocusWidget (MyGUI::Widget* widget) = 0;
virtual Loading::Listener* getLoadingScreen() = 0; virtual Loading::Listener* getLoadingScreen() = 0;
/// Should the cursor be visible?
virtual bool getCursorVisible() = 0;
}; };
} }

View file

@ -73,57 +73,4 @@ namespace MWGui
return mSize; return mSize;
} }
// ----------------------------------------------------------------------------------------
Cursor::Cursor()
{
// hide mygui's pointer since we're rendering it ourselves (because mygui's pointer doesn't support rotation)
MyGUI::PointerManager::getInstance().setVisible(false);
MyGUI::PointerManager::getInstance().eventChangeMousePointer += MyGUI::newDelegate(this, &Cursor::onCursorChange);
mWidget = MyGUI::Gui::getInstance().createWidget<MyGUI::ImageBox>("RotatingSkin",0,0,0,0,MyGUI::Align::Default,"Pointer","");
onCursorChange(MyGUI::PointerManager::getInstance().getDefaultPointer());
}
Cursor::~Cursor()
{
}
void Cursor::onCursorChange(const std::string &name)
{
ResourceImageSetPointerFix* imgSetPtr = dynamic_cast<ResourceImageSetPointerFix*>(
MyGUI::PointerManager::getInstance().getByName(name));
assert(imgSetPtr != NULL);
MyGUI::ResourceImageSet* imgSet = imgSetPtr->getImageSet();
std::string texture = imgSet->getIndexInfo(0,0).texture;
mSize = imgSetPtr->getSize();
mHotSpot = imgSetPtr->getHotSpot();
int rotation = imgSetPtr->getRotation();
mWidget->setImageTexture(texture);
MyGUI::ISubWidget* main = mWidget->getSubWidgetMain();
MyGUI::RotatingSkin* rotatingSubskin = main->castType<MyGUI::RotatingSkin>();
rotatingSubskin->setCenter(MyGUI::IntPoint(mSize.width/2,mSize.height/2));
rotatingSubskin->setAngle(Ogre::Degree(rotation).valueRadians());
}
void Cursor::update()
{
MyGUI::IntPoint position = MyGUI::InputManager::getInstance().getMousePosition();
mWidget->setPosition(position - mHotSpot);
mWidget->setSize(mSize);
}
void Cursor::setVisible(bool visible)
{
mWidget->setVisible(visible);
}
} }

View file

@ -39,23 +39,6 @@ namespace MWGui
int mRotation; // rotation in degrees int mRotation; // rotation in degrees
}; };
class Cursor
{
public:
Cursor();
~Cursor();
void update ();
void setVisible (bool visible);
void onCursorChange (const std::string& name);
private:
MyGUI::ImageBox* mWidget;
MyGUI::IntSize mSize;
MyGUI::IntPoint mHotSpot;
};
} }
#endif #endif

View file

@ -10,7 +10,6 @@ namespace MWGui
MessageBoxManager::MessageBoxManager () MessageBoxManager::MessageBoxManager ()
{ {
// defines
mMessageBoxSpeed = 0.1; mMessageBoxSpeed = 0.1;
mInterMessageBoxe = NULL; mInterMessageBoxe = NULL;
mStaticMessageBox = NULL; mStaticMessageBox = NULL;
@ -19,47 +18,26 @@ namespace MWGui
void MessageBoxManager::onFrame (float frameDuration) void MessageBoxManager::onFrame (float frameDuration)
{ {
std::vector<MessageBoxManagerTimer>::iterator it; std::vector<MessageBox*>::iterator it;
for(it = mTimers.begin(); it != mTimers.end();) for(it = mMessageBoxes.begin(); it != mMessageBoxes.end();)
{ {
// if this messagebox is already deleted, remove the timer and move on (*it)->mCurrentTime += frameDuration;
if (std::find(mMessageBoxes.begin(), mMessageBoxes.end(), it->messageBox) == mMessageBoxes.end()) if((*it)->mCurrentTime >= (*it)->mMaxTime && *it != mStaticMessageBox)
{ {
it = mTimers.erase(it); delete *it;
continue; it = mMessageBoxes.erase(it);
}
it->current += frameDuration;
if(it->current >= it->max)
{
it->messageBox->mMarkedToDelete = true;
if(*mMessageBoxes.begin() == it->messageBox) // if this box is the last one
{
// collect all with mMarkedToDelete and delete them.
// and place the other messageboxes on the right position
int height = 0;
std::vector<MessageBox*>::iterator it2 = mMessageBoxes.begin();
while(it2 != mMessageBoxes.end())
{
if((*it2)->mMarkedToDelete)
{
delete (*it2);
it2 = mMessageBoxes.erase(it2);
}
else {
(*it2)->update(height);
height += (*it2)->getHeight();
++it2;
}
}
}
it = mTimers.erase(it);
} }
else else
{
++it; ++it;
} }
float height = 0;
it = mMessageBoxes.begin();
while(it != mMessageBoxes.end())
{
(*it)->update(height);
height += (*it)->getHeight();
++it;
} }
if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) { if(mInterMessageBoxe != NULL && mInterMessageBoxe->mMarkedToDelete) {
@ -74,14 +52,13 @@ namespace MWGui
void MessageBoxManager::createMessageBox (const std::string& message, bool stat) void MessageBoxManager::createMessageBox (const std::string& message, bool stat)
{ {
MessageBox *box = new MessageBox(*this, message); MessageBox *box = new MessageBox(*this, message);
box->mCurrentTime = 0;
box->mMaxTime = message.length()*mMessageBoxSpeed;
if(stat) if(stat)
mStaticMessageBox = box; mStaticMessageBox = box;
else
removeMessageBox(message.length()*mMessageBoxSpeed, box);
mMessageBoxes.push_back(box); mMessageBoxes.push_back(box);
std::vector<MessageBox*>::iterator it;
if(mMessageBoxes.size() > 3) { if(mMessageBoxes.size() > 3) {
delete *mMessageBoxes.begin(); delete *mMessageBoxes.begin();
@ -89,7 +66,7 @@ namespace MWGui
} }
int height = 0; int height = 0;
for(it = mMessageBoxes.begin(); it != mMessageBoxes.end(); ++it) for(std::vector<MessageBox*>::iterator it = mMessageBoxes.begin(); it != mMessageBoxes.end(); ++it)
{ {
(*it)->update(height); (*it)->update(height);
height += (*it)->getHeight(); height += (*it)->getHeight();
@ -119,15 +96,6 @@ namespace MWGui
return mInterMessageBoxe != NULL; return mInterMessageBoxe != NULL;
} }
void MessageBoxManager::removeMessageBox (float time, MessageBox *msgbox)
{
MessageBoxManagerTimer timer;
timer.current = 0;
timer.max = time;
timer.messageBox = msgbox;
mTimers.insert(mTimers.end(), timer);
}
bool MessageBoxManager::removeMessageBox (MessageBox *msgbox) bool MessageBoxManager::removeMessageBox (MessageBox *msgbox)
{ {
@ -169,12 +137,13 @@ namespace MWGui
: Layout("openmw_messagebox.layout") : Layout("openmw_messagebox.layout")
, mMessageBoxManager(parMessageBoxManager) , mMessageBoxManager(parMessageBoxManager)
, mMessage(message) , mMessage(message)
, mCurrentTime(0)
, mMaxTime(0)
{ {
// defines // defines
mFixedWidth = 300; mFixedWidth = 300;
mBottomPadding = 20; mBottomPadding = 20;
mNextBoxPadding = 20; mNextBoxPadding = 20;
mMarkedToDelete = false;
getWidget(mMessageWidget, "message"); getWidget(mMessageWidget, "message");

View file

@ -19,13 +19,6 @@ namespace MWGui
class InteractiveMessageBox; class InteractiveMessageBox;
class MessageBoxManager; class MessageBoxManager;
class MessageBox; class MessageBox;
struct MessageBoxManagerTimer {
float current;
float max;
MessageBox *messageBox;
};
class MessageBoxManager class MessageBoxManager
{ {
public: public:
@ -36,7 +29,6 @@ namespace MWGui
bool createInteractiveMessageBox (const std::string& message, const std::vector<std::string>& buttons); bool createInteractiveMessageBox (const std::string& message, const std::vector<std::string>& buttons);
bool isInteractiveMessageBox (); bool isInteractiveMessageBox ();
void removeMessageBox (float time, MessageBox *msgbox);
bool removeMessageBox (MessageBox *msgbox); bool removeMessageBox (MessageBox *msgbox);
void setMessageBoxSpeed (int speed); void setMessageBoxSpeed (int speed);
@ -54,7 +46,6 @@ namespace MWGui
std::vector<MessageBox*> mMessageBoxes; std::vector<MessageBox*> mMessageBoxes;
InteractiveMessageBox* mInterMessageBoxe; InteractiveMessageBox* mInterMessageBoxe;
MessageBox* mStaticMessageBox; MessageBox* mStaticMessageBox;
std::vector<MessageBoxManagerTimer> mTimers;
float mMessageBoxSpeed; float mMessageBoxSpeed;
int mLastButtonPressed; int mLastButtonPressed;
}; };
@ -67,7 +58,8 @@ namespace MWGui
int getHeight (); int getHeight ();
void update (int height); void update (int height);
bool mMarkedToDelete; float mCurrentTime;
float mMaxTime;
protected: protected:
MessageBoxManager& mMessageBoxManager; MessageBoxManager& mMessageBoxManager;

View file

@ -100,7 +100,6 @@ namespace MWGui
, mRepair(NULL) , mRepair(NULL)
, mCompanionWindow(NULL) , mCompanionWindow(NULL)
, mTranslationDataStorage (translationDataStorage) , mTranslationDataStorage (translationDataStorage)
, mSoftwareCursor(NULL)
, mCharGen(NULL) , mCharGen(NULL)
, mInputBlocker(NULL) , mInputBlocker(NULL)
, mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD")) , mCrosshairEnabled(Settings::Manager::getBool ("crosshair", "HUD"))
@ -128,7 +127,6 @@ namespace MWGui
, mFPS(0.0f) , mFPS(0.0f)
, mTriangleCount(0) , mTriangleCount(0)
, mBatchCount(0) , mBatchCount(0)
, mUseHardwareCursors(Settings::Manager::getBool("hardware cursors", "GUI"))
{ {
// Set up the GUI system // Set up the GUI system
mGuiManager = new OEngine::GUI::MyGUIManager(mRendering->getWindow(), mRendering->getScene(), false, logpath); mGuiManager = new OEngine::GUI::MyGUIManager(mRendering->getWindow(), mRendering->getScene(), false, logpath);
@ -173,16 +171,19 @@ namespace MWGui
mLoadingScreen->onResChange (w,h); mLoadingScreen->onResChange (w,h);
//set up the hardware cursor manager //set up the hardware cursor manager
mSoftwareCursor = new Cursor();
mCursorManager = new SFO::SDLCursorManager(); mCursorManager = new SFO::SDLCursorManager();
MyGUI::PointerManager::getInstance().eventChangeMousePointer += MyGUI::newDelegate(this, &WindowManager::onCursorChange); MyGUI::PointerManager::getInstance().eventChangeMousePointer += MyGUI::newDelegate(this, &WindowManager::onCursorChange);
MyGUI::InputManager::getInstance().eventChangeKeyFocus += MyGUI::newDelegate(this, &WindowManager::onKeyFocusChanged); MyGUI::InputManager::getInstance().eventChangeKeyFocus += MyGUI::newDelegate(this, &WindowManager::onKeyFocusChanged);
setUseHardwareCursors(mUseHardwareCursors); mCursorManager->setEnabled(true);
onCursorChange(MyGUI::PointerManager::getInstance().getDefaultPointer()); onCursorChange(MyGUI::PointerManager::getInstance().getDefaultPointer());
mCursorManager->cursorVisibilityChange(false); SDL_ShowCursor(false);
// hide mygui's pointer
MyGUI::PointerManager::getInstance().setVisible(false);
} }
void WindowManager::initUI() void WindowManager::initUI()
@ -313,7 +314,6 @@ namespace MWGui
delete mMerchantRepair; delete mMerchantRepair;
delete mRepair; delete mRepair;
delete mSoulgemDialog; delete mSoulgemDialog;
delete mSoftwareCursor;
delete mCursorManager; delete mCursorManager;
delete mRecharge; delete mRecharge;
@ -344,8 +344,6 @@ namespace MWGui
mHud->setBatchCount(mBatchCount); mHud->setBatchCount(mBatchCount);
mHud->update(); mHud->update();
mSoftwareCursor->update();
} }
void WindowManager::updateVisible() void WindowManager::updateVisible()
@ -879,21 +877,9 @@ namespace MWGui
MWBase::Environment::get().getInputManager()->setDragDrop(dragDrop); MWBase::Environment::get().getInputManager()->setDragDrop(dragDrop);
} }
void WindowManager::setUseHardwareCursors(bool use)
{
mCursorManager->setEnabled(use);
mSoftwareCursor->setVisible(!use && mCursorVisible);
}
void WindowManager::setCursorVisible(bool visible) void WindowManager::setCursorVisible(bool visible)
{ {
if(mCursorVisible == visible)
return;
mCursorVisible = visible; mCursorVisible = visible;
mCursorManager->cursorVisibilityChange(visible);
mSoftwareCursor->setVisible(!mUseHardwareCursors && visible);
} }
void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result) void WindowManager::onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result)
@ -924,8 +910,6 @@ namespace MWGui
mHud->setFpsLevel(Settings::Manager::getInt("fps", "HUD")); mHud->setFpsLevel(Settings::Manager::getInt("fps", "HUD"));
mToolTips->setDelay(Settings::Manager::getFloat("tooltip delay", "GUI")); mToolTips->setDelay(Settings::Manager::getFloat("tooltip delay", "GUI"));
setUseHardwareCursors(Settings::Manager::getBool("hardware cursors", "GUI"));
for (Settings::CategorySettingVector::const_iterator it = changed.begin(); for (Settings::CategorySettingVector::const_iterator it = changed.begin();
it != changed.end(); ++it) it != changed.end(); ++it)
{ {
@ -977,8 +961,6 @@ namespace MWGui
void WindowManager::onCursorChange(const std::string &name) void WindowManager::onCursorChange(const std::string &name)
{ {
mSoftwareCursor->onCursorChange(name);
if(!mCursorManager->cursorChanged(name)) if(!mCursorManager->cursorChanged(name))
return; //the cursor manager doesn't want any more info about this cursor return; //the cursor manager doesn't want any more info about this cursor
//See if we can get the information we need out of the cursor resource //See if we can get the information we need out of the cursor resource
@ -1376,4 +1358,9 @@ namespace MWGui
mRecharge->start(soulgem); mRecharge->start(soulgem);
} }
bool WindowManager::getCursorVisible()
{
return mCursorVisible;
}
} }

View file

@ -278,6 +278,8 @@ namespace MWGui
void onSoulgemDialogButtonPressed (int button); void onSoulgemDialogButtonPressed (int button);
virtual bool getCursorVisible();
private: private:
bool mConsoleOnlyScripts; bool mConsoleOnlyScripts;
@ -369,9 +371,6 @@ namespace MWGui
unsigned int mTriangleCount; unsigned int mTriangleCount;
unsigned int mBatchCount; unsigned int mBatchCount;
bool mUseHardwareCursors;
void setUseHardwareCursors(bool use);
/** /**
* Called when MyGUI tries to retrieve a tag. This usually corresponds to a GMST string, * Called when MyGUI tries to retrieve a tag. This usually corresponds to a GMST string,
* so this method will retrieve the GMST with the name \a _tag and place the result in \a _result * so this method will retrieve the GMST with the name \a _tag and place the result in \a _result

View file

@ -264,6 +264,8 @@ namespace MWInput
void InputManager::update(float dt, bool loading) void InputManager::update(float dt, bool loading)
{ {
mInputManager->setMouseVisible(MWBase::Environment::get().getWindowManager()->getCursorVisible());
mInputManager->capture(loading); mInputManager->capture(loading);
// inject some fake mouse movement to force updating MyGUI's widget states // inject some fake mouse movement to force updating MyGUI's widget states
// this shouldn't do any harm since we're moving back to the original position afterwards // this shouldn't do any harm since we're moving back to the original position afterwards

View file

@ -211,7 +211,7 @@ namespace MWMechanics
float currentDiff = creatureStats.getMagicEffects().get(EffectKey(ESM::MagicEffect::RestoreHealth+i)).mMagnitude float currentDiff = creatureStats.getMagicEffects().get(EffectKey(ESM::MagicEffect::RestoreHealth+i)).mMagnitude
- creatureStats.getMagicEffects().get(EffectKey(ESM::MagicEffect::DamageHealth+i)).mMagnitude - creatureStats.getMagicEffects().get(EffectKey(ESM::MagicEffect::DamageHealth+i)).mMagnitude
- creatureStats.getMagicEffects().get(EffectKey(ESM::MagicEffect::AbsorbHealth)).mMagnitude; - creatureStats.getMagicEffects().get(EffectKey(ESM::MagicEffect::AbsorbHealth+i)).mMagnitude;
stat.setCurrent(stat.getCurrent() + currentDiff * duration); stat.setCurrent(stat.getCurrent() + currentDiff * duration);
creatureStats.setDynamic(i, stat); creatureStats.setDynamic(i, stat);
@ -219,16 +219,34 @@ namespace MWMechanics
// Apply damage ticks // Apply damage ticks
int damageEffects[] = { int damageEffects[] = {
ESM::MagicEffect::FireDamage, ESM::MagicEffect::ShockDamage, ESM::MagicEffect::FrostDamage, ESM::MagicEffect::Poison ESM::MagicEffect::FireDamage, ESM::MagicEffect::ShockDamage, ESM::MagicEffect::FrostDamage, ESM::MagicEffect::Poison,
ESM::MagicEffect::SunDamage
}; };
DynamicStat<float> health = creatureStats.getHealth();
for (unsigned int i=0; i<sizeof(damageEffects)/sizeof(int); ++i) for (unsigned int i=0; i<sizeof(damageEffects)/sizeof(int); ++i)
{ {
float magnitude = creatureStats.getMagicEffects().get(EffectKey(damageEffects[i])).mMagnitude; float magnitude = creatureStats.getMagicEffects().get(EffectKey(damageEffects[i])).mMagnitude;
DynamicStat<float> health = creatureStats.getHealth();
health.setCurrent(health.getCurrent() - magnitude * duration); if (damageEffects[i] == ESM::MagicEffect::SunDamage)
creatureStats.setHealth(health); {
// isInCell shouldn't be needed, but updateActor called during game start
if (!ptr.isInCell() || !ptr.getCell()->isExterior())
continue;
float time = MWBase::Environment::get().getWorld()->getTimeStamp().getHour();
float timeDiff = std::min(7.f, std::max(0.f, std::abs(time - 13)));
float damageScale = 1.f - timeDiff / 7.f;
// When cloudy, the sun damage effect is halved
int weather = MWBase::Environment::get().getWorld()->getCurrentWeather();
if (weather > 1)
damageScale *= 0.5;
health.setCurrent(health.getCurrent() - magnitude * duration * damageScale);
}
else
health.setCurrent(health.getCurrent() - magnitude * duration);
} }
creatureStats.setHealth(health);
} }
void Actors::calculateNpcStatModifiers (const MWWorld::Ptr& ptr) void Actors::calculateNpcStatModifiers (const MWWorld::Ptr& ptr)
@ -324,7 +342,7 @@ namespace MWMechanics
} }
} }
Actors::Actors() : mDuration (0) {} Actors::Actors() {}
void Actors::addActor (const MWWorld::Ptr& ptr) void Actors::addActor (const MWWorld::Ptr& ptr)
{ {
@ -377,14 +395,8 @@ namespace MWMechanics
void Actors::update (float duration, bool paused) void Actors::update (float duration, bool paused)
{ {
mDuration += duration;
//if (mDuration>=0.25)
if (!paused) if (!paused)
{ {
float totalDuration = mDuration;
mDuration = 0;
for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();iter++) for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();iter++)
{ {
const MWWorld::Class &cls = MWWorld::Class::get(iter->first); const MWWorld::Class &cls = MWWorld::Class::get(iter->first);
@ -396,9 +408,9 @@ namespace MWMechanics
if(iter->second->isDead()) if(iter->second->isDead())
iter->second->resurrect(); iter->second->resurrect();
updateActor(iter->first, totalDuration); updateActor(iter->first, duration);
if(iter->first.getTypeName() == typeid(ESM::NPC).name()) if(iter->first.getTypeName() == typeid(ESM::NPC).name())
updateNpc(iter->first, totalDuration, paused); updateNpc(iter->first, duration, paused);
if(!stats.isDead()) if(!stats.isDead())
continue; continue;

View file

@ -30,8 +30,6 @@ namespace MWMechanics
std::map<std::string, int> mDeathCount; std::map<std::string, int> mDeathCount;
float mDuration;
void updateNpc(const MWWorld::Ptr &ptr, float duration, bool paused); void updateNpc(const MWWorld::Ptr &ptr, float duration, bool paused);

View file

@ -157,7 +157,7 @@ namespace MWMechanics
} }
} }
else else
applyInstantEffect(mTarget, effectIt->mEffectID, magnitude); applyInstantEffect(target, effectIt->mEffectID, magnitude);
if (target.getClass().isActor() || magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration) if (target.getClass().isActor() || magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)
{ {

View file

@ -66,7 +66,7 @@ namespace MWMechanics
int i=0; int i=0;
for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->mEffects.mList.begin(); it != spell->mEffects.mList.end(); ++it) for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->mEffects.mList.begin(); it != spell->mEffects.mList.end(); ++it)
{ {
effects.add (*it, iter->second[i]); effects.add (*it, it->mMagnMin + (it->mMagnMax - it->mMagnMin) * iter->second[i]);
++i; ++i;
} }
} }

View file

@ -72,7 +72,6 @@ namespace MWRender
mAnimation = new NpcAnimation(mCharacter, mNode, mAnimation = new NpcAnimation(mCharacter, mNode,
0, true, (renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal)); 0, true, (renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal));
mAnimation->updateParts();
Ogre::Vector3 scale = mNode->getScale(); Ogre::Vector3 scale = mNode->getScale();
mCamera->setPosition(mPosition * scale); mCamera->setPosition(mPosition * scale);
@ -114,7 +113,6 @@ namespace MWRender
delete mAnimation; delete mAnimation;
mAnimation = new NpcAnimation(mCharacter, mNode, mAnimation = new NpcAnimation(mCharacter, mNode,
0, true, (renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal)); 0, true, (renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal));
mAnimation->updateParts();
float scale=1.f; float scale=1.f;
MWWorld::Class::get(mCharacter).adjustScale(mCharacter, scale); MWWorld::Class::get(mCharacter).adjustScale(mCharacter, scale);
@ -142,6 +140,9 @@ namespace MWRender
void InventoryPreview::update(int sizeX, int sizeY) void InventoryPreview::update(int sizeX, int sizeY)
{ {
// TODO: can we avoid this. Vampire state needs to be updated.
mAnimation->rebuild();
MWWorld::InventoryStore &inv = MWWorld::Class::get(mCharacter).getInventoryStore(mCharacter); MWWorld::InventoryStore &inv = MWWorld::Class::get(mCharacter).getInventoryStore(mCharacter);
MWWorld::ContainerStoreIterator iter = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); MWWorld::ContainerStoreIterator iter = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
std::string groupname; std::string groupname;
@ -176,11 +177,12 @@ namespace MWRender
groupname = "inventoryhandtohand"; groupname = "inventoryhandtohand";
} }
if(groupname != mCurrentAnimGroup) // TODO see above
{ //if(groupname != mCurrentAnimGroup)
//{
mCurrentAnimGroup = groupname; mCurrentAnimGroup = groupname;
mAnimation->play(mCurrentAnimGroup, 1, Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0); mAnimation->play(mCurrentAnimGroup, 1, Animation::Group_All, false, 1.0f, "start", "stop", 0.0f, 0);
} //}
MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft); MWWorld::ContainerStoreIterator torch = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedLeft);
if(torch != inv.end() && torch->getTypeName() == typeid(ESM::Light).name()) if(torch != inv.end() && torch->getTypeName() == typeid(ESM::Light).name())

View file

@ -19,6 +19,42 @@
#include "renderconst.hpp" #include "renderconst.hpp"
#include "camera.hpp" #include "camera.hpp"
namespace
{
std::string getVampireHead(const std::string& race, bool female)
{
static std::map <std::pair<std::string,int>, const ESM::BodyPart* > sVampireMapping;
std::pair<std::string, int> thisCombination = std::make_pair(race, int(female));
if (sVampireMapping.find(thisCombination) == sVampireMapping.end())
{
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const MWWorld::Store<ESM::BodyPart> &partStore = store.get<ESM::BodyPart>();
for(MWWorld::Store<ESM::BodyPart>::iterator it = partStore.begin(); it != partStore.end(); ++it)
{
const ESM::BodyPart& bodypart = *it;
if (!bodypart.mData.mVampire)
continue;
if (bodypart.mData.mType != ESM::BodyPart::MT_Skin)
continue;
if (bodypart.mData.mPart != ESM::BodyPart::MP_Head)
continue;
if (female != (bodypart.mData.mFlags & ESM::BodyPart::BPF_Female))
continue;
if (!Misc::StringUtils::ciEqual(bodypart.mRace, race))
continue;
sVampireMapping[thisCombination] = &*it;
}
}
assert(sVampireMapping[thisCombination]);
return "meshes\\" + sVampireMapping[thisCombination]->mModel;
}
}
namespace MWRender namespace MWRender
{ {
@ -110,18 +146,23 @@ void NpcAnimation::updateNpcBase()
const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore();
const ESM::Race *race = store.get<ESM::Race>().find(mNpc->mRace); const ESM::Race *race = store.get<ESM::Race>().find(mNpc->mRace);
bool isWerewolf = MWWorld::Class::get(mPtr).getNpcStats(mPtr).isWerewolf(); bool isWerewolf = mPtr.getClass().getNpcStats(mPtr).isWerewolf();
bool vampire = mPtr.getClass().getCreatureStats(mPtr).getMagicEffects().get(ESM::MagicEffect::Vampirism).mMagnitude;
if(!isWerewolf) if (isWerewolf)
{
mHeadModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHead)->mModel;
mHairModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHair)->mModel;
}
else
{ {
mHeadModel = "meshes\\" + store.get<ESM::BodyPart>().find("WerewolfHead")->mModel; mHeadModel = "meshes\\" + store.get<ESM::BodyPart>().find("WerewolfHead")->mModel;
mHairModel = "meshes\\" + store.get<ESM::BodyPart>().find("WerewolfHair")->mModel; mHairModel = "meshes\\" + store.get<ESM::BodyPart>().find("WerewolfHair")->mModel;
} }
else
{
if (vampire)
mHeadModel = getVampireHead(mNpc->mRace, mNpc->mFlags & ESM::NPC::Female);
else
mHeadModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHead)->mModel;
mHairModel = "meshes\\" + store.get<ESM::BodyPart>().find(mNpc->mHair)->mModel;
}
bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0; bool isBeast = (race->mData.mFlags & ESM::Race::Beast) != 0;
std::string smodel = (mViewMode != VM_FirstPerson) ? std::string smodel = (mViewMode != VM_FirstPerson) ?
@ -270,6 +311,8 @@ void NpcAnimation::updateParts()
// Remember body parts so we only have to search through the store once for each race/gender/viewmode combination // Remember body parts so we only have to search through the store once for each race/gender/viewmode combination
static std::map< std::pair<std::string,int>,std::vector<const ESM::BodyPart*> > sRaceMapping; static std::map< std::pair<std::string,int>,std::vector<const ESM::BodyPart*> > sRaceMapping;
static std::map <std::pair<std::string,int>, std::vector<const ESM::BodyPart*> > sVampireMapping;
static const int Flag_Female = 1<<0; static const int Flag_Female = 1<<0;
static const int Flag_FirstPerson = 1<<1; static const int Flag_FirstPerson = 1<<1;

View file

@ -22,9 +22,6 @@ public:
/// \brief Follow up a cursorChanged() call with enough info to create an cursor. /// \brief Follow up a cursorChanged() call with enough info to create an cursor.
virtual void receiveCursorInfo(const std::string &name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) = 0; virtual void receiveCursorInfo(const std::string &name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) = 0;
/// \brief Tell the manager when the cursor visibility changed
virtual void cursorVisibilityChange(bool visible) = 0;
/// \brief sets whether to actively manage cursors or not /// \brief sets whether to actively manage cursors or not
virtual void setEnabled(bool enabled) = 0; virtual void setEnabled(bool enabled) = 0;
}; };

View file

@ -10,7 +10,6 @@ namespace SFO
SDLCursorManager::SDLCursorManager() : SDLCursorManager::SDLCursorManager() :
mEnabled(false), mEnabled(false),
mCursorVisible(false),
mInitialized(false) mInitialized(false)
{ {
} }
@ -70,27 +69,7 @@ namespace SFO
void SDLCursorManager::_setGUICursor(const std::string &name) void SDLCursorManager::_setGUICursor(const std::string &name)
{ {
if(mEnabled && mCursorVisible) SDL_SetCursor(mCursorMap.find(name)->second);
{
SDL_SetCursor(mCursorMap.find(name)->second);
_setCursorVisible(mCursorVisible);
}
}
void SDLCursorManager::_setCursorVisible(bool visible)
{
if(!mEnabled)
return;
SDL_ShowCursor(visible ? SDL_TRUE : SDL_FALSE);
}
void SDLCursorManager::cursorVisibilityChange(bool visible)
{
mCursorVisible = visible;
_setGUICursor(mCurrentCursor);
_setCursorVisible(visible);
} }
void SDLCursorManager::receiveCursorInfo(const std::string& name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y) void SDLCursorManager::receiveCursorInfo(const std::string& name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y)

View file

@ -19,14 +19,12 @@ namespace SFO
virtual bool cursorChanged(const std::string &name); virtual bool cursorChanged(const std::string &name);
virtual void receiveCursorInfo(const std::string &name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y); virtual void receiveCursorInfo(const std::string &name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y);
virtual void cursorVisibilityChange(bool visible);
private: private:
void _createCursorFromResource(const std::string &name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y); void _createCursorFromResource(const std::string &name, int rotDegrees, Ogre::TexturePtr tex, Uint8 size_x, Uint8 size_y, Uint8 hotspot_x, Uint8 hotspot_y);
void _putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel); void _putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
void _setGUICursor(const std::string& name); void _setGUICursor(const std::string& name);
void _setCursorVisible(bool visible);
typedef std::map<std::string, SDL_Cursor*> CursorMap; typedef std::map<std::string, SDL_Cursor*> CursorMap;
CursorMap mCursorMap; CursorMap mCursorMap;
@ -34,7 +32,6 @@ namespace SFO
std::string mCurrentCursor; std::string mCurrentCursor;
bool mEnabled; bool mEnabled;
bool mInitialized; bool mInitialized;
bool mCursorVisible;
}; };
} }

View file

@ -23,7 +23,11 @@ namespace SFO
mJoyListener(NULL), mJoyListener(NULL),
mKeyboardListener(NULL), mKeyboardListener(NULL),
mMouseListener(NULL), mMouseListener(NULL),
mWindowListener(NULL) mWindowListener(NULL),
mWindowHasFocus(true),
mWantGrab(false),
mWantRelative(false),
mWantMouseVisible(false)
{ {
_setupOISKeys(); _setupOISKeys();
} }
@ -51,13 +55,16 @@ namespace SFO
switch(evt.type) switch(evt.type)
{ {
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
//ignore this if it happened due to a warp // Ignore this if it happened due to a warp
if(!_handleWarpMotion(evt.motion)) if(!_handleWarpMotion(evt.motion))
{ {
mMouseListener->mouseMoved(_packageMouseMotion(evt)); // If in relative mode, don't trigger events unless window has focus
if (!mWantRelative || mWindowHasFocus)
mMouseListener->mouseMoved(_packageMouseMotion(evt));
//try to keep the mouse inside the window // Try to keep the mouse inside the window
_wrapMousePointer(evt.motion); if (mWindowHasFocus)
_wrapMousePointer(evt.motion);
} }
break; break;
case SDL_MOUSEWHEEL: case SDL_MOUSEWHEEL:
@ -118,11 +125,11 @@ namespace SFO
switch (evt.window.event) { switch (evt.window.event) {
case SDL_WINDOWEVENT_ENTER: case SDL_WINDOWEVENT_ENTER:
mMouseInWindow = true; mMouseInWindow = true;
updateMouseSettings();
break; break;
case SDL_WINDOWEVENT_LEAVE: case SDL_WINDOWEVENT_LEAVE:
mMouseInWindow = false; mMouseInWindow = false;
SDL_SetWindowGrab(mSDLWindow, SDL_FALSE); updateMouseSettings();
SDL_SetRelativeMouseMode(SDL_FALSE);
break; break;
case SDL_WINDOWEVENT_SIZE_CHANGED: case SDL_WINDOWEVENT_SIZE_CHANGED:
int w,h; int w,h;
@ -149,10 +156,15 @@ namespace SFO
break; break;
case SDL_WINDOWEVENT_FOCUS_GAINED: case SDL_WINDOWEVENT_FOCUS_GAINED:
mWindowHasFocus = true;
updateMouseSettings();
if (mWindowListener) if (mWindowListener)
mWindowListener->windowFocusChange(true); mWindowListener->windowFocusChange(true);
break; break;
case SDL_WINDOWEVENT_FOCUS_LOST: case SDL_WINDOWEVENT_FOCUS_LOST:
mWindowHasFocus = false;
updateMouseSettings();
if (mWindowListener) if (mWindowListener)
mWindowListener->windowFocusChange(false); mWindowListener->windowFocusChange(false);
break; break;
@ -193,25 +205,43 @@ namespace SFO
/// \brief Locks the pointer to the window /// \brief Locks the pointer to the window
void InputWrapper::setGrabPointer(bool grab) void InputWrapper::setGrabPointer(bool grab)
{ {
mGrabPointer = grab && mMouseInWindow; mWantGrab = grab;
SDL_SetWindowGrab(mSDLWindow, grab && mMouseInWindow ? SDL_TRUE : SDL_FALSE); updateMouseSettings();
} }
/// \brief Set the mouse to relative positioning. Doesn't move the cursor /// \brief Set the mouse to relative positioning. Doesn't move the cursor
/// and disables mouse acceleration. /// and disables mouse acceleration.
void InputWrapper::setMouseRelative(bool relative) void InputWrapper::setMouseRelative(bool relative)
{ {
if(mMouseRelative == relative && mMouseInWindow) mWantRelative = relative;
updateMouseSettings();
}
void InputWrapper::setMouseVisible(bool visible)
{
mWantMouseVisible = visible;
updateMouseSettings();
}
void InputWrapper::updateMouseSettings()
{
mGrabPointer = mWantGrab && mMouseInWindow && mWindowHasFocus;
SDL_SetWindowGrab(mSDLWindow, mGrabPointer ? SDL_TRUE : SDL_FALSE);
SDL_ShowCursor(mWantMouseVisible || !mWindowHasFocus);
bool relative = mWantRelative && mMouseInWindow && mWindowHasFocus;
if(mMouseRelative == relative)
return; return;
mMouseRelative = relative && mMouseInWindow; mMouseRelative = relative;
mWrapPointer = false; mWrapPointer = false;
//eep, wrap the pointer manually if the input driver doesn't support //eep, wrap the pointer manually if the input driver doesn't support
//relative positioning natively //relative positioning natively
int success = SDL_SetRelativeMouseMode(relative && mMouseInWindow ? SDL_TRUE : SDL_FALSE); int success = SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE);
if(relative && mMouseInWindow && success != 0) if(relative && success != 0)
mWrapPointer = true; mWrapPointer = true;
//now remove all mouse events using the old setting from the queue //now remove all mouse events using the old setting from the queue

View file

@ -28,6 +28,7 @@ namespace SFO
bool isModifierHeld(SDL_Keymod mod); bool isModifierHeld(SDL_Keymod mod);
bool isKeyDown(SDL_Scancode key); bool isKeyDown(SDL_Scancode key);
void setMouseVisible (bool visible);
void setMouseRelative(bool relative); void setMouseRelative(bool relative);
bool getMouseRelative() { return mMouseRelative; } bool getMouseRelative() { return mMouseRelative; }
void setGrabPointer(bool grab); void setGrabPointer(bool grab);
@ -36,6 +37,8 @@ namespace SFO
void warpMouse(int x, int y); void warpMouse(int x, int y);
void updateMouseSettings();
private: private:
void handleWindowEvent(const SDL_Event& evt); void handleWindowEvent(const SDL_Event& evt);
@ -57,14 +60,19 @@ namespace SFO
Uint16 mWarpX; Uint16 mWarpX;
Uint16 mWarpY; Uint16 mWarpY;
bool mWarpCompensate; bool mWarpCompensate;
bool mMouseRelative;
bool mWrapPointer; bool mWrapPointer;
bool mWantMouseVisible;
bool mWantGrab;
bool mWantRelative;
bool mGrabPointer; bool mGrabPointer;
bool mMouseRelative;
Sint32 mMouseZ; Sint32 mMouseZ;
Sint32 mMouseX; Sint32 mMouseX;
Sint32 mMouseY; Sint32 mMouseY;
bool mWindowHasFocus;
bool mMouseInWindow; bool mMouseInWindow;
SDL_Window* mSDLWindow; SDL_Window* mSDLWindow;