Merge pull request #384 from TES3MP/0.6.3 while resolving conflicts

Conflicts:
 	apps/openmw-mp/Player.cpp
	apps/openmw-mp/Script/Functions/Mechanics.cpp
	apps/openmw-mp/Script/Functions/Mechanics.hpp
	apps/openmw-mp/Script/Functions/Quests.cpp
	apps/openmw-mp/Script/Functions/Quests.hpp
	apps/openmw-mp/Script/ScriptFunctions.hpp
	apps/openmw-mp/processors/player/ProcessorRecordDynamic.hpp
	apps/openmw/mwmp/LocalPlayer.hpp
	apps/openmw/mwmp/WorldEvent.cpp
	apps/openmw/mwworld/worldimp.cpp
	components/openmw-mp/Base/BasePlayer.hpp
sol2-server-rewrite
David Cernat 7 years ago
commit ac374a8ef9

@ -6,6 +6,7 @@ set(LAUNCHER
playpage.cpp playpage.cpp
textslotmsgbox.cpp textslotmsgbox.cpp
settingspage.cpp settingspage.cpp
advancedpage.cpp
utils/profilescombobox.cpp utils/profilescombobox.cpp
utils/textinputdialog.cpp utils/textinputdialog.cpp
@ -21,6 +22,7 @@ set(LAUNCHER_HEADER
playpage.hpp playpage.hpp
textslotmsgbox.hpp textslotmsgbox.hpp
settingspage.hpp settingspage.hpp
advancedpage.hpp
utils/profilescombobox.hpp utils/profilescombobox.hpp
utils/textinputdialog.hpp utils/textinputdialog.hpp
@ -35,6 +37,7 @@ set(LAUNCHER_HEADER_MOC
playpage.hpp playpage.hpp
textslotmsgbox.hpp textslotmsgbox.hpp
settingspage.hpp settingspage.hpp
advancedpage.hpp
utils/textinputdialog.hpp utils/textinputdialog.hpp
utils/profilescombobox.hpp utils/profilescombobox.hpp
@ -49,6 +52,7 @@ set(LAUNCHER_UI
${CMAKE_SOURCE_DIR}/files/ui/playpage.ui ${CMAKE_SOURCE_DIR}/files/ui/playpage.ui
${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui
${CMAKE_SOURCE_DIR}/files/ui/settingspage.ui ${CMAKE_SOURCE_DIR}/files/ui/settingspage.ui
${CMAKE_SOURCE_DIR}/files/ui/advancedpage.ui
) )
source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER}) source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER})

@ -0,0 +1,89 @@
#include "advancedpage.hpp"
#include <components/files/configurationmanager.hpp>
Launcher::AdvancedPage::AdvancedPage(Files::ConfigurationManager &cfg, Settings::Manager &engineSettings, QWidget *parent)
: QWidget(parent)
, mCfgMgr(cfg)
, mEngineSettings(engineSettings)
{
setObjectName ("AdvancedPage");
setupUi(this);
loadSettings();
}
bool Launcher::AdvancedPage::loadSettings()
{
// Game Settings
loadSettingBool(canLootDuringDeathAnimationCheckBox, "can loot during death animation", "Game");
loadSettingBool(followersAttackOnSightCheckBox, "followers attack on sight", "Game");
loadSettingBool(preventMerchantEquippingCheckBox, "prevent merchant equipping", "Game");
loadSettingBool(showEffectDurationCheckBox, "show effect duration", "Game");
loadSettingBool(showMeleeInfoCheckBox, "show enchant chance", "Game");
loadSettingBool(showMeleeInfoCheckBox, "show melee info", "Game");
loadSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game");
// Expected values are (0, 1, 2, 3)
int showOwnedIndex = mEngineSettings.getInt("show owned", "Game");
// Match the index with the option. Will default to 0 if invalid.
if (showOwnedIndex >= 0 && showOwnedIndex <= 3)
showOwnedComboBox->setCurrentIndex(showOwnedIndex);
// Input Settings
loadSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input");
loadSettingBool(grabCursorCheckBox, "grab cursor", "Input");
loadSettingBool(toggleSneakCheckBox, "toggle sneak", "Input");
// Other Settings
loadSettingBool(timePlayedCheckbox, "timeplayed", "Saves");
QString screenshotFormatString = QString::fromStdString(mEngineSettings.getString("screenshot format", "General")).toUpper();
if (screenshotFormatComboBox->findText(screenshotFormatString) == -1)
screenshotFormatComboBox->addItem(screenshotFormatString);
screenshotFormatComboBox->setCurrentIndex(screenshotFormatComboBox->findText(screenshotFormatString));
return true;
}
void Launcher::AdvancedPage::saveSettings()
{
// Ensure we only set the new settings if they changed. This is to avoid cluttering the
// user settings file (which by definition should only contain settings the user has touched)
// Game Settings
saveSettingBool(canLootDuringDeathAnimationCheckBox, "can loot during death animation", "Game");
saveSettingBool(followersAttackOnSightCheckBox, "followers attack on sight", "Game");
saveSettingBool(preventMerchantEquippingCheckBox, "prevent merchant equipping", "Game");
saveSettingBool(showEffectDurationCheckBox, "show effect duration", "Game");
saveSettingBool(showMeleeInfoCheckBox, "show enchant chance", "Game");
saveSettingBool(showMeleeInfoCheckBox, "show melee info", "Game");
saveSettingBool(showProjectileDamageCheckBox, "show projectile damage", "Game");
int showOwnedCurrentIndex = showOwnedComboBox->currentIndex();
if (showOwnedCurrentIndex != mEngineSettings.getInt("show owned", "Game"))
mEngineSettings.setInt("show owned", "Game", showOwnedCurrentIndex);
// Input Settings
saveSettingBool(allowThirdPersonZoomCheckBox, "allow third person zoom", "Input");
saveSettingBool(grabCursorCheckBox, "grab cursor", "Input");
saveSettingBool(toggleSneakCheckBox, "toggle sneak", "Input");
// Other Settings
saveSettingBool(timePlayedCheckbox, "timeplayed", "Saves");
std::string screenshotFormatString = screenshotFormatComboBox->currentText().toLower().toStdString();
if (screenshotFormatString != mEngineSettings.getString("screenshot format", "General"))
mEngineSettings.setString("screenshot format", "General", screenshotFormatString);
}
void Launcher::AdvancedPage::loadSettingBool(QCheckBox *checkbox, const std::string &setting, const std::string &group) {
if (mEngineSettings.getBool(setting, group))
checkbox->setCheckState(Qt::Checked);
}
void Launcher::AdvancedPage::saveSettingBool(QCheckBox *checkbox, const std::string &setting, const std::string &group) {
bool cValue = checkbox->checkState();
if (cValue != mEngineSettings.getBool(setting, group))
mEngineSettings.setBool(setting, group, cValue);
}

@ -0,0 +1,32 @@
#ifndef ADVANCEDPAGE_H
#define ADVANCEDPAGE_H
#include <QWidget>
#include "ui_advancedpage.h"
#include <components/settings/settings.hpp>
namespace Files { struct ConfigurationManager; }
namespace Launcher
{
class AdvancedPage : public QWidget, private Ui::AdvancedPage
{
Q_OBJECT
public:
AdvancedPage(Files::ConfigurationManager &cfg, Settings::Manager &engineSettings, QWidget *parent = 0);
bool loadSettings();
void saveSettings();
private:
Files::ConfigurationManager &mCfgMgr;
Settings::Manager &mEngineSettings;
void loadSettingBool(QCheckBox *checkbox, const std::string& setting, const std::string& group);
void saveSettingBool(QCheckBox *checkbox, const std::string& setting, const std::string& group);
};
}
#endif

@ -2,9 +2,7 @@
#include <components/version/version.hpp> #include <components/version/version.hpp>
#include <QLabel>
#include <QDate> #include <QDate>
#include <QTime>
#include <QMessageBox> #include <QMessageBox>
#include <QPushButton> #include <QPushButton>
#include <QFontDatabase> #include <QFontDatabase>
@ -12,8 +10,6 @@
#include <QFileDialog> #include <QFileDialog>
#include <QCloseEvent> #include <QCloseEvent>
#include <QTextCodec> #include <QTextCodec>
#include <QFile>
#include <QDir>
#include <QDebug> #include <QDebug>
@ -21,6 +17,7 @@
#include "graphicspage.hpp" #include "graphicspage.hpp"
#include "datafilespage.hpp" #include "datafilespage.hpp"
#include "settingspage.hpp" #include "settingspage.hpp"
#include "advancedpage.hpp"
using namespace Process; using namespace Process;
@ -104,6 +101,12 @@ void Launcher::MainDialog::createIcons()
settingsButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom); settingsButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
settingsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); settingsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
QListWidgetItem *advancedButton = new QListWidgetItem(iconWidget);
advancedButton->setIcon(QIcon::fromTheme("emblem-system"));
advancedButton->setText(tr("Advanced"));
advancedButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
advancedButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
connect(iconWidget, connect(iconWidget,
SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*))); this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*)));
@ -116,6 +119,7 @@ void Launcher::MainDialog::createPages()
mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this); mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
mGraphicsPage = new GraphicsPage(mCfgMgr, mEngineSettings, this); mGraphicsPage = new GraphicsPage(mCfgMgr, mEngineSettings, this);
mSettingsPage = new SettingsPage(mCfgMgr, mGameSettings, mLauncherSettings, this); mSettingsPage = new SettingsPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
mAdvancedPage = new AdvancedPage(mCfgMgr, mEngineSettings, this);
// Set the combobox of the play page to imitate the combobox on the datafilespage // Set the combobox of the play page to imitate the combobox on the datafilespage
mPlayPage->setProfilesModel(mDataFilesPage->profilesModel()); mPlayPage->setProfilesModel(mDataFilesPage->profilesModel());
@ -126,6 +130,7 @@ void Launcher::MainDialog::createPages()
pagesWidget->addWidget(mDataFilesPage); pagesWidget->addWidget(mDataFilesPage);
pagesWidget->addWidget(mGraphicsPage); pagesWidget->addWidget(mGraphicsPage);
pagesWidget->addWidget(mSettingsPage); pagesWidget->addWidget(mSettingsPage);
pagesWidget->addWidget(mAdvancedPage);
// Select the first page // Select the first page
iconWidget->setCurrentItem(iconWidget->item(0), QItemSelectionModel::Select); iconWidget->setCurrentItem(iconWidget->item(0), QItemSelectionModel::Select);
@ -245,6 +250,9 @@ bool Launcher::MainDialog::reloadSettings()
if (!mGraphicsPage->loadSettings()) if (!mGraphicsPage->loadSettings())
return false; return false;
if (!mAdvancedPage->loadSettings())
return false;
return true; return true;
} }
@ -483,6 +491,7 @@ bool Launcher::MainDialog::writeSettings()
mDataFilesPage->saveSettings(); mDataFilesPage->saveSettings();
mGraphicsPage->saveSettings(); mGraphicsPage->saveSettings();
mSettingsPage->saveSettings(); mSettingsPage->saveSettings();
mAdvancedPage->saveSettings();
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str()); QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
QDir dir(userPath); QDir dir(userPath);

@ -30,6 +30,7 @@ namespace Launcher
class DataFilesPage; class DataFilesPage;
class UnshieldThread; class UnshieldThread;
class SettingsPage; class SettingsPage;
class AdvancedPage;
enum FirstRunDialogResult enum FirstRunDialogResult
{ {
@ -88,6 +89,7 @@ namespace Launcher
GraphicsPage *mGraphicsPage; GraphicsPage *mGraphicsPage;
DataFilesPage *mDataFilesPage; DataFilesPage *mDataFilesPage;
SettingsPage *mSettingsPage; SettingsPage *mSettingsPage;
AdvancedPage *mAdvancedPage;
Process::ProcessInvoker *mGameInvoker; Process::ProcessInvoker *mGameInvoker;
Process::ProcessInvoker *mWizardInvoker; Process::ProcessInvoker *mWizardInvoker;

@ -61,6 +61,7 @@ void Player::Init(LuaState &lua)
"hair", sol::property(&Player::getHair, &Player::setHair), "hair", sol::property(&Player::getHair, &Player::setHair),
"birthsign", sol::property(&Player::getBirthsign, &Player::setBirthsign), "birthsign", sol::property(&Player::getBirthsign, &Player::setBirthsign),
"bounty", sol::property(&Player::getBounty, &Player::setBounty), "bounty", sol::property(&Player::getBounty, &Player::setBounty),
"reputation", sol::property(&Player::getReputation, &Player::setReputation),
"levelProgress", sol::property(&Player::getLevelProgress, &Player::setLevelProgress), "levelProgress", sol::property(&Player::getLevelProgress, &Player::setLevelProgress),
"creatureModel", sol::property(&Player::getCreatureModel, &Player::setCreatureModel), "creatureModel", sol::property(&Player::getCreatureModel, &Player::setCreatureModel),
"isCreatureName", sol::property(&Player::isCreatureName, &Player::creatureName), "isCreatureName", sol::property(&Player::isCreatureName, &Player::creatureName),
@ -89,10 +90,18 @@ void Player::Init(LuaState &lua)
"getQuickKeys", &Player::getQuickKeys, "getQuickKeys", &Player::getQuickKeys,
"getWeatherMgr", &Player::getWeatherMgr, "getWeatherMgr", &Player::getWeatherMgr,
"getMarkPosition", &Player::getMarkPosition,
"setMarkPosition", &Player::setMarkPosition,
"getMarkRotation", &Player::getMarkRotation,
"setMarkRotation", &Player::setMarkRotation,
"getMarkCell", &Player::getMarkCell,
"setMarkCell", &Player::setMarkCell,
"getCellState", &Player::getCellState, "getCellState", &Player::getCellState,
"cellStateSize", &Player::cellStateSize, "cellStateSize", &Player::cellStateSize,
"addCellExplored", &Player::addCellExplored, "addCellExplored", &Player::addCellExplored,
"setAuthority", &Player::setAuthority, "setAuthority", &Player::setAuthority,
"storedData", &Player::storedData, "storedData", &Player::storedData,
"customData", &Player::customData, "customData", &Player::customData,
"markedForDeletion", sol::property(&Player::isMarkedForDeleteion) "markedForDeletion", sol::property(&Player::isMarkedForDeleteion)
@ -115,11 +124,15 @@ Player::Player(RakNet::RakNetGUID guid) : BasePlayer(guid), NetActor(), changedM
handshakeCounter = 0; handshakeCounter = 0;
loadState = NOTLOADED; loadState = NOTLOADED;
resetUpdateFlags(); resetUpdateFlags();
cell.blank(); cell.blank();
npc.blank(); npc.blank();
npcStats.blank(); npcStats.blank();
creatureStats.blank(); creatureStats.blank();
charClass.blank(); charClass.blank();
scale = 1;
isWerewolf = false;
markedForDeletion = false; markedForDeletion = false;
storedData = mwmp::Networking::get().getState().getState()->create_table(); storedData = mwmp::Networking::get().getState().getState()->create_table();
customData = mwmp::Networking::get().getState().getState()->create_table(); customData = mwmp::Networking::get().getState().getState()->create_table();
@ -227,6 +240,24 @@ void Player::update()
inventory.resetInventoryFlag(); inventory.resetInventoryFlag();
} }
if (changedMarkLocation)
{
miscellaneousChangeType = mwmp::MiscellaneousChangeType::MarkLocation;
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_MISCELLANEOUS);
packet->setPlayer(this);
packet->Send(false);
changedMarkLocation = false;
}
if (changedSelectedSpell)
{
miscellaneousChangeType = mwmp::MiscellaneousChangeType::SelectedSpell;
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_MISCELLANEOUS);
packet->setPlayer(this);
packet->Send(false);
changedSelectedSpell = false;
}
if (changedMap) if (changedMap)
{ {
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_MAP); auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_MAP);
@ -610,6 +641,22 @@ void Player::setBounty(int bounty)
packet->Send(true); packet->Send(true);
} }
int Player::getReputation() const
{
return npcStats.mReputation;
}
void Player::setReputation(int reputation, bool toOthers)
{
npcStats.mReputation = reputation;
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_REPUTATION);
packet->setPlayer(this);
packet->Send(false);
if (toOthers)
packet->Send(true);
}
int Player::getLevelProgress() const int Player::getLevelProgress() const
{ {
return npcStats.mLevelProgress; return npcStats.mLevelProgress;
@ -806,6 +853,70 @@ void Player::setWerewolfState(bool state)
packet->Send(true); packet->Send(true);
} }
float Player::getScale() const
{
return scale;
}
void Player::setScale(float newScale)
{
scale = newScale;
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_SHAPESHIFT);
packet->setPlayer(this);
packet->Send(false);
packet->Send(true);
}
std::tuple<float, float, float> Player::getMarkPosition()
{
return make_tuple(markPosition.pos[0], markPosition.pos[1], markPosition.pos[2]);
}
void Player::setMarkPosition(float x, float y, float z)
{
markPosition.pos[0] = x;
markPosition.pos[1] = y;
markPosition.pos[2] = z;
changedMarkLocation = true;
}
std::tuple<float, float> Player::getMarkRotation()
{
return make_tuple(markPosition.rot[0], markPosition.rot[2]);
}
void Player::setMarkRotation(float x, float z)
{
markPosition.rot[0] = x;
markPosition.rot[2] = z;
changedMarkLocation = true;
}
std::string Player::getMarkCell()
{
return markCell.getDescription();
}
void Player::setMarkCell(const std::string &cellDescription)
{
markCell = Utils::getCellFromDescription(cellDescription);
changedMarkLocation = true;
}
std::string Player::getSelectedSpell()
{
return selectedSpellId;
}
void Player::setSelectedSpell(const std::string &newSelectedSpell)
{
selectedSpellId = newSelectedSpell;
changedSelectedSpell = true;
}
size_t Player::cellStateSize() const size_t Player::cellStateSize() const
{ {
return cellStateChanges.cellStates.size(); return cellStateChanges.cellStates.size();

@ -104,6 +104,9 @@ public:
int getBounty() const; int getBounty() const;
void setBounty(int bounty); void setBounty(int bounty);
int getReputation() const;
void setReputation(int reputation, bool toOthers);
int getLevel() const; int getLevel() const;
void setLevel(int level); void setLevel(int level);
int getLevelProgress() const; int getLevelProgress() const;
@ -142,6 +145,9 @@ public:
bool getWerewolfState() const; bool getWerewolfState() const;
void setWerewolfState(bool state); void setWerewolfState(bool state);
float getScale() const;
void setScale(float newScale);
std::string getCreatureModel() const; std::string getCreatureModel() const;
void setCreatureModel(const std::string &model); void setCreatureModel(const std::string &model);
void creatureName(bool useName); void creatureName(bool useName);
@ -172,6 +178,16 @@ public:
int getSkillIncrease(unsigned short attributeId) const; int getSkillIncrease(unsigned short attributeId) const;
void setSkillIncrease(unsigned short attributeId, int increase); void setSkillIncrease(unsigned short attributeId, int increase);
std::tuple<float, float, float> getMarkPosition();
void setMarkPosition(float x, float y, float z);
std::tuple<float, float> getMarkRotation();
void setMarkRotation(float x, float z);
std::string getMarkCell();
void setMarkCell(const std::string &cellDescription);
std::string getSelectedSpell();
void setSelectedSpell(const std::string &newSelectedSpellId);
CellState getCellState(int i); CellState getCellState(int i);
size_t cellStateSize() const; size_t cellStateSize() const;
void addCellExplored(const std::string &cellDescription); void addCellExplored(const std::string &cellDescription);
@ -197,7 +213,7 @@ private:
CellController::TContainer cells; CellController::TContainer cells;
int handshakeCounter; int handshakeCounter;
int loadState; int loadState;
bool /*statsChanged, attributesChanged, skillsChanged, baseInfoChanged, positionChanged,*/ changedMap; bool /*statsChanged, attributesChanged, skillsChanged, baseInfoChanged, positionChanged,*/ changedMarkLocation, changedSelectedSpell, changedMap;
CharClass cClass; CharClass cClass;
GameSettings settings; GameSettings settings;
Books books; Books books;

@ -69,6 +69,7 @@ EventController::EventController(LuaState *luaCtrl)
ADD_CORE_EVENT(ON_PLAYER_SENDMESSAGE), ADD_CORE_EVENT(ON_PLAYER_SENDMESSAGE),
ADD_CORE_EVENT(ON_PLAYER_ENDCHARGEN), ADD_CORE_EVENT(ON_PLAYER_ENDCHARGEN),
ADD_CORE_EVENT(ON_PLAYER_WEATHER), ADD_CORE_EVENT(ON_PLAYER_WEATHER),
ADD_CORE_EVENT(ON_RECORD_DYNAMIC),
ADD_CORE_EVENT(ON_CHANNEL_ACTION), ADD_CORE_EVENT(ON_CHANNEL_ACTION),
ADD_CORE_EVENT(ON_GUI_ACTION), ADD_CORE_EVENT(ON_GUI_ACTION),
ADD_CORE_EVENT(ON_REQUEST_PLUGIN_LIST), ADD_CORE_EVENT(ON_REQUEST_PLUGIN_LIST),

@ -46,6 +46,8 @@ namespace CoreEvent
ON_PLAYER_ENDCHARGEN, ON_PLAYER_ENDCHARGEN,
ON_PLAYER_WEATHER, ON_PLAYER_WEATHER,
ON_RECORD_DYNAMIC,
ON_CHANNEL_ACTION, ON_CHANNEL_ACTION,
ON_GUI_ACTION, ON_GUI_ACTION,

@ -11,6 +11,7 @@
#include "player/ProcessorGUIMessageBox.hpp" #include "player/ProcessorGUIMessageBox.hpp"
#include "player/ProcessorGUIWindow.hpp" #include "player/ProcessorGUIWindow.hpp"
#include "player/ProcessorGameWeather.hpp" #include "player/ProcessorGameWeather.hpp"
#include "player/ProcessorRecordDynamic.hpp"
#include "player/ProcessorPlayerCharGen.hpp" #include "player/ProcessorPlayerCharGen.hpp"
#include "player/ProcessorPlayerAnimFlags.hpp" #include "player/ProcessorPlayerAnimFlags.hpp"
#include "player/ProcessorPlayerAnimPlay.hpp" #include "player/ProcessorPlayerAnimPlay.hpp"
@ -28,10 +29,13 @@
#include "player/ProcessorPlayerInventory.hpp" #include "player/ProcessorPlayerInventory.hpp"
#include "player/ProcessorPlayerJournal.hpp" #include "player/ProcessorPlayerJournal.hpp"
#include "player/ProcessorPlayerKillCount.hpp" #include "player/ProcessorPlayerKillCount.hpp"
#include "player/ProcessorPlayerInteraction.hpp"
#include "player/ProcessorPlayerLevel.hpp" #include "player/ProcessorPlayerLevel.hpp"
#include "player/ProcessorPlayerMap.hpp" #include "player/ProcessorPlayerMap.hpp"
#include "player/ProcessorPlayerMiscellaneous.hpp"
#include "player/ProcessorPlayerPosition.hpp" #include "player/ProcessorPlayerPosition.hpp"
#include "player/ProcessorPlayerQuickKeys.hpp" #include "player/ProcessorPlayerQuickKeys.hpp"
#include "player/ProcessorPlayerReputation.hpp"
#include "player/ProcessorPlayerRest.hpp" #include "player/ProcessorPlayerRest.hpp"
#include "player/ProcessorPlayerResurrect.hpp" #include "player/ProcessorPlayerResurrect.hpp"
#include "player/ProcessorPlayerShapeshift.hpp" #include "player/ProcessorPlayerShapeshift.hpp"
@ -50,6 +54,7 @@
#include "actor/ProcessorActorCellChange.hpp" #include "actor/ProcessorActorCellChange.hpp"
#include "actor/ProcessorActorDeath.hpp" #include "actor/ProcessorActorDeath.hpp"
#include "actor/ProcessorActorEquipment.hpp" #include "actor/ProcessorActorEquipment.hpp"
#include "actor/ProcessorActorInteraction.hpp"
#include "actor/ProcessorActorStatsDynamic.hpp" #include "actor/ProcessorActorStatsDynamic.hpp"
#include "actor/ProcessorActorPosition.hpp" #include "actor/ProcessorActorPosition.hpp"
#include "actor/ProcessorActorSpeech.hpp" #include "actor/ProcessorActorSpeech.hpp"
@ -70,7 +75,9 @@
#include "world/ProcessorScriptLocalShort.hpp" #include "world/ProcessorScriptLocalShort.hpp"
#include "world/ProcessorScriptLocalFloat.hpp" #include "world/ProcessorScriptLocalFloat.hpp"
#include "world/ProcessorScriptMemberShort.hpp" #include "world/ProcessorScriptMemberShort.hpp"
#include "world/ProcessorScriptMemberFloat.hpp"
#include "world/ProcessorScriptGlobalShort.hpp" #include "world/ProcessorScriptGlobalShort.hpp"
#include "world/ProcessorScriptGlobalFloat.hpp"
#include "world/ProcessorVideoPlay.hpp" #include "world/ProcessorVideoPlay.hpp"
@ -82,6 +89,7 @@ void ProcessorInitializer()
PlayerProcessor::AddProcessor(new ProcessorGUIMessageBox()); PlayerProcessor::AddProcessor(new ProcessorGUIMessageBox());
PlayerProcessor::AddProcessor(new ProcessorGUIWindow()); PlayerProcessor::AddProcessor(new ProcessorGUIWindow());
PlayerProcessor::AddProcessor(new ProcessorGameWeather()); PlayerProcessor::AddProcessor(new ProcessorGameWeather());
PlayerProcessor::AddProcessor(new ProcessorRecordDynamic());
PlayerProcessor::AddProcessor(new ProcessorPlayerCharGen()); PlayerProcessor::AddProcessor(new ProcessorPlayerCharGen());
PlayerProcessor::AddProcessor(new ProcessorPlayerAnimFlags()); PlayerProcessor::AddProcessor(new ProcessorPlayerAnimFlags());
PlayerProcessor::AddProcessor(new ProcessorPlayerAnimPlay()); PlayerProcessor::AddProcessor(new ProcessorPlayerAnimPlay());
@ -99,10 +107,13 @@ void ProcessorInitializer()
PlayerProcessor::AddProcessor(new ProcessorPlayerInventory()); PlayerProcessor::AddProcessor(new ProcessorPlayerInventory());
PlayerProcessor::AddProcessor(new ProcessorPlayerJournal()); PlayerProcessor::AddProcessor(new ProcessorPlayerJournal());
PlayerProcessor::AddProcessor(new ProcessorPlayerKillCount()); PlayerProcessor::AddProcessor(new ProcessorPlayerKillCount());
PlayerProcessor::AddProcessor(new ProcessorPlayerInteraction());
PlayerProcessor::AddProcessor(new ProcessorPlayerLevel()); PlayerProcessor::AddProcessor(new ProcessorPlayerLevel());
PlayerProcessor::AddProcessor(new ProcessorPlayerMap()); PlayerProcessor::AddProcessor(new ProcessorPlayerMap());
PlayerProcessor::AddProcessor(new ProcessorPlayerMiscellaneous());
PlayerProcessor::AddProcessor(new ProcessorPlayerPosition()); PlayerProcessor::AddProcessor(new ProcessorPlayerPosition());
PlayerProcessor::AddProcessor(new ProcessorPlayerQuickKeys()); PlayerProcessor::AddProcessor(new ProcessorPlayerQuickKeys());
PlayerProcessor::AddProcessor(new ProcessorPlayerReputation());
PlayerProcessor::AddProcessor(new ProcessorPlayerRest()); PlayerProcessor::AddProcessor(new ProcessorPlayerRest());
PlayerProcessor::AddProcessor(new ProcessorPlayerResurrect()); PlayerProcessor::AddProcessor(new ProcessorPlayerResurrect());
PlayerProcessor::AddProcessor(new ProcessorPlayerShapeshift()); PlayerProcessor::AddProcessor(new ProcessorPlayerShapeshift());
@ -120,6 +131,7 @@ void ProcessorInitializer()
ActorProcessor::AddProcessor(new ProcessorActorCellChange()); ActorProcessor::AddProcessor(new ProcessorActorCellChange());
ActorProcessor::AddProcessor(new ProcessorActorDeath()); ActorProcessor::AddProcessor(new ProcessorActorDeath());
ActorProcessor::AddProcessor(new ProcessorActorEquipment()); ActorProcessor::AddProcessor(new ProcessorActorEquipment());
ActorProcessor::AddProcessor(new ProcessorActorInteraction());
ActorProcessor::AddProcessor(new ProcessorActorPosition()); ActorProcessor::AddProcessor(new ProcessorActorPosition());
ActorProcessor::AddProcessor(new ProcessorActorSpeech()); ActorProcessor::AddProcessor(new ProcessorActorSpeech());
ActorProcessor::AddProcessor(new ProcessorActorStatsDynamic()); ActorProcessor::AddProcessor(new ProcessorActorStatsDynamic());
@ -141,6 +153,8 @@ void ProcessorInitializer()
WorldProcessor::AddProcessor(new ProcessorScriptLocalShort()); WorldProcessor::AddProcessor(new ProcessorScriptLocalShort());
WorldProcessor::AddProcessor(new ProcessorScriptLocalFloat()); WorldProcessor::AddProcessor(new ProcessorScriptLocalFloat());
WorldProcessor::AddProcessor(new ProcessorScriptMemberShort()); WorldProcessor::AddProcessor(new ProcessorScriptMemberShort());
WorldProcessor::AddProcessor(new ProcessorScriptMemberFloat());
WorldProcessor::AddProcessor(new ProcessorScriptGlobalShort()); WorldProcessor::AddProcessor(new ProcessorScriptGlobalShort());
WorldProcessor::AddProcessor(new ProcessorScriptGlobalFloat());
WorldProcessor::AddProcessor(new ProcessorVideoPlay()); WorldProcessor::AddProcessor(new ProcessorVideoPlay());
} }

@ -16,7 +16,7 @@ namespace mwmp
void Do(ActorPacket &packet, const std::shared_ptr<Player> &player, BaseActorList &actorList) override void Do(ActorPacket &packet, const std::shared_ptr<Player> &player, BaseActorList &actorList) override
{ {
// Send only to players who have the cell loaded // Send only to players who have the cell loaded
Cell *serverCell = CellController::get().getCell(&actorList.cell); Cell *serverCell = CellController::get().getCell(actorList.cell);
if (serverCell != nullptr && *serverCell->getAuthority() == actorList.guid) if (serverCell != nullptr && *serverCell->getAuthority() == actorList.guid)
serverCell->sendToLoaded(&packet, &actorList); serverCell->sendToLoaded(&packet, &actorList);

@ -1,14 +1,14 @@
#ifndef OPENMW_PROCESSORPLAYERRECORDDYNAMIC_HPP #ifndef OPENMW_PROCESSORRECORDDYNAMIC_HPP
#define OPENMW_PROCESSORPLAYERRECORDDYNAMIC_HPP #define OPENMW_PROCESSORRECORDDYNAMIC_HPP
#include "../PlayerProcessor.hpp" #include "../PlayerProcessor.hpp"
namespace mwmp namespace mwmp
{ {
class ProcessorPlayerRecordDynamic final : public PlayerProcessor class ProcessorRecordDynamic final : public PlayerProcessor
{ {
public: public:
ProcessorPlayerRecordDynamic() ProcessorRecordDynamic()
{ {
BPP_INIT(ID_RECORD_DYNAMIC) BPP_INIT(ID_RECORD_DYNAMIC)
} }
@ -17,9 +17,9 @@ namespace mwmp
{ {
DEBUG_PRINTF(strPacketID.c_str()); DEBUG_PRINTF(strPacketID.c_str());
Script::Call<Script::CallbackIdentity("OnRecordDynamic")>(player.getId()); Networking::get().getState().getEventCtrl().Call<CoreEvent::ON_RECORD_DYNAMIC>(player);
} }
}; };
} }
#endif //OPENMW_PROCESSORPLAYERRECORDDYNAMIC_HPP #endif //OPENMW_PROCESSORRECORDDYNAMIC_HPP

@ -232,7 +232,8 @@ namespace MWGui
/* /*
Start of tes3mp addition Start of tes3mp addition
Send a PLAYER_QUICKKEYS packet whenever a key is assigned to an item Send a PlayerQuickKeys packet whenever a key is assigned to an item
by a player, not by a packet received from the server
*/ */
if (!mwmp::Main::get().getLocalPlayer()->isReceivingQuickKeys) if (!mwmp::Main::get().getLocalPlayer()->isReceivingQuickKeys)
mwmp::Main::get().getLocalPlayer()->sendQuickKey(mSelectedIndex, mwmp::QuickKey::Type::Item, item.getCellRef().getRefId()); mwmp::Main::get().getLocalPlayer()->sendQuickKey(mSelectedIndex, mwmp::QuickKey::Type::Item, item.getCellRef().getRefId());
@ -407,6 +408,16 @@ namespace MWGui
store.setSelectedEnchantItem(store.end()); store.setSelectedEnchantItem(store.end());
MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player))); MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player)));
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell); MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell);
/*
Start of tes3mp addition
Send a PlayerMiscellaneous packet with the player's new selected spell
*/
mwmp::Main::get().getLocalPlayer()->sendSelectedSpell(spellId);
/*
End of tes3mp addition
*/
} }
else if (type == Type_Item) else if (type == Type_Item)
{ {

@ -186,6 +186,16 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player))); MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player)));
updateSpells(); updateSpells();
/*
Start of tes3mp addition
Send a PlayerMiscellaneous packet with the player's new selected spell
*/
mwmp::Main::get().getLocalPlayer()->sendSelectedSpell(spellId);
/*
End of tes3mp addition
*/
} }
void SpellWindow::onDeleteSpellAccept() void SpellWindow::onDeleteSpellAccept()

@ -186,10 +186,25 @@ namespace MWInput
} }
} }
bool isLeftOrRightButton(int action, ICS::InputControlSystem* ics, int deviceId, bool joystick)
{
int mouseBinding = ics->getMouseButtonBinding(ics->getControl(action), ICS::Control::INCREASE);
if (mouseBinding != ICS_MAX_DEVICE_BUTTONS)
return true;
int buttonBinding = ics->getJoystickButtonBinding(ics->getControl(action), deviceId, ICS::Control::INCREASE);
if (joystick && (buttonBinding == 0 || buttonBinding == 1))
return true;
return false;
}
void InputManager::handleGuiArrowKey(int action) void InputManager::handleGuiArrowKey(int action)
{ {
if (SDL_IsTextInputActive()) if (SDL_IsTextInputActive())
return; return;
if (isLeftOrRightButton(action, mInputBinder, mFakeDeviceID, mJoystickLastUsed))
return;
MyGUI::KeyCode key; MyGUI::KeyCode key;
switch (action) switch (action)
{ {
@ -1185,7 +1200,7 @@ namespace MWInput
{ {
if (MWBase::Environment::get().getWindowManager()->isGuiMode()) if (MWBase::Environment::get().getWindowManager()->isGuiMode())
{ {
if (!SDL_IsTextInputActive()) if (!SDL_IsTextInputActive() && !isLeftOrRightButton(A_Activate, mInputBinder, mFakeDeviceID, mJoystickLastUsed))
MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Return, 0); MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Return, 0);
} }
else if (mControlSwitch["playercontrols"]) else if (mControlSwitch["playercontrols"])

@ -579,9 +579,16 @@ namespace MWMechanics
{ {
std::string itFaction = playerFactionIt->first; std::string itFaction = playerFactionIt->first;
// Ignore the faction, if a player was expelled from it.
if (playerStats.getExpelled(itFaction))
continue;
int itReaction = MWBase::Environment::get().getDialogueManager()->getFactionReaction(npcFaction, itFaction); int itReaction = MWBase::Environment::get().getDialogueManager()->getFactionReaction(npcFaction, itFaction);
if (playerFactionIt == playerStats.getFactionRanks().begin() || itReaction < reaction) if (playerFactionIt == playerStats.getFactionRanks().begin() || itReaction < reaction)
{
reaction = static_cast<float>(itReaction); reaction = static_cast<float>(itReaction);
rank = playerFactionIt->second;
}
} }
} }
else else

@ -755,6 +755,17 @@ namespace MWMechanics
{ {
MWBase::Environment::get().getWorld()->getPlayer().markPosition( MWBase::Environment::get().getWorld()->getPlayer().markPosition(
target.getCell(), target.getRefData().getPosition()); target.getCell(), target.getRefData().getPosition());
/*
Start of tes3mp addition
Send a PlayerMiscellaneous packet with the player's new mark location
*/
mwmp::Main::get().getLocalPlayer()->sendMarkLocation(*target.getCell()->getCell(), target.getRefData().getPosition());
/*
End of tes3mp addition
*/
return true; return true;
} }
else if (effectId == ESM::MagicEffect::Recall) else if (effectId == ESM::MagicEffect::Recall)

@ -364,7 +364,6 @@ void CellController::openContainer(const MWWorld::Ptr &container)
/*if (::Misc::StringUtils::ciEqual(name, "gold_001")) /*if (::Misc::StringUtils::ciEqual(name, "gold_001"))
cont.remove("gold_001", count, container);*/ cont.remove("gold_001", count, container);*/
} }
} }
void CellController::closeContainer(const MWWorld::Ptr &container) void CellController::closeContainer(const MWWorld::Ptr &container)

@ -242,6 +242,7 @@ void DedicatedPlayer::setCell()
void DedicatedPlayer::setShapeshift() void DedicatedPlayer::setShapeshift()
{ {
MWBase::Environment::get().getWorld()->scaleObject(ptr, scale);
MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptr, isWerewolf); MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptr, isWerewolf);
} }

@ -19,6 +19,7 @@
#include "../mwmechanics/aitravel.hpp" #include "../mwmechanics/aitravel.hpp"
#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/mechanicsmanagerimp.hpp" #include "../mwmechanics/mechanicsmanagerimp.hpp"
#include "../mwmechanics/spellcasting.hpp"
#include "../mwscript/scriptmanagerimp.hpp" #include "../mwscript/scriptmanagerimp.hpp"
@ -65,6 +66,7 @@ LocalPlayer::LocalPlayer()
jailProgressText = ""; jailProgressText = "";
jailEndText = ""; jailEndText = "";
scale = 1;
isWerewolf = false; isWerewolf = false;
diedSinceArrestAttempt = false; diedSinceArrestAttempt = false;
@ -106,6 +108,7 @@ void LocalPlayer::update()
updateSkills(); updateSkills();
updateLevel(); updateLevel();
updateBounty(); updateBounty();
updateReputation();
} }
} }
@ -322,6 +325,19 @@ void LocalPlayer::updateBounty(bool forceUpdate)
} }
} }
void LocalPlayer::updateReputation(bool forceUpdate)
{
MWWorld::Ptr ptrPlayer = getPlayerPtr();
const MWMechanics::NpcStats &ptrNpcStats = ptrPlayer.getClass().getNpcStats(ptrPlayer);
if (ptrNpcStats.getReputation() != npcStats.mReputation || forceUpdate)
{
npcStats.mReputation = ptrNpcStats.getReputation();
getNetworking()->getPlayerPacket(ID_PLAYER_REPUTATION)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_REPUTATION)->Send();
}
}
void LocalPlayer::updatePosition(bool forceUpdate) void LocalPlayer::updatePosition(bool forceUpdate)
{ {
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
@ -920,6 +936,15 @@ void LocalPlayer::setBounty()
ptrNpcStats->setBounty(npcStats.mBounty); ptrNpcStats->setBounty(npcStats.mBounty);
} }
void LocalPlayer::setReputation()
{
MWBase::World *world = MWBase::Environment::get().getWorld();
MWWorld::Ptr ptrPlayer = world->getPlayerPtr();
MWMechanics::NpcStats *ptrNpcStats = &ptrPlayer.getClass().getNpcStats(ptrPlayer);
ptrNpcStats->setReputation(npcStats.mReputation);
}
void LocalPlayer::setPosition() void LocalPlayer::setPosition()
{ {
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
@ -1235,9 +1260,33 @@ void LocalPlayer::setMapExplored()
void LocalPlayer::setShapeshift() void LocalPlayer::setShapeshift()
{ {
MWWorld::Ptr ptrPlayer = getPlayerPtr(); MWWorld::Ptr ptrPlayer = getPlayerPtr();
MWBase::Environment::get().getWorld()->scaleObject(ptrPlayer, scale);
MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptrPlayer, isWerewolf); MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptrPlayer, isWerewolf);
} }
void LocalPlayer::setMarkLocation()
{
MWWorld::CellStore *ptrCellStore = Main::get().getCellController()->getCellStore(markCell);
if (ptrCellStore)
MWBase::Environment::get().getWorld()->getPlayer().markPosition(ptrCellStore, markPosition);
}
void LocalPlayer::setSelectedSpell()
{
MWWorld::Ptr ptrPlayer = getPlayerPtr();
MWMechanics::CreatureStats& stats = ptrPlayer.getClass().getCreatureStats(ptrPlayer);
MWMechanics::Spells& spells = stats.getSpells();
if (!spells.hasSpell(selectedSpellId))
return;
MWBase::Environment::get().getWindowManager()->setSelectedSpell(selectedSpellId,
int(MWMechanics::getSpellSuccessChance(selectedSpellId, ptrPlayer)));
}
void LocalPlayer::sendClass() void LocalPlayer::sendClass()
{ {
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
@ -1367,7 +1416,7 @@ void LocalPlayer::sendSpellRemoval(const ESM::Spell &spell)
*/ */
} }
void LocalPlayer::sendQuickKey(int slot, QuickKey::Type type, const std::string& itemId) void LocalPlayer::sendQuickKey(unsigned short slot, QuickKey::Type type, const std::string& itemId)
{ {
quickKeyChanges.quickKeys.clear(); quickKeyChanges.quickKeys.clear();
@ -1512,7 +1561,17 @@ void LocalPlayer::sendBook(const std::string& bookId)
getNetworking()->getPlayerPacket(ID_PLAYER_BOOK)->Send(); getNetworking()->getPlayerPacket(ID_PLAYER_BOOK)->Send();
} }
void LocalPlayer::sendShapeshift(bool werewolfState) void LocalPlayer::sendScale(float newScale)
{
scale = newScale;
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Sending ID_PLAYER_SHAPESHIFT with scale of %f", scale);
getNetworking()->getPlayerPacket(ID_PLAYER_SHAPESHIFT)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_SHAPESHIFT)->Send();
}
void LocalPlayer::sendWerewolfState(bool werewolfState)
{ {
isWerewolf = werewolfState; isWerewolf = werewolfState;
@ -1522,6 +1581,25 @@ void LocalPlayer::sendShapeshift(bool werewolfState)
getNetworking()->getPlayerPacket(ID_PLAYER_SHAPESHIFT)->Send(); getNetworking()->getPlayerPacket(ID_PLAYER_SHAPESHIFT)->Send();
} }
void LocalPlayer::sendMarkLocation(const ESM::Cell& newMarkCell, const ESM::Position& newMarkPosition)
{
miscellaneousChangeType = mwmp::MiscellaneousChangeType::MarkLocation;
markCell = newMarkCell;
markPosition = newMarkPosition;
getNetworking()->getPlayerPacket(ID_PLAYER_MISCELLANEOUS)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_MISCELLANEOUS)->Send();
}
void LocalPlayer::sendSelectedSpell(const std::string& newSelectedSpellId)
{
miscellaneousChangeType = mwmp::MiscellaneousChangeType::SelectedSpell;
selectedSpellId = newSelectedSpellId;
getNetworking()->getPlayerPacket(ID_PLAYER_MISCELLANEOUS)->setPlayer(this);
getNetworking()->getPlayerPacket(ID_PLAYER_MISCELLANEOUS)->Send();
}
void LocalPlayer::clearCellStates() void LocalPlayer::clearCellStates()
{ {
cellStateChanges.cellStates.clear(); cellStateChanges.cellStates.clear();

@ -29,6 +29,7 @@ namespace mwmp
void updateSkills(bool forceUpdate = false); void updateSkills(bool forceUpdate = false);
void updateLevel(bool forceUpdate = false); void updateLevel(bool forceUpdate = false);
void updateBounty(bool forceUpdate = false); void updateBounty(bool forceUpdate = false);
void updateReputation(bool forceUpdate = false);
void updatePosition(bool forceUpdate = false); void updatePosition(bool forceUpdate = false);
void updateCell(bool forceUpdate = false); void updateCell(bool forceUpdate = false);
void updateChar(); void updateChar();
@ -55,6 +56,7 @@ namespace mwmp
void setSkills(); void setSkills();
void setLevel(); void setLevel();
void setBounty(); void setBounty();
void setReputation();
void setPosition(); void setPosition();
void setCell(); void setCell();
void setClass(); void setClass();
@ -67,16 +69,18 @@ namespace mwmp
void setBooks(); void setBooks();
void setMapExplored(); void setMapExplored();
void setShapeshift(); void setShapeshift();
void setMarkLocation();
void setSelectedSpell();
void sendClass(); void sendClass();
void sendInventory(); void sendInventory();
void sendSpellbook(); void sendSpellbook();
void sendCellStates(); void sendCellStates();
void sendSpellAddition(std::string id); void sendSpellAddition(std::string id);
void sendSpellAddition(const ESM::Spell &spell); void sendSpellAddition(const ESM::Spell& spell);
void sendSpellRemoval(std::string id); void sendSpellRemoval(std::string id);
void sendSpellRemoval(const ESM::Spell &spell); void sendSpellRemoval(const ESM::Spell& spell);
void sendQuickKey(int slot, QuickKey::Type type, const std::string& itemId = ""); void sendQuickKey(unsigned short slot, QuickKey::Type type, const std::string& itemId = "");
void sendJournalEntry(const std::string& quest, int index, const MWWorld::Ptr& actor); void sendJournalEntry(const std::string& quest, int index, const MWWorld::Ptr& actor);
void sendJournalIndex(const std::string& quest, int index); void sendJournalIndex(const std::string& quest, int index);
void sendFactionRank(const std::string& factionId, int rank); void sendFactionRank(const std::string& factionId, int rank);
@ -85,7 +89,10 @@ namespace mwmp
void sendTopic(const std::string& topic); void sendTopic(const std::string& topic);
void sendKill(const std::string& refId, int number); void sendKill(const std::string& refId, int number);
void sendBook(const std::string& bookId); void sendBook(const std::string& bookId);
void sendShapeshift(bool isWerewolf); void sendScale(float newScale);
void sendWerewolfState(bool isWerewolf);
void sendMarkLocation(const ESM::Cell& newMarkCell, const ESM::Position& newMarkPosition);
void sendSelectedSpell(const std::string& newSelectedSpellId);
void clearCellStates(); void clearCellStates();
void clearCurrentContainer(); void clearCurrentContainer();

@ -166,26 +166,35 @@ void WorldEvent::placeObjects(MWWorld::CellStore* cellStore)
// Only create this object if it doesn't already exist // Only create this object if it doesn't already exist
if (!ptrFound) if (!ptrFound)
{ {
MWWorld::ManualRef ref(world->getStore(), worldObject.refId, 1); try
MWWorld::Ptr newPtr = ref.getPtr(); {
MWWorld::ManualRef ref(world->getStore(), worldObject.refId, 1);
if (worldObject.count > 1) MWWorld::Ptr newPtr = ref.getPtr();
newPtr.getRefData().setCount(worldObject.count);
if (worldObject.charge > -1) if (worldObject.count > 1)
newPtr.getCellRef().setCharge(worldObject.charge); newPtr.getRefData().setCount(worldObject.count);
if (worldObject.enchantmentCharge > -1.0f) if (worldObject.charge > -1)
newPtr.getCellRef().setEnchantmentCharge(worldObject.enchantmentCharge); newPtr.getCellRef().setCharge(worldObject.charge);
newPtr.getCellRef().setGoldValue(worldObject.goldValue); if (worldObject.enchantmentCharge > -1.0f)
newPtr = world->placeObject(newPtr, cellStore, worldObject.position); newPtr.getCellRef().setEnchantmentCharge(worldObject.enchantmentCharge);
// Because gold automatically gets replaced with a new object, make sure we set the mpNum at the end newPtr.getCellRef().setGoldValue(worldObject.goldValue);
newPtr.getCellRef().setMpNum(worldObject.mpNum); newPtr = world->placeObject(newPtr, cellStore, worldObject.position);
// Because gold automatically gets replaced with a new object, make sure we set the mpNum at the end
newPtr.getCellRef().setMpNum(worldObject.mpNum);
if (guid == Main::get().getLocalPlayer()->guid && worldObject.droppedByPlayer)
world->PCDropped(newPtr);
if (guid == Main::get().getLocalPlayer()->guid && worldObject.droppedByPlayer) }
world->PCDropped(newPtr); catch (std::exception&)
{
LOG_APPEND(Log::LOG_INFO, "-- Ignored placement of invalid object");
}
} }
else else
LOG_APPEND(Log::LOG_VERBOSE, "-- Object already existed!"); LOG_APPEND(Log::LOG_VERBOSE, "-- Object already existed!");
@ -468,24 +477,20 @@ void WorldEvent::runConsoleCommands(MWWorld::CellStore* cellStore)
if (worldObject.isPlayer) if (worldObject.isPlayer)
{ {
BasePlayer *player = 0;
if (worldObject.guid == Main::get().getLocalPlayer()->guid) if (worldObject.guid == Main::get().getLocalPlayer()->guid)
{ {
player = Main::get().getLocalPlayer();
LOG_APPEND(Log::LOG_VERBOSE, "-- running on local player"); LOG_APPEND(Log::LOG_VERBOSE, "-- running on local player");
windowManager->setConsolePtr(static_cast<LocalPlayer*>(player)->getPlayerPtr()); windowManager->setConsolePtr(Main::get().getLocalPlayer()->getPlayerPtr());
windowManager->executeCommandInConsole(consoleCommand); windowManager->executeCommandInConsole(consoleCommand);
} }
else else
{ {
player = PlayerList::getPlayer(worldObject.guid); DedicatedPlayer *player = PlayerList::getPlayer(worldObject.guid);
if (player != 0) if (player != 0)
{ {
LOG_APPEND(Log::LOG_VERBOSE, "-- running on player %s", player->npc.mName.c_str()); LOG_APPEND(Log::LOG_VERBOSE, "-- running on player %s", player->npc.mName.c_str());
windowManager->setConsolePtr(static_cast<DedicatedPlayer*>(player)->getPtr()); windowManager->setConsolePtr(player->getPtr());
windowManager->executeCommandInConsole(consoleCommand); windowManager->executeCommandInConsole(consoleCommand);
} }
} }
@ -508,7 +513,7 @@ void WorldEvent::runConsoleCommands(MWWorld::CellStore* cellStore)
} }
windowManager->clearConsolePtr(); windowManager->clearConsolePtr();
} }
} }
void WorldEvent::setLocalShorts(MWWorld::CellStore* cellStore) void WorldEvent::setLocalShorts(MWWorld::CellStore* cellStore)

@ -23,7 +23,16 @@ namespace mwmp
if (!isRequest()) if (!isRequest())
{ {
LocalPlayer &localPlayer = static_cast<LocalPlayer&>(*player); LocalPlayer &localPlayer = static_cast<LocalPlayer&>(*player);
//localPlayer.setMiscellaneous();
switch (player->miscellaneousChangeType)
{
case MiscellaneousChangeType::MarkLocation:
localPlayer.setMarkLocation();
break;
case MiscellaneousChangeType::SelectedSpell:
localPlayer.setSelectedSpell();
break;
}
} }
} }
}; };

@ -16,19 +16,13 @@ namespace mwmp
virtual void Do(PlayerPacket &packet, BasePlayer *player) virtual void Do(PlayerPacket &packet, BasePlayer *player)
{ {
if (isLocal()) if (isRequest())
{ {
//if (isRequest()) static_cast<LocalPlayer *>(player)->updateReputation(true);
// static_cast<LocalPlayer *>(player)->updateReputation(true);
//else
// static_cast<LocalPlayer *>(player)->setReputation();
} }
else if (player != 0) else if (player != 0)
{ {
MWWorld::Ptr ptrPlayer = static_cast<DedicatedPlayer *>(player)->getPtr(); static_cast<LocalPlayer *>(player)->setReputation();
MWMechanics::NpcStats *ptrNpcStats = &ptrPlayer.getClass().getNpcStats(ptrPlayer);
ptrNpcStats->setReputation(player->npcStats.mReputation);
} }
} }
}; };

@ -1203,6 +1203,18 @@ void SkyManager::create()
mCreated = true; mCreated = true;
} }
class RainCounter : public osgParticle::ConstantRateCounter
{
public:
virtual int numParticlesToCreate(double dt) const
{
// limit dt to avoid large particle emissions if there are jumps in the simulation time
// 0.2 seconds is the same cap as used in Engine's frame loop
dt = std::min(dt, 0.2);
return ConstantRateCounter::numParticlesToCreate(dt);
}
};
class RainShooter : public osgParticle::Shooter class RainShooter : public osgParticle::Shooter
{ {
public: public:
@ -1473,7 +1485,7 @@ void SkyManager::createRain()
placer->setZRange(300, 300); placer->setZRange(300, 300);
emitter->setPlacer(placer); emitter->setPlacer(placer);
osg::ref_ptr<osgParticle::ConstantRateCounter> counter (new osgParticle::ConstantRateCounter); osg::ref_ptr<RainCounter> counter (new RainCounter);
counter->setNumberOfParticlesPerSecondToCreate(600.0); counter->setNumberOfParticlesPerSecondToCreate(600.0);
emitter->setCounter(counter); emitter->setCounter(counter);

@ -1231,7 +1231,7 @@ namespace MWScript
When the player's werewolf state changes, send an ID_PLAYER_SHAPESHIFT packet When the player's werewolf state changes, send an ID_PLAYER_SHAPESHIFT packet
*/ */
if (ptr == MWMechanics::getPlayer()) if (ptr == MWMechanics::getPlayer())
mwmp::Main::get().getLocalPlayer()->sendShapeshift(set); mwmp::Main::get().getLocalPlayer()->sendWerewolfState(set);
/* /*
End of tes3mp addition End of tes3mp addition
*/ */

@ -8,6 +8,8 @@
#include <components/openmw-mp/Log.hpp> #include <components/openmw-mp/Log.hpp>
#include "../mwmp/Main.hpp" #include "../mwmp/Main.hpp"
#include "../mwmp/Networking.hpp" #include "../mwmp/Networking.hpp"
#include "../mwmp/LocalPlayer.hpp"
#include "../mwmp/PlayerList.hpp"
#include "../mwmp/WorldEvent.hpp" #include "../mwmp/WorldEvent.hpp"
/* /*
End of tes3mp addition End of tes3mp addition
@ -57,16 +59,26 @@ namespace MWScript
/* /*
Start of tes3mp addition Start of tes3mp addition
Send an ID_OBJECT_SCALE every time an object's scale is changed Send an ID_PLAYER_SHAPESHIFT every time a player changes
through a script their own scale
Otherwise, send an ID_OBJECT_SCALE every time an object's
scale is changed through a script
*/ */
if (ptr.isInCell() && (ptr.getCellRef().getScale() != scale)) if (ptr == MWMechanics::getPlayer())
mwmp::Main::get().getLocalPlayer()->sendScale(scale);
else if (ptr.isInCell() && (ptr.getCellRef().getScale() != scale))
{ {
// Ignore attempts to change another player's scale
mwmp::WorldEvent *worldEvent = mwmp::Main::get().getNetworking()->getWorldEvent(); if (mwmp::PlayerList::isDedicatedPlayer(ptr))
worldEvent->reset(); return;
worldEvent->addObjectScale(ptr, scale); else
worldEvent->sendObjectScale(); {
mwmp::WorldEvent *worldEvent = mwmp::Main::get().getNetworking()->getWorldEvent();
worldEvent->reset();
worldEvent->addObjectScale(ptr, scale);
worldEvent->sendObjectScale();
}
} }
/* /*
End of tes3mp addition End of tes3mp addition

@ -168,16 +168,16 @@ namespace MWWorld
ToUTF8::Utf8Encoder* encoder, const std::map<std::string,std::string>& fallbackMap, ToUTF8::Utf8Encoder* encoder, const std::map<std::string,std::string>& fallbackMap,
int activationDistanceOverride, const std::string& startCell, const std::string& startupScript, int activationDistanceOverride, const std::string& startCell, const std::string& startupScript,
const std::string& resourcePath, const std::string& userDataPath) const std::string& resourcePath, const std::string& userDataPath)
: mResourceSystem(resourceSystem), mFallback(fallbackMap), mPlayer (0), mLocalScripts (mStore), : mResourceSystem(resourceSystem), mFallback(fallbackMap), mLocalScripts (mStore),
mSky (true), mCells (mStore, mEsm), mSky (true), mCells (mStore, mEsm),
mGodMode(false), mScriptsEnabled(true), mContentFiles (contentFiles), mUserDataPath(userDataPath), mGodMode(false), mScriptsEnabled(true), mContentFiles (contentFiles), mUserDataPath(userDataPath),
mActivationDistanceOverride (activationDistanceOverride), mStartupScript(startupScript), mActivationDistanceOverride (activationDistanceOverride), mStartupScript(startupScript),
mStartCell (startCell), mDistanceToFacedObject(-1), mTeleportEnabled(true), mStartCell (startCell), mDistanceToFacedObject(-1), mTeleportEnabled(true),
mLevitationEnabled(true), mGoToJail(false), mDaysInPrison(0), mSpellPreloadTimer(0.f) mLevitationEnabled(true), mGoToJail(false), mDaysInPrison(0), mSpellPreloadTimer(0.f)
{ {
mPhysics = new MWPhysics::PhysicsSystem(resourceSystem, rootNode); mPhysics.reset(new MWPhysics::PhysicsSystem(resourceSystem, rootNode));
mRendering = new MWRender::RenderingManager(viewer, rootNode, resourceSystem, workQueue, &mFallback, resourcePath); mRendering.reset(new MWRender::RenderingManager(viewer, rootNode, resourceSystem, workQueue, &mFallback, resourcePath));
mProjectileManager.reset(new ProjectileManager(mRendering->getLightRoot(), resourceSystem, mRendering, mPhysics)); mProjectileManager.reset(new ProjectileManager(mRendering->getLightRoot(), resourceSystem, mRendering.get(), mPhysics.get()));
mRendering->preloadCommonAssets(); mRendering->preloadCommonAssets();
@ -209,10 +209,10 @@ namespace MWWorld
mSwimHeightScale = mStore.get<ESM::GameSetting>().find("fSwimHeightScale")->getFloat(); mSwimHeightScale = mStore.get<ESM::GameSetting>().find("fSwimHeightScale")->getFloat();
mWeatherManager = new MWWorld::WeatherManager(*mRendering, mFallback, mStore); mWeatherManager.reset(new MWWorld::WeatherManager(*mRendering, mFallback, mStore));
mwmp::Main::get().setWeatherManager(mWeatherManager); mwmp::Main::get().setWeatherManager(mWeatherManager.get());
mWorldScene = new Scene(*mRendering, mPhysics); mWorldScene.reset(new Scene(*mRendering.get(), mPhysics.get()));
} }
void World::fillGlobalVariables() void World::fillGlobalVariables()
@ -245,9 +245,9 @@ namespace MWWorld
// we don't want old weather to persist on a new game // we don't want old weather to persist on a new game
// Note that if reset later, the initial ChangeWeather that the chargen script calls will be lost. // Note that if reset later, the initial ChangeWeather that the chargen script calls will be lost.
delete mWeatherManager; mWeatherManager.reset();
mWeatherManager = new MWWorld::WeatherManager(*mRendering, mFallback, mStore); mWeatherManager.reset(new MWWorld::WeatherManager(*mRendering.get(), mFallback, mStore));
mwmp::Main::get().setWeatherManager(mWeatherManager); mwmp::Main::get().setWeatherManager(mWeatherManager.get());
if (!bypass) if (!bypass)
{ {
@ -527,12 +527,6 @@ namespace MWWorld
{ {
// Must be cleared before mRendering is destroyed // Must be cleared before mRendering is destroyed
mProjectileManager->clear(); mProjectileManager->clear();
delete mWeatherManager;
delete mWorldScene;
delete mRendering;
delete mPhysics;
delete mPlayer;
} }
const ESM::Cell *World::getExterior (const std::string& cellName) const const ESM::Cell *World::getExterior (const std::string& cellName) const
@ -2316,7 +2310,7 @@ namespace MWWorld
{ {
const ESM::NPC *player = mStore.get<ESM::NPC>().find("player"); const ESM::NPC *player = mStore.get<ESM::NPC>().find("player");
if (!mPlayer) if (!mPlayer)
mPlayer = new MWWorld::Player(player); mPlayer.reset(new MWWorld::Player(player));
else else
{ {
// Remove the old CharacterController // Remove the old CharacterController
@ -3669,17 +3663,17 @@ namespace MWWorld
if (MWMechanics::isSummoningEffect(it->mEffectID)) if (MWMechanics::isSummoningEffect(it->mEffectID))
{ {
preload(mWorldScene, mStore, "VFX_Summon_Start"); preload(mWorldScene.get(), mStore, "VFX_Summon_Start");
preload(mWorldScene, mStore, MWMechanics::getSummonedCreature(it->mEffectID)); preload(mWorldScene.get(), mStore, MWMechanics::getSummonedCreature(it->mEffectID));
} }
preload(mWorldScene, mStore, effect->mCasting); preload(mWorldScene.get(), mStore, effect->mCasting);
preload(mWorldScene, mStore, effect->mHit); preload(mWorldScene.get(), mStore, effect->mHit);
if (it->mArea > 0) if (it->mArea > 0)
preload(mWorldScene, mStore, effect->mArea); preload(mWorldScene.get(), mStore, effect->mArea);
if (it->mRange == ESM::RT_Target) if (it->mRange == ESM::RT_Target)
preload(mWorldScene, mStore, effect->mBolt); preload(mWorldScene.get(), mStore, effect->mBolt);
} }
} }

@ -74,17 +74,11 @@ namespace MWWorld
Resource::ResourceSystem* mResourceSystem; Resource::ResourceSystem* mResourceSystem;
Fallback::Map mFallback; Fallback::Map mFallback;
MWRender::RenderingManager* mRendering;
MWWorld::WeatherManager* mWeatherManager;
MWWorld::Scene *mWorldScene;
MWWorld::Player *mPlayer;
std::vector<ESM::ESMReader> mEsm; std::vector<ESM::ESMReader> mEsm;
MWWorld::ESMStore mStore; MWWorld::ESMStore mStore;
LocalScripts mLocalScripts; LocalScripts mLocalScripts;
MWWorld::Globals mGlobalVariables; MWWorld::Globals mGlobalVariables;
MWPhysics::PhysicsSystem *mPhysics;
bool mSky; bool mSky;
ESM::Variant* mGameHour; ESM::Variant* mGameHour;
@ -98,6 +92,11 @@ namespace MWWorld
std::string mCurrentWorldSpace; std::string mCurrentWorldSpace;
std::unique_ptr<MWWorld::Player> mPlayer;
std::unique_ptr<MWPhysics::PhysicsSystem> mPhysics;
std::unique_ptr<MWRender::RenderingManager> mRendering;
std::unique_ptr<MWWorld::Scene> mWorldScene;
std::unique_ptr<MWWorld::WeatherManager> mWeatherManager;
std::shared_ptr<ProjectileManager> mProjectileManager; std::shared_ptr<ProjectileManager> mProjectileManager;
bool mGodMode; bool mGodMode;

@ -187,6 +187,12 @@ namespace mwmp
TribunalTemple TribunalTemple
}; };
enum class MiscellaneousChangeType : uint8_t
{
MarkLocation = 0,
SelectedSpell
};
class BasePlayer : public mwmp::BaseNetCreature class BasePlayer : public mwmp::BaseNetCreature
{ {
public: public:
@ -316,6 +322,7 @@ namespace mwmp
std::string sound; std::string sound;
Animation animation; Animation animation;
float scale;
bool isWerewolf; bool isWerewolf;
std::string creatureModel; std::string creatureModel;
bool useCreatureName; bool useCreatureName;
@ -329,10 +336,15 @@ namespace mwmp
std::string jailEndText; std::string jailEndText;
ResurrectType resurrectType; ResurrectType resurrectType;
MiscellaneousChangeType miscellaneousChangeType;
ESM::Cell markCell;
ESM::Position markPosition;
std::string selectedSpellId;
bool diedSinceArrestAttempt;
bool isReceivingQuickKeys; bool isReceivingQuickKeys;
bool isPlayingAnimation; bool isPlayingAnimation;
bool diedSinceArrestAttempt;
}; };
} }

@ -12,5 +12,20 @@ void PacketPlayerMiscellaneous::Packet(RakNet::BitStream *bs, bool send)
{ {
PlayerPacket::Packet(bs, send); PlayerPacket::Packet(bs, send);
// Placeholder RW(player->miscellaneousChangeType, send);
switch (player->miscellaneousChangeType)
{
case MiscellaneousChangeType::MarkLocation:
RW(player->markCell.mData, send, 1);
RW(player->markCell.mName, send, 1);
RW(player->markPosition.pos, send);
RW(player->markPosition.rot[0], send);
RW(player->markPosition.rot[2], send);
break;
case MiscellaneousChangeType::SelectedSpell:
RW(player->selectedSpellId, send, 1);
break;
}
} }

@ -12,5 +12,5 @@ void PacketPlayerReputation::Packet(RakNet::BitStream *bs, bool send)
{ {
PlayerPacket::Packet(bs, send); PlayerPacket::Packet(bs, send);
// Placeholder RW(player->npcStats.mReputation, send);
} }

@ -12,5 +12,6 @@ void PacketPlayerShapeshift::Packet(RakNet::BitStream *bs, bool send)
{ {
PlayerPacket::Packet(bs, send); PlayerPacket::Packet(bs, send);
RW(player->scale, send);
RW(player->isWerewolf, send); RW(player->isWerewolf, send);
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

@ -9,8 +9,9 @@
</qresource> </qresource>
<qresource prefix="icons/tango"> <qresource prefix="icons/tango">
<file alias="index.theme">icons/tango/index.theme</file> <file alias="index.theme">icons/tango/index.theme</file>
<file alias="48x48/video-display.png">icons/tango/48x48/video-display.png</file> <file alias="48x48/emblem-system.png">icons/tango/48x48/emblem-system.png</file>
<file alias="48x48/preferences-system.png">icons/tango/48x48/preferences-system.png</file> <file alias="48x48/preferences-system.png">icons/tango/48x48/preferences-system.png</file>
<file alias="48x48/video-display.png">icons/tango/48x48/video-display.png</file>
<file alias="16x16/document-new.png">icons/tango/16x16/document-new.png</file> <file alias="16x16/document-new.png">icons/tango/16x16/document-new.png</file>
<file alias="16x16/edit-copy.png">icons/tango/16x16/edit-copy.png</file> <file alias="16x16/edit-copy.png">icons/tango/16x16/edit-copy.png</file>
<file alias="16x16/edit-delete.png">icons/tango/16x16/edit-delete.png</file> <file alias="16x16/edit-delete.png">icons/tango/16x16/edit-delete.png</file>

@ -0,0 +1,286 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AdvancedPage</class>
<widget class="QWidget" name="AdvancedPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>434</width>
<height>373</height>
</rect>
</property>
<layout class="QVBoxLayout" name="pageVerticalLayout">
<item>
<widget class="QLabel" name="pageDescriptionLabel">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This temporary page contains new settings that will be available in-game in a post-1.0 release of OpenMW.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>393</width>
<height>437</height>
</rect>
</property>
<layout class="QVBoxLayout" name="scrollAreaVerticalLayout">
<item>
<widget class="QGroupBox" name="gameGroup">
<property name="title">
<string>Game</string>
</property>
<layout class="QVBoxLayout" name="gameGroupVerticalLayout">
<item>
<widget class="QCheckBox" name="canLootDuringDeathAnimationCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If this setting is true, the player is allowed to loot actors (e.g. summoned creatures) during death animation, if they are not in combat. However disposing corpses during death animation is not recommended - death counter may not be incremented, and this behaviour can break quests. This is how original Morrowind behaves.&lt;/p&gt;&lt;p&gt;If this setting is false, player has to wait until end of death animation in all cases. This case is more safe, but makes using of summoned creatures exploit (looting summoned Dremoras and Golden Saints for expensive weapons) a lot harder.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Can loot during death animation</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="followersAttackOnSightCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Makes player followers and escorters start combat with enemies who have started combat with them or the player. Otherwise they wait for the enemies or the player to do an attack first.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Followers attack on sight</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="preventMerchantEquippingCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Prevents merchants from equipping items that are sold to them.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Prevent merchant equipping</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="showEffectDurationCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Show the remaining duration of magic effects and lights if this setting is true. The remaining duration is displayed in the tooltip by hovering over the magical effect. &lt;/p&gt;&lt;p&gt;The default value is false.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Show effect duration</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="showEnchantChanceCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Whether or not the chance of success will be displayed in the enchanting menu.&lt;/p&gt;&lt;p&gt;The default value is false.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Show enchant chance</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="showMeleeInfoCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If this setting is true, melee weapons reach and speed will be showed on item tooltip.&lt;/p&gt;&lt;p&gt;The default value is false.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Show melee info</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="showProjectileDamageCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If this setting is true, damage bonus of arrows and bolts will be showed on item tooltip.&lt;/p&gt;&lt;p&gt;The default value is false.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Show projectile damage</string>
</property>
</widget>
</item>
<item alignment="Qt::AlignLeft">
<widget class="QWidget" name="showOwnedGroup" native="true">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Enable visual clues for items owned by NPCs when the crosshair is on the object.&lt;/p&gt;&lt;p&gt;The default value is Off.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>-1</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item alignment="Qt::AlignRight">
<widget class="QLabel" name="showOwnedLabel">
<property name="text">
<string>Show owned:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="showOwnedComboBox">
<item>
<property name="text">
<string>Off</string>
</property>
</item>
<item>
<property name="text">
<string>Tool Tip Only</string>
</property>
</item>
<item>
<property name="text">
<string>Crosshair Only</string>
</property>
</item>
<item>
<property name="text">
<string>Tool Tip and Crosshair</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="inputGroup">
<property name="title">
<string>Input</string>
</property>
<layout class="QVBoxLayout" name="inputGroupVerticalLayout">
<item>
<widget class="QCheckBox" name="allowThirdPersonZoomCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Allow zooming in and out using the middle mouse wheel in third person view. This feature may not work correctly if the mouse wheel is bound to other actions, and may be triggered accidentally in some cases, so is disabled by default.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Allow third person zoom</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="grabCursorCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;OpenMW will capture control of the cursor if this setting is true.&lt;/p&gt;&lt;p&gt;In “look mode”, OpenMW will center the cursor regardless of the value of this setting (since the cursor/crosshair is always centered in the OpenMW window). However, in GUI mode, this setting determines the behavior when the cursor is moved outside the OpenMW window. If true, the cursor movement stops at the edge of the window preventing access to other applications. If false, the cursor is allowed to move freely on the desktop.&lt;/p&gt;&lt;p&gt;This setting does not apply to the screen where escape has been pressed, where the cursor is never captured. Regardless of this setting “Alt-Tab” or some other operating system dependent key sequence can be used to allow the operating system to regain control of the mouse cursor. This setting interacts with the minimize on focus loss setting by affecting what counts as a focus loss. Specifically on a two-screen configuration it may be more convenient to access the second screen with setting disabled.&lt;/p&gt;&lt;p&gt;Note for developers: its desirable to have this setting disabled when running the game in a debugger, to prevent the mouse cursor from becoming unusable when the game pauses on a breakpoint.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Grab cursor</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="toggleSneakCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This setting causes the behavior of the sneak key (bound to Ctrl by default) to toggle sneaking on and off rather than requiring the key to be held down while sneaking. Players that spend significant time sneaking may find the character easier to control with this option enabled. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Toggle sneak</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="otherGroup">
<property name="title">
<string>Other</string>
</property>
<layout class="QVBoxLayout" name="otherGroupVerticalLayout">
<item>
<widget class="QCheckBox" name="timePlayedCheckbox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This setting determines whether the amount of the time the player has spent playing will be displayed for each saved game in the Load menu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Add &quot;Time Played&quot; to saves</string>
</property>
</widget>
</item>
<item alignment="Qt::AlignLeft">
<widget class="QWidget" name="screenshotFormatGroup" native="true">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Specify the format for screen shots taken by pressing the screen shot key (bound to F12 by default). This setting should be the file extension commonly associated with the desired format. The formats supported will be determined at compilation, but “jpg”, “png”, and “tga” should be allowed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>-1</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item alignment="Qt::AlignRight">
<widget class="QLabel" name="screenshotFormatLabel">
<property name="text">
<string>Screenshot Format</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="screenshotFormatComboBox">
<item>
<property name="text">
<string>JPG</string>
</property>
</item>
<item>
<property name="text">
<string>PNG</string>
</property>
</item>
<item>
<property name="text">
<string>TGA</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

@ -6,13 +6,13 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>635</width> <width>720</width>
<height>565</height> <height>565</height>
</rect> </rect>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>635</width> <width>720</width>
<height>565</height> <height>565</height>
</size> </size>
</property> </property>

Loading…
Cancel
Save