merge
actorid
graffy76 11 years ago
commit b94466dbb4

@ -11,8 +11,6 @@
#include <QFile>
#include <QSortFilterProxyModel>
#include <QDebug>
#include <components/files/configurationmanager.hpp>
#include <boost/version.hpp>
@ -263,13 +261,11 @@ void CSMSettings::UserSettings::saveSettings
QString CSMSettings::UserSettings::settingValue (const QString &settingKey)
{
QStringList names = settingKey.split('.');
qDebug () << "looking for " << names.at(0) << ',' << names.at(1);
Setting *setting = findSetting(names.at(0), names.at(1));
if (setting)
{
qDebug() << "setting found";
if (!setting->definedValues().isEmpty())
return setting->definedValues().at(0);
}

@ -59,9 +59,6 @@ void OMW::Engine::executeLocalScripts()
MWScript::InterpreterContext interpreterContext (
&script.second.getRefData().getLocals(), script.second);
MWBase::Environment::get().getScriptManager()->run (script.first, interpreterContext);
if (MWBase::Environment::get().getWorld()->hasCellChanged())
break;
}
localScripts.setIgnore (MWWorld::Ptr());
@ -101,15 +98,10 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
// global scripts
MWBase::Environment::get().getScriptManager()->getGlobalScripts().run();
bool changed = MWBase::Environment::get().getWorld()->hasCellChanged();
// local scripts
executeLocalScripts(); // This does not handle the case where a global script causes a
// cell change, followed by a cell change in a local script during
// the same frame.
executeLocalScripts();
if (changed) // keep change flag for another frame, if cell changed happened in local script
MWBase::Environment::get().getWorld()->markCellAsUnchanged();
MWBase::Environment::get().getWorld()->markCellAsUnchanged();
if (!paused)
MWBase::Environment::get().getWorld()->advanceTime(

@ -45,9 +45,6 @@ namespace MWBase
virtual void goodbye() = 0;
virtual MWWorld::Ptr getActor() const = 0;
///< Return the actor the player is currently talking to.
virtual void say(const MWWorld::Ptr &actor, const std::string &topic) const = 0;
//calbacks for the GUI

@ -160,10 +160,16 @@ namespace MWBase
virtual bool isAIActive() = 0;
virtual void getObjectsInRange (const Ogre::Vector3& position, float radius, std::vector<MWWorld::Ptr>& objects) = 0;
virtual void getActorsInRange(const Ogre::Vector3 &position, float radius, std::vector<MWWorld::Ptr> &objects) = 0;
///return the list of actors which are following the given actor (ie AiFollow is active and the target is the actor)
///return the list of actors which are following the given actor
/**ie AiFollow is active and the target is the actor**/
virtual std::list<MWWorld::Ptr> getActorsFollowing(const MWWorld::Ptr& actor) = 0;
///Returns a list of actors who are fighting the given actor within the fAlarmDistance
/** ie AiCombat is active and the target is the actor **/
virtual std::list<MWWorld::Ptr> getActorsFighting(const MWWorld::Ptr& actor) = 0;
virtual void playerLoaded() = 0;
};
}

@ -65,6 +65,14 @@ namespace MWBase
///
/// \note \a slot must belong to \a character.
///Simple saver, writes over the file if already existing
/** Used for quick save and autosave **/
virtual void quickSave(std::string = "Quicksave")=0;
///Simple loader, loads the last saved file
/** Used for quickload **/
virtual void quickLoad()=0;
virtual MWState::Character *getCurrentCharacter (bool create = true) = 0;
///< \param create Create a new character, if there is no current character.

@ -111,7 +111,7 @@ namespace MWClass
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
MWWorld::InventoryStore& invStore = MWWorld::Class::get(player).getInventoryStore(player);
bool needKey = ptr.getCellRef().mLockLevel>0;
bool needKey = ptr.getCellRef().mLockLevel > 0;
bool hasKey = false;
std::string keyName;
@ -132,7 +132,7 @@ namespace MWClass
if (needKey && hasKey)
{
MWBase::Environment::get().getWindowManager ()->messageBox (keyName + " #{sKeyUsed}");
ptr.getCellRef().mLockLevel = 0;
unlock(ptr);
// using a key disarms the trap
ptr.getCellRef().mTrap = "";
}
@ -211,6 +211,8 @@ namespace MWClass
std::string text;
if (ref->mRef.mLockLevel > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel);
else if (ref->mRef.mLockLevel < 0)
text += "\n#{sUnlocked}";
if (ref->mRef.mTrap != "")
text += "\n#{sTrapped}";
@ -240,17 +242,18 @@ namespace MWClass
void Container::lock (const MWWorld::Ptr& ptr, int lockLevel) const
{
if (lockLevel<0)
lockLevel = 0;
ptr.getCellRef().mLockLevel = lockLevel;
if(lockLevel!=0)
ptr.getCellRef().mLockLevel = abs(lockLevel); //Changes lock to locklevel, in positive
else
ptr.getCellRef().mLockLevel = abs(ptr.getCellRef().mLockLevel); //No locklevel given, just flip the oriional one
}
void Container::unlock (const MWWorld::Ptr& ptr) const
{
ptr.getCellRef().mLockLevel = 0;
ptr.getCellRef().mLockLevel = -abs(ptr.getCellRef().mLockLevel); //Makes lockLevel negative
}
MWWorld::Ptr
Container::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const
{

@ -48,7 +48,7 @@ namespace MWClass
///< Returns total weight of objects inside this object (including modifications from magic
/// effects). Throws an exception, if the object can't hold other objects.
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const;
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel = 0) const;
///< Lock object
virtual void unlock (const MWWorld::Ptr& ptr) const;

@ -76,7 +76,7 @@ namespace MWClass
MWWorld::ContainerStore &invStore = get(actor).getContainerStore(actor);
bool needKey = ptr.getCellRef().mLockLevel>0;
bool needKey = ptr.getCellRef().mLockLevel > 0;
bool hasKey = false;
std::string keyName;
@ -98,7 +98,7 @@ namespace MWClass
{
if(actor == MWBase::Environment::get().getWorld()->getPlayerPtr())
MWBase::Environment::get().getWindowManager()->messageBox(keyName + " #{sKeyUsed}");
ptr.getCellRef().mLockLevel = 0;
unlock(ptr); //Call the function here. because that makes sense.
// using a key disarms the trap
ptr.getCellRef().mTrap = "";
}
@ -158,15 +158,15 @@ namespace MWClass
void Door::lock (const MWWorld::Ptr& ptr, int lockLevel) const
{
if (lockLevel<0)
lockLevel = 0;
ptr.getCellRef().mLockLevel = lockLevel;
if(lockLevel!=0)
ptr.getCellRef().mLockLevel = abs(lockLevel); //Changes lock to locklevel, in positive
else
ptr.getCellRef().mLockLevel = abs(ptr.getCellRef().mLockLevel); //No locklevel given, just flip the origional one
}
void Door::unlock (const MWWorld::Ptr& ptr) const
{
ptr.getCellRef().mLockLevel = 0;
ptr.getCellRef().mLockLevel = -abs(ptr.getCellRef().mLockLevel); //Makes lockLevel negative
}
std::string Door::getScript (const MWWorld::Ptr& ptr) const
@ -210,6 +210,8 @@ namespace MWClass
if (ref->mRef.mLockLevel > 0)
text += "\n#{sLockLevel}: " + MWGui::ToolTips::toString(ref->mRef.mLockLevel);
else if (ref->mRef.mLockLevel < 0)
text += "\n#{sUnlocked}";
if (ref->mRef.mTrap != "")
text += "\n#{sTrapped}";

