Merge remote-tracking branch 'scrawl/master'

pull/263/head
Marc Zinnschlag 10 years ago
commit b5d5eadf79

@ -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)

@ -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

@ -463,6 +463,8 @@ namespace MWClass
if(getCreatureStats(ptr).isDead())
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));
}
@ -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

@ -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<DoorCustomData&>(*ptr.getRefData().getCustomData());
customData.mDoorState = state;

@ -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);

@ -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

@ -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<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)
{
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::string>(std::abs(mCurrentBalance)));
}
}
@ -460,16 +463,19 @@ namespace MWGui
mPlayerGold->setCaptionWithReplacing("#{sYourGold} " + boost::lexical_cast<std::string>(playerGold));
std::string balanceCaption;
if (mCurrentBalance > 0)
{
mTotalBalanceLabel->setCaptionWithReplacing("#{sTotalSold}");
mTotalBalance->setCaption(boost::lexical_cast<std::string>(mCurrentBalance));
balanceCaption = boost::lexical_cast<std::string>(mCurrentBalance);
}
else
{
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()));
}

@ -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();

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

@ -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);

@ -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)
{

@ -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);
}
}

@ -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++;

@ -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;

@ -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())
{

@ -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);

@ -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();
}
};

@ -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);
}
};

@ -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.

@ -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<ESM::GameSetting>().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<ESM::GameSetting>().find("iDaysinPrisonMod")->getInt();
int days = std::max(1, bounty / iDaysinPrisonMod);
int days = mDaysInPrison;
advanceTime(days * 24);
for (int i=0; i<days*24; ++i)
MWBase::Environment::get().getMechanicsManager ()->rest (true);

@ -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

@ -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,

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

@ -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<Ogre::MemoryDataStream *>(stream.get());
if (mem != 0) { // likely
const char *ptr = reinterpret_cast<char *>(mem->getCurrentPtr());

@ -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();

Loading…
Cancel
Save