1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-27 03:35:27 +00:00

Merge remote-tracking branch 'scrawl/master'

This commit is contained in:
Marc Zinnschlag 2014-09-11 09:01:21 +02:00
commit b5d5eadf79
25 changed files with 117 additions and 90 deletions

View File

@ -509,7 +509,7 @@ void OMW::Engine::screenshot()
int shotCount = 0; int shotCount = 0;
const std::string& screenshotPath = mCfgMgr.getUserDataPath().string(); 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 // Find the first unused filename with a do-while
std::ostringstream stream; std::ostringstream stream;
do do
@ -518,11 +518,11 @@ void OMW::Engine::screenshot()
stream.str(""); stream.str("");
stream.clear(); 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())); } while (boost::filesystem::exists(stream.str()));
mOgre->screenshot(stream.str()); mOgre->screenshot(stream.str(), format);
} }
void OMW::Engine::setCompileAll (bool all) void OMW::Engine::setCompileAll (bool all)

View File

@ -396,6 +396,7 @@ namespace MWBase
virtual void activateDoor(const MWWorld::Ptr& door) = 0; virtual void activateDoor(const MWWorld::Ptr& door) = 0;
/// update movement state of a non-teleport door as specified /// update movement state of a non-teleport door as specified
/// @param state see MWClass::setDoorState /// @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 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 virtual bool getPlayerStandingOn (const MWWorld::Ptr& object) = 0; ///< @return true if the player is standing on \a object

View File

@ -463,6 +463,8 @@ namespace MWClass
if(getCreatureStats(ptr).isDead()) if(getCreatureStats(ptr).isDead())
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr, true)); return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionOpen(ptr, true));
if(ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat())
return boost::shared_ptr<MWWorld::Action>(new MWWorld::FailedAction(""));
return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionTalk(ptr)); return boost::shared_ptr<MWWorld::Action>(new MWWorld::ActionTalk(ptr));
} }
@ -514,9 +516,7 @@ namespace MWClass
bool Creature::hasToolTip (const MWWorld::Ptr& ptr) const bool Creature::hasToolTip (const MWWorld::Ptr& ptr) const
{ {
/// \todo We don't want tooltips for Creatures in combat mode. return !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat() || getCreatureStats(ptr).isDead();
return true;
} }
float Creature::getSpeed(const MWWorld::Ptr &ptr) const float Creature::getSpeed(const MWWorld::Ptr &ptr) const

View File

@ -324,6 +324,9 @@ namespace MWClass
void Door::setDoorState (const MWWorld::Ptr &ptr, int state) const 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); ensureCustomData(ptr);
DoorCustomData& customData = dynamic_cast<DoorCustomData&>(*ptr.getRefData().getCustomData()); DoorCustomData& customData = dynamic_cast<DoorCustomData&>(*ptr.getRefData().getCustomData());
customData.mDoorState = state; customData.mDoorState = state;

View File

@ -74,7 +74,7 @@ namespace MWClass
if(!model.empty()) if(!model.empty())
physics.addObject(ptr,ref->mBase->mData.mFlags & ESM::Light::Carry); 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::Environment::get().getSoundManager()->playSound3D(ptr, ref->mBase->mSound, 1.0, 1.0,
MWBase::SoundManager::Play_TypeSfx, MWBase::SoundManager::Play_TypeSfx,
MWBase::SoundManager::Play_Loop); MWBase::SoundManager::Play_Loop);

View File

@ -1060,9 +1060,7 @@ namespace MWClass
bool Npc::hasToolTip (const MWWorld::Ptr& ptr) const bool Npc::hasToolTip (const MWWorld::Ptr& ptr) const
{ {
/// \todo We don't want tooltips for NPCs in combat mode. return !ptr.getClass().getCreatureStats(ptr).getAiSequence().isInCombat() || getCreatureStats(ptr).isDead();
return true;
} }
MWGui::ToolTipInfo Npc::getToolTipInfo (const MWWorld::Ptr& ptr) const MWGui::ToolTipInfo Npc::getToolTipInfo (const MWWorld::Ptr& ptr) const

View File