@ -36,7 +36,7 @@ namespace MWClass
static std::string getDestination (const MWWorld::LiveCellRef<ESM::Door>& door);
///< @return destination cell name or token
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel) const;
virtual void lock (const MWWorld::Ptr& ptr, int lockLevel = 0) const;
///< Lock object
virtual void unlock (const MWWorld::Ptr& ptr) const;
@ -48,6 +48,7 @@ namespace MWClass
static void registerSelf();
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
private:
};
}

@ -468,11 +468,6 @@ namespace MWDialogue
mIsInChoice = true;
}
MWWorld::Ptr DialogueManager::getActor() const
{
return mActor;
}
void DialogueManager::goodbye()
{
mIsInChoice = true;

@ -68,9 +68,6 @@ namespace MWDialogue
virtual void goodbye();
virtual MWWorld::Ptr getActor() const;
///< Return the actor the player is currently talking to.
virtual bool checkServiceRefused ();
virtual void say(const MWWorld::Ptr &actor, const std::string &topic) const;

@ -111,8 +111,14 @@ bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const
// check cell
if (!info.mCell.empty())
if (!Misc::StringUtils::ciEqual(player.getCell()->getCell()->mName, info.mCell))
{
// supports partial matches, just like getPcCell
const std::string& playerCell = player.getCell()->getCell()->mName;
bool match = playerCell.length()>=info.mCell.length() &&
Misc::StringUtils::ciEqual(playerCell.substr (0, info.mCell.length()), info.mCell);
if (!match)
return false;
}
return true;
}

@ -52,7 +52,7 @@ namespace MWGui
, mWeaponVisible(true)
, mSpellVisible(true)
, mWorldMouseOver(false)
, mEnemyHealthTimer(0)
, mEnemyHealthTimer(-1)
, mIsDrowning(false)
, mWeaponSpellTimer(0.f)
, mDrowningFlashTheta(0.f)
@ -639,4 +639,10 @@ namespace MWGui
updateEnemyHealthBar();
}
void HUD::resetEnemy()
{
mEnemy = MWWorld::Ptr();
mEnemyHealthTimer = -1;
}
}

@ -56,6 +56,7 @@ namespace MWGui
void update();
void setEnemy(const MWWorld::Ptr& enemy);
void resetEnemy();
private:
MyGUI::ProgressBar *mHealth, *mMagicka, *mStamina, *mEnemyHealth, *mDrowning;

@ -14,6 +14,8 @@
#include "../mwrender/globalmap.hpp"
#include "../components/esm/globalmap.hpp"
#include "widgets.hpp"
namespace MWGui
@ -436,7 +438,6 @@ namespace MWGui
worldY * mGlobalMapRender->getHeight()+6,
12, 12);
static int _counter=0;
MyGUI::Button* markerWidget = mGlobalMapOverlay->createWidget<MyGUI::Button>("ButtonImage",
widgetCoord, MyGUI::Align::Default, "Door" + boost::lexical_cast<std::string>(_counter));
@ -452,6 +453,11 @@ namespace MWGui
markerWidget->setUserString("ToolTipType", "Layout");
markerWidget->setUserString("ToolTipLayout", "TextToolTipOneLine");
markerWidget->setUserString("Caption_TextOneLine", name);
CellId cell;
cell.first = x;
cell.second = y;
mMarkers.push_back(cell);
}
void MapWindow::cellExplored(int x, int y)
@ -580,6 +586,7 @@ namespace MWGui
void MapWindow::clear()
{
mMarkers.clear();
mGlobalMapRender->clear();
while (mEventBoxGlobal->getChildCount())
@ -590,19 +597,31 @@ namespace MWGui
void MapWindow::write(ESM::ESMWriter &writer)
{
mGlobalMapRender->write(writer);
ESM::GlobalMap map;
mGlobalMapRender->write(map);
map.mMarkers = mMarkers;
writer.startRecord(ESM::REC_GMAP);
map.save(writer);
writer.endRecord(ESM::REC_GMAP);
}
void MapWindow::readRecord(ESM::ESMReader &reader, int32_t type)
{
std::vector<std::pair<int, int> > exploredCells;
mGlobalMapRender->readRecord(reader, type, exploredCells);
for (std::vector<std::pair<int, int> >::iterator it = exploredCells.begin(); it != exploredCells.end(); ++it)
if (type == ESM::REC_GMAP)
{
const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Cell>().search(it->first, it->second);
if (cell && !cell->mName.empty())
addVisitedLocation(cell->mName, it->first, it->second);
ESM::GlobalMap map;
map.load(reader);
mGlobalMapRender->read(map);
for (std::vector<ESM::GlobalMap::CellId>::iterator it = map.mMarkers.begin(); it != map.mMarkers.end(); ++it)
{
const ESM::Cell* cell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Cell>().search(it->first, it->second);
if (cell && !cell->mName.empty())
addVisitedLocation(cell->mName, it->first, it->second);
}
}
}
}

@ -55,6 +55,9 @@ namespace MWGui
bool mChanged;
bool mFogOfWar;
typedef std::pair<int, int> CellId;
std::vector<CellId> mMarkers;
std::vector<MyGUI::ImageBox*> mMapWidgets;
std::vector<MyGUI::ImageBox*> mFogWidgets;

@ -325,7 +325,6 @@ namespace MWGui
}
store.setSelectedEnchantItem(it);
MWBase::Environment::get().getWindowManager()->setSelectedEnchantItem(item);
}
}

@ -322,7 +322,6 @@ namespace MWGui
}
store.setSelectedEnchantItem(it);
MWBase::Environment::get().getWindowManager()->setSelectedEnchantItem(item);
updateSpells();
}

@ -8,6 +8,7 @@
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/statemanager.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/cellstore.hpp"
@ -15,6 +16,7 @@
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "../mwstate/charactermanager.hpp"
namespace MWGui
{
@ -119,6 +121,8 @@ namespace MWGui
MWBase::World* world = MWBase::Environment::get().getWorld();
world->getFader ()->fadeOut(0.2);
setVisible(false);
if(Settings::Manager::getBool("autosave","Saves") && mSleeping) //autosaves when enabled and sleeping (Not resting, apparently)
MWBase::Environment::get().getStateManager()->quickSave("Autosave");
mProgressBar.setVisible (true);
mWaiting = true;
@ -238,6 +242,7 @@ namespace MWGui
}
}
void WaitDialog::wakeUp ()
{
mSleeping = false;

@ -34,6 +34,7 @@ namespace MWGui
bool getSleeping() { return mWaiting && mSleeping; }
void wakeUp();
void autosave();
protected:
MyGUI::TextBox* mDateTimeText;

@ -187,7 +187,7 @@ namespace MWGui
MyGUI::InputManager::getInstance().eventChangeKeyFocus += MyGUI::newDelegate(this, &WindowManager::onKeyFocusChanged);
onCursorChange(MyGUI::PointerManager::getInstance().getDefaultPointer());
SDL_ShowCursor(false);
//SDL_ShowCursor(false);
mCursorManager->setEnabled(true);
@ -289,6 +289,10 @@ namespace MWGui
void WindowManager::setNewGame(bool newgame)
{
// This method will always be called after loading a savegame or starting a new game
// Reset enemy, it could be a dangling pointer from a previous game
mHud->resetEnemy();
if (newgame)
{
disallowAll();

@ -19,6 +19,7 @@
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/statemanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwworld/player.hpp"
#include "../mwworld/class.hpp"
@ -113,6 +114,7 @@ namespace MWInput
, mTimeIdle(0.f)
, mOverencumberedMessageDelay(0.f)
, mAlwaysRunActive(false)
, mControlsDisabled(false)
{
Ogre::RenderWindow* window = ogre.getWindow ();
@ -252,25 +254,32 @@ namespace MWInput
case A_ToggleHUD:
MWBase::Environment::get().getWindowManager()->toggleHud();
break;
case A_QuickSave:
quickSave();
break;
case A_QuickLoad:
quickLoad();
break;
}
}
}
void InputManager::update(float dt, bool disableControls, bool disableEvents)
{
mControlsDisabled = disableControls;
mInputManager->setMouseVisible(MWBase::Environment::get().getWindowManager()->getCursorVisible());
mInputManager->capture(disableEvents);
// inject some fake mouse movement to force updating MyGUI's widget states
MyGUI::InputManager::getInstance().injectMouseMove( int(mMouseX), int(mMouseY), mMouseWheel);
// update values of channels (as a result of pressed keys)
if (!disableControls)
mInputBinder->update(dt);
if (disableControls)
if (mControlsDisabled)
return;
// update values of channels (as a result of pressed keys)
mInputBinder->update(dt);
bool grab = !MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu)
&& MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Console;
@ -477,7 +486,7 @@ namespace MWInput
if (text)
{
edit->addText(MyGUI::UString(text));
edit->insertText(MyGUI::UString(text), edit->getTextCursor());
SDL_free(text);
}
}
@ -502,7 +511,8 @@ namespace MWInput
}
}
mInputBinder->keyPressed (arg);
if (!mControlsDisabled)
mInputBinder->keyPressed (arg);
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
@ -638,6 +648,13 @@ namespace MWInput
}
}
void InputManager::quickLoad() {
MWBase::Environment::get().getStateManager()->quickLoad();
}
void InputManager::quickSave() {
MWBase::Environment::get().getStateManager()->quickSave();
}
void InputManager::toggleSpell()
{
if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return;
@ -679,8 +696,12 @@ namespace MWInput
if (!MWBase::Environment::get().getWindowManager()->getRestEnabled () || MWBase::Environment::get().getWindowManager()->isGuiMode ())
return;
/// \todo check if resting is currently allowed (enemies nearby?)
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_Rest);
if(mPlayer->isInCombat()) {//Check if in combat
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage2}"); //Nope,
return;
}
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_Rest); //Open rest GUI
}
void InputManager::screenshot()
@ -842,6 +863,8 @@ namespace MWInput
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_QuickSave] = SDL_GetKeyFromScancode(SDL_SCANCODE_F5);
defaultKeyBindings[A_QuickLoad] = SDL_GetKeyFromScancode(SDL_SCANCODE_F9);
std::map<int, int> defaultMouseButtonBindings;
defaultMouseButtonBindings[A_Inventory] = SDL_BUTTON_RIGHT;
@ -918,6 +941,8 @@ namespace MWInput
descriptions[A_QuickKey9] = "sQuick9Cmd";
descriptions[A_QuickKey10] = "sQuick10Cmd";
descriptions[A_AlwaysRun] = "sAlways_Run";
descriptions[A_QuickSave] = "sQuickSaveCmd";
descriptions[A_QuickLoad] = "sQuickLoadCmd";
if (descriptions[action] == "")
return ""; // not configurable
@ -961,6 +986,8 @@ namespace MWInput
ret.push_back(A_Journal);
ret.push_back(A_Rest);
ret.push_back(A_Console);
ret.push_back(A_QuickSave);
ret.push_back(A_QuickLoad);
ret.push_back(A_Screenshot);
ret.push_back(A_QuickKeysMenu);
ret.push_back(A_QuickKey1);

@ -68,7 +68,7 @@ namespace MWInput
/// Clear all savegame-specific data
virtual void clear();
virtual void update(float dt, bool disableControls, bool disableEvents=false);
virtual void update(float dt, bool disableControls=false, bool disableEvents=false);
void setPlayer (MWWorld::Player* player) { mPlayer = player; }
@ -145,6 +145,8 @@ namespace MWInput
bool mInvertY;
bool mControlsDisabled;
float mCameraSensitivity;
float mUISensitivity;
float mCameraYMultiplier;
@ -183,6 +185,8 @@ namespace MWInput
void toggleWalking();
void toggleAutoMove();
void rest();
void quickLoad();
void quickSave();
void quickKey (int index);
void showQuickKeysMenu();

@ -176,7 +176,7 @@ namespace MWMechanics
adjustMagicEffects (ptr);
if (ptr.getClass().getCreatureStats(ptr).needToRecalcDynamicStats())
calculateDynamicStats (ptr);
calculateCreatureStatModifiers (ptr, duration);
// AI
@ -764,7 +764,7 @@ namespace MWMechanics
creatureStats.setHostile(false);
creatureStats.setAttacked(false);
creatureStats.setAlarmed(false);
// Update witness crime id
npcStats.setCrimeId(-1);
}
@ -1038,4 +1038,26 @@ namespace MWMechanics
}
return list;
}
std::list<MWWorld::Ptr> Actors::getActorsFighting(const MWWorld::Ptr& actor) {
std::list<MWWorld::Ptr> list;
std::vector<MWWorld::Ptr> neighbors;
Ogre::Vector3 position = Ogre::Vector3(actor.getRefData().getPosition().pos);
getObjectsInRange(position,
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fAlarmRadius")->getFloat(),
neighbors); //only care about those within the alarm disance
for(std::vector<MWWorld::Ptr>::iterator iter(neighbors.begin());iter != neighbors.end();iter++)
{
const MWWorld::Class &cls = MWWorld::Class::get(*iter);
CreatureStats &stats = cls.getCreatureStats(*iter);
if(stats.getAiSequence().getTypeId() == AiPackage::TypeIdCombat)
{
MWMechanics::AiCombat* package = static_cast<MWMechanics::AiCombat*>(stats.getAiSequence().getActivePackage());
if(package->getTargetId() == actor.getCellRef().mRefID)
list.push_front(*iter);
}
}
return list;
}
}

@ -98,8 +98,13 @@ namespace MWMechanics
void getObjectsInRange(const Ogre::Vector3& position, float radius, std::vector<MWWorld::Ptr>& out);
///Returns the list of actors which are following the given actor
/**ie AiFollow is active and the target is the actor **/
std::list<MWWorld::Ptr> getActorsFollowing(const MWWorld::Ptr& actor);
///<return the list of actors which are following the given actor (ie AiFollow is active and the target is the actor)
///Returns the list of actors which are fighting the given actor
/**ie AiCombat is active and the target is the actor **/
std::list<MWWorld::Ptr> getActorsFighting(const MWWorld::Ptr& actor);
private:
PtrControllerMap mActors;

@ -8,6 +8,7 @@
#include "steering.hpp"
#include "movement.hpp"
#include "creaturestats.hpp"
namespace MWMechanics
{
@ -30,6 +31,8 @@ namespace MWMechanics
Movement &movement = actor.getClass().getMovementSettings(actor);
const ESM::Cell *cell = actor.getCell()->getCell();
actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, false);
MWWorld::Ptr player = world->getPlayerPtr();
if(cell->mData.mX != player.getCell()->getCell()->mData.mX)
{

@ -740,10 +740,6 @@ bool CharacterController::updateWeaponState()
MWBase::Environment::get().getWindowManager()->messageBox(resultMessage);
if(!resultSound.empty())
MWBase::Environment::get().getSoundManager()->playSound(resultSound, 1.0f, 1.0f);
// Set again, just to update the charge bar
if(item.getRefData().getCount())
MWBase::Environment::get().getWindowManager()->setSelectedWeapon(item);
}
else if (ammunition)
{

@ -325,6 +325,19 @@ namespace MWMechanics
winMgr->updateSkillArea();
winMgr->setValue("level", stats.getLevel());
// Update the equipped weapon icon
MWWorld::InventoryStore& inv = mWatched.getClass().getInventoryStore(mWatched);
MWWorld::ContainerStoreIterator weapon = inv.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
if (weapon == inv.end())
winMgr->unsetSelectedWeapon();
else
winMgr->setSelectedWeapon(*weapon);
// Update the selected spell icon
MWWorld::ContainerStoreIterator enchantItem = inv.getSelectedEnchantItem();
if (enchantItem != inv.end())
winMgr->setSelectedEnchantItem(*enchantItem);
}
if (mUpdatePlayer)
@ -772,6 +785,11 @@ namespace MWMechanics
bool MechanicsManager::sleepInBed(const MWWorld::Ptr &ptr, const MWWorld::Ptr &bed)
{
if(MWBase::Environment::get().getWorld()->getPlayer().isInCombat()) {
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage2}");
return true;
}
MWWorld::Ptr victim;
if (isAllowedToUse(ptr, bed, victim))
return false;
@ -832,17 +850,17 @@ namespace MWMechanics
// Find all the NPCs within the alarm radius
std::vector<MWWorld::Ptr> neighbors;
mActors.getObjectsInRange(Ogre::Vector3(ptr.getRefData().getPosition().pos),
mActors.getObjectsInRange(Ogre::Vector3(ptr.getRefData().getPosition().pos),
esmStore.get<ESM::GameSetting>().find("fAlarmRadius")->getInt(), neighbors);
// Find an actor who witnessed the crime
for (std::vector<MWWorld::Ptr>::iterator it = neighbors.begin(); it != neighbors.end(); ++it)
{
{
if (*it == ptr) continue; // not the player
// Was the crime seen?
if ( ( MWBase::Environment::get().getWorld()->getLOS(ptr, *it) && awarenessCheck(ptr, *it) ) ||
type == OT_Assault )
type == OT_Assault )
{
// Will the witness report the crime?
@ -853,7 +871,7 @@ namespace MWMechanics
// Tell everyone, including yourself
for (std::vector<MWWorld::Ptr>::iterator it1 = neighbors.begin(); it1 != neighbors.end(); ++it1)
{
{
if (*it1 == ptr) continue; // not the player
// TODO: Add more messages
@ -861,9 +879,9 @@ namespace MWMechanics
MWBase::Environment::get().getDialogueManager()->say(*it1, "thief");
else if (type == OT_Assault)
MWBase::Environment::get().getDialogueManager()->say(*it1, "attack");
// Will other witnesses paticipate in crime
if ( it1->getClass().getCreatureStats(*it1).getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm
if ( it1->getClass().getCreatureStats(*it1).getAiSetting(CreatureStats::AI_Alarm).getBase() >= alarm
|| type == OT_Assault )
{
it1->getClass().getNpcStats(*it1).setCrimeId(id);
@ -884,7 +902,7 @@ namespace MWMechanics
void MechanicsManager::reportCrime(const MWWorld::Ptr &ptr, const MWWorld::Ptr &victim, OffenseType type, int arg)
{
const MWWorld::Store<ESM::GameSetting>& store = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
// Bounty for each type of crime
if (type == OT_Trespassing || type == OT_SleepingInOwnedBed)
arg = store.find("iCrimeTresspass")->getInt();
@ -989,8 +1007,17 @@ namespace MWMechanics
mObjects.getObjectsInRange(position, radius, objects);
}
void MechanicsManager::getActorsInRange(const Ogre::Vector3 &position, float radius, std::vector<MWWorld::Ptr> &objects)
{
mActors.getObjectsInRange(position, radius, objects);
}
std::list<MWWorld::Ptr> MechanicsManager::getActorsFollowing(const MWWorld::Ptr& actor)
{
return mActors.getActorsFollowing(actor);
}
std::list<MWWorld::Ptr> MechanicsManager::getActorsFighting(const MWWorld::Ptr& actor) {
return mActors.getActorsFighting(actor);
}
}

@ -120,7 +120,7 @@ namespace MWMechanics
/// Utility to check if opening (i.e. unlocking) this object is illegal and calling commitCrime if so
virtual void objectOpened (const MWWorld::Ptr& ptr, const MWWorld::Ptr& item);
/// Attempt sleeping in a bed. If this is illegal, call commitCrime.
/// @return was it illegal, and someone saw you doing it?
/// @return was it illegal, and someone saw you doing it? Also returns fail when enemies are nearby
virtual bool sleepInBed (const MWWorld::Ptr& ptr, const MWWorld::Ptr& bed);
virtual void forceStateUpdate(const MWWorld::Ptr &ptr);
@ -134,9 +134,12 @@ namespace MWMechanics
virtual void updateMagicEffects (const MWWorld::Ptr& ptr);
virtual void getObjectsInRange (const Ogre::Vector3& position, float radius, std::vector<MWWorld::Ptr>& objects);
virtual void getActorsInRange(const Ogre::Vector3 &position, float radius, std::vector<MWWorld::Ptr> &objects);
virtual std::list<MWWorld::Ptr> getActorsFollowing(const MWWorld::Ptr& actor);
virtual std::list<MWWorld::Ptr> getActorsFighting(const MWWorld::Ptr& actor);
virtual bool toggleAI();
virtual bool isAIActive();

@ -491,7 +491,7 @@ void MWMechanics::NpcStats::readState (const ESM::NpcStats& state)
if (iter->second.mExpelled)
mExpelled.insert (iter->first);
if (iter->second.mRank)
if (iter->second.mRank >= 0)
mFactionRank.insert (std::make_pair (iter->first, iter->second.mRank));
if (iter->second.mReputation)

@ -29,7 +29,7 @@ namespace MWMechanics
void Security::pickLock(const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick,
std::string& resultMessage, std::string& resultSound)
{
if (lock.getCellRef().mLockLevel <= 0)
if (!(lock.getCellRef().mLockLevel > 0)) //If it's unlocked back out immediately
return;
int lockStrength = lock.getCellRef().mLockLevel;

@ -420,19 +420,20 @@ namespace MWMechanics
{
if (effectId == ESM::MagicEffect::Lock)
{
if (target.getCellRef().mLockLevel < magnitude)
if (target.getCellRef().mLockLevel < magnitude) //If the door is not already locked to a higher value, lock it to spell magnitude
target.getCellRef().mLockLevel = magnitude;
}
else if (effectId == ESM::MagicEffect::Open)
{
if (target.getCellRef().mLockLevel <= magnitude)
{
//Door not already unlocked
if (target.getCellRef().mLockLevel > 0)
{
MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock", 1.f, 1.f);
MWBase::Environment::get().getMechanicsManager()->objectOpened(caster, target);
}
target.getCellRef().mLockLevel = 0;
target.getCellRef().mLockLevel = -abs(target.getCellRef().mLockLevel); //unlocks the door
}
else
MWBase::Environment::get().getSoundManager()->playSound3D(target, "Open Lock Fail", 1.f, 1.f);
@ -574,7 +575,6 @@ namespace MWMechanics
{
if (mCaster.getRefData().getHandle() == "player")
{
MWBase::Environment::get().getWindowManager()->setSelectedEnchantItem(item); // Set again to show the modified charge
mCaster.getClass().skillUsageSucceeded (mCaster, ESM::Skill::Enchant, 3);
}
}

@ -231,9 +231,8 @@ namespace MWRender
mOverlayTexture->getBuffer()->blitFromMemory(pb);
}
void GlobalMap::write(ESM::ESMWriter &writer)
void GlobalMap::write(ESM::GlobalMap& map)
{
ESM::GlobalMap map;
map.mBounds.mMinX = mMinX;
map.mBounds.mMaxX = mMaxX;
map.mBounds.mMinY = mMinY;
@ -244,95 +243,68 @@ namespace MWRender
Ogre::DataStreamPtr encoded = image.encode("png");
map.mImageData.resize(encoded->size());
encoded->read(&map.mImageData[0], encoded->size());
writer.startRecord(ESM::REC_GMAP);
map.save(writer);
writer.endRecord(ESM::REC_GMAP);
}
void GlobalMap::readRecord(ESM::ESMReader &reader, int32_t type, std::vector<std::pair<int, int> >& exploredCells)
void GlobalMap::read(ESM::GlobalMap& map)
{
if (type == ESM::REC_GMAP)
{
ESM::GlobalMap map;
map.load(reader);
const ESM::GlobalMap::Bounds& bounds = map.mBounds;
if (bounds.mMaxX-bounds.mMinX <= 0)
return;
if (bounds.mMaxY-bounds.mMinY <= 0)
return;
if (bounds.mMinX > bounds.mMaxX
|| bounds.mMinY > bounds.mMaxY)
throw std::runtime_error("invalid map bounds");
const ESM::GlobalMap::Bounds& bounds = map.mBounds;
Ogre::Image image;
Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream(&map.mImageData[0], map.mImageData.size()));
image.load(stream, "png");
int xLength = (bounds.mMaxX-bounds.mMinX+1);
int yLength = (bounds.mMaxY-bounds.mMinY+1);
// Size of one cell in image space
int cellImageSizeSrc = image.getWidth() / xLength;
if (int(image.getHeight() / yLength) != cellImageSizeSrc)
throw std::runtime_error("cell size must be quadratic");
// Determine which cells were explored by reading the image data
for (int x=0; x < xLength; ++x)
{
for (int y=0; y < yLength; ++y)
{
unsigned int imageX = (x) * cellImageSizeSrc;
// NB y + 1, because we want the top left corner, not bottom left where the origin of the cell is
unsigned int imageY = (yLength - (y + 1)) * cellImageSizeSrc;
if (bounds.mMaxX-bounds.mMinX <= 0)
return;
if (bounds.mMaxY-bounds.mMinY <= 0)
return;
assert(imageX < image.getWidth());
assert(imageY < image.getHeight());
if (bounds.mMinX > bounds.mMaxX
|| bounds.mMinY > bounds.mMaxY)
throw std::runtime_error("invalid map bounds");
if (image.getColourAt(imageX, imageY, 0).a > 0)
exploredCells.push_back(std::make_pair(x+bounds.mMinX,y+bounds.mMinY));
}
}
Ogre::Image image;
Ogre::DataStreamPtr stream(new Ogre::MemoryDataStream(&map.mImageData[0], map.mImageData.size()));
image.load(stream, "png");
int xLength = (bounds.mMaxX-bounds.mMinX+1);
int yLength = (bounds.mMaxY-bounds.mMinY+1);
// Size of one cell in image space
int cellImageSizeSrc = image.getWidth() / xLength;
if (int(image.getHeight() / yLength) != cellImageSizeSrc)
throw std::runtime_error("cell size must be quadratic");
// If cell bounds of the currently loaded content and the loaded savegame do not match,
// we need to resize source/dest boxes to accommodate
// This means nonexisting cells will be dropped silently
int cellImageSizeDst = 24;
// Completely off-screen? -> no need to blit anything
if (bounds.mMaxX < mMinX
|| bounds.mMaxY < mMinY
|| bounds.mMinX > mMaxX
|| bounds.mMinY > mMaxY)
return;
// If cell bounds of the currently loaded content and the loaded savegame do not match,
// we need to resize source/dest boxes to accommodate
// This means nonexisting cells will be dropped silently
int cellImageSizeDst = 24;
// Completely off-screen? -> no need to blit anything
if (bounds.mMaxX < mMinX
|| bounds.mMaxY < mMinY
|| bounds.mMinX > mMaxX
|| bounds.mMinY > mMaxY)
return;
int leftDiff = (mMinX - bounds.mMinX);
int topDiff = (bounds.mMaxY - mMaxY);
int rightDiff = (bounds.mMaxX - mMaxX);
int bottomDiff = (mMinY - bounds.mMinY);
Ogre::Image::Box srcBox ( std::max(0, leftDiff * cellImageSizeSrc),
std::max(0, topDiff * cellImageSizeSrc),
std::min(image.getWidth(), image.getWidth() - rightDiff * cellImageSizeSrc),
std::min(image.getHeight(), image.getHeight() - bottomDiff * cellImageSizeSrc));
Ogre::Image::Box destBox ( std::max(0, -leftDiff * cellImageSizeDst),
std::max(0, -topDiff * cellImageSizeDst),
std::min(mOverlayTexture->getWidth(), mOverlayTexture->getWidth() + rightDiff * cellImageSizeDst),
std::min(mOverlayTexture->getHeight(), mOverlayTexture->getHeight() + bottomDiff * cellImageSizeDst));
// Looks like there is no interface for blitting from memory with src/dst boxes.
// So we create a temporary texture for blitting.
Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton().createManual("@temp",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, image.getWidth(),
image.getHeight(), 0, Ogre::PF_A8B8G8R8);
tex->loadImage(image);
mOverlayTexture->getBuffer()->blit(tex->getBuffer(), srcBox, destBox);
Ogre::TextureManager::getSingleton().remove("@temp");
}
int leftDiff = (mMinX - bounds.mMinX);
int topDiff = (bounds.mMaxY - mMaxY);
int rightDiff = (bounds.mMaxX - mMaxX);
int bottomDiff = (mMinY - bounds.mMinY);
Ogre::Image::Box srcBox ( std::max(0, leftDiff * cellImageSizeSrc),
std::max(0, topDiff * cellImageSizeSrc),
std::min(image.getWidth(), image.getWidth() - rightDiff * cellImageSizeSrc),
std::min(image.getHeight(), image.getHeight() - bottomDiff * cellImageSizeSrc));
Ogre::Image::Box destBox ( std::max(0, -leftDiff * cellImageSizeDst),
std::max(0, -topDiff * cellImageSizeDst),
std::min(mOverlayTexture->getWidth(), mOverlayTexture->getWidth() + rightDiff * cellImageSizeDst),
std::min(mOverlayTexture->getHeight(), mOverlayTexture->getHeight() + bottomDiff * cellImageSizeDst));
// Looks like there is no interface for blitting from memory with src/dst boxes.
// So we create a temporary texture for blitting.
Ogre::TexturePtr tex = Ogre::TextureManager::getSingleton().createManual("@temp",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, image.getWidth(),
image.getHeight(), 0, Ogre::PF_A8B8G8R8);
tex->loadImage(image);
mOverlayTexture->getBuffer()->blit(tex->getBuffer(), srcBox, destBox);
Ogre::TextureManager::getSingleton().remove("@temp");
}
}

@ -12,8 +12,7 @@ namespace Loading
namespace ESM
{
class ESMWriter;
class ESMReader;
class GlobalMap;
}
namespace MWRender
@ -40,8 +39,8 @@ namespace MWRender
/// Clears the overlay
void clear();
void write (ESM::ESMWriter& writer);
void readRecord (ESM::ESMReader& reader, int32_t type, std::vector<std::pair<int, int> >& exploredCells);
void write (ESM::GlobalMap& map);
void read (ESM::GlobalMap& map);
private:
std::string mCacheDir;

@ -68,7 +68,8 @@ namespace MWRender
float HeadAnimationTime::getValue() const
{
// TODO: Handle eye blinking (time is in the text keys)
// TODO use time from text keys (Talk Start/Stop, Blink Start/Stop)
// TODO: Handle eye blinking
if (MWBase::Environment::get().getSoundManager()->sayDone(mReference))
return 0;
else

@ -54,7 +54,10 @@ op 0x20025: AiFollowCell, explicit reference
op 0x20026: ModRegion
op 0x20027: RemoveSoulGem
op 0x20028: RemoveSoulGem, explicit reference
opcodes 0x20029-0x3ffff unused
op 0x20029: PCRaiseRank, explicit reference
op 0x2002a: PCLowerRank, explicit reference
op 0x2002b: PCJoinFaction, explicit reference
opcodes 0x2002c-0x3ffff unused
Segment 4:
(not implemented yet)

@ -131,7 +131,10 @@ namespace MWScript
{
MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Integer lockLevel = 100;
Interpreter::Type_Integer lockLevel = ptr.getCellRef().mLockLevel;
if(lockLevel==0) { //no lock level was ever set, set to 100 as default
lockLevel = 100;
}
if (arg0==1)
{
@ -283,7 +286,7 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime)
{
// We are ignoring the DontSaveObject statement for now. Probably not worth
/// bothering with. The incompatibility we are creating should be marginal at most.
// bothering with. The incompatibility we are creating should be marginal at most.
}
};
@ -320,7 +323,7 @@ namespace MWScript
{
MWWorld::Ptr ptr = R()(runtime);
runtime.push (ptr.getCellRef ().mLockLevel > 0);
runtime.push (ptr.getCellRef().mLockLevel > 0);
}
};

@ -29,10 +29,8 @@
namespace
{
std::string getDialogueActorFaction()
std::string getDialogueActorFaction(MWWorld::Ptr actor)
{
MWWorld::Ptr actor = MWBase::Environment::get().getDialogueManager()->getActor();
const MWMechanics::NpcStats &stats = MWWorld::Class::get (actor).getNpcStats (actor);
if (stats.getFactionRanks().empty())
@ -523,6 +521,7 @@ namespace MWScript
}
};
template<class R>
class OpPCJoinFaction : public Interpreter::Opcode1
{
public:
@ -533,7 +532,8 @@ namespace MWScript
if(arg0==0)
{
factionID = getDialogueActorFaction();
MWWorld::Ptr actor = R()(runtime);
factionID = getDialogueActorFaction(actor);
}
else
{
@ -552,6 +552,7 @@ namespace MWScript
}
};
template<class R>
class OpPCRaiseRank : public Interpreter::Opcode1
{
public:
@ -562,7 +563,8 @@ namespace MWScript
if(arg0==0)
{
factionID = getDialogueActorFaction();
MWWorld::Ptr actor = R()(runtime);
factionID = getDialogueActorFaction(actor);
}
else
{
@ -585,6 +587,7 @@ namespace MWScript
}
};
template<class R>
class OpPCLowerRank : public Interpreter::Opcode1
{
public:
@ -595,7 +598,8 @@ namespace MWScript
if(arg0==0)
{
factionID = getDialogueActorFaction();
MWWorld::Ptr actor = R()(runtime);
factionID = getDialogueActorFaction(actor);
}
else
{
@ -1180,9 +1184,12 @@ namespace MWScript
interpreter.installSegment5 (Compiler::Stats::opcodeGetSpell, new OpGetSpell<ImplicitRef>);
interpreter.installSegment5 (Compiler::Stats::opcodeGetSpellExplicit, new OpGetSpell<ExplicitRef>);
interpreter.installSegment3(Compiler::Stats::opcodePCRaiseRank,new OpPCRaiseRank);
interpreter.installSegment3(Compiler::Stats::opcodePCLowerRank,new OpPCLowerRank);
interpreter.installSegment3(Compiler::Stats::opcodePCJoinFaction,new OpPCJoinFaction);
interpreter.installSegment3(Compiler::Stats::opcodePCRaiseRank,new OpPCRaiseRank<ImplicitRef>);
interpreter.installSegment3(Compiler::Stats::opcodePCLowerRank,new OpPCLowerRank<ImplicitRef>);
interpreter.installSegment3(Compiler::Stats::opcodePCJoinFaction,new OpPCJoinFaction<ImplicitRef>);
interpreter.installSegment3(Compiler::Stats::opcodePCRaiseRankExplicit,new OpPCRaiseRank<ExplicitRef>);
interpreter.installSegment3(Compiler::Stats::opcodePCLowerRankExplicit,new OpPCLowerRank<ExplicitRef>);
interpreter.installSegment3(Compiler::Stats::opcodePCJoinFactionExplicit,new OpPCJoinFaction<ExplicitRef>);
interpreter.installSegment3(Compiler::Stats::opcodeGetPCRank,new OpGetPCRank<ImplicitRef>);
interpreter.installSegment3(Compiler::Stats::opcodeGetPCRankExplicit,new OpGetPCRank<ExplicitRef>);

@ -223,6 +223,31 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
slot->mPath.parent_path().filename().string());
}
void MWState::StateManager::quickSave (std::string name)
{
if (mState!=State_Running ||
MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")!=-1) // char gen
{
//You can not save your game right now
MWBase::Environment::get().getWindowManager()->messageBox("#{sSaveGameDenied}");
return;
}
const Slot* slot = NULL;
Character* mCurrentCharacter = getCurrentCharacter(true); //Get current character
//Find quicksave slot
for (Character::SlotIterator it = mCurrentCharacter->begin(); it != mCurrentCharacter->end(); ++it)
{
if (it->mProfile.mDescription == name)
slot = &*it;
}
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage4}");
saveGame(name, slot);
}
void MWState::StateManager::loadGame (const Character *character, const Slot *slot)
{
try
@ -309,13 +334,6 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl
MWBase::Environment::get().getMechanicsManager()->playerLoaded();
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayerPtr();
//Update the weapon icon in the hud with whatever the player is currently holding.
MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr);
MWWorld::ContainerStoreIterator item = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight);
if (item != invStore.end())
MWBase::Environment::get().getWindowManager()->setSelectedWeapon(*item);
ESM::CellId cellId = ptr.getCell()->getCell()->getCellId();
@ -328,6 +346,16 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl
}
}
void MWState::StateManager::quickLoad()
{
if (Character* mCurrentCharacter = getCurrentCharacter (false))
if (const MWState::Slot* slot = &*mCurrentCharacter->begin()) //Get newest save
{
//MWBase::Environment::get().getWindowManager()->messageBox("#{sLoadingMessage14}"); //it overlaps
loadGame (mCurrentCharacter, slot);
}
}
MWState::Character *MWState::StateManager::getCurrentCharacter (bool create)
{
return mCharacterManager.getCurrentCharacter (create);

@ -49,6 +49,15 @@ namespace MWState
///
/// \note Slot must belong to the current character.
///Saves a file, using supplied filename, overwritting if needed
/** This is mostly used for quicksaving and autosaving, for they use the same name over and over again
\param name Name of save, defaults to "Quicksave"**/
virtual void quickSave(std::string name = "Quicksave");
///Loads the last saved file
/** Used for quickload **/
virtual void quickLoad();
virtual void loadGame (const Character *character, const Slot *slot);
///< Load a saved game file from \a slot.
///

@ -2,11 +2,19 @@
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/player.hpp"
namespace MWWorld
{
void ActionAlchemy::executeImp (const Ptr& actor)
{
if(MWBase::Environment::get().getWorld()->getPlayer().isInCombat()) { //Ensure we're not in combat
MWBase::Environment::get().getWindowManager()->messageBox("#{sInventoryMessage3}");
return;
}
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Alchemy);
}
}

@ -3,6 +3,9 @@
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/player.hpp"
#include "../mwmechanics/npcstats.hpp"
@ -19,8 +22,13 @@ namespace MWWorld
{
}
void ActionRead::executeImp (const MWWorld::Ptr& actor)
{
void ActionRead::executeImp (const MWWorld::Ptr& actor) {
if(MWBase::Environment::get().getWorld()->getPlayer().isInCombat()) { //Ensure we're not in combat
MWBase::Environment::get().getWindowManager()->messageBox("#{sInventoryMessage4}");
return;
}
LiveCellRef<ESM::Book> *ref = getTarget().get<ESM::Book>();
if (ref->mBase->mData.mIsScroll)

@ -2,6 +2,8 @@
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/player.hpp"
namespace MWWorld
{
@ -12,6 +14,11 @@ namespace MWWorld
void ActionRepair::executeImp (const Ptr& actor)
{
if(MWBase::Environment::get().getWorld()->getPlayer().isInCombat()) {
MWBase::Environment::get().getWindowManager()->messageBox("#{sInventoryMessage2}");
return;
}
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Repair);
MWBase::Environment::get().getWindowManager()->startRepairItem(getTarget());
}

@ -2,20 +2,26 @@
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/player.hpp"
namespace MWWorld
{
ActionSoulgem::ActionSoulgem(const Ptr &object)
: Action(false, object)
{
ActionSoulgem::ActionSoulgem(const Ptr &object)
: Action(false, object)
{
}
}
void ActionSoulgem::executeImp(const Ptr &actor)
{
MWBase::Environment::get().getWindowManager()->showSoulgemDialog(getTarget());
}
void ActionSoulgem::executeImp(const Ptr &actor)
{
if(MWBase::Environment::get().getWorld()->getPlayer().isInCombat()) { //Ensure we're not in combat
MWBase::Environment::get().getWindowManager()->messageBox("#{sInventoryMessage5}");
return;
}
MWBase::Environment::get().getWindowManager()->showSoulgemDialog(getTarget());
}
}

@ -52,7 +52,7 @@ namespace
iter!=collection.mList.end(); ++iter)
{
if (iter->mData.getCount()==0 && iter->mRef.mRefNum.mContentFile==-1)
continue; // deleted file that did not came from a content file -> ignore
continue; // deleted reference that did not come from a content file -> ignore
RecordType state;
iter->save (state);
@ -72,13 +72,17 @@ namespace
RecordType state;
state.load (reader);
std::map<int, int>::const_iterator iter =
contentFileMap.find (state.mRef.mRefNum.mContentFile);
// If the reference came from a content file, make sure this content file is loaded
if (state.mRef.mRefNum.mContentFile != -1)
{
std::map<int, int>::const_iterator iter =
contentFileMap.find (state.mRef.mRefNum.mContentFile);
if (iter==contentFileMap.end())
return; // content file has been removed -> skip
if (iter==contentFileMap.end())
return; // content file has been removed -> skip
state.mRef.mRefNum.mContentFile = iter->second;
state.mRef.mRefNum.mContentFile = iter->second;
}
if (!MWWorld::LiveCellRef<T>::checkState (state))
return; // not valid anymore with current content files -> skip

@ -397,7 +397,7 @@ namespace MWWorld
void Class::writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state) const {}
int Class::getBaseGold(const MWWorld::Ptr& ptr) const
int Class::getBaseGold(const MWWorld::Ptr& ptr) const
{
throw std::runtime_error("class does not support base gold");
}

@ -8,7 +8,6 @@
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwmechanics/npcstats.hpp"
@ -150,10 +149,6 @@ void MWWorld::InventoryStore::equip (int slot, const ContainerStoreIterator& ite
fireEquipmentChangedEvent();
updateMagicEffects(actor);
// Update HUD icon for player weapon
if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
MWBase::Environment::get().getWindowManager()->setSelectedWeapon(*getSlot(slot));
}
void MWWorld::InventoryStore::unequipAll(const MWWorld::Ptr& actor)
@ -494,7 +489,6 @@ int MWWorld::InventoryStore::remove(const Ptr& item, int count, const Ptr& actor
&& *mSelectedEnchantItem == item && actor.getRefData().getHandle() == "player")
{
mSelectedEnchantItem = end();
MWBase::Environment::get().getWindowManager()->unsetSelectedSpell();
}
updateRechargingItems();
@ -532,18 +526,9 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::unequipSlot(int slot, c
if (script != "")
(*it).getRefData().getLocals().setVarByInt(script, "onpcequip", 0);
// Update HUD icon when removing player weapon or selected enchanted item.
// We have to check for both as the weapon could also be the enchanted item.
if (slot == MWWorld::InventoryStore::Slot_CarriedRight)
{
// weapon
MWBase::Environment::get().getWindowManager()->unsetSelectedWeapon();
}
if ((mSelectedEnchantItem != end()) && (mSelectedEnchantItem == it))
{
// enchanted item
mSelectedEnchantItem = end();
MWBase::Environment::get().getWindowManager()->unsetSelectedSpell();
}
}

@ -9,13 +9,18 @@
#include <components/esm/defs.hpp>
#include <components/esm/loadbsgn.hpp>
#include "../mwworld/esmstore.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp"
#include "../mwmechanics/movement.hpp"
#include "../mwmechanics/npcstats.hpp"
#include "../mwmechanics/actors.hpp"
#include "../mwmechanics/mechanicsmanagerimp.hpp"
#include "class.hpp"
#include "ptr.hpp"
@ -130,8 +135,25 @@ namespace MWWorld
ptr.getClass().getCreatureStats(ptr).setMovementFlag(MWMechanics::CreatureStats::Flag_Sneak, sneak);
// TODO show sneak indicator only when the player is not detected by any actor
MWBase::Environment::get().getWindowManager()->setSneakVisibility(sneak);
if (sneak == true)
{
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
// Find all the actors who might be able to see the player
std::vector<MWWorld::Ptr> neighbors;
MWBase::Environment::get().getMechanicsManager()->getActorsInRange( Ogre::Vector3(ptr.getRefData().getPosition().pos),
esmStore.get<ESM::GameSetting>().find("fSneakUseDist")->getInt(), neighbors);
for (std::vector<MWWorld::Ptr>::iterator it = neighbors.begin(); it != neighbors.end(); ++it)
{
if ( MWBase::Environment::get().getMechanicsManager()->awarenessCheck(ptr, *it) )
{
MWBase::Environment::get().getWindowManager()->setSneakVisibility(false);
break;
}
}
if (neighbors.size() == 0)
MWBase::Environment::get().getWindowManager()->setSneakVisibility(true);
}
}
void Player::yaw(float yaw)
@ -166,6 +188,10 @@ namespace MWWorld
mTeleported = teleported;
}
bool Player::isInCombat() {
return MWBase::Environment::get().getMechanicsManager()->getActorsFighting(getPlayer()).size() != 0;
}
void Player::markPosition(CellStore *markedCell, ESM::Position markedPosition)
{
mMarkedCell = markedCell;

@ -44,7 +44,7 @@ namespace MWWorld
int mCurrentCrimeId; // the id assigned witnesses
int mPayedCrimeId; // the last id payed off (0 bounty)
public:
Player(const ESM::NPC *player, const MWBase::World& world);
@ -90,6 +90,9 @@ namespace MWWorld
bool wasTeleported() const;
void setTeleported(bool teleported);
///Checks all actors to see if anyone has an aipackage against you
bool isInCombat();
void clear();
void write (ESM::ESMWriter& writer) const;

@ -2056,7 +2056,6 @@ namespace MWWorld
{
// Update the GUI only when called on the player
MWBase::WindowManager* windowManager = MWBase::Environment::get().getWindowManager();
windowManager->unsetSelectedWeapon();
if (werewolf)
{
@ -2695,6 +2694,7 @@ namespace MWWorld
MWWorld::Ptr closestChest;
float closestDistance = FLT_MAX;
//Find closest stolen_goods chest
std::vector<MWWorld::Ptr> chests;
mCells.getInteriorPtrs("stolen_goods", chests);
@ -2712,17 +2712,18 @@ namespace MWWorld
}
}
if (!closestChest.isEmpty())
if (!closestChest.isEmpty()) //Found a close chest
{
ContainerStore& store = ptr.getClass().getContainerStore(ptr);
for (ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
for (ContainerStoreIterator it = store.begin(); it != store.end(); ++it) //Move all stolen stuff into chest
{
if (!it->getCellRef().mOwner.empty() && it->getCellRef().mOwner != "player")
if (!it->getCellRef().mOwner.empty() && it->getCellRef().mOwner != "player") //Not owned by no one/player?
{
closestChest.getClass().getContainerStore(closestChest).add(*it, it->getRefData().getCount(), closestChest);
store.remove(*it, it->getRefData().getCount(), ptr);
}
}
closestChest.getCellRef().mLockLevel = abs(closestChest.getCellRef().mLockLevel);
}
}
@ -2791,7 +2792,7 @@ namespace MWWorld
message += "\n" + skillMsg;
}
// TODO: Sleep the player
// TODO: Sleep the player
std::vector<std::string> buttons;
buttons.push_back("#{sOk}");

@ -409,9 +409,9 @@ namespace Compiler
opcodeResurrectExplicit);
extensions.registerFunction ("getspell", 'l', "c", opcodeGetSpell, opcodeGetSpellExplicit);
extensions.registerInstruction("pcraiserank","/S",opcodePCRaiseRank);
extensions.registerInstruction("pclowerrank","/S",opcodePCLowerRank);
extensions.registerInstruction("pcjoinfaction","/S",opcodePCJoinFaction);
extensions.registerInstruction("pcraiserank","/S",opcodePCRaiseRank, opcodePCRaiseRankExplicit);
extensions.registerInstruction("pclowerrank","/S",opcodePCLowerRank, opcodePCLowerRankExplicit);
extensions.registerInstruction("pcjoinfaction","/S",opcodePCJoinFaction, opcodePCJoinFactionExplicit);
extensions.registerInstruction ("moddisposition","l",opcodeModDisposition,
opcodeModDispositionExplicit);
extensions.registerInstruction ("setdisposition","l",opcodeSetDisposition,

@ -330,6 +330,10 @@ namespace Compiler
const int opcodePCRaiseRank = 0x2000b;
const int opcodePCLowerRank = 0x2000c;
const int opcodePCJoinFaction = 0x2000d;
const int opcodePCRaiseRankExplicit = 0x20029;
const int opcodePCLowerRankExplicit = 0x2002a;
const int opcodePCJoinFactionExplicit = 0x2002b;
const int opcodeGetPCRank = 0x2000e;
const int opcodeGetPCRankExplicit = 0x2000f;
const int opcodeModDisposition = 0x200014d;

@ -54,8 +54,9 @@ void ESM::CellRef::load (ESMReader& esm, bool wideRefNum)
else
mTeleport = false;
mLockLevel = -1;
mLockLevel = 0; //Set to 0 to indicate no lock
esm.getHNOT (mLockLevel, "FLTV");
mKey = esm.getHNOString ("KNAM");
mTrap = esm.getHNOString ("TNAM");
@ -113,8 +114,9 @@ void ESM::CellRef::save (ESMWriter &esm, bool wideRefNum, bool inInventory) cons
esm.writeHNOCString("DNAM", mDestCell);
}
if (mLockLevel != -1 && !inInventory)
esm.writeHNT("FLTV", mLockLevel);
if (mLockLevel != 0 && !inInventory) {
esm.writeHNT("FLTV", mLockLevel);
}
if (!inInventory)
esm.writeHNOCString ("KNAM", mKey);

@ -14,6 +14,15 @@ void ESM::GlobalMap::load (ESMReader &esm)
esm.getSubHeader();
mImageData.resize(esm.getSubSize());
esm.getExact(&mImageData[0], mImageData.size());
while (esm.isNextSub("MRK_"))
{
esm.getSubHeader();
CellId cell;
esm.getT(cell.first);
esm.getT(cell.second);
mMarkers.push_back(cell);
}
}
void ESM::GlobalMap::save (ESMWriter &esm) const
@ -23,4 +32,12 @@ void ESM::GlobalMap::save (ESMWriter &esm) const
esm.startSubRecord("DATA");
esm.write(&mImageData[0], mImageData.size());
esm.endRecord("DATA");
for (std::vector<CellId>::const_iterator it = mMarkers.begin(); it != mMarkers.end(); ++it)
{
esm.startSubRecord("MRK_");
esm.writeT(it->first);
esm.writeT(it->second);
esm.endRecord("MRK_");
}
}

@ -25,6 +25,9 @@ namespace ESM
std::vector<char> mImageData;
typedef std::pair<int, int> CellId;
std::vector<CellId> mMarkers;
void load (ESMReader &esm);
void save (ESMWriter &esm) const;
};

@ -199,6 +199,11 @@ struct KeyListT {
key.mContinuity = nif->getFloat();
}
}
else if (mInterpolationType == 0)
{
if (count != 0)
nif->file->fail("Interpolation type 0 doesn't work with keys");
}
else
nif->file->fail("Unhandled interpolation type: "+Ogre::StringConverter::toString(mInterpolationType));
}

@ -3,10 +3,10 @@
<MyGUI type="Layout">
<Widget type="Window" skin="MW_Window_NoCaption" layer="Windows" position="0 0 400 426" name="_Main">
<Property key="MinSize" value="400 426"/>
<Property key="MaxSize" value="400 426"/>
<Property key="MinSize" value="400 496"/>
<Property key="MaxSize" value="400 496"/>
<Widget type="TabControl" skin="TabControl" position="8 8 368 340" align="Left Top" name="SettingsTab">
<Widget type="TabControl" skin="TabControl" position="8 8 368 410" align="Left Top" name="SettingsTab">
<Property key="ButtonAutoWidth" value="true"/>
<Widget type="TabItem" skin="" position="4 28 360 312">
@ -95,6 +95,18 @@
<Property key="Caption" value="Grab cursor"/>
</Widget>
</Widget>
<Widget type="HBox" skin="" position="4 290 260 24">
<Widget type="AutoSizedButton" skin="MW_Button" align="Left Top" name="AutosaveButton">
<UserString key="SettingCategory" value="Saves"/>
<UserString key="SettingName" value="autosave"/>
<UserString key="SettingType" value="CheckButton"/>
</Widget>
<Widget type="AutoSizedTextBox" skin="SandText" align="Left Top">
<Property key="Caption" value="#{sQuick_Save}"/>
</Widget>
</Widget>
</Widget>
<Widget type="TabItem" skin="" position="4 28 360 312">
<Property key="Caption" value=" #{sAudio} "/>

@ -174,6 +174,8 @@ best attack = false
[Saves]
character =
# Save when resting
autosave = true
[Windows]
inventory x = 0

Loading…
Cancel
Save