diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index fa4c693375..1247ceda12 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -509,7 +509,7 @@ void OMW::Engine::screenshot() int shotCount = 0; const std::string& screenshotPath = mCfgMgr.getUserDataPath().string(); - + std::string format = Settings::Manager::getString("screenshot format", "General"); // Find the first unused filename with a do-while std::ostringstream stream; do @@ -518,11 +518,11 @@ void OMW::Engine::screenshot() stream.str(""); stream.clear(); - stream << screenshotPath << "screenshot" << std::setw(3) << std::setfill('0') << shotCount++ << ".png"; + stream << screenshotPath << "screenshot" << std::setw(3) << std::setfill('0') << shotCount++ << "." << format; } while (boost::filesystem::exists(stream.str())); - mOgre->screenshot(stream.str()); + mOgre->screenshot(stream.str(), format); } void OMW::Engine::setCompileAll (bool all) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f07bb3eb9b..2055aeeae5 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -396,6 +396,7 @@ namespace MWBase virtual void activateDoor(const MWWorld::Ptr& door) = 0; /// update movement state of a non-teleport door as specified /// @param state see MWClass::setDoorState + /// @note throws an exception when invoked on a teleport door virtual void activateDoor(const MWWorld::Ptr& door, int state) = 0; virtual bool getPlayerStandingOn (const MWWorld::Ptr& object) = 0; ///< @return true if the player is standing on \a object diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 6aa4d58ed0..139f390f88 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -463,6 +463,8 @@ namespace MWClass if(getCreatureStats(ptr).isDead()) return boost::shared_ptr(new MWWorld::ActionOpen(ptr, true)); + if(ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat()) + return boost::shared_ptr(new MWWorld::FailedAction("")); return boost::shared_ptr(new MWWorld::ActionTalk(ptr)); } @@ -514,9 +516,7 @@ namespace MWClass bool Creature::hasToolTip (const MWWorld::Ptr& ptr) const { - /// \todo We don't want tooltips for Creatures in combat mode. - - return true; + return !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat() || getCreatureStats(ptr).isDead(); } float Creature::getSpeed(const MWWorld::Ptr &ptr) const diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 153432af6e..fa9db9e160 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -324,6 +324,9 @@ namespace MWClass void Door::setDoorState (const MWWorld::Ptr &ptr, int state) const { + if (ptr.getCellRef().getTeleport()) + throw std::runtime_error("load doors can't be moved"); + ensureCustomData(ptr); DoorCustomData& customData = dynamic_cast(*ptr.getRefData().getCustomData()); customData.mDoorState = state; diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 8c2decb722..eabebc72a0 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -74,7 +74,7 @@ namespace MWClass if(!model.empty()) physics.addObject(ptr,ref->mBase->mData.mFlags & ESM::Light::Carry); - if (!ref->mBase->mSound.empty()) + if (!ref->mBase->mSound.empty() && !(ref->mBase->mData.mFlags & ESM::Light::OffDefault)) MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0, MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_Loop); diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 006ed06f86..8915f66543 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1060,9 +1060,7 @@ namespace MWClass bool Npc::hasToolTip (const MWWorld::Ptr& ptr) const { - /// \todo We don't want tooltips for NPCs in combat mode. - - return true; + return !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat() || getCreatureStats(ptr).isDead(); } MWGui::ToolTipInfo Npc::getToolTipInfo (const MWWorld::Ptr& ptr) const diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index ccfe6b1eb0..67bdc14acf 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -22,6 +22,7 @@ #include "tradeitemmodel.hpp" #include "countdialog.hpp" #include "dialogue.hpp" +#include "controllers.hpp" namespace { @@ -44,8 +45,6 @@ namespace MWGui TradeWindow::TradeWindow() : WindowBase("openmw_trade_window.layout") , mCurrentBalance(0) - , mBalanceButtonsState(BBS_None) - , mBalanceChangePause(0.0) , mItemToSell(-1) , mTradeModel(NULL) , mSortModel(NULL) @@ -240,21 +239,6 @@ namespace MWGui } } - void TradeWindow::onFrame(float frameDuration) - { - if (!mMainWidget->getVisible() || mBalanceButtonsState == BBS_None) - return; - - mBalanceChangePause -= frameDuration; - if (mBalanceChangePause < 0.0) { - mBalanceChangePause += sBalanceChangeInterval; - if (mBalanceButtonsState == BBS_Increase) - onIncreaseButtonTriggered(); - else if (mBalanceButtonsState == BBS_Decrease) - onDecreaseButtonTriggered(); - } - } - void TradeWindow::onOfferButtonClicked(MyGUI::Widget* _sender) { TradeItemModel* playerItemModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel(); @@ -407,23 +391,38 @@ namespace MWGui updateLabels(); } + void TradeWindow::addRepeatController(MyGUI::Widget *widget) + { + MyGUI::ControllerItem* item = MyGUI::ControllerManager::getInstance().createItem(Controllers::ControllerRepeatClick::getClassTypeName()); + Controllers::ControllerRepeatClick* controller = item->castType(); + controller->eventRepeatClick += MyGUI::newDelegate(this, &TradeWindow::onRepeatClick); + controller->setRepeat(sBalanceChangeInitialPause, sBalanceChangeInterval); + MyGUI::ControllerManager::getInstance().addItem(widget, controller); + } + void TradeWindow::onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { - mBalanceButtonsState = BBS_Increase; - mBalanceChangePause = sBalanceChangeInitialPause; + addRepeatController(_sender); onIncreaseButtonTriggered(); } void TradeWindow::onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) { - mBalanceButtonsState = BBS_Decrease; - mBalanceChangePause = sBalanceChangeInitialPause; + addRepeatController(_sender); onDecreaseButtonTriggered(); } + void TradeWindow::onRepeatClick(MyGUI::Widget* widget, MyGUI::ControllerItem* controller) + { + if (widget == mIncreaseButton) + onIncreaseButtonTriggered(); + else if (widget == mDecreaseButton) + onDecreaseButtonTriggered(); + } + void TradeWindow::onBalanceButtonReleased(MyGUI::Widget *_sender, int _left, int _top, MyGUI::MouseButton _id) { - mBalanceButtonsState = BBS_None; + MyGUI::ControllerManager::getInstance().removeItem(_sender); } void TradeWindow::onBalanceEdited(MyGUI::EditBox *_sender) @@ -436,6 +435,10 @@ namespace MWGui } catch (std::bad_cast&) { + if (_sender->getCaption().empty()) + mTotalBalance->setCaption("0"); + else + mTotalBalance->setCaption(boost::lexical_cast(std::abs(mCurrentBalance))); } } @@ -460,16 +463,19 @@ namespace MWGui mPlayerGold->setCaptionWithReplacing("#{sYourGold} " + boost::lexical_cast(playerGold)); + std::string balanceCaption; if (mCurrentBalance > 0) { mTotalBalanceLabel->setCaptionWithReplacing("#{sTotalSold}"); - mTotalBalance->setCaption(boost::lexical_cast(mCurrentBalance)); + balanceCaption = boost::lexical_cast(mCurrentBalance); } else { mTotalBalanceLabel->setCaptionWithReplacing("#{sTotalCost}"); - mTotalBalance->setCaption(boost::lexical_cast(-mCurrentBalance)); + balanceCaption = boost::lexical_cast(-mCurrentBalance); } + if (balanceCaption != mTotalBalance->getCaption().asUTF8()) // Don't reset text cursor if text doesn't need to be changed + mTotalBalance->setCaption(balanceCaption); mMerchantGold->setCaptionWithReplacing("#{sSellerGold} " + boost::lexical_cast(getMerchantGold())); } diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index 7baf0ce8ec..b822331c35 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -28,8 +28,6 @@ namespace MWGui void startTrade(const MWWorld::Ptr& actor); - void onFrame(float frameDuration); - void borrowItem (int index, size_t count); void returnItem (int index, size_t count); @@ -71,14 +69,6 @@ namespace MWGui int mCurrentBalance; int mCurrentMerchantOffer; - enum BalanceButtonsState { - BBS_None, - BBS_Increase, - BBS_Decrease - } mBalanceButtonsState; - /// pause before next balance change will trigger while user holds +/- button pressed - float mBalanceChangePause; - void sellToNpc(const MWWorld::Ptr& item, int count, bool boughtItem); ///< only used for adjusting the gold balance void buyFromNpc(const MWWorld::Ptr& item, int count, bool soldItem); ///< only used for adjusting the gold balance @@ -93,6 +83,9 @@ namespace MWGui void onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onBalanceButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id); void onBalanceEdited(MyGUI::EditBox* _sender); + void onRepeatClick(MyGUI::Widget* widget, MyGUI::ControllerItem* controller); + + void addRepeatController(MyGUI::Widget* widget); void onIncreaseButtonTriggered(); void onDecreaseButtonTriggered(); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index a750e266c8..f6ad6500cc 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -848,7 +848,6 @@ namespace MWGui mHud->onFrame(frameDuration); mTrainingWindow->onFrame (frameDuration); - mTradeWindow->onFrame(frameDuration); mTrainingWindow->checkReferenceAvailable(); mDialogueWindow->checkReferenceAvailable(); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index e1f7c31fc9..2a0acf4167 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -498,7 +498,14 @@ namespace MWInput void InputManager::keyPressed( const SDL_KeyboardEvent &arg ) { + // HACK: to make Morrowind's default keybinding for the console work without printing an extra "^" upon closing + // This assumes that SDL_TextInput events always come *after* the key event + // (which is somewhat reasonable, and hopefully true for all SDL platforms) OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); + if (mInputBinder->getKeyBinding(mInputBinder->getControl(A_Console), ICS::Control::INCREASE) + == arg.keysym.sym + && MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_Console) + SDL_StopTextInput(); bool consumed = false; if (kc != OIS::KC_UNASSIGNED) @@ -873,7 +880,7 @@ namespace MWInput defaultKeyBindings[A_ToggleWeapon] = SDL_GetKeyFromScancode(SDL_SCANCODE_F); defaultKeyBindings[A_ToggleSpell] = SDL_GetKeyFromScancode(SDL_SCANCODE_R); defaultKeyBindings[A_QuickKeysMenu] = SDL_GetKeyFromScancode(SDL_SCANCODE_F1); - defaultKeyBindings[A_Console] = SDL_GetKeyFromScancode(SDL_SCANCODE_F2); + defaultKeyBindings[A_Console] = SDL_GetKeyFromScancode(SDL_SCANCODE_GRAVE); defaultKeyBindings[A_Run] = SDL_GetKeyFromScancode(SDL_SCANCODE_LSHIFT); defaultKeyBindings[A_Sneak] = SDL_GetKeyFromScancode(SDL_SCANCODE_LCTRL); defaultKeyBindings[A_AutoMove] = SDL_GetKeyFromScancode(SDL_SCANCODE_Q); @@ -894,7 +901,7 @@ namespace MWInput defaultKeyBindings[A_QuickKey10] = SDL_GetKeyFromScancode(SDL_SCANCODE_0); defaultKeyBindings[A_Screenshot] = SDL_GetKeyFromScancode(SDL_SCANCODE_F12); defaultKeyBindings[A_ToggleHUD] = SDL_GetKeyFromScancode(SDL_SCANCODE_F11); - defaultKeyBindings[A_AlwaysRun] = SDL_GetKeyFromScancode(SDL_SCANCODE_Y); + defaultKeyBindings[A_AlwaysRun] = SDL_GetKeyFromScancode(SDL_SCANCODE_CAPSLOCK); defaultKeyBindings[A_QuickSave] = SDL_GetKeyFromScancode(SDL_SCANCODE_F5); defaultKeyBindings[A_QuickLoad] = SDL_GetKeyFromScancode(SDL_SCANCODE_F9); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 8159583a5f..31a0856605 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1120,7 +1120,11 @@ namespace MWMechanics { updateActor(iter->first, duration); - if (MWBase::Environment::get().getMechanicsManager()->isAIActive()) + // AI processing is only done within distance of 7168 units to the player. Note the "AI distance" slider doesn't affect this + // (it only does some throttling for targets beyond the "AI distance", so doesn't give any guarantees as to whether AI will be enabled or not) + if (MWBase::Environment::get().getMechanicsManager()->isAIActive() && + Ogre::Vector3(player.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(iter->first.getRefData().getPosition().pos)) + <= 7168*7168) { if (timerUpdateAITargets == 0) { diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index ff03293416..f015bb8a4e 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -97,7 +97,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po MWWorld::Ptr door = getNearbyDoor(actor); if(door != MWWorld::Ptr()) // NOTE: checks interior cells only { - if(door.getCellRef().getTrap().empty() && door.getClass().getDoorState(door) == 0) { //Open the door if untrapped + if(!door.getCellRef().getTeleport() && door.getCellRef().getTrap().empty() && door.getClass().getDoorState(door) == 0) { //Open the door if untrapped MWBase::Environment::get().getWorld()->activateDoor(door, 1); } } diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 2f51b64677..eafbdd59c5 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -434,7 +434,8 @@ namespace MWMechanics if (mSaidGreeting == Greet_None) { - if ((playerDistSqr <= helloDistance*helloDistance) && MWBase::Environment::get().getWorld()->getLOS(player, actor) + if ((playerDistSqr <= helloDistance*helloDistance) && + !player.getClass().getCreatureStats(player).isDead() && MWBase::Environment::get().getWorld()->getLOS(player, actor) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, actor)) mGreetingTimer++; diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index d856b73898..9d1e5e52f2 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -716,6 +716,7 @@ bool CharacterController::updateCreatureState() 0.0f, 0); mUpperBodyState = UpperCharState_StartToMinAttack; } + stats.setAttackingOrSpell(false); } bool animPlaying = mAnimation->getInfo(mCurrentWeapon); @@ -911,6 +912,7 @@ bool CharacterController::updateWeaponState() else if(mWeaponType == WeapType_PickProbe) { MWWorld::Ptr item = *weapon; + // TODO: this will only work for the player, and needs to be fixed if NPCs should ever use lockpicks/probes. MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getFacedObject(); std::string resultMessage, resultSound; diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index a1f0d994af..373ca7af93 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -519,7 +519,7 @@ namespace MWMechanics MWBase::Environment::get().getWorld()->explodeSpell(mHitPosition, effects, caster, mId, mSourceName); if (!reflectedEffects.mList.empty()) - inflict(caster, target, reflectedEffects, range, true); + inflict(caster, target, reflectedEffects, range, true, exploded); if (!appliedLastingEffects.empty()) { diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index a8b453e890..81b92dcbf5 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -873,10 +873,13 @@ void Animation::play(const std::string &groupname, int priority, int groups, boo mStates[groupname] = state; NifOgre::TextKeyMap::const_iterator textkey(textkeys.lower_bound(state.mTime)); - while(textkey != textkeys.end() && textkey->first <= state.mTime) + if (state.mPlaying) { - handleTextKey(state, groupname, textkey, textkeys); - ++textkey; + while(textkey != textkeys.end() && textkey->first <= state.mTime) + { + handleTextKey(state, groupname, textkey, textkeys); + ++textkey; + } } if(state.mTime >= state.mLoopStopTime && state.mLoopCount > 0) @@ -887,7 +890,7 @@ void Animation::play(const std::string &groupname, int priority, int groups, boo if(state.mTime >= state.mLoopStopTime) break; - textkey = textkeys.lower_bound(state.mTime); + NifOgre::TextKeyMap::const_iterator textkey(textkeys.lower_bound(state.mTime)); while(textkey != textkeys.end() && textkey->first <= state.mTime) { handleTextKey(state, groupname, textkey, textkeys); diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index 52957b00f5..bd91943ad3 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -148,7 +148,7 @@ namespace MWScript // Instantly reset door to closed state // This is done when using Lock in scripts, but not when using Lock spells. - if (ptr.getTypeName() == typeid(ESM::Door).name()) + if (ptr.getTypeName() == typeid(ESM::Door).name() && !ptr.getCellRef().getTeleport()) { MWBase::Environment::get().getWorld()->activateDoor(ptr, 0); MWBase::Environment::get().getWorld()->localRotateObject(ptr, 0, 0, 0); @@ -871,7 +871,6 @@ namespace MWScript { MWBase::World* world = MWBase::Environment::get().getWorld(); world->goToJail(); - MWBase::Environment::get().getWorld()->getPlayer().recordCrimeId(); } }; diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 42f44512a9..e74388effc 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -463,25 +463,26 @@ namespace MWScript Interpreter::Type_Float zRot = runtime[0].mFloat; runtime.pop(); - int cx,cy; - MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy); - MWWorld::CellStore* store = MWBase::Environment::get().getWorld()->getExterior(cx,cy); - if(store) + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + MWWorld::CellStore* store = NULL; + if (player.getCell()->isExterior()) { - ESM::Position pos; - pos.pos[0] = x; - pos.pos[1] = y; - pos.pos[2] = z; - pos.rot[0] = pos.rot[1] = 0; - pos.rot[2] = zRot; - MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID); - ref.getPtr().getCellRef().setPosition(pos); - MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),store,pos); + int cx,cy; + MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy); + store = MWBase::Environment::get().getWorld()->getExterior(cx,cy); } else - { - throw std::runtime_error ("unknown cell"); - } + store = player.getCell(); + + ESM::Position pos; + pos.pos[0] = x; + pos.pos[1] = y; + pos.pos[2] = z; + pos.rot[0] = pos.rot[1] = 0; + pos.rot[2] = zRot; + MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(),itemID); + ref.getPtr().getCellRef().setPosition(pos); + MWBase::Environment::get().getWorld()->safePlaceObject(ref.getPtr(),store,pos); } }; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index f01018ed0f..80ad66743f 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -259,10 +259,6 @@ namespace MWWorld void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) { - // CellChanged events should not trigger when crossing exterior cell borders - // TODO: check worldspace - bool cellChanged = !mCurrentCell || !mCurrentCell->isExterior(); - Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen(); Loading::ScopedLoad load(loadingListener); @@ -362,7 +358,7 @@ namespace MWWorld // Sky system MWBase::Environment::get().getWorld()->adjustSky(); - mCellChanged = cellChanged; + mCellChanged = true; } //We need the ogre renderer and a scene node. diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 6a8322d4d1..66fe13e067 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -149,7 +149,7 @@ namespace MWWorld mActivationDistanceOverride (activationDistanceOverride), mFallback(fallbackMap), mTeleportEnabled(true), mLevitationEnabled(true), mGodMode(false), mContentFiles (contentFiles), - mGoToJail(false), + mGoToJail(false), mDaysInPrison(0), mStartCell (startCell), mStartupScript(startupScript) { mPhysics = new PhysicsSystem(renderer); @@ -259,7 +259,8 @@ namespace MWWorld mWeatherManager = 0; mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback); - MWBase::Environment::get().getWindowManager()->executeInConsole(mStartupScript); + if (!mStartupScript.empty()) + MWBase::Environment::get().getWindowManager()->executeInConsole(mStartupScript); } void World::clear() @@ -2798,8 +2799,19 @@ namespace MWWorld { if (!mGoToJail) { - // Save for next update, since the player should be able to read the dialog text first + // Reset bounty and forget the crime now, but don't change cell yet (the player should be able to read the dialog text first) mGoToJail = true; + + MWWorld::Ptr player = getPlayerPtr(); + + int bounty = player.getClass().getNpcStats(player).getBounty(); + player.getClass().getNpcStats(player).setBounty(0); + mPlayer->recordCrimeId(); + confiscateStolenItems(player); + + int iDaysinPrisonMod = getStore().get().find("iDaysinPrisonMod")->getInt(); + mDaysInPrison = std::max(1, bounty / iDaysinPrisonMod); + return; } else @@ -2810,13 +2822,8 @@ namespace MWWorld MWWorld::Ptr player = getPlayerPtr(); teleportToClosestMarker(player, "prisonmarker"); - int bounty = player.getClass().getNpcStats(player).getBounty(); - player.getClass().getNpcStats(player).setBounty(0); - confiscateStolenItems(player); - - int iDaysinPrisonMod = getStore().get().find("iDaysinPrisonMod")->getInt(); - int days = std::max(1, bounty / iDaysinPrisonMod); + int days = mDaysInPrison; advanceTime(days * 24); for (int i=0; irest (true); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 54827d042f..d4f11f5b67 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -141,6 +141,7 @@ namespace MWWorld bool mTeleportEnabled; bool mLevitationEnabled; bool mGoToJail; + int mDaysInPrison; float feetToGameUnits(float feet); @@ -474,6 +475,7 @@ namespace MWWorld /// update movement state of a non-teleport door as specified /// @param state see MWClass::setDoorState + /// @note throws an exception when invoked on a teleport door virtual void activateDoor(const MWWorld::Ptr& door, int state); virtual bool getPlayerStandingOn (const MWWorld::Ptr& object); ///< @return true if the player is standing on \a object diff --git a/components/nifogre/controller.hpp b/components/nifogre/controller.hpp index aa60482e3c..cc750ea65e 100644 --- a/components/nifogre/controller.hpp +++ b/components/nifogre/controller.hpp @@ -89,6 +89,9 @@ namespace NifOgre { if(mDeltaInput) { + if (mStopTime - mStartTime == 0.f) + return 0.f; + mDeltaCount += value*mFrequency; if(mDeltaCount < mStartTime) mDeltaCount = mStopTime - std::fmod(mStartTime - mDeltaCount, diff --git a/files/settings-default.cfg b/files/settings-default.cfg index ab9de47a4c..fc651f4632 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -60,6 +60,8 @@ num mipmaps = 8 shader mode = +screenshot format = png + [Shadows] # Shadows are only supported when object shaders are on! enabled = false diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index 78eff6aeed..fa98433acb 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -44,7 +44,7 @@ void OgreRenderer::update(float dt) { } -void OgreRenderer::screenshot(const std::string &file) +void OgreRenderer::screenshot(const std::string &file, const std::string& imageFormat) { /* Since Ogre uses narrow character interfaces, it does not support Unicode paths on Windows. Therefore we had to implement screenshot @@ -65,7 +65,7 @@ void OgreRenderer::screenshot(const std::string &file) ); mWindow->copyContentsToMemory(image.getPixelBox()); - Ogre::DataStreamPtr stream = image.encode("png"); + Ogre::DataStreamPtr stream = image.encode(imageFormat); Ogre::MemoryDataStream *mem = dynamic_cast(stream.get()); if (mem != 0) { // likely const char *ptr = reinterpret_cast(mem->getCurrentPtr()); diff --git a/libs/openengine/ogre/renderer.hpp b/libs/openengine/ogre/renderer.hpp index c7ec2ec449..5dba15b5a8 100644 --- a/libs/openengine/ogre/renderer.hpp +++ b/libs/openengine/ogre/renderer.hpp @@ -108,7 +108,7 @@ namespace OEngine void update(float dt); /// Write a screenshot to file - void screenshot(const std::string &file); + void screenshot(const std::string &file, const std::string& imageFormat); float getFPS();