@ -22,6 +22,7 @@
#include "tradeitemmodel.hpp" #include "tradeitemmodel.hpp"
#include "countdialog.hpp" #include "countdialog.hpp"
#include "dialogue.hpp" #include "dialogue.hpp"
#include "controllers.hpp"
namespace namespace
{ {
@ -44,8 +45,6 @@ namespace MWGui
TradeWindow::TradeWindow() TradeWindow::TradeWindow()
: WindowBase("openmw_trade_window.layout") : WindowBase("openmw_trade_window.layout")
, mCurrentBalance(0) , mCurrentBalance(0)
, mBalanceButtonsState(BBS_None)
, mBalanceChangePause(0.0)
, mItemToSell(-1) , mItemToSell(-1)
, mTradeModel(NULL) , mTradeModel(NULL)
, mSortModel(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) void TradeWindow::onOfferButtonClicked(MyGUI::Widget* _sender)
{ {
TradeItemModel* playerItemModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel(); TradeItemModel* playerItemModel = MWBase::Environment::get().getWindowManager()->getInventoryWindow()->getTradeModel();
@ -407,23 +391,38 @@ namespace MWGui
updateLabels(); updateLabels();
} }
void TradeWindow::addRepeatController(MyGUI::Widget *widget)
{
MyGUI::ControllerItem* item = MyGUI::ControllerManager::getInstance().createItem(Controllers::ControllerRepeatClick::getClassTypeName());
Controllers::ControllerRepeatClick* controller = item->castType<Controllers::ControllerRepeatClick>();
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) void TradeWindow::onIncreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{ {
mBalanceButtonsState = BBS_Increase; addRepeatController(_sender);
mBalanceChangePause = sBalanceChangeInitialPause;
onIncreaseButtonTriggered(); onIncreaseButtonTriggered();
} }
void TradeWindow::onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) void TradeWindow::onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
{ {
mBalanceButtonsState = BBS_Decrease; addRepeatController(_sender);
mBalanceChangePause = sBalanceChangeInitialPause;
onDecreaseButtonTriggered(); 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) 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) void TradeWindow::onBalanceEdited(MyGUI::EditBox *_sender)
@ -436,6 +435,10 @@ namespace MWGui
} }
catch (std::bad_cast&) catch (std::bad_cast&)
{ {
if (_sender->getCaption().empty())
mTotalBalance->setCaption("0");
else
mTotalBalance->setCaption(boost::lexical_cast<std::string>(std::abs(mCurrentBalance)));
} }
} }
@ -460,16 +463,19 @@ namespace MWGui
mPlayerGold->setCaptionWithReplacing("#{sYourGold} " + boost::lexical_cast<std::string>(playerGold)); mPlayerGold->setCaptionWithReplacing("#{sYourGold} " + boost::lexical_cast<std::string>(playerGold));
std::string balanceCaption;
if (mCurrentBalance > 0) if (mCurrentBalance > 0)
{ {
mTotalBalanceLabel->setCaptionWithReplacing("#{sTotalSold}"); mTotalBalanceLabel->setCaptionWithReplacing("#{sTotalSold}");
mTotalBalance->setCaption(boost::lexical_cast<std::string>(mCurrentBalance)); balanceCaption = boost::lexical_cast<std::string>(mCurrentBalance);
} }
else else
{ {
mTotalBalanceLabel->setCaptionWithReplacing("#{sTotalCost}"); mTotalBalanceLabel->setCaptionWithReplacing("#{sTotalCost}");
mTotalBalance->setCaption(boost::lexical_cast<std::string>(-mCurrentBalance)); balanceCaption = boost::lexical_cast<std::string>(-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<std::string>(getMerchantGold())); mMerchantGold->setCaptionWithReplacing("#{sSellerGold} " + boost::lexical_cast<std::string>(getMerchantGold()));
} }

View File

@ -28,8 +28,6 @@ namespace MWGui
void startTrade(const MWWorld::Ptr& actor); void startTrade(const MWWorld::Ptr& actor);
void onFrame(float frameDuration);
void borrowItem (int index, size_t count); void borrowItem (int index, size_t count);
void returnItem (int index, size_t count); void returnItem (int index, size_t count);
@ -71,14 +69,6 @@ namespace MWGui
int mCurrentBalance; int mCurrentBalance;
int mCurrentMerchantOffer; 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 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 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 onDecreaseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id);
void onBalanceButtonReleased(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 onBalanceEdited(MyGUI::EditBox* _sender);
void onRepeatClick(MyGUI::Widget* widget, MyGUI::ControllerItem* controller);
void addRepeatController(MyGUI::Widget* widget);
void onIncreaseButtonTriggered(); void onIncreaseButtonTriggered();
void onDecreaseButtonTriggered(); void onDecreaseButtonTriggered();

View File

@ -848,7 +848,6 @@ namespace MWGui
mHud->onFrame(frameDuration); mHud->onFrame(frameDuration);
mTrainingWindow->onFrame (frameDuration); mTrainingWindow->onFrame (frameDuration);
mTradeWindow->onFrame(frameDuration);
mTrainingWindow->checkReferenceAvailable(); mTrainingWindow->checkReferenceAvailable();
mDialogueWindow->checkReferenceAvailable(); mDialogueWindow->checkReferenceAvailable();

View File

@ -498,7 +498,14 @@ namespace MWInput
void InputManager::keyPressed( const SDL_KeyboardEvent &arg ) 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); 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; bool consumed = false;
if (kc != OIS::KC_UNASSIGNED) if (kc != OIS::KC_UNASSIGNED)
@ -873,7 +880,7 @@ namespace MWInput
defaultKeyBindings[A_ToggleWeapon] = SDL_GetKeyFromScancode(SDL_SCANCODE_F); defaultKeyBindings[A_ToggleWeapon] = SDL_GetKeyFromScancode(SDL_SCANCODE_F);
defaultKeyBindings[A_ToggleSpell] = SDL_GetKeyFromScancode(SDL_SCANCODE_R); defaultKeyBindings[A_ToggleSpell] = SDL_GetKeyFromScancode(SDL_SCANCODE_R);
defaultKeyBindings[A_QuickKeysMenu] = SDL_GetKeyFromScancode(SDL_SCANCODE_F1); 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_Run] = SDL_GetKeyFromScancode(SDL_SCANCODE_LSHIFT);
defaultKeyBindings[A_Sneak] = SDL_GetKeyFromScancode(SDL_SCANCODE_LCTRL); defaultKeyBindings[A_Sneak] = SDL_GetKeyFromScancode(SDL_SCANCODE_LCTRL);
defaultKeyBindings[A_AutoMove] = SDL_GetKeyFromScancode(SDL_SCANCODE_Q); defaultKeyBindings[A_AutoMove] = SDL_GetKeyFromScancode(SDL_SCANCODE_Q);
@ -894,7 +901,7 @@ namespace MWInput
defaultKeyBindings[A_QuickKey10] = SDL_GetKeyFromScancode(SDL_SCANCODE_0); defaultKeyBindings[A_QuickKey10] = SDL_GetKeyFromScancode(SDL_SCANCODE_0);
defaultKeyBindings[A_Screenshot] = SDL_GetKeyFromScancode(SDL_SCANCODE_F12); defaultKeyBindings[A_Screenshot] = SDL_GetKeyFromScancode(SDL_SCANCODE_F12);
defaultKeyBindings[A_ToggleHUD] = SDL_GetKeyFromScancode(SDL_SCANCODE_F11); 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_QuickSave] = SDL_GetKeyFromScancode(SDL_SCANCODE_F5);
defaultKeyBindings[A_QuickLoad] = SDL_GetKeyFromScancode(SDL_SCANCODE_F9); defaultKeyBindings[A_QuickLoad] = SDL_GetKeyFromScancode(SDL_SCANCODE_F9);

View File

@ -1120,7 +1120,11 @@ namespace MWMechanics
{ {
updateActor(iter->first, duration); 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) if (timerUpdateAITargets == 0)
{ {

View File

@ -97,7 +97,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, ESM::Pathgrid::Po
MWWorld::Ptr door = getNearbyDoor(actor); MWWorld::Ptr door = getNearbyDoor(actor);
if(door != MWWorld::Ptr()) // NOTE: checks interior cells only if(door != MWWorld::Ptr()) // NOTE: checks interior cells only
{ {
if(door.getCellRef().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); MWBase::Environment::get().getWorld()->activateDoor(door, 1);
} }
} }

View File

@ -434,7 +434,8 @@ namespace MWMechanics
if (mSaidGreeting == Greet_None) 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)) && MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, actor))
mGreetingTimer++; mGreetingTimer++;

View File

@ -716,6 +716,7 @@ bool CharacterController::updateCreatureState()
0.0f, 0); 0.0f, 0);
mUpperBodyState = UpperCharState_StartToMinAttack; mUpperBodyState = UpperCharState_StartToMinAttack;
} }
stats.setAttackingOrSpell(false);
} }
bool animPlaying = mAnimation->getInfo(mCurrentWeapon); bool animPlaying = mAnimation->getInfo(mCurrentWeapon);
@ -911,6 +912,7 @@ bool CharacterController::updateWeaponState()
else if(mWeaponType == WeapType_PickProbe) else if(mWeaponType == WeapType_PickProbe)
{ {
MWWorld::Ptr item = *weapon; 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(); MWWorld::Ptr target = MWBase::Environment::get().getWorld()->getFacedObject();
std::string resultMessage, resultSound; std::string resultMessage, resultSound;

View File

@ -519,7 +519,7 @@ namespace MWMechanics
MWBase::Environment::get().getWorld()->explodeSpell(mHitPosition, effects, caster, mId, mSourceName); MWBase::Environment::get().getWorld()->explodeSpell(mHitPosition, effects, caster, mId, mSourceName);
if (!reflectedEffects.mList.empty()) if (!reflectedEffects.mList.empty())
inflict(caster, target, reflectedEffects, range, true); inflict(caster, target, reflectedEffects, range, true, exploded);
if (!appliedLastingEffects.empty()) if (!appliedLastingEffects.empty())
{ {

View File

@ -873,10 +873,13 @@ void Animation::play(const std::string &groupname, int priority, int groups, boo
mStates[groupname] = state; mStates[groupname] = state;
NifOgre::TextKeyMap::const_iterator textkey(textkeys.lower_bound(state.mTime)); 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); while(textkey != textkeys.end() && textkey->first <= state.mTime)
++textkey; {
handleTextKey(state, groupname, textkey, textkeys);
++textkey;
}
} }
if(state.mTime >= state.mLoopStopTime && state.mLoopCount > 0) 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) if(state.mTime >= state.mLoopStopTime)
break; 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) while(textkey != textkeys.end() && textkey->first <= state.mTime)
{ {
handleTextKey(state, groupname, textkey, textkeys); handleTextKey(state, groupname, textkey, textkeys);

View File

@ -148,7 +148,7 @@ namespace MWScript
// Instantly reset door to closed state // Instantly reset door to closed state
// This is done when using Lock in scripts, but not when using Lock spells. // 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()->activateDoor(ptr, 0);
MWBase::Environment::get().getWorld()->localRotateObject(ptr, 0, 0, 0); MWBase::Environment::get().getWorld()->localRotateObject(ptr, 0, 0, 0);
@ -871,7 +871,6 @@ namespace MWScript
{ {
MWBase::World* world = MWBase::Environment::get().getWorld(); MWBase::World* world = MWBase::Environment::get().getWorld();
world->goToJail(); world->goToJail();
MWBase::Environment::get().getWorld()->getPlayer().recordCrimeId();
} }
}; };

View File

@ -463,25 +463,26 @@ namespace MWScript
Interpreter::Type_Float zRot = runtime[0].mFloat; Interpreter::Type_Float zRot = runtime[0].mFloat;
runtime.pop(); runtime.pop();
int cx,cy; MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy); MWWorld::CellStore* store = NULL;
MWWorld::CellStore* store = MWBase::Environment::get().getWorld()->getExterior(cx,cy); if (player.getCell()->isExterior())
if(store)
{ {
ESM::Position pos; int cx,cy;
pos.pos[0] = x; MWBase::Environment::get().getWorld()->positionToIndex(x,y,cx,cy);
pos.pos[1] = y; store = MWBase::Environment::get().getWorld()->getExterior(cx,cy);
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);
} }
else else
{ store = player.getCell();
throw std::runtime_error ("unknown cell");
} 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);
} }
}; };

View File

@ -259,10 +259,6 @@ namespace MWWorld
void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) 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::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen();
Loading::ScopedLoad load(loadingListener); Loading::ScopedLoad load(loadingListener);
@ -362,7 +358,7 @@ namespace MWWorld
// Sky system // Sky system
MWBase::Environment::get().getWorld()->adjustSky(); MWBase::Environment::get().getWorld()->adjustSky();
mCellChanged = cellChanged; mCellChanged = true;
} }
//We need the ogre renderer and a scene node. //We need the ogre renderer and a scene node.

View File

@ -149,7 +149,7 @@ namespace MWWorld
mActivationDistanceOverride (activationDistanceOverride), mActivationDistanceOverride (activationDistanceOverride),
mFallback(fallbackMap), mTeleportEnabled(true), mLevitationEnabled(true), mFallback(fallbackMap), mTeleportEnabled(true), mLevitationEnabled(true),
mGodMode(false), mContentFiles (contentFiles), mGodMode(false), mContentFiles (contentFiles),
mGoToJail(false), mGoToJail(false), mDaysInPrison(0),
mStartCell (startCell), mStartupScript(startupScript) mStartCell (startCell), mStartupScript(startupScript)
{ {
mPhysics = new PhysicsSystem(renderer); mPhysics = new PhysicsSystem(renderer);
@ -259,7 +259,8 @@ namespace MWWorld
mWeatherManager = 0; mWeatherManager = 0;
mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback); mWeatherManager = new MWWorld::WeatherManager(mRendering,&mFallback);
MWBase::Environment::get().getWindowManager()->executeInConsole(mStartupScript); if (!mStartupScript.empty())
MWBase::Environment::get().getWindowManager()->executeInConsole(mStartupScript);
} }
void World::clear() void World::clear()
@ -2798,8 +2799,19 @@ namespace MWWorld
{ {
if (!mGoToJail) 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; 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<ESM::GameSetting>().find("iDaysinPrisonMod")->getInt();
mDaysInPrison = std::max(1, bounty / iDaysinPrisonMod);
return; return;
} }
else else
@ -2810,13 +2822,8 @@ namespace MWWorld
MWWorld::Ptr player = getPlayerPtr(); MWWorld::Ptr player = getPlayerPtr();
teleportToClosestMarker(player, "prisonmarker"); teleportToClosestMarker(player, "prisonmarker");
int bounty = player.getClass().getNpcStats(player).getBounty();
player.getClass().getNpcStats(player).setBounty(0);
confiscateStolenItems(player);
int iDaysinPrisonMod = getStore().get<ESM::GameSetting>().find("iDaysinPrisonMod")->getInt();
int days = std::max(1, bounty / iDaysinPrisonMod);
int days = mDaysInPrison;
advanceTime(days * 24); advanceTime(days * 24);
for (int i=0; i<days*24; ++i) for (int i=0; i<days*24; ++i)
MWBase::Environment::get().getMechanicsManager ()->rest (true); MWBase::Environment::get().getMechanicsManager ()->rest (true);

View File

@ -141,6 +141,7 @@ namespace MWWorld
bool mTeleportEnabled; bool mTeleportEnabled;
bool mLevitationEnabled; bool mLevitationEnabled;
bool mGoToJail; bool mGoToJail;
int mDaysInPrison;
float feetToGameUnits(float feet); float feetToGameUnits(float feet);
@ -474,6 +475,7 @@ namespace MWWorld
/// update movement state of a non-teleport door as specified /// update movement state of a non-teleport door as specified
/// @param state see MWClass::setDoorState /// @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 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 virtual bool getPlayerStandingOn (const MWWorld::Ptr& object); ///< @return true if the player is standing on \a object

View File

@ -89,6 +89,9 @@ namespace NifOgre
{ {
if(mDeltaInput) if(mDeltaInput)
{ {
if (mStopTime - mStartTime == 0.f)
return 0.f;
mDeltaCount += value*mFrequency; mDeltaCount += value*mFrequency;
if(mDeltaCount < mStartTime) if(mDeltaCount < mStartTime)
mDeltaCount = mStopTime - std::fmod(mStartTime - mDeltaCount, mDeltaCount = mStopTime - std::fmod(mStartTime - mDeltaCount,

View File

@ -60,6 +60,8 @@ num mipmaps = 8
shader mode = shader mode =
screenshot format = png
[Shadows] [Shadows]
# Shadows are only supported when object shaders are on! # Shadows are only supported when object shaders are on!
enabled = false enabled = false

View File

@ -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 /* Since Ogre uses narrow character interfaces, it does not support
Unicode paths on Windows. Therefore we had to implement screenshot 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()); mWindow->copyContentsToMemory(image.getPixelBox());
Ogre::DataStreamPtr stream = image.encode("png"); Ogre::DataStreamPtr stream = image.encode(imageFormat);
Ogre::MemoryDataStream *mem = dynamic_cast<Ogre::MemoryDataStream *>(stream.get()); Ogre::MemoryDataStream *mem = dynamic_cast<Ogre::MemoryDataStream *>(stream.get());
if (mem != 0) { // likely if (mem != 0) { // likely
const char *ptr = reinterpret_cast<char *>(mem->getCurrentPtr()); const char *ptr = reinterpret_cast<char *>(mem->getCurrentPtr());

View File

@ -108,7 +108,7 @@ namespace OEngine
void update(float dt); void update(float dt);
/// Write a screenshot to file /// Write a screenshot to file
void screenshot(const std::string &file); void screenshot(const std::string &file, const std::string& imageFormat);
float getFPS(); float getFPS();