mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:53:51 +00:00
Merge remote-tracking branch 'upstream/master'
Conflicts: apps/openmw/mwmechanics/aipursue.hpp apps/openmw/mwmechanics/aisequence.hpp
This commit is contained in:
commit
dbf06d8c8b
49 changed files with 542 additions and 285 deletions
|
@ -434,7 +434,6 @@ IF(NOT WIN32 AND NOT APPLE)
|
||||||
|
|
||||||
# Install licenses
|
# Install licenses
|
||||||
INSTALL(FILES "DejaVu Font License.txt" DESTINATION "${LICDIR}" )
|
INSTALL(FILES "DejaVu Font License.txt" DESTINATION "${LICDIR}" )
|
||||||
INSTALL(FILES "OFL.txt" DESTINATION "${LICDIR}" )
|
|
||||||
INSTALL(FILES "extern/shiny/License.txt" DESTINATION "${LICDIR}" RENAME "Shiny License.txt" )
|
INSTALL(FILES "extern/shiny/License.txt" DESTINATION "${LICDIR}" RENAME "Shiny License.txt" )
|
||||||
ENDIF (DPKG_PROGRAM)
|
ENDIF (DPKG_PROGRAM)
|
||||||
|
|
||||||
|
|
|
@ -195,13 +195,13 @@ CSMSettings::UserSettings::~UserSettings()
|
||||||
void CSMSettings::UserSettings::loadSettings (const QString &fileName)
|
void CSMSettings::UserSettings::loadSettings (const QString &fileName)
|
||||||
{
|
{
|
||||||
mUserFilePath = QString::fromUtf8
|
mUserFilePath = QString::fromUtf8
|
||||||
(mCfgMgr.getUserConfigPath().c_str()) + fileName.toUtf8();
|
(mCfgMgr.getUserConfigPath().string().c_str()) + fileName.toUtf8();
|
||||||
|
|
||||||
QString global = QString::fromUtf8
|
QString global = QString::fromUtf8
|
||||||
(mCfgMgr.getGlobalPath().c_str()) + fileName.toUtf8();
|
(mCfgMgr.getGlobalPath().string().c_str()) + fileName.toUtf8();
|
||||||
|
|
||||||
QString local = QString::fromUtf8
|
QString local = QString::fromUtf8
|
||||||
(mCfgMgr.getLocalPath().c_str()) + fileName.toUtf8();
|
(mCfgMgr.getLocalPath().string().c_str()) + fileName.toUtf8();
|
||||||
|
|
||||||
//open user and global streams
|
//open user and global streams
|
||||||
QTextStream *userStream = openFilestream (mUserFilePath, true);
|
QTextStream *userStream = openFilestream (mUserFilePath, true);
|
||||||
|
|
|
@ -183,7 +183,7 @@ CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CS
|
||||||
{
|
{
|
||||||
delegate = CommandDelegateFactoryCollection::get().makeDelegate (
|
delegate = CommandDelegateFactoryCollection::get().makeDelegate (
|
||||||
display, mUndoStack, mParent);
|
display, mUndoStack, mParent);
|
||||||
mDelegates.insert(std::make_pair<int, CommandDelegate*>(display, delegate));
|
mDelegates.insert(std::make_pair(display, delegate));
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
delegate = delegateIt->second;
|
delegate = delegateIt->second;
|
||||||
|
|
|
@ -67,7 +67,7 @@ add_openmw_dir (mwclass
|
||||||
|
|
||||||
add_openmw_dir (mwmechanics
|
add_openmw_dir (mwmechanics
|
||||||
mechanicsmanagerimp stat character creaturestats magiceffects movement actors objects
|
mechanicsmanagerimp stat character creaturestats magiceffects movement actors objects
|
||||||
drawstate spells activespells npcstats aipackage aisequence aipersue alchemy aiwander aitravel aifollow
|
drawstate spells activespells npcstats aipackage aisequence aipursue alchemy aiwander aitravel aifollow
|
||||||
aiescort aiactivate aicombat repair enchanting pathfinding pathgrid security spellsuccess spellcasting
|
aiescort aiactivate aicombat repair enchanting pathfinding pathgrid security spellsuccess spellcasting
|
||||||
disease pickpocket levelledlist combat steering obstacle
|
disease pickpocket levelledlist combat steering obstacle
|
||||||
)
|
)
|
||||||
|
|
|
@ -305,6 +305,10 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) = 0;
|
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) = 0;
|
||||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0;
|
virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0;
|
||||||
|
virtual int countSavedGameRecords() const = 0;
|
||||||
|
|
||||||
|
/// Does the current stack of GUI-windows permit saving?
|
||||||
|
virtual bool isSavingAllowed() const = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -624,6 +624,8 @@ namespace MWClass
|
||||||
if (!attacker.isEmpty() && ptr.getClass().isNpc() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30)
|
if (!attacker.isEmpty() && ptr.getClass().isNpc() && ptr.getClass().getCreatureStats(ptr).getAiSetting(MWMechanics::CreatureStats::AI_Fight).getModified() <= 30)
|
||||||
MWBase::Environment::get().getMechanicsManager()->commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault);
|
MWBase::Environment::get().getMechanicsManager()->commitCrime(attacker, ptr, MWBase::MechanicsManager::OT_Assault);
|
||||||
|
|
||||||
|
getCreatureStats(ptr).setAttacked(true);
|
||||||
|
|
||||||
if(!successful)
|
if(!successful)
|
||||||
{
|
{
|
||||||
// TODO: Handle HitAttemptOnMe script function
|
// TODO: Handle HitAttemptOnMe script function
|
||||||
|
@ -659,7 +661,6 @@ namespace MWClass
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getDialogueManager()->say(ptr, "hit");
|
MWBase::Environment::get().getDialogueManager()->say(ptr, "hit");
|
||||||
}
|
}
|
||||||
getCreatureStats(ptr).setAttacked(true);
|
|
||||||
|
|
||||||
// Check for knockdown
|
// Check for knockdown
|
||||||
float agilityTerm = getCreatureStats(ptr).getAttribute(ESM::Attribute::Agility).getModified() * fKnockDownMult->getFloat();
|
float agilityTerm = getCreatureStats(ptr).getAttribute(ESM::Attribute::Agility).getModified() * fKnockDownMult->getFloat();
|
||||||
|
|
|
@ -215,16 +215,22 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
std::vector<std::string> matches;
|
std::vector<std::string> matches;
|
||||||
listNames();
|
listNames();
|
||||||
mCommandLine->setCaption(complete( mCommandLine->getOnlyText(), matches ));
|
std::string oldCaption = mCommandLine->getCaption();
|
||||||
#if 0
|
std::string newCaption = complete( mCommandLine->getOnlyText(), matches );
|
||||||
int i = 0;
|
mCommandLine->setCaption(newCaption);
|
||||||
for(std::vector<std::string>::iterator it=matches.begin(); it < matches.end(); ++it,++i )
|
|
||||||
|
// List candidates if repeatedly pressing tab
|
||||||
|
if (oldCaption == newCaption && matches.size())
|
||||||
{
|
{
|
||||||
printOK( *it );
|
int i = 0;
|
||||||
if( i == 50 )
|
printOK("");
|
||||||
break;
|
for(std::vector<std::string>::iterator it=matches.begin(); it < matches.end(); ++it,++i )
|
||||||
|
{
|
||||||
|
printOK( *it );
|
||||||
|
if( i == 50 )
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mCommandHistory.empty()) return;
|
if(mCommandHistory.empty()) return;
|
||||||
|
|
|
@ -196,6 +196,16 @@ namespace MWGui
|
||||||
bitmapFile->read(&textureData[0], width*height*4);
|
bitmapFile->read(&textureData[0], width*height*4);
|
||||||
bitmapFile->close();
|
bitmapFile->close();
|
||||||
|
|
||||||
|
std::string resourceName;
|
||||||
|
if (name.size() >= 5 && Misc::StringUtils::ciEqual(name.substr(0, 5), "magic"))
|
||||||
|
resourceName = "Magic Cards";
|
||||||
|
else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "century"))
|
||||||
|
resourceName = "Century Gothic";
|
||||||
|
else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "daedric"))
|
||||||
|
resourceName = "Daedric";
|
||||||
|
else
|
||||||
|
return; // no point in loading it, since there is no way of using additional fonts
|
||||||
|
|
||||||
std::string textureName = name;
|
std::string textureName = name;
|
||||||
Ogre::Image image;
|
Ogre::Image image;
|
||||||
image.loadDynamicImage(&textureData[0], width, height, Ogre::PF_BYTE_RGBA);
|
image.loadDynamicImage(&textureData[0], width, height, Ogre::PF_BYTE_RGBA);
|
||||||
|
@ -208,18 +218,11 @@ namespace MWGui
|
||||||
// Register the font with MyGUI
|
// Register the font with MyGUI
|
||||||
MyGUI::ResourceManualFont* font = static_cast<MyGUI::ResourceManualFont*>(
|
MyGUI::ResourceManualFont* font = static_cast<MyGUI::ResourceManualFont*>(
|
||||||
MyGUI::FactoryManager::getInstance().createObject("Resource", "ResourceManualFont"));
|
MyGUI::FactoryManager::getInstance().createObject("Resource", "ResourceManualFont"));
|
||||||
|
|
||||||
// We need to emulate loading from XML because the data members are private as of mygui 3.2.0
|
// We need to emulate loading from XML because the data members are private as of mygui 3.2.0
|
||||||
MyGUI::xml::Document xmlDocument;
|
MyGUI::xml::Document xmlDocument;
|
||||||
MyGUI::xml::ElementPtr root = xmlDocument.createRoot("ResourceManualFont");
|
MyGUI::xml::ElementPtr root = xmlDocument.createRoot("ResourceManualFont");
|
||||||
|
root->addAttribute("name", resourceName);
|
||||||
if (name.size() >= 5 && Misc::StringUtils::ciEqual(name.substr(0, 5), "magic"))
|
|
||||||
root->addAttribute("name", "Magic Cards");
|
|
||||||
else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "century"))
|
|
||||||
root->addAttribute("name", "Century Gothic");
|
|
||||||
else if (name.size() >= 7 && Misc::StringUtils::ciEqual(name.substr(0, 7), "daedric"))
|
|
||||||
root->addAttribute("name", "Daedric");
|
|
||||||
else
|
|
||||||
return; // no point in loading it, since there is no way of using additional fonts
|
|
||||||
|
|
||||||
MyGUI::xml::ElementPtr defaultHeight = root->createChild("Property");
|
MyGUI::xml::ElementPtr defaultHeight = root->createChild("Property");
|
||||||
defaultHeight->addAttribute("key", "DefaultHeight");
|
defaultHeight->addAttribute("key", "DefaultHeight");
|
||||||
|
@ -285,6 +288,7 @@ namespace MWGui
|
||||||
|
|
||||||
font->deserialization(root, MyGUI::Version(3,2,0));
|
font->deserialization(root, MyGUI::Version(3,2,0));
|
||||||
|
|
||||||
|
MyGUI::ResourceManager::getInstance().removeByName(font->getResourceName());
|
||||||
MyGUI::ResourceManager::getInstance().addResource(font);
|
MyGUI::ResourceManager::getInstance().addResource(font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace MWGui
|
||||||
, mTrading(false)
|
, mTrading(false)
|
||||||
, mLastXSize(0)
|
, mLastXSize(0)
|
||||||
, mLastYSize(0)
|
, mLastYSize(0)
|
||||||
, mPreview(MWBase::Environment::get().getWorld ()->getPlayerPtr())
|
, mPreview(new MWRender::InventoryPreview(MWBase::Environment::get().getWorld ()->getPlayerPtr()))
|
||||||
, mPreviewDirty(true)
|
, mPreviewDirty(true)
|
||||||
, mDragAndDrop(dragAndDrop)
|
, mDragAndDrop(dragAndDrop)
|
||||||
, mSelectedItem(-1)
|
, mSelectedItem(-1)
|
||||||
|
@ -91,8 +91,8 @@ namespace MWGui
|
||||||
mTradeModel = new TradeItemModel(new InventoryItemModel(mPtr), MWWorld::Ptr());
|
mTradeModel = new TradeItemModel(new InventoryItemModel(mPtr), MWWorld::Ptr());
|
||||||
mSortModel = new SortFilterItemModel(mTradeModel);
|
mSortModel = new SortFilterItemModel(mTradeModel);
|
||||||
mItemView->setModel(mSortModel);
|
mItemView->setModel(mSortModel);
|
||||||
mPreview = MWRender::InventoryPreview(mPtr);
|
mPreview.reset(new MWRender::InventoryPreview(mPtr));
|
||||||
mPreview.setup();
|
mPreview->setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryWindow::setGuiMode(GuiMode mode)
|
void InventoryWindow::setGuiMode(GuiMode mode)
|
||||||
|
@ -444,7 +444,7 @@ namespace MWGui
|
||||||
|
|
||||||
MWWorld::Ptr InventoryWindow::getAvatarSelectedItem(int x, int y)
|
MWWorld::Ptr InventoryWindow::getAvatarSelectedItem(int x, int y)
|
||||||
{
|
{
|
||||||
int slot = mPreview.getSlotSelected (x, y);
|
int slot = mPreview->getSlotSelected (x, y);
|
||||||
|
|
||||||
if (slot == -1)
|
if (slot == -1)
|
||||||
return MWWorld::Ptr();
|
return MWWorld::Ptr();
|
||||||
|
@ -493,7 +493,7 @@ namespace MWGui
|
||||||
mPreviewDirty = false;
|
mPreviewDirty = false;
|
||||||
MyGUI::IntSize size = mAvatarImage->getSize();
|
MyGUI::IntSize size = mAvatarImage->getSize();
|
||||||
|
|
||||||
mPreview.update (size.width, size.height);
|
mPreview->update (size.width, size.height);
|
||||||
|
|
||||||
mAvatarImage->setImageTexture("CharacterPreview");
|
mAvatarImage->setImageTexture("CharacterPreview");
|
||||||
mAvatarImage->setImageCoord(MyGUI::IntCoord(0, 0, std::min(512, size.width), std::min(1024, size.height)));
|
mAvatarImage->setImageCoord(MyGUI::IntCoord(0, 0, std::min(512, size.width), std::min(1024, size.height)));
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace MWGui
|
||||||
MWWorld::Ptr getAvatarSelectedItem(int x, int y);
|
MWWorld::Ptr getAvatarSelectedItem(int x, int y);
|
||||||
|
|
||||||
void rebuildAvatar() {
|
void rebuildAvatar() {
|
||||||
mPreview.rebuild();
|
mPreview->rebuild();
|
||||||
}
|
}
|
||||||
|
|
||||||
TradeItemModel* getTradeModel();
|
TradeItemModel* getTradeModel();
|
||||||
|
@ -81,7 +81,7 @@ namespace MWGui
|
||||||
int mLastXSize;
|
int mLastXSize;
|
||||||
int mLastYSize;
|
int mLastYSize;
|
||||||
|
|
||||||
MWRender::InventoryPreview mPreview;
|
std::auto_ptr<MWRender::InventoryPreview> mPreview;
|
||||||
|
|
||||||
bool mTrading;
|
bool mTrading;
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,8 @@ namespace MWGui
|
||||||
buttons.push_back("loadgame");
|
buttons.push_back("loadgame");
|
||||||
|
|
||||||
if (state==MWBase::StateManager::State_Running &&
|
if (state==MWBase::StateManager::State_Running &&
|
||||||
MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")==-1)
|
MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")==-1 &&
|
||||||
|
MWBase::Environment::get().getWindowManager()->isSavingAllowed())
|
||||||
buttons.push_back("savegame");
|
buttons.push_back("savegame");
|
||||||
|
|
||||||
buttons.push_back("options");
|
buttons.push_back("options");
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
#include <components/esm/quickkeys.hpp>
|
||||||
|
|
||||||
#include "../mwworld/inventorystore.hpp"
|
#include "../mwworld/inventorystore.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
@ -55,6 +57,14 @@ namespace MWGui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QuickKeysMenu::clear()
|
||||||
|
{
|
||||||
|
for (int i=0; i<10; ++i)
|
||||||
|
{
|
||||||
|
unassign(mQuickKeyButtons[i], i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QuickKeysMenu::~QuickKeysMenu()
|
QuickKeysMenu::~QuickKeysMenu()
|
||||||
{
|
{
|
||||||
delete mAssignDialog;
|
delete mAssignDialog;
|
||||||
|
@ -154,8 +164,6 @@ namespace MWGui
|
||||||
frame->setUserString ("ToolTipType", "ItemPtr");
|
frame->setUserString ("ToolTipType", "ItemPtr");
|
||||||
frame->setUserData(item);
|
frame->setUserData(item);
|
||||||
frame->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked);
|
frame->eventMouseButtonClick += MyGUI::newDelegate(this, &QuickKeysMenu::onQuickKeyButtonClicked);
|
||||||
|
|
||||||
|
|
||||||
MyGUI::ImageBox* image = frame->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
|
MyGUI::ImageBox* image = frame->createWidget<MyGUI::ImageBox>("ImageBox", MyGUI::IntCoord(5, 5, 32, 32), MyGUI::Align::Default);
|
||||||
std::string path = std::string("icons\\");
|
std::string path = std::string("icons\\");
|
||||||
path += MWWorld::Class::get(item).getInventoryIcon(item);
|
path += MWWorld::Class::get(item).getInventoryIcon(item);
|
||||||
|
@ -165,7 +173,8 @@ namespace MWGui
|
||||||
image->setImageTexture (path);
|
image->setImageTexture (path);
|
||||||
image->setNeedMouseFocus (false);
|
image->setNeedMouseFocus (false);
|
||||||
|
|
||||||
mItemSelectionDialog->setVisible(false);
|
if (mItemSelectionDialog)
|
||||||
|
mItemSelectionDialog->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuickKeysMenu::onAssignItemCancel()
|
void QuickKeysMenu::onAssignItemCancel()
|
||||||
|
@ -198,7 +207,8 @@ namespace MWGui
|
||||||
image->setImageTexture (path);
|
image->setImageTexture (path);
|
||||||
image->setNeedMouseFocus (false);
|
image->setNeedMouseFocus (false);
|
||||||
|
|
||||||
mMagicSelectionDialog->setVisible(false);
|
if (mMagicSelectionDialog)
|
||||||
|
mMagicSelectionDialog->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuickKeysMenu::onAssignMagic (const std::string& spellId)
|
void QuickKeysMenu::onAssignMagic (const std::string& spellId)
|
||||||
|
@ -239,7 +249,8 @@ namespace MWGui
|
||||||
image->setImageTexture (path);
|
image->setImageTexture (path);
|
||||||
image->setNeedMouseFocus (false);
|
image->setNeedMouseFocus (false);
|
||||||
|
|
||||||
mMagicSelectionDialog->setVisible(false);
|
if (mMagicSelectionDialog)
|
||||||
|
mMagicSelectionDialog->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuickKeysMenu::onAssignMagicCancel ()
|
void QuickKeysMenu::onAssignMagicCancel ()
|
||||||
|
@ -374,6 +385,110 @@ namespace MWGui
|
||||||
center();
|
center();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QuickKeysMenu::write(ESM::ESMWriter &writer)
|
||||||
|
{
|
||||||
|
writer.startRecord(ESM::REC_KEYS);
|
||||||
|
|
||||||
|
ESM::QuickKeys keys;
|
||||||
|
|
||||||
|
for (int i=0; i<10; ++i)
|
||||||
|
{
|
||||||
|
MyGUI::Button* button = mQuickKeyButtons[i];
|
||||||
|
|
||||||
|
int type = *button->getUserData<QuickKeyType>();
|
||||||
|
|
||||||
|
ESM::QuickKeys::QuickKey key;
|
||||||
|
key.mType = type;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case Type_Unassigned:
|
||||||
|
break;
|
||||||
|
case Type_Item:
|
||||||
|
case Type_MagicItem:
|
||||||
|
{
|
||||||
|
MWWorld::Ptr item = *button->getChildAt(0)->getUserData<MWWorld::Ptr>();
|
||||||
|
key.mId = item.getCellRef().mRefID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Type_Magic:
|
||||||
|
std::string spellId = button->getChildAt(0)->getUserString("Spell");
|
||||||
|
key.mId = spellId;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
keys.mKeys.push_back(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
keys.save(writer);
|
||||||
|
|
||||||
|
writer.endRecord(ESM::REC_KEYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickKeysMenu::readRecord(ESM::ESMReader &reader, int32_t type)
|
||||||
|
{
|
||||||
|
if (type != ESM::REC_KEYS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ESM::QuickKeys keys;
|
||||||
|
keys.load(reader);
|
||||||
|
|
||||||
|
int i=0;
|
||||||
|
for (std::vector<ESM::QuickKeys::QuickKey>::const_iterator it = keys.mKeys.begin(); it != keys.mKeys.end(); ++it)
|
||||||
|
{
|
||||||
|
if (i >= 10)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mSelectedIndex = i;
|
||||||
|
int keyType = it->mType;
|
||||||
|
std::string id = it->mId;
|
||||||
|
MyGUI::Button* button = mQuickKeyButtons[i];
|
||||||
|
|
||||||
|
switch (keyType)
|
||||||
|
{
|
||||||
|
case Type_Magic:
|
||||||
|
onAssignMagic(id);
|
||||||
|
break;
|
||||||
|
case Type_Item:
|
||||||
|
case Type_MagicItem:
|
||||||
|
{
|
||||||
|
// Find the item by id
|
||||||
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||||
|
MWWorld::InventoryStore& store = player.getClass().getInventoryStore(player);
|
||||||
|
MWWorld::Ptr item;
|
||||||
|
for (MWWorld::ContainerStoreIterator it = store.begin(); it != store.end(); ++it)
|
||||||
|
{
|
||||||
|
if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, id))
|
||||||
|
{
|
||||||
|
if (item.isEmpty() ||
|
||||||
|
// Prefer the stack with the lowest remaining uses
|
||||||
|
(it->getCellRef().mCharge != -1 && (item.getCellRef().mCharge == -1 || it->getCellRef().mCharge < item.getCellRef().mCharge) ))
|
||||||
|
{
|
||||||
|
item = *it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.isEmpty())
|
||||||
|
unassign(button, i);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (keyType == Type_Item)
|
||||||
|
onAssignItem(item);
|
||||||
|
else if (keyType == Type_MagicItem)
|
||||||
|
onAssignMagicItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Type_Unassigned:
|
||||||
|
unassign(button, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,11 @@ namespace MWGui
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void write (ESM::ESMWriter& writer);
|
||||||
|
void readRecord (ESM::ESMReader& reader, int32_t type);
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MyGUI::EditBox* mInstructionLabel;
|
MyGUI::EditBox* mInstructionLabel;
|
||||||
MyGUI::Button* mOkButton;
|
MyGUI::Button* mOkButton;
|
||||||
|
|
|
@ -17,6 +17,8 @@ namespace MWGui
|
||||||
|
|
||||||
void checkReferenceAvailable(); ///< closes the window, if the MW-reference has become unavailable
|
void checkReferenceAvailable(); ///< closes the window, if the MW-reference has become unavailable
|
||||||
|
|
||||||
|
void resetReference() { mPtr = MWWorld::Ptr(); mCurrentPlayerCell = NULL; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void onReferenceUnavailable() = 0; ///< called when reference has become unavailable
|
virtual void onReferenceUnavailable() = 0; ///< called when reference has become unavailable
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
onSlotSelected(sender, pos);
|
onSlotSelected(sender, pos);
|
||||||
|
|
||||||
if (MyGUI::InputManager::getInstance().isShiftPressed())
|
if (pos != MyGUI::ITEM_NONE && MyGUI::InputManager::getInstance().isShiftPressed())
|
||||||
{
|
{
|
||||||
ConfirmationDialog* dialog = MWBase::Environment::get().getWindowManager()->getConfirmationDialog();
|
ConfirmationDialog* dialog = MWBase::Environment::get().getWindowManager()->getConfirmationDialog();
|
||||||
dialog->open("#{sMessage3}");
|
dialog->open("#{sMessage3}");
|
||||||
|
@ -206,6 +206,13 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage65}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage65}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setVisible(false);
|
||||||
|
MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_MainMenu);
|
||||||
|
|
||||||
|
if (mSaving)
|
||||||
|
{
|
||||||
MWBase::Environment::get().getStateManager()->saveGame (mSaveNameEdit->getCaption(), mCurrentSlot);
|
MWBase::Environment::get().getStateManager()->saveGame (mSaveNameEdit->getCaption(), mCurrentSlot);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -213,12 +220,9 @@ namespace MWGui
|
||||||
if (mCurrentCharacter && mCurrentSlot)
|
if (mCurrentCharacter && mCurrentSlot)
|
||||||
{
|
{
|
||||||
MWBase::Environment::get().getStateManager()->loadGame (mCurrentCharacter, mCurrentSlot);
|
MWBase::Environment::get().getStateManager()->loadGame (mCurrentCharacter, mCurrentSlot);
|
||||||
MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_MainMenu);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setVisible(false);
|
|
||||||
|
|
||||||
if (MWBase::Environment::get().getStateManager()->getState()==
|
if (MWBase::Environment::get().getStateManager()->getState()==
|
||||||
MWBase::StateManager::State_NoGame)
|
MWBase::StateManager::State_NoGame)
|
||||||
{
|
{
|
||||||
|
|
|
@ -475,7 +475,7 @@ namespace MWGui
|
||||||
text += std::string("#DDC79E") + faction->mName;
|
text += std::string("#DDC79E") + faction->mName;
|
||||||
|
|
||||||
if (expelled.find(it->first) != expelled.end())
|
if (expelled.find(it->first) != expelled.end())
|
||||||
text += "\n#{sExpelled}";
|
text += "\n#BF9959#{sExpelled}";
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
text += std::string("\n#BF9959") + faction->mRanks[it->second];
|
text += std::string("\n#BF9959") + faction->mRanks[it->second];
|
||||||
|
|
|
@ -1405,16 +1405,49 @@ namespace MWGui
|
||||||
void WindowManager::clear()
|
void WindowManager::clear()
|
||||||
{
|
{
|
||||||
mMap->clear();
|
mMap->clear();
|
||||||
|
mQuickKeysMenu->clear();
|
||||||
|
|
||||||
|
mTrainingWindow->resetReference();
|
||||||
|
mDialogueWindow->resetReference();
|
||||||
|
mTradeWindow->resetReference();
|
||||||
|
mSpellBuyingWindow->resetReference();
|
||||||
|
mSpellCreationDialog->resetReference();
|
||||||
|
mEnchantingDialog->resetReference();
|
||||||
|
mContainerWindow->resetReference();
|
||||||
|
mCompanionWindow->resetReference();
|
||||||
|
mConsole->resetReference();
|
||||||
|
|
||||||
|
mGuiModes.clear();
|
||||||
|
updateVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowManager::write(ESM::ESMWriter &writer, Loading::Listener& progress)
|
void WindowManager::write(ESM::ESMWriter &writer, Loading::Listener& progress)
|
||||||
{
|
{
|
||||||
mMap->write(writer, progress);
|
mMap->write(writer, progress);
|
||||||
|
|
||||||
|
mQuickKeysMenu->write(writer);
|
||||||
|
progress.increaseProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowManager::readRecord(ESM::ESMReader &reader, int32_t type)
|
void WindowManager::readRecord(ESM::ESMReader &reader, int32_t type)
|
||||||
{
|
{
|
||||||
mMap->readRecord(reader, type);
|
if (type == ESM::REC_GMAP)
|
||||||
|
mMap->readRecord(reader, type);
|
||||||
|
else if (type == ESM::REC_KEYS)
|
||||||
|
mQuickKeysMenu->readRecord(reader, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
int WindowManager::countSavedGameRecords() const
|
||||||
|
{
|
||||||
|
return 1 // Global map
|
||||||
|
+ 1; // QuickKeysMenu
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WindowManager::isSavingAllowed() const
|
||||||
|
{
|
||||||
|
return !MyGUI::InputManager::getInstance().isModalAny()
|
||||||
|
// TODO: remove this, once we have properly serialized the state of open windows
|
||||||
|
&& (!isGuiMode() || (mGuiModes.size() == 1 && getMode() == GM_MainMenu));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowManager::playVideo(const std::string &name, bool allowSkipping)
|
void WindowManager::playVideo(const std::string &name, bool allowSkipping)
|
||||||
|
|
|
@ -293,6 +293,10 @@ namespace MWGui
|
||||||
|
|
||||||
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress);
|
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress);
|
||||||
virtual void readRecord (ESM::ESMReader& reader, int32_t type);
|
virtual void readRecord (ESM::ESMReader& reader, int32_t type);
|
||||||
|
virtual int countSavedGameRecords() const;
|
||||||
|
|
||||||
|
/// Does the current stack of GUI-windows permit saving?
|
||||||
|
virtual bool isSavingAllowed() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mConsoleOnlyScripts;
|
bool mConsoleOnlyScripts;
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
#include "aicombat.hpp"
|
#include "aicombat.hpp"
|
||||||
#include "aifollow.hpp"
|
#include "aifollow.hpp"
|
||||||
#include "aipersue.hpp"
|
#include "aipursue.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
@ -719,34 +719,33 @@ namespace MWMechanics
|
||||||
CreatureStats& creatureStats = MWWorld::Class::get(ptr).getCreatureStats(ptr);
|
CreatureStats& creatureStats = MWWorld::Class::get(ptr).getCreatureStats(ptr);
|
||||||
NpcStats& npcStats = MWWorld::Class::get(ptr).getNpcStats(ptr);
|
NpcStats& npcStats = MWWorld::Class::get(ptr).getNpcStats(ptr);
|
||||||
|
|
||||||
// If I'm a guard and I'm not hostile
|
if (ptr.getClass().isClass(ptr, "Guard") && creatureStats.getAiSequence().getTypeId() != AiPackage::TypeIdPursue && !creatureStats.isHostile())
|
||||||
if (ptr.getClass().isClass(ptr, "Guard") && !creatureStats.isHostile())
|
|
||||||
{
|
{
|
||||||
/// \todo Move me! I shouldn't be here...
|
/// \todo Move me! I shouldn't be here...
|
||||||
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore();
|
||||||
float cutoff = float(esmStore.get<ESM::GameSetting>().find("iCrimeThreshold")->getInt()) *
|
float cutoff = float(esmStore.get<ESM::GameSetting>().find("iCrimeThreshold")->getInt());
|
||||||
float(esmStore.get<ESM::GameSetting>().find("iCrimeThresholdMultiplier")->getInt()) *
|
// Force dialogue on sight if bounty is greater than the cutoff
|
||||||
esmStore.get<ESM::GameSetting>().find("fCrimeGoldDiscountMult")->getFloat();
|
// In vanilla morrowind, the greeting dialogue is scripted to either arrest the player (< 5000 bounty) or attack (>= 5000 bounty)
|
||||||
// Attack on sight if bounty is greater than the cutoff
|
|
||||||
if ( player.getClass().getNpcStats(player).getBounty() >= cutoff
|
if ( player.getClass().getNpcStats(player).getBounty() >= cutoff
|
||||||
|
// TODO: do not run these two every frame. keep an Aware state for each actor and update it every 0.2 s or so?
|
||||||
&& MWBase::Environment::get().getWorld()->getLOS(ptr, player)
|
&& MWBase::Environment::get().getWorld()->getLOS(ptr, player)
|
||||||
&& MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr))
|
&& MWBase::Environment::get().getMechanicsManager()->awarenessCheck(player, ptr))
|
||||||
{
|
{
|
||||||
creatureStats.getAiSequence().stack(AiCombat(player), ptr);
|
creatureStats.getAiSequence().stack(AiPursue(player.getClass().getId(player)), ptr);
|
||||||
creatureStats.setHostile(true);
|
creatureStats.setAlarmed(true);
|
||||||
npcStats.setCrimeId( MWBase::Environment::get().getWorld()->getPlayer().getCrimeId() );
|
npcStats.setCrimeId(MWBase::Environment::get().getWorld()->getPlayer().getNewCrimeId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if I was a witness to a crime
|
// if I was a witness to a crime
|
||||||
if (npcStats.getCrimeId() != -1)
|
if (npcStats.getCrimeId() != -1)
|
||||||
{
|
{
|
||||||
// if you've payed for your crimes and I havent noticed
|
// if you've paid for your crimes and I havent noticed
|
||||||
if( npcStats.getCrimeId() <= MWBase::Environment::get().getWorld()->getPlayer().getCrimeId() )
|
if( npcStats.getCrimeId() <= MWBase::Environment::get().getWorld()->getPlayer().getCrimeId() )
|
||||||
{
|
{
|
||||||
// Calm witness down
|
// Calm witness down
|
||||||
if (ptr.getClass().isClass(ptr, "Guard"))
|
if (ptr.getClass().isClass(ptr, "Guard"))
|
||||||
creatureStats.getAiSequence().stopPersue();
|
creatureStats.getAiSequence().stopPursuit();
|
||||||
creatureStats.getAiSequence().stopCombat();
|
creatureStats.getAiSequence().stopCombat();
|
||||||
|
|
||||||
// Reset factors to attack
|
// Reset factors to attack
|
||||||
|
@ -761,13 +760,12 @@ namespace MWMechanics
|
||||||
else if (!creatureStats.isHostile())
|
else if (!creatureStats.isHostile())
|
||||||
{
|
{
|
||||||
if (ptr.getClass().isClass(ptr, "Guard"))
|
if (ptr.getClass().isClass(ptr, "Guard"))
|
||||||
creatureStats.getAiSequence().stack(AiPersue(player.getClass().getId(player)), ptr);
|
creatureStats.getAiSequence().stack(AiPursue(player.getClass().getId(player)), ptr);
|
||||||
else
|
else
|
||||||
creatureStats.getAiSequence().stack(AiCombat(player), ptr);
|
creatureStats.getAiSequence().stack(AiCombat(player), ptr);
|
||||||
creatureStats.setHostile(true);
|
creatureStats.setHostile(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if I didn't report a crime was I attacked?
|
// if I didn't report a crime was I attacked?
|
||||||
else if (creatureStats.getAttacked() && !creatureStats.isHostile())
|
else if (creatureStats.getAttacked() && !creatureStats.isHostile())
|
||||||
{
|
{
|
||||||
|
|
|
@ -392,7 +392,7 @@ namespace MWMechanics
|
||||||
else // remote pathfinding
|
else // remote pathfinding
|
||||||
{
|
{
|
||||||
bool preferShortcut = false;
|
bool preferShortcut = false;
|
||||||
bool inLOS;
|
bool inLOS = MWBase::Environment::get().getWorld()->getLOS(actor, mTarget);
|
||||||
|
|
||||||
if(mReadyToAttack) isStuck = false;
|
if(mReadyToAttack) isStuck = false;
|
||||||
|
|
||||||
|
@ -400,7 +400,7 @@ namespace MWMechanics
|
||||||
if(!isStuck
|
if(!isStuck
|
||||||
&& (!mForceNoShortcut
|
&& (!mForceNoShortcut
|
||||||
|| (Ogre::Vector3(mShortcutFailPos.pos) - vActorPos).length() >= PATHFIND_SHORTCUT_RETRY_DIST)
|
|| (Ogre::Vector3(mShortcutFailPos.pos) - vActorPos).length() >= PATHFIND_SHORTCUT_RETRY_DIST)
|
||||||
&& (inLOS = MWBase::Environment::get().getWorld()->getLOS(actor, mTarget)))
|
&& inLOS)
|
||||||
{
|
{
|
||||||
if(speed == 0.0f) speed = actorCls.getSpeed(actor);
|
if(speed == 0.0f) speed = actorCls.getSpeed(actor);
|
||||||
// maximum dist before pit/obstacle for actor to avoid them depending on his speed
|
// maximum dist before pit/obstacle for actor to avoid them depending on his speed
|
||||||
|
@ -437,7 +437,7 @@ namespace MWMechanics
|
||||||
if(inLOS && mPathFinder.getPath().size() > 1)
|
if(inLOS && mPathFinder.getPath().size() > 1)
|
||||||
{
|
{
|
||||||
// get point just before target
|
// get point just before target
|
||||||
std::list<ESM::Pathgrid::Point>::iterator pntIter = --mPathFinder.getPath().end();
|
std::list<ESM::Pathgrid::Point>::const_iterator pntIter = --mPathFinder.getPath().end();
|
||||||
--pntIter;
|
--pntIter;
|
||||||
Ogre::Vector3 vBeforeTarget = Ogre::Vector3(pntIter->mX, pntIter->mY, pntIter->mZ);
|
Ogre::Vector3 vBeforeTarget = Ogre::Vector3(pntIter->mX, pntIter->mY, pntIter->mZ);
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace MWMechanics
|
||||||
TypeIdFollow = 3,
|
TypeIdFollow = 3,
|
||||||
TypeIdActivate = 4,
|
TypeIdActivate = 4,
|
||||||
TypeIdCombat = 5,
|
TypeIdCombat = 5,
|
||||||
TypeIdPersue = 6
|
TypeIdPursue = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
///Default Deconstructor
|
///Default Deconstructor
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "aipersue.hpp"
|
#include "aipursue.hpp"
|
||||||
|
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
|
@ -11,15 +11,15 @@
|
||||||
#include "movement.hpp"
|
#include "movement.hpp"
|
||||||
#include "creaturestats.hpp"
|
#include "creaturestats.hpp"
|
||||||
|
|
||||||
MWMechanics::AiPersue::AiPersue(const std::string &objectId)
|
MWMechanics::AiPursue::AiPursue(const std::string &objectId)
|
||||||
: mObjectId(objectId)
|
: mObjectId(objectId)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
MWMechanics::AiPersue *MWMechanics::AiPersue::clone() const
|
MWMechanics::AiPursue *MWMechanics::AiPursue::clone() const
|
||||||
{
|
{
|
||||||
return new AiPersue(*this);
|
return new AiPursue(*this);
|
||||||
}
|
}
|
||||||
bool MWMechanics::AiPersue::execute (const MWWorld::Ptr& actor, float duration)
|
bool MWMechanics::AiPursue::execute (const MWWorld::Ptr& actor, float duration)
|
||||||
{
|
{
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
ESM::Position pos = actor.getRefData().getPosition();
|
ESM::Position pos = actor.getRefData().getPosition();
|
||||||
|
@ -52,11 +52,13 @@ bool MWMechanics::AiPersue::execute (const MWWorld::Ptr& actor, float duration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Big TODO: Sync this with current AiFollow. Move common code to a shared base class or helpers (applies to all AI packages, way too much duplicated code)
|
||||||
|
|
||||||
MWWorld::Ptr target = world->getPtr(mObjectId,false);
|
MWWorld::Ptr target = world->getPtr(mObjectId,false);
|
||||||
ESM::Position targetPos = target.getRefData().getPosition();
|
ESM::Position targetPos = target.getRefData().getPosition();
|
||||||
|
|
||||||
bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY;
|
bool cellChange = cell->mData.mX != mCellX || cell->mData.mY != mCellY;
|
||||||
if(!mPathFinder.isPathConstructed() || cellChange)
|
if(!mPathFinder.isPathConstructed() || cellChange || mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2]))
|
||||||
{
|
{
|
||||||
mCellX = cell->mData.mX;
|
mCellX = cell->mData.mX;
|
||||||
mCellY = cell->mData.mY;
|
mCellY = cell->mData.mY;
|
||||||
|
@ -76,15 +78,7 @@ bool MWMechanics::AiPersue::execute (const MWWorld::Ptr& actor, float duration)
|
||||||
|
|
||||||
if((pos.pos[0]-targetPos.pos[0])*(pos.pos[0]-targetPos.pos[0])+
|
if((pos.pos[0]-targetPos.pos[0])*(pos.pos[0]-targetPos.pos[0])+
|
||||||
(pos.pos[1]-targetPos.pos[1])*(pos.pos[1]-targetPos.pos[1])+
|
(pos.pos[1]-targetPos.pos[1])*(pos.pos[1]-targetPos.pos[1])+
|
||||||
(pos.pos[2]-targetPos.pos[2])*(pos.pos[2]-targetPos.pos[2]) < 200*200)
|
(pos.pos[2]-targetPos.pos[2])*(pos.pos[2]-targetPos.pos[2]) < 100*100)
|
||||||
{
|
|
||||||
movement.mPosition[1] = 0;
|
|
||||||
MWWorld::Ptr target = world->getPtr(mObjectId,false);
|
|
||||||
MWWorld::Class::get(target).activate(target,actor).get()->execute(actor);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mPathFinder.checkPathCompleted(pos.pos[0], pos.pos[1], pos.pos[2]))
|
|
||||||
{
|
{
|
||||||
movement.mPosition[1] = 0;
|
movement.mPosition[1] = 0;
|
||||||
MWWorld::Ptr target = world->getPtr(mObjectId,false);
|
MWWorld::Ptr target = world->getPtr(mObjectId,false);
|
||||||
|
@ -100,7 +94,7 @@ bool MWMechanics::AiPersue::execute (const MWWorld::Ptr& actor, float duration)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MWMechanics::AiPersue::getTypeId() const
|
int MWMechanics::AiPursue::getTypeId() const
|
||||||
{
|
{
|
||||||
return TypeIdPersue;
|
return TypeIdPursue;
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef GAME_MWMECHANICS_AIPERSUE_H
|
#ifndef GAME_MWMECHANICS_AIPURSUE_H
|
||||||
#define GAME_MWMECHANICS_AIPERSUE_H
|
#define GAME_MWMECHANICS_AIPURSUE_H
|
||||||
|
|
||||||
#include "aipackage.hpp"
|
#include "aipackage.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -17,6 +17,12 @@ namespace MWMechanics
|
||||||
/** \param objectId Actor to pursue **/
|
/** \param objectId Actor to pursue **/
|
||||||
AiPersue(const std::string &objectId);
|
AiPersue(const std::string &objectId);
|
||||||
virtual AiPersue *clone() const;
|
virtual AiPersue *clone() const;
|
||||||
|
|
||||||
|
class AiPursue : public AiPackage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AiPursue(const std::string &objectId);
|
||||||
|
virtual AiPursue *clone() const;
|
||||||
virtual bool execute (const MWWorld::Ptr& actor,float duration);
|
virtual bool execute (const MWWorld::Ptr& actor,float duration);
|
||||||
virtual int getTypeId() const;
|
virtual int getTypeId() const;
|
||||||
|
|
|
@ -73,9 +73,9 @@ void MWMechanics::AiSequence::stopCombat()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWMechanics::AiSequence::stopPersue()
|
void MWMechanics::AiSequence::stopPursuit()
|
||||||
{
|
{
|
||||||
while (getTypeId() == AiPackage::TypeIdPersue)
|
while (getTypeId() == AiPackage::TypeIdPursue)
|
||||||
{
|
{
|
||||||
delete *mPackages.begin();
|
delete *mPackages.begin();
|
||||||
mPackages.erase (mPackages.begin());
|
mPackages.erase (mPackages.begin());
|
||||||
|
@ -93,11 +93,16 @@ void MWMechanics::AiSequence::execute (const MWWorld::Ptr& actor,float duration)
|
||||||
{
|
{
|
||||||
if (!mPackages.empty())
|
if (!mPackages.empty())
|
||||||
{
|
{
|
||||||
mLastAiPackage = mPackages.front()->getTypeId();
|
MWMechanics::AiPackage* package = mPackages.front();
|
||||||
if (mPackages.front()->execute (actor,duration))
|
mLastAiPackage = package->getTypeId();
|
||||||
|
if (package->execute (actor,duration))
|
||||||
{
|
{
|
||||||
delete *mPackages.begin();
|
// To account for the rare case where AiPackage::execute() queued another AI package
|
||||||
mPackages.erase (mPackages.begin());
|
// (e.g. AiPursue executing a dialogue script that uses startCombat)
|
||||||
|
std::list<MWMechanics::AiPackage*>::iterator toRemove =
|
||||||
|
std::find(mPackages.begin(), mPackages.end(), package);
|
||||||
|
mPackages.erase(toRemove);
|
||||||
|
delete package;
|
||||||
mDone = true;
|
mDone = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -118,7 +123,7 @@ void MWMechanics::AiSequence::clear()
|
||||||
|
|
||||||
void MWMechanics::AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor)
|
void MWMechanics::AiSequence::stack (const AiPackage& package, const MWWorld::Ptr& actor)
|
||||||
{
|
{
|
||||||
if (package.getTypeId() == AiPackage::TypeIdCombat || package.getTypeId() == AiPackage::TypeIdPersue)
|
if (package.getTypeId() == AiPackage::TypeIdCombat || package.getTypeId() == AiPackage::TypeIdPursue)
|
||||||
{
|
{
|
||||||
// Notify AiWander of our current position so we can return to it after combat finished
|
// Notify AiWander of our current position so we can return to it after combat finished
|
||||||
for (std::list<AiPackage *>::const_iterator iter (mPackages.begin()); iter!=mPackages.end(); ++iter)
|
for (std::list<AiPackage *>::const_iterator iter (mPackages.begin()); iter!=mPackages.end(); ++iter)
|
||||||
|
|
|
@ -65,6 +65,9 @@ namespace MWMechanics
|
||||||
/// Has a package been completed during the last update?
|
/// Has a package been completed during the last update?
|
||||||
bool isPackageDone() const;
|
bool isPackageDone() const;
|
||||||
|
|
||||||
|
/// Removes all pursue packages until first non-pursue or stack empty.
|
||||||
|
void stopPursuit();
|
||||||
|
|
||||||
/// Execute current package, switching if needed.
|
/// Execute current package, switching if needed.
|
||||||
void execute (const MWWorld::Ptr& actor,float duration);
|
void execute (const MWWorld::Ptr& actor,float duration);
|
||||||
|
|
||||||
|
|
|
@ -489,12 +489,13 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim
|
||||||
mIdleState = CharState_Idle;
|
mIdleState = CharState_Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshCurrentAnims(mIdleState, mMovementState, true);
|
|
||||||
|
|
||||||
if(mDeathState != CharState_None)
|
if(mDeathState != CharState_None)
|
||||||
{
|
{
|
||||||
playRandomDeath(1.0f);
|
playRandomDeath(1.0f);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
refreshCurrentAnims(mIdleState, mMovementState, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
CharacterController::~CharacterController()
|
CharacterController::~CharacterController()
|
||||||
|
|
|
@ -21,194 +21,199 @@ namespace MWRender
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
|
|
||||||
class Movement;
|
class Movement;
|
||||||
class CreatureStats;
|
class CreatureStats;
|
||||||
|
|
||||||
enum Priority {
|
///Priority of actions
|
||||||
Priority_Default,
|
enum Priority {
|
||||||
Priority_Jump,
|
Priority_Default,
|
||||||
Priority_Movement,
|
Priority_Jump,
|
||||||
Priority_Hit,
|
Priority_Movement,
|
||||||
Priority_Weapon,
|
Priority_Hit,
|
||||||
Priority_Knockdown,
|
Priority_Weapon,
|
||||||
Priority_Torch,
|
Priority_Knockdown,
|
||||||
|
Priority_Torch,
|
||||||
|
|
||||||
Priority_Death,
|
Priority_Death,
|
||||||
|
|
||||||
Num_Priorities
|
Num_Priorities
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CharacterState {
|
/// Current action of the character
|
||||||
CharState_None,
|
enum CharacterState {
|
||||||
|
CharState_None,
|
||||||
|
|
||||||
CharState_SpecialIdle,
|
CharState_SpecialIdle,
|
||||||
CharState_Idle,
|
CharState_Idle,
|
||||||
CharState_Idle2,
|
CharState_Idle2,
|
||||||
CharState_Idle3,
|
CharState_Idle3,
|
||||||
CharState_Idle4,
|
CharState_Idle4,
|
||||||
CharState_Idle5,
|
CharState_Idle5,
|
||||||
CharState_Idle6,
|
CharState_Idle6,
|
||||||
CharState_Idle7,
|
CharState_Idle7,
|
||||||
CharState_Idle8,
|
CharState_Idle8,
|
||||||
CharState_Idle9,
|
CharState_Idle9,
|
||||||
CharState_IdleSwim,
|
CharState_IdleSwim,
|
||||||
CharState_IdleSneak,
|
CharState_IdleSneak,
|
||||||
|
|
||||||
CharState_WalkForward,
|
CharState_WalkForward,
|
||||||
CharState_WalkBack,
|
CharState_WalkBack,
|
||||||
CharState_WalkLeft,
|
CharState_WalkLeft,
|
||||||
CharState_WalkRight,
|
CharState_WalkRight,
|
||||||
|
|
||||||
CharState_SwimWalkForward,
|
CharState_SwimWalkForward,
|
||||||
CharState_SwimWalkBack,
|
CharState_SwimWalkBack,
|
||||||
CharState_SwimWalkLeft,
|
CharState_SwimWalkLeft,
|
||||||
CharState_SwimWalkRight,
|
CharState_SwimWalkRight,
|
||||||
|
|
||||||
CharState_RunForward,
|
CharState_RunForward,
|
||||||
CharState_RunBack,
|
CharState_RunBack,
|
||||||
CharState_RunLeft,
|
CharState_RunLeft,
|
||||||
CharState_RunRight,
|
CharState_RunRight,
|
||||||
|
|
||||||
CharState_SwimRunForward,
|
CharState_SwimRunForward,
|
||||||
CharState_SwimRunBack,
|
CharState_SwimRunBack,
|
||||||
CharState_SwimRunLeft,
|
CharState_SwimRunLeft,
|
||||||
CharState_SwimRunRight,
|
CharState_SwimRunRight,
|
||||||
|
|
||||||
CharState_SneakForward,
|
CharState_SneakForward,
|
||||||
CharState_SneakBack,
|
CharState_SneakBack,
|
||||||
CharState_SneakLeft,
|
CharState_SneakLeft,
|
||||||
CharState_SneakRight,
|
CharState_SneakRight,
|
||||||
|
|
||||||
CharState_TurnLeft,
|
CharState_TurnLeft,
|
||||||
CharState_TurnRight,
|
CharState_TurnRight,
|
||||||
|
|
||||||
CharState_Jump,
|
CharState_Jump,
|
||||||
|
|
||||||
CharState_Death1,
|
CharState_Death1,
|
||||||
CharState_Death2,
|
CharState_Death2,
|
||||||
CharState_Death3,
|
CharState_Death3,
|
||||||
CharState_Death4,
|
CharState_Death4,
|
||||||
CharState_Death5,
|
CharState_Death5,
|
||||||
CharState_SwimDeath,
|
CharState_SwimDeath,
|
||||||
CharState_DeathKnockDown,
|
CharState_DeathKnockDown,
|
||||||
CharState_DeathKnockOut,
|
CharState_DeathKnockOut,
|
||||||
|
|
||||||
CharState_Hit,
|
CharState_Hit,
|
||||||
CharState_KnockDown,
|
CharState_KnockDown,
|
||||||
CharState_KnockOut,
|
CharState_KnockOut,
|
||||||
CharState_Block
|
CharState_Block
|
||||||
};
|
};
|
||||||
|
|
||||||
enum WeaponType {
|
///Weapon type
|
||||||
WeapType_None,
|
enum WeaponType {
|
||||||
|
WeapType_None,
|
||||||
|
|
||||||
WeapType_HandToHand,
|
WeapType_HandToHand,
|
||||||
WeapType_OneHand,
|
WeapType_OneHand,
|
||||||
WeapType_TwoHand,
|
WeapType_TwoHand,
|
||||||
WeapType_TwoWide,
|
WeapType_TwoWide,
|
||||||
WeapType_BowAndArrow,
|
WeapType_BowAndArrow,
|
||||||
WeapType_Crossbow,
|
WeapType_Crossbow,
|
||||||
WeapType_Thrown,
|
WeapType_Thrown,
|
||||||
WeapType_PickProbe,
|
WeapType_PickProbe,
|
||||||
|
|
||||||
WeapType_Spell
|
WeapType_Spell
|
||||||
};
|
};
|
||||||
|
|
||||||
enum UpperBodyCharacterState {
|
///Specific, weapon based state of the character
|
||||||
UpperCharState_Nothing,
|
enum UpperBodyCharacterState {
|
||||||
UpperCharState_EquipingWeap,
|
UpperCharState_Nothing,
|
||||||
UpperCharState_UnEquipingWeap,
|
UpperCharState_EquipingWeap,
|
||||||
UpperCharState_WeapEquiped,
|
UpperCharState_UnEquipingWeap,
|
||||||
UpperCharState_StartToMinAttack,
|
UpperCharState_WeapEquiped,
|
||||||
UpperCharState_MinAttackToMaxAttack,
|
UpperCharState_StartToMinAttack,
|
||||||
UpperCharState_MaxAttackToMinHit,
|
UpperCharState_MinAttackToMaxAttack,
|
||||||
UpperCharState_MinHitToHit,
|
UpperCharState_MaxAttackToMinHit,
|
||||||
UpperCharState_FollowStartToFollowStop,
|
UpperCharState_MinHitToHit,
|
||||||
UpperCharState_CastingSpell
|
UpperCharState_FollowStartToFollowStop,
|
||||||
};
|
UpperCharState_CastingSpell
|
||||||
|
};
|
||||||
|
|
||||||
enum JumpingState {
|
///Current jumping state
|
||||||
JumpState_None,
|
enum JumpingState {
|
||||||
JumpState_Falling,
|
JumpState_None,
|
||||||
JumpState_Landing
|
JumpState_Falling,
|
||||||
};
|
JumpState_Landing
|
||||||
|
};
|
||||||
|
|
||||||
class CharacterController
|
class CharacterController
|
||||||
{
|
{
|
||||||
MWWorld::Ptr mPtr;
|
MWWorld::Ptr mPtr;
|
||||||
MWRender::Animation *mAnimation;
|
MWRender::Animation *mAnimation;
|
||||||
|
|
||||||
typedef std::deque<std::pair<std::string,size_t> > AnimationQueue;
|
typedef std::deque<std::pair<std::string,size_t> > AnimationQueue;
|
||||||
AnimationQueue mAnimQueue;
|
AnimationQueue mAnimQueue;
|
||||||
|
|
||||||
CharacterState mIdleState;
|
CharacterState mIdleState;
|
||||||
std::string mCurrentIdle;
|
std::string mCurrentIdle;
|
||||||
|
|
||||||
CharacterState mMovementState;
|
CharacterState mMovementState;
|
||||||
std::string mCurrentMovement;
|
std::string mCurrentMovement;
|
||||||
float mMovementSpeed;
|
float mMovementSpeed;
|
||||||
float mMovementAnimVelocity;
|
float mMovementAnimVelocity;
|
||||||
|
|
||||||
CharacterState mDeathState;
|
CharacterState mDeathState;
|
||||||
std::string mCurrentDeath;
|
std::string mCurrentDeath;
|
||||||
|
|
||||||
CharacterState mHitState;
|
CharacterState mHitState;
|
||||||
std::string mCurrentHit;
|
std::string mCurrentHit;
|
||||||
|
|
||||||
UpperBodyCharacterState mUpperBodyState;
|
UpperBodyCharacterState mUpperBodyState;
|
||||||
|
|
||||||
JumpingState mJumpState;
|
JumpingState mJumpState;
|
||||||
std::string mCurrentJump;
|
std::string mCurrentJump;
|
||||||
|
|
||||||
WeaponType mWeaponType;
|
WeaponType mWeaponType;
|
||||||
std::string mCurrentWeapon;
|
std::string mCurrentWeapon;
|
||||||
|
|
||||||
bool mSkipAnim;
|
bool mSkipAnim;
|
||||||
|
|
||||||
// counted for skill increase
|
// counted for skill increase
|
||||||
float mSecondsOfSwimming;
|
float mSecondsOfSwimming;
|
||||||
float mSecondsOfRunning;
|
float mSecondsOfRunning;
|
||||||
|
|
||||||
std::string mAttackType; // slash, chop or thrust
|
std::string mAttackType; // slash, chop or thrust
|
||||||
void determineAttackType();
|
void determineAttackType();
|
||||||
|
|
||||||
void refreshCurrentAnims(CharacterState idle, CharacterState movement, bool force=false);
|
void refreshCurrentAnims(CharacterState idle, CharacterState movement, bool force=false);
|
||||||
|
|
||||||
void clearAnimQueue();
|
void clearAnimQueue();
|
||||||
|
|
||||||
bool updateWeaponState();
|
bool updateWeaponState();
|
||||||
bool updateCreatureState();
|
bool updateCreatureState();
|
||||||
|
|
||||||
void updateVisibility();
|
void updateVisibility();
|
||||||
|
|
||||||
void playRandomDeath(float startpoint = 0.0f);
|
void playRandomDeath(float startpoint = 0.0f);
|
||||||
|
|
||||||
/// choose a random animation group with \a prefix and numeric suffix
|
/// choose a random animation group with \a prefix and numeric suffix
|
||||||
/// @param num if non-NULL, the chosen animation number will be written here
|
/// @param num if non-NULL, the chosen animation number will be written here
|
||||||
std::string chooseRandomGroup (const std::string& prefix, int* num = NULL);
|
std::string chooseRandomGroup (const std::string& prefix, int* num = NULL);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim);
|
CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim);
|
||||||
virtual ~CharacterController();
|
virtual ~CharacterController();
|
||||||
|
|
||||||
// Be careful when to call this, see comment in Actors
|
// Be careful when to call this, see comment in Actors
|
||||||
void updateContinuousVfx();
|
void updateContinuousVfx();
|
||||||
|
|
||||||
void updatePtr(const MWWorld::Ptr &ptr);
|
void updatePtr(const MWWorld::Ptr &ptr);
|
||||||
|
|
||||||
void update(float duration);
|
void update(float duration);
|
||||||
|
|
||||||
void playGroup(const std::string &groupname, int mode, int count);
|
void playGroup(const std::string &groupname, int mode, int count);
|
||||||
void skipAnim();
|
void skipAnim();
|
||||||
bool isAnimPlaying(const std::string &groupName);
|
bool isAnimPlaying(const std::string &groupName);
|
||||||
|
|
||||||
bool kill();
|
bool kill();
|
||||||
void resurrect();
|
void resurrect();
|
||||||
bool isDead() const
|
bool isDead() const
|
||||||
{ return mDeathState != CharState_None; }
|
{ return mDeathState != CharState_None; }
|
||||||
|
|
||||||
void forceStateUpdate();
|
void forceStateUpdate();
|
||||||
};
|
};
|
||||||
|
|
||||||
void getWeaponGroup(WeaponType weaptype, std::string &group);
|
void getWeaponGroup(WeaponType weaptype, std::string &group);
|
||||||
MWWorld::ContainerStoreIterator getActiveWeapon(CreatureStats &stats, MWWorld::InventoryStore &inv, WeaponType *weaptype);
|
MWWorld::ContainerStoreIterator getActiveWeapon(CreatureStats &stats, MWWorld::InventoryStore &inv, WeaponType *weaptype);
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace MWMechanics
|
||||||
return mPath.size();
|
return mPath.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<ESM::Pathgrid::Point> getPath() const
|
const std::list<ESM::Pathgrid::Point>& getPath() const
|
||||||
{
|
{
|
||||||
return mPath;
|
return mPath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,10 @@ namespace MWRender
|
||||||
|
|
||||||
virtual void rebuild();
|
virtual void rebuild();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CharacterPreview(const CharacterPreview&);
|
||||||
|
CharacterPreview& operator=(const CharacterPreview&);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool renderHeadOnly() { return false; }
|
virtual bool renderHeadOnly() { return false; }
|
||||||
|
|
||||||
|
|
|
@ -563,7 +563,8 @@ void RenderingManager::configureAmbient(MWWorld::CellStore &mCell)
|
||||||
Ogre::ColourValue colour;
|
Ogre::ColourValue colour;
|
||||||
colour.setAsABGR (mCell.getCell()->mAmbi.mSunlight);
|
colour.setAsABGR (mCell.getCell()->mAmbi.mSunlight);
|
||||||
mSun->setDiffuseColour (colour);
|
mSun->setDiffuseColour (colour);
|
||||||
mSun->setDirection(0,-1,0);
|
mSun->setDirection(1,-1,-1);
|
||||||
|
sunEnable(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Switch through lighting modes.
|
// Switch through lighting modes.
|
||||||
|
|
|
@ -28,7 +28,9 @@ RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager)
|
||||||
mRippleAreaLength(1000),
|
mRippleAreaLength(1000),
|
||||||
mImpulseSize(20),
|
mImpulseSize(20),
|
||||||
mTexelOffset(0,0),
|
mTexelOffset(0,0),
|
||||||
mFirstUpdate(true)
|
mFirstUpdate(true),
|
||||||
|
mRectangle(NULL),
|
||||||
|
mImpulse(NULL)
|
||||||
{
|
{
|
||||||
Ogre::AxisAlignedBox aabInf;
|
Ogre::AxisAlignedBox aabInf;
|
||||||
aabInf.setInfinite();
|
aabInf.setInfinite();
|
||||||
|
@ -105,6 +107,7 @@ RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager)
|
||||||
RippleSimulation::~RippleSimulation()
|
RippleSimulation::~RippleSimulation()
|
||||||
{
|
{
|
||||||
delete mRectangle;
|
delete mRectangle;
|
||||||
|
delete mImpulse;
|
||||||
|
|
||||||
Ogre::Root::getSingleton().destroySceneManager(mSceneMgr);
|
Ogre::Root::getSingleton().destroySceneManager(mSceneMgr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,7 +201,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
|
||||||
+MWBase::Environment::get().getWorld()->countSavedGameRecords()
|
+MWBase::Environment::get().getWorld()->countSavedGameRecords()
|
||||||
+MWBase::Environment::get().getScriptManager()->getGlobalScripts().countSavedGameRecords()
|
+MWBase::Environment::get().getScriptManager()->getGlobalScripts().countSavedGameRecords()
|
||||||
+MWBase::Environment::get().getDialogueManager()->countSavedGameRecords()
|
+MWBase::Environment::get().getDialogueManager()->countSavedGameRecords()
|
||||||
+1; // global map
|
+MWBase::Environment::get().getWindowManager()->countSavedGameRecords();
|
||||||
writer.setRecordCount (recordCount);
|
writer.setRecordCount (recordCount);
|
||||||
|
|
||||||
writer.save (stream);
|
writer.save (stream);
|
||||||
|
@ -235,8 +235,9 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
|
||||||
|
|
||||||
void MWState::StateManager::quickSave (std::string name)
|
void MWState::StateManager::quickSave (std::string name)
|
||||||
{
|
{
|
||||||
if (mState!=State_Running ||
|
if (!(mState==State_Running &&
|
||||||
MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")!=-1) // char gen
|
MWBase::Environment::get().getWorld()->getGlobalInt ("chargenstate")==-1 // char gen
|
||||||
|
&& MWBase::Environment::get().getWindowManager()->isSavingAllowed()))
|
||||||
{
|
{
|
||||||
//You can not save your game right now
|
//You can not save your game right now
|
||||||
MWBase::Environment::get().getWindowManager()->messageBox("#{sSaveGameDenied}");
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sSaveGameDenied}");
|
||||||
|
@ -323,7 +324,7 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ESM::REC_GMAP:
|
case ESM::REC_GMAP:
|
||||||
|
case ESM::REC_KEYS:
|
||||||
MWBase::Environment::get().getWindowManager()->readRecord(reader, n.val);
|
MWBase::Environment::get().getWindowManager()->readRecord(reader, n.val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -231,6 +231,8 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr
|
||||||
{
|
{
|
||||||
CellStore *cell;
|
CellStore *cell;
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWorld()->getLocalScripts().add(script, item);
|
||||||
|
|
||||||
if(&(MWWorld::Class::get (player).getContainerStore (player)) == this)
|
if(&(MWWorld::Class::get (player).getContainerStore (player)) == this)
|
||||||
{
|
{
|
||||||
cell = 0; // Items in player's inventory have cell set to 0, so their scripts will never be removed
|
cell = 0; // Items in player's inventory have cell set to 0, so their scripts will never be removed
|
||||||
|
@ -243,7 +245,6 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr
|
||||||
|
|
||||||
item.mCell = cell;
|
item.mCell = cell;
|
||||||
item.mContainerStore = 0;
|
item.mContainerStore = 0;
|
||||||
MWBase::Environment::get().getWorld()->getLocalScripts().add(script, item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return it;
|
return it;
|
||||||
|
|
|
@ -227,10 +227,6 @@ namespace MWWorld
|
||||||
Ogre::Vector3 inertia(0.0f);
|
Ogre::Vector3 inertia(0.0f);
|
||||||
Ogre::Vector3 velocity;
|
Ogre::Vector3 velocity;
|
||||||
|
|
||||||
bool canWalk = ptr.getClass().canWalk(ptr);
|
|
||||||
bool isBipedal = ptr.getClass().isBipedal(ptr);
|
|
||||||
bool isNpc = ptr.getClass().isNpc();
|
|
||||||
|
|
||||||
if(position.z < waterlevel || isFlying) // under water by 3/4 or can fly
|
if(position.z < waterlevel || isFlying) // under water by 3/4 or can fly
|
||||||
{
|
{
|
||||||
// TODO: Shouldn't water have higher drag in calculating velocity?
|
// TODO: Shouldn't water have higher drag in calculating velocity?
|
||||||
|
@ -277,14 +273,11 @@ namespace MWWorld
|
||||||
// NOTE: velocity is either z axis only or x & z axis
|
// NOTE: velocity is either z axis only or x & z axis
|
||||||
Ogre::Vector3 nextpos = newPosition + velocity * remainingTime;
|
Ogre::Vector3 nextpos = newPosition + velocity * remainingTime;
|
||||||
|
|
||||||
// If not able to fly, walk or bipedal don't allow to move out of water
|
// If not able to fly, don't allow to swim up into the air
|
||||||
// TODO: this if condition may not work for large creatures or situations
|
// TODO: this if condition may not work for large creatures or situations
|
||||||
// where the creature gets above the waterline for some reason
|
// where the creature gets above the waterline for some reason
|
||||||
if(newPosition.z < waterlevel && // started 3/4 under water
|
if(newPosition.z < waterlevel && // started 3/4 under water
|
||||||
!isFlying && // can't fly
|
!isFlying && // can't fly
|
||||||
!canWalk && // can't walk
|
|
||||||
!isBipedal && // not bipedal (assume bipedals can walk)
|
|
||||||
!isNpc && // FIXME: shouldn't really need this
|
|
||||||
nextpos.z > waterlevel && // but about to go above water
|
nextpos.z > waterlevel && // but about to go above water
|
||||||
newPosition.z <= waterlevel)
|
newPosition.z <= waterlevel)
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace MWWorld
|
||||||
mTeleported(false),
|
mTeleported(false),
|
||||||
mMarkedCell(NULL),
|
mMarkedCell(NULL),
|
||||||
mCurrentCrimeId(-1),
|
mCurrentCrimeId(-1),
|
||||||
mPayedCrimeId(-1)
|
mPaidCrimeId(-1)
|
||||||
{
|
{
|
||||||
mPlayer.mBase = player;
|
mPlayer.mBase = player;
|
||||||
mPlayer.mRef.mRefID = "player";
|
mPlayer.mRef.mRefID = "player";
|
||||||
|
@ -223,7 +223,7 @@ namespace MWWorld
|
||||||
player.mCellId = mCellStore->getCell()->getCellId();
|
player.mCellId = mCellStore->getCell()->getCellId();
|
||||||
|
|
||||||
player.mCurrentCrimeId = mCurrentCrimeId;
|
player.mCurrentCrimeId = mCurrentCrimeId;
|
||||||
player.mPayedCrimeId = mPayedCrimeId;
|
player.mPaidCrimeId = mPaidCrimeId;
|
||||||
|
|
||||||
player.mBirthsign = mSign;
|
player.mBirthsign = mSign;
|
||||||
|
|
||||||
|
@ -273,7 +273,7 @@ namespace MWWorld
|
||||||
throw std::runtime_error ("invalid player state record (birthsign)");
|
throw std::runtime_error ("invalid player state record (birthsign)");
|
||||||
|
|
||||||
mCurrentCrimeId = player.mCurrentCrimeId;
|
mCurrentCrimeId = player.mCurrentCrimeId;
|
||||||
mPayedCrimeId = player.mPayedCrimeId;
|
mPaidCrimeId = player.mPaidCrimeId;
|
||||||
|
|
||||||
mSign = player.mBirthsign;
|
mSign = player.mBirthsign;
|
||||||
|
|
||||||
|
@ -318,11 +318,11 @@ namespace MWWorld
|
||||||
|
|
||||||
void Player::recordCrimeId()
|
void Player::recordCrimeId()
|
||||||
{
|
{
|
||||||
mPayedCrimeId = mCurrentCrimeId;
|
mPaidCrimeId = mCurrentCrimeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Player::getCrimeId() const
|
int Player::getCrimeId() const
|
||||||
{
|
{
|
||||||
return mPayedCrimeId;
|
return mPaidCrimeId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace MWWorld
|
||||||
bool mTeleported;
|
bool mTeleported;
|
||||||
|
|
||||||
int mCurrentCrimeId; // the id assigned witnesses
|
int mCurrentCrimeId; // the id assigned witnesses
|
||||||
int mPayedCrimeId; // the last id payed off (0 bounty)
|
int mPaidCrimeId; // the last id paid off (0 bounty)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -105,8 +105,8 @@ namespace MWWorld
|
||||||
bool readRecord (ESM::ESMReader& reader, int32_t type);
|
bool readRecord (ESM::ESMReader& reader, int32_t type);
|
||||||
|
|
||||||
int getNewCrimeId(); // get new id for witnesses
|
int getNewCrimeId(); // get new id for witnesses
|
||||||
void recordCrimeId(); // record the payed crime id when bounty is 0
|
void recordCrimeId(); // record the paid crime id when bounty is 0
|
||||||
int getCrimeId() const; // get the last payed crime id
|
int getCrimeId() const; // get the last paid crime id
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -329,7 +329,6 @@ void WeatherManager::update(float duration)
|
||||||
const bool exterior = (world->isCellExterior() || world->isCellQuasiExterior());
|
const bool exterior = (world->isCellExterior() || world->isCellQuasiExterior());
|
||||||
if (!exterior)
|
if (!exterior)
|
||||||
{
|
{
|
||||||
mRendering->sunDisable(false);
|
|
||||||
mRendering->skyDisable();
|
mRendering->skyDisable();
|
||||||
mRendering->getSkyManager()->setLightningStrength(0.f);
|
mRendering->getSkyManager()->setLightningStrength(0.f);
|
||||||
stopSounds(true);
|
stopSounds(true);
|
||||||
|
|
|
@ -45,7 +45,7 @@ add_component_dir (esm
|
||||||
loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat
|
loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat
|
||||||
loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter
|
loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter
|
||||||
savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate dialoguestate statstate
|
savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate dialoguestate statstate
|
||||||
npcstats creaturestats weatherstate
|
npcstats creaturestats weatherstate quickkeys
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (misc
|
add_component_dir (misc
|
||||||
|
|
|
@ -34,6 +34,12 @@ struct Position
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
template <int a, int b, int c, int d>
|
||||||
|
struct FourCC
|
||||||
|
{
|
||||||
|
static const unsigned int value = (((((d << 8) | c) << 8) | b) << 8) | a;
|
||||||
|
};
|
||||||
|
|
||||||
enum RecNameInts
|
enum RecNameInts
|
||||||
{
|
{
|
||||||
// format 0 / legacy
|
// format 0 / legacy
|
||||||
|
@ -93,6 +99,7 @@ enum RecNameInts
|
||||||
REC_GMAP = 0x50414d47,
|
REC_GMAP = 0x50414d47,
|
||||||
REC_DIAS = 0x53414944,
|
REC_DIAS = 0x53414944,
|
||||||
REC_WTHR = 0x52485457,
|
REC_WTHR = 0x52485457,
|
||||||
|
REC_KEYS = FourCC<'K','E','Y','S'>::value,
|
||||||
|
|
||||||
// format 1
|
// format 1
|
||||||
REC_FILT = 0x544C4946
|
REC_FILT = 0x544C4946
|
||||||
|
|
|
@ -33,7 +33,7 @@ struct Creature
|
||||||
|
|
||||||
Respawn = 0x002,
|
Respawn = 0x002,
|
||||||
Weapon = 0x004, // Has weapon and shield
|
Weapon = 0x004, // Has weapon and shield
|
||||||
None = 0x008, // ??
|
None = 0x008, // ?? This flag appears set for every creature in Morrowind.esm
|
||||||
Essential = 0x080,
|
Essential = 0x080,
|
||||||
|
|
||||||
// Blood types
|
// Blood types
|
||||||
|
|
|
@ -28,8 +28,8 @@ void ESM::Player::load (ESMReader &esm)
|
||||||
|
|
||||||
mCurrentCrimeId = -1;
|
mCurrentCrimeId = -1;
|
||||||
esm.getHNOT (mCurrentCrimeId, "CURD");
|
esm.getHNOT (mCurrentCrimeId, "CURD");
|
||||||
mPayedCrimeId = -1;
|
mPaidCrimeId = -1;
|
||||||
esm.getHNOT (mPayedCrimeId, "PAYD");
|
esm.getHNOT (mPaidCrimeId, "PAYD");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESM::Player::save (ESMWriter &esm) const
|
void ESM::Player::save (ESMWriter &esm) const
|
||||||
|
@ -52,5 +52,5 @@ void ESM::Player::save (ESMWriter &esm) const
|
||||||
esm.writeHNString ("SIGN", mBirthsign);
|
esm.writeHNString ("SIGN", mBirthsign);
|
||||||
|
|
||||||
esm.writeHNT ("CURD", mCurrentCrimeId);
|
esm.writeHNT ("CURD", mCurrentCrimeId);
|
||||||
esm.writeHNT ("PAYD", mPayedCrimeId);
|
esm.writeHNT ("PAYD", mPaidCrimeId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,11 @@ namespace ESM
|
||||||
std::string mBirthsign;
|
std::string mBirthsign;
|
||||||
|
|
||||||
int mCurrentCrimeId;
|
int mCurrentCrimeId;
|
||||||
int mPayedCrimeId;
|
int mPaidCrimeId;
|
||||||
|
|
||||||
void load (ESMReader &esm);
|
void load (ESMReader &esm);
|
||||||
void save (ESMWriter &esm) const;
|
void save (ESMWriter &esm) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
43
components/esm/quickkeys.cpp
Normal file
43
components/esm/quickkeys.cpp
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#include "quickkeys.hpp"
|
||||||
|
|
||||||
|
#include "esmwriter.hpp"
|
||||||
|
#include "esmreader.hpp"
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
|
||||||
|
void QuickKeys::load(ESMReader &esm)
|
||||||
|
{
|
||||||
|
while (esm.isNextSub("KEY_"))
|
||||||
|
{
|
||||||
|
esm.getSubHeader();
|
||||||
|
int keyType;
|
||||||
|
esm.getHNT(keyType, "TYPE");
|
||||||
|
std::string id;
|
||||||
|
id = esm.getHNString("ID__");
|
||||||
|
|
||||||
|
QuickKey key;
|
||||||
|
key.mType = keyType;
|
||||||
|
key.mId = id;
|
||||||
|
|
||||||
|
mKeys.push_back(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QuickKeys::save(ESMWriter &esm) const
|
||||||
|
{
|
||||||
|
const std::string recKey = "KEY_";
|
||||||
|
|
||||||
|
for (std::vector<QuickKey>::const_iterator it = mKeys.begin(); it != mKeys.end(); ++it)
|
||||||
|
{
|
||||||
|
esm.startSubRecord(recKey);
|
||||||
|
|
||||||
|
esm.writeHNT("TYPE", it->mType);
|
||||||
|
esm.writeHNString("ID__", it->mId);
|
||||||
|
|
||||||
|
esm.endRecord(recKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
28
components/esm/quickkeys.hpp
Normal file
28
components/esm/quickkeys.hpp
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef OPENMW_COMPONENTS_ESM_QUICKKEYS_H
|
||||||
|
#define OPENMW_COMPONENTS_ESM_QUICKKEYS_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
class ESMReader;
|
||||||
|
class ESMWriter;
|
||||||
|
|
||||||
|
struct QuickKeys
|
||||||
|
{
|
||||||
|
struct QuickKey
|
||||||
|
{
|
||||||
|
int mType;
|
||||||
|
std::string mId; // Spell or Item ID
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<QuickKey> mKeys;
|
||||||
|
|
||||||
|
void load (ESMReader &esm);
|
||||||
|
void save (ESMWriter &esm) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -62,6 +62,7 @@ namespace OgreInit
|
||||||
OgreInit::~OgreInit()
|
OgreInit::~OgreInit()
|
||||||
{
|
{
|
||||||
delete mRoot;
|
delete mRoot;
|
||||||
|
delete Ogre::LogManager::getSingletonPtr();
|
||||||
|
|
||||||
std::vector<Ogre::ParticleEmitterFactory*>::iterator ei;
|
std::vector<Ogre::ParticleEmitterFactory*>::iterator ei;
|
||||||
for(ei = mEmitterFactories.begin();ei != mEmitterFactories.end();++ei)
|
for(ei = mEmitterFactories.begin();ei != mEmitterFactories.end();++ei)
|
||||||
|
|
|
@ -337,6 +337,8 @@ namespace Terrain
|
||||||
it->mTarget->loadLayers(*it);
|
it->mTarget->loadLayers(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete data;
|
||||||
|
|
||||||
mRootNode->loadMaterials();
|
mRootNode->loadMaterials();
|
||||||
|
|
||||||
mLayerLoadPending = false;
|
mLayerLoadPending = false;
|
||||||
|
|
6
extern/sdl4ogre/sdlinputwrapper.cpp
vendored
6
extern/sdl4ogre/sdlinputwrapper.cpp
vendored
|
@ -115,7 +115,7 @@ namespace SFO
|
||||||
mWindowListener->windowClosed();
|
mWindowListener->windowClosed();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
std::cerr << "Unhandled SDL event of type " << evt.type << std::endl;
|
std::cerr << "Unhandled SDL event of type 0x" << std::hex << evt.type << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,8 +241,8 @@ namespace SFO
|
||||||
|
|
||||||
//eep, wrap the pointer manually if the input driver doesn't support
|
//eep, wrap the pointer manually if the input driver doesn't support
|
||||||
//relative positioning natively
|
//relative positioning natively
|
||||||
int success = SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE);
|
bool success = SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE) == 0;
|
||||||
if(relative && success != 0)
|
if(relative && !success)
|
||||||
mWrapPointer = true;
|
mWrapPointer = true;
|
||||||
|
|
||||||
//now remove all mouse events using the old setting from the queue
|
//now remove all mouse events using the old setting from the queue
|
||||||
|
|
|
@ -49,22 +49,6 @@
|
||||||
<BasisSkin type="SimpleText" offset="0 0 16 16" align="Stretch"/>
|
<BasisSkin type="SimpleText" offset="0 0 16 16" align="Stretch"/>
|
||||||
</Skin>
|
</Skin>
|
||||||
|
|
||||||
<Skin name="DaedricText" size="16 16">
|
|
||||||
<Property key="FontName" value="daedric36"/>
|
|
||||||
<Property key="FontHeight" value="36"/>
|
|
||||||
<Property key="TextAlign" value="Default"/>
|
|
||||||
<Property key="TextColour" value="1 1 1"/>
|
|
||||||
<BasisSkin type="SimpleText" offset="0 0 16 16" align="Stretch"/>
|
|
||||||
</Skin>
|
|
||||||
|
|
||||||
<Skin name="DaedricText_orig" size="16 16">
|
|
||||||
<Property key="FontName" value="daedric_orig36"/>
|
|
||||||
<Property key="FontHeight" value="36"/>
|
|
||||||
<Property key="TextAlign" value="Default"/>
|
|
||||||
<Property key="TextColour" value="1 1 1"/>
|
|
||||||
<BasisSkin type="SimpleText" offset="0 0 16 16" align="Stretch"/>
|
|
||||||
</Skin>
|
|
||||||
|
|
||||||
<Skin name="MW_StatNameC" size="200 18">
|
<Skin name="MW_StatNameC" size="200 18">
|
||||||
<Child type="TextBoxC" skin="SandText" offset="0 0 200 18" align="Left HStretch" name="StatName"/>
|
<Child type="TextBoxC" skin="SandText" offset="0 0 200 18" align="Left HStretch" name="StatName"/>
|
||||||
</Skin>
|
</Skin>
|
||||||
|
|
|
@ -133,9 +133,9 @@ distant land = false
|
||||||
shader = true
|
shader = true
|
||||||
|
|
||||||
[Water]
|
[Water]
|
||||||
shader = true
|
shader = false
|
||||||
|
|
||||||
refraction = true
|
refraction = false
|
||||||
|
|
||||||
rtt size = 512
|
rtt size = 512
|
||||||
reflect terrain = true
|
reflect terrain = true
|
||||||
|
|
Loading…
Reference in a new issue