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 6 years ago
commit ac374a8ef9

@ -6,6 +6,7 @@ set(LAUNCHER
playpage.cpp
textslotmsgbox.cpp
settingspage.cpp
advancedpage.cpp
utils/profilescombobox.cpp
utils/textinputdialog.cpp
@ -21,6 +22,7 @@ set(LAUNCHER_HEADER
playpage.hpp
textslotmsgbox.hpp
settingspage.hpp
advancedpage.hpp
utils/profilescombobox.hpp
utils/textinputdialog.hpp
@ -35,6 +37,7 @@ set(LAUNCHER_HEADER_MOC
playpage.hpp
textslotmsgbox.hpp
settingspage.hpp
advancedpage.hpp
utils/textinputdialog.hpp
utils/profilescombobox.hpp
@ -49,6 +52,7 @@ set(LAUNCHER_UI
${CMAKE_SOURCE_DIR}/files/ui/playpage.ui
${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui
${CMAKE_SOURCE_DIR}/files/ui/settingspage.ui
${CMAKE_SOURCE_DIR}/files/ui/advancedpage.ui
)
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 <QLabel>
#include <QDate>
#include <QTime>
#include <QMessageBox>
#include <QPushButton>
#include <QFontDatabase>
@ -12,8 +10,6 @@
#include <QFileDialog>
#include <QCloseEvent>
#include <QTextCodec>
#include <QFile>
#include <QDir>
#include <QDebug>
@ -21,6 +17,7 @@
#include "graphicspage.hpp"
#include "datafilespage.hpp"
#include "settingspage.hpp"
#include "advancedpage.hpp"
using namespace Process;
@ -104,6 +101,12 @@ void Launcher::MainDialog::createIcons()
settingsButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
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,
SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*)));
@ -116,6 +119,7 @@ void Launcher::MainDialog::createPages()
mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
mGraphicsPage = new GraphicsPage(mCfgMgr, mEngineSettings, 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
mPlayPage->setProfilesModel(mDataFilesPage->profilesModel());
@ -126,6 +130,7 @@ void Launcher::MainDialog::createPages()
pagesWidget->addWidget(mDataFilesPage);
pagesWidget->addWidget(mGraphicsPage);
pagesWidget->addWidget(mSettingsPage);
pagesWidget->addWidget(mAdvancedPage);
// Select the first page
iconWidget->setCurrentItem(iconWidget->item(0), QItemSelectionModel::Select);
@ -245,6 +250,9 @@ bool Launcher::MainDialog::reloadSettings()
if (!mGraphicsPage->loadSettings())
return false;
if (!mAdvancedPage->loadSettings())
return false;
return true;
}
@ -483,6 +491,7 @@ bool Launcher::MainDialog::writeSettings()
mDataFilesPage->saveSettings();
mGraphicsPage->saveSettings();
mSettingsPage->saveSettings();
mAdvancedPage->saveSettings();
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
QDir dir(userPath);

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

@ -61,6 +61,7 @@ void Player::Init(LuaState &lua)
"hair", sol::property(&Player::getHair, &Player::setHair),
"birthsign", sol::property(&Player::getBirthsign, &Player::setBirthsign),
"bounty", sol::property(&Player::getBounty, &Player::setBounty),
"reputation", sol::property(&Player::getReputation, &Player::setReputation),
"levelProgress", sol::property(&Player::getLevelProgress, &Player::setLevelProgress),
"creatureModel", sol::property(&Player::getCreatureModel, &Player::setCreatureModel),
"isCreatureName", sol::property(&Player::isCreatureName, &Player::creatureName),
@ -89,10 +90,18 @@ void Player::Init(LuaState &lua)
"getQuickKeys", &Player::getQuickKeys,
"getWeatherMgr", &Player::getWeatherMgr,
"getMarkPosition", &Player::getMarkPosition,
"setMarkPosition", &Player::setMarkPosition,
"getMarkRotation", &Player::getMarkRotation,
"setMarkRotation", &Player::setMarkRotation,
"getMarkCell", &Player::getMarkCell,
"setMarkCell", &Player::setMarkCell,
"getCellState", &Player::getCellState,
"cellStateSize", &Player::cellStateSize,
"addCellExplored", &Player::addCellExplored,
"setAuthority", &Player::setAuthority,
"storedData", &Player::storedData,
"customData", &Player::customData,
"markedForDeletion", sol::property(&Player::isMarkedForDeleteion)
@ -115,11 +124,15 @@ Player::Player(RakNet::RakNetGUID guid) : BasePlayer(guid), NetActor(), changedM
handshakeCounter = 0;
loadState = NOTLOADED;
resetUpdateFlags();
cell.blank();
npc.blank();
npcStats.blank();
creatureStats.blank();
charClass.blank();
scale = 1;
isWerewolf = false;
markedForDeletion = false;
storedData = mwmp::Networking::get().getState().getState()->create_table();
customData = mwmp::Networking::get().getState().getState()->create_table();
@ -227,6 +240,24 @@ void Player::update()
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)
{
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_MAP);
@ -610,6 +641,22 @@ void Player::setBounty(int bounty)
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
{
return npcStats.mLevelProgress;
@ -806,6 +853,70 @@ void Player::setWerewolfState(bool state)
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
{
return cellStateChanges.cellStates.size();

@ -104,6 +104,9 @@ public:
int getBounty() const;
void setBounty(int bounty);
int getReputation() const;
void setReputation(int reputation, bool toOthers);
int getLevel() const;
void setLevel(int level);
int getLevelProgress() const;
@ -142,6 +145,9 @@ public:
bool getWerewolfState() const;
void setWerewolfState(bool state);
float getScale() const;
void setScale(float newScale);
std::string getCreatureModel() const;
void setCreatureModel(const std::string &model);
void creatureName(bool useName);
@ -172,6 +178,16 @@ public:
int getSkillIncrease(unsigned short attributeId) const;
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);
size_t cellStateSize() const;
void addCellExplored(const std::string &cellDescription);
@ -197,7 +213,7 @@ private:
CellController::TContainer cells;
int handshakeCounter;
int loadState;
bool /*statsChanged, attributesChanged, skillsChanged, baseInfoChanged, positionChanged,*/ changedMap;
bool /*statsChanged, attributesChanged, skillsChanged, baseInfoChanged, positionChanged,*/ changedMarkLocation, changedSelectedSpell, changedMap;
CharClass cClass;
GameSettings settings;
Books books;

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

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

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

@ -16,7 +16,7 @@ namespace mwmp
void Do(ActorPacket &packet, const std::shared_ptr<Player> &player, BaseActorList &actorList) override
{
// 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)
serverCell->sendToLoaded(&packet, &actorList);

@ -1,14 +1,14 @@
#ifndef OPENMW_PROCESSORPLAYERRECORDDYNAMIC_HPP
#define OPENMW_PROCESSORPLAYERRECORDDYNAMIC_HPP
#ifndef OPENMW_PROCESSORRECORDDYNAMIC_HPP
#define OPENMW_PROCESSORRECORDDYNAMIC_HPP
#include "../PlayerProcessor.hpp"
namespace mwmp
{
class ProcessorPlayerRecordDynamic final : public PlayerProcessor
class ProcessorRecordDynamic final : public PlayerProcessor
{
public:
ProcessorPlayerRecordDynamic()
ProcessorRecordDynamic()
{
BPP_INIT(ID_RECORD_DYNAMIC)
}
@ -17,9 +17,9 @@ namespace mwmp
{
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
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)
mwmp::Main::get().getLocalPlayer()->sendQuickKey(mSelectedIndex, mwmp::QuickKey::Type::Item, item.getCellRef().getRefId());
@ -407,6 +408,16 @@ namespace MWGui
store.setSelectedEnchantItem(store.end());
MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player)));
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)
{

@ -186,6 +186,16 @@ namespace MWGui
MWBase::Environment::get().getWindowManager()->setSelectedSpell(spellId, int(MWMechanics::getSpellSuccessChance(spellId, player)));
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()

@ -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)
{
if (SDL_IsTextInputActive())
return;
if (isLeftOrRightButton(action, mInputBinder, mFakeDeviceID, mJoystickLastUsed))
return;
MyGUI::KeyCode key;
switch (action)
{
@ -1185,7 +1200,7 @@ namespace MWInput
{
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);
}
else if (mControlSwitch["playercontrols"])

@ -579,9 +579,16 @@ namespace MWMechanics
{
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);
if (playerFactionIt == playerStats.getFactionRanks().begin() || itReaction < reaction)
{
reaction = static_cast<float>(itReaction);
rank = playerFactionIt->second;
}
}
}
else

@ -755,6 +755,17 @@ namespace MWMechanics
{
MWBase::Environment::get().getWorld()->getPlayer().markPosition(
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;
}
else if (effectId == ESM::MagicEffect::Recall)

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

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

@ -19,6 +19,7 @@
#include "../mwmechanics/aitravel.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/mechanicsmanagerimp.hpp"
#include "../mwmechanics/spellcasting.hpp"
#include "../mwscript/scriptmanagerimp.hpp"
@ -65,6 +66,7 @@ LocalPlayer::LocalPlayer()
jailProgressText = "";
jailEndText = "";
scale = 1;
isWerewolf = false;
diedSinceArrestAttempt = false;
@ -106,6 +108,7 @@ void LocalPlayer::update()
updateSkills();
updateLevel();
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)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
@ -920,6 +936,15 @@ void LocalPlayer::setBounty()
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()
{
MWBase::World *world = MWBase::Environment::get().getWorld();
@ -1235,9 +1260,33 @@ void LocalPlayer::setMapExplored()
void LocalPlayer::setShapeshift()
{
MWWorld::Ptr ptrPlayer = getPlayerPtr();
MWBase::Environment::get().getWorld()->scaleObject(ptrPlayer, scale);
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()
{
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();
@ -1512,7 +1561,17 @@ void LocalPlayer::sendBook(const std::string& bookId)
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;
@ -1522,6 +1581,25 @@ void LocalPlayer::sendShapeshift(bool werewolfState)
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()
{
cellStateChanges.cellStates.clear();

@ -29,6 +29,7 @@ namespace mwmp
void updateSkills(bool forceUpdate = false);
void updateLevel(bool forceUpdate = false);
void updateBounty(bool forceUpdate = false);
void updateReputation(bool forceUpdate = false);
void updatePosition(bool forceUpdate = false);
void updateCell(bool forceUpdate = false);
void updateChar();
@ -55,6 +56,7 @@ namespace mwmp
void setSkills();
void setLevel();
void setBounty();
void setReputation();
void setPosition();
void setCell();
void setClass();
@ -67,16 +69,18 @@ namespace mwmp
void setBooks();
void setMapExplored();
void setShapeshift();
void setMarkLocation();
void setSelectedSpell();
void sendClass();
void sendInventory();
void sendSpellbook();
void sendCellStates();
void sendSpellAddition(std::string id);
void sendSpellAddition(const ESM::Spell &spell);
void sendSpellAddition(const ESM::Spell& spell);
void sendSpellRemoval(std::string id);
void sendSpellRemoval(const ESM::Spell &spell);
void sendQuickKey(int slot, QuickKey::Type type, const std::string& itemId = "");
void sendSpellRemoval(const ESM::Spell& spell);
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 sendJournalIndex(const std::string& quest, int index);
void sendFactionRank(const std::string& factionId, int rank);
@ -85,7 +89,10 @@ namespace mwmp
void sendTopic(const std::string& topic);
void sendKill(const std::string& refId, int number);
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 clearCurrentContainer();

@ -166,26 +166,35 @@ void WorldEvent::placeObjects(MWWorld::CellStore* cellStore)
// Only create this object if it doesn't already exist
if (!ptrFound)
{
MWWorld::ManualRef ref(world->getStore(), worldObject.refId, 1);
MWWorld::Ptr newPtr = ref.getPtr();
try
{
MWWorld::ManualRef ref(world->getStore(), worldObject.refId, 1);
if (worldObject.count > 1)
newPtr.getRefData().setCount(worldObject.count);
MWWorld::Ptr newPtr = ref.getPtr();
if (worldObject.charge > -1)
newPtr.getCellRef().setCharge(worldObject.charge);
if (worldObject.count > 1)
newPtr.getRefData().setCount(worldObject.count);
if (worldObject.enchantmentCharge > -1.0f)
newPtr.getCellRef().setEnchantmentCharge(worldObject.enchantmentCharge);
if (worldObject.charge > -1)
newPtr.getCellRef().setCharge(worldObject.charge);
newPtr.getCellRef().setGoldValue(worldObject.goldValue);
newPtr = world->placeObject(newPtr, cellStore, worldObject.position);
if (worldObject.enchantmentCharge > -1.0f)
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().setMpNum(worldObject.mpNum);
newPtr.getCellRef().setGoldValue(worldObject.goldValue);
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
LOG_APPEND(Log::LOG_VERBOSE, "-- Object already existed!");
@ -468,24 +477,20 @@ void WorldEvent::runConsoleCommands(MWWorld::CellStore* cellStore)
if (worldObject.isPlayer)
{
BasePlayer *player = 0;
if (worldObject.guid == Main::get().getLocalPlayer()->guid)
{
player = Main::get().getLocalPlayer();
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);
}
else
{
player = PlayerList::getPlayer(worldObject.guid);
DedicatedPlayer *player = PlayerList::getPlayer(worldObject.guid);
if (player != 0)
{
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);
}
}
@ -508,7 +513,7 @@ void WorldEvent::runConsoleCommands(MWWorld::CellStore* cellStore)
}
windowManager->clearConsolePtr();
}
}
}
void WorldEvent::setLocalShorts(MWWorld::CellStore* cellStore)

@ -23,7 +23,16 @@ namespace mwmp
if (!isRequest())
{
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)
{
if (isLocal())
if (isRequest())
{
//if (isRequest())
// static_cast<LocalPlayer *>(player)->updateReputation(true);
//else
// static_cast<LocalPlayer *>(player)->setReputation();
static_cast<LocalPlayer *>(player)->updateReputation(true);
}
else if (player != 0)
{
MWWorld::Ptr ptrPlayer = static_cast<DedicatedPlayer *>(player)->getPtr();
MWMechanics::NpcStats *ptrNpcStats = &ptrPlayer.getClass().getNpcStats(ptrPlayer);
ptrNpcStats->setReputation(player->npcStats.mReputation);
static_cast<LocalPlayer *>(player)->setReputation();
}
}
};

@ -1203,6 +1203,18 @@ void SkyManager::create()
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
{
public:
@ -1473,7 +1485,7 @@ void SkyManager::createRain()
placer->setZRange(300, 300);
emitter->setPlacer(placer);
osg::ref_ptr<osgParticle::ConstantRateCounter> counter (new osgParticle::ConstantRateCounter);
osg::ref_ptr<RainCounter> counter (new RainCounter);
counter->setNumberOfParticlesPerSecondToCreate(600.0);
emitter->setCounter(counter);

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

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

@ -168,16 +168,16 @@ namespace MWWorld
ToUTF8::Utf8Encoder* encoder, const std::map<std::string,std::string>& fallbackMap,
int activationDistanceOverride, const std::string& startCell, const std::string& startupScript,
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),
mGodMode(false), mScriptsEnabled(true), mContentFiles (contentFiles), mUserDataPath(userDataPath),
mActivationDistanceOverride (activationDistanceOverride), mStartupScript(startupScript),
mStartCell (startCell), mDistanceToFacedObject(-1), mTeleportEnabled(true),
mLevitationEnabled(true), mGoToJail(false), mDaysInPrison(0), mSpellPreloadTimer(0.f)
{
mPhysics = new MWPhysics::PhysicsSystem(resourceSystem, rootNode);
mRendering = new MWRender::RenderingManager(viewer, rootNode, resourceSystem, workQueue, &mFallback, resourcePath);
mProjectileManager.reset(new ProjectileManager(mRendering->getLightRoot(), resourceSystem, mRendering, mPhysics));
mPhysics.reset(new MWPhysics::PhysicsSystem(resourceSystem, rootNode));
mRendering.reset(new MWRender::RenderingManager(viewer, rootNode, resourceSystem, workQueue, &mFallback, resourcePath));
mProjectileManager.reset(new ProjectileManager(mRendering->getLightRoot(), resourceSystem, mRendering.get(), mPhysics.get()));
mRendering->preloadCommonAssets();
@ -209,10 +209,10 @@ namespace MWWorld
mSwimHeightScale = mStore.get<ESM::GameSetting>().find("fSwimHeightScale")->getFloat();
mWeatherManager = new MWWorld::WeatherManager(*mRendering, mFallback, mStore);
mwmp::Main::get().setWeatherManager(mWeatherManager);
mWeatherManager.reset(new MWWorld::WeatherManager(*mRendering, mFallback, mStore));
mwmp::Main::get().setWeatherManager(mWeatherManager.get());
mWorldScene = new Scene(*mRendering, mPhysics);
mWorldScene.reset(new Scene(*mRendering.get(), mPhysics.get()));
}
void World::fillGlobalVariables()
@ -245,9 +245,9 @@ namespace MWWorld
// 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.
delete mWeatherManager;
mWeatherManager = new MWWorld::WeatherManager(*mRendering, mFallback, mStore);
mwmp::Main::get().setWeatherManager(mWeatherManager);
mWeatherManager.reset();
mWeatherManager.reset(new MWWorld::WeatherManager(*mRendering.get(), mFallback, mStore));
mwmp::Main::get().setWeatherManager(mWeatherManager.get());
if (!bypass)
{
@ -527,12 +527,6 @@ namespace MWWorld
{
// Must be cleared before mRendering is destroyed
mProjectileManager->clear();
delete mWeatherManager;
delete mWorldScene;
delete mRendering;
delete mPhysics;
delete mPlayer;
}
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");
if (!mPlayer)
mPlayer = new MWWorld::Player(player);
mPlayer.reset(new MWWorld::Player(player));
else
{
// Remove the old CharacterController
@ -3669,17 +3663,17 @@ namespace MWWorld
if (MWMechanics::isSummoningEffect(it->mEffectID))
{
preload(mWorldScene, mStore, "VFX_Summon_Start");
preload(mWorldScene, mStore, MWMechanics::getSummonedCreature(it->mEffectID));
preload(mWorldScene.get(), mStore, "VFX_Summon_Start");
preload(mWorldScene.get(), mStore, MWMechanics::getSummonedCreature(it->mEffectID));
}
preload(mWorldScene, mStore, effect->mCasting);
preload(mWorldScene, mStore, effect->mHit);
preload(mWorldScene.get(), mStore, effect->mCasting);
preload(mWorldScene.get(), mStore, effect->mHit);
if (it->mArea > 0)
preload(mWorldScene, mStore, effect->mArea);
preload(mWorldScene.get(), mStore, effect->mArea);
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;
Fallback::Map mFallback;
MWRender::RenderingManager* mRendering;
MWWorld::WeatherManager* mWeatherManager;
MWWorld::Scene *mWorldScene;
MWWorld::Player *mPlayer;
std::vector<ESM::ESMReader> mEsm;
MWWorld::ESMStore mStore;
LocalScripts mLocalScripts;
MWWorld::Globals mGlobalVariables;
MWPhysics::PhysicsSystem *mPhysics;
bool mSky;
ESM::Variant* mGameHour;
@ -98,6 +92,11 @@ namespace MWWorld
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;
bool mGodMode;

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

@ -12,5 +12,20 @@ void PacketPlayerMiscellaneous::Packet(RakNet::BitStream *bs, bool 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);
// Placeholder
RW(player->npcStats.mReputation, send);
}

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

@ -9,8 +9,9 @@
</qresource>
<qresource prefix="icons/tango">
<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/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/edit-copy.png">icons/tango/16x16/edit-copy.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>
<x>0</x>
<y>0</y>
<width>635</width>
<width>720</width>
<height>565</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>635</width>
<width>720</width>
<height>565</height>
</size>
</property>

Loading…
Cancel
Save