mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-05 22:19:42 +00:00
Add TES3MP 0.8.0 commits up to 28 Apr 2022
# Conflicts: # apps/openmw/mwclass/creature.cpp # apps/openmw/mwclass/npc.cpp
This commit is contained in:
commit
a032c8d399
33 changed files with 501 additions and 194 deletions
|
@ -10,7 +10,7 @@ When it's combined with Mads Buvik Sandvei's [fork adding VR support to OpenMW](
|
|||
|
||||
* TES3MP version: 0.8.0
|
||||
* OpenMW version: 0.47.0
|
||||
* License: GPLv3 (see [LICENSE](https://github.com/TES3MP/TES3MP/blob/master/LICENSE) for more information)
|
||||
* License: GPLv3 with additional allowed terms (see [LICENSE](https://github.com/TES3MP/TES3MP/blob/master/LICENSE) for more information)
|
||||
|
||||
Font Licenses:
|
||||
* DejaVuLGCSansMono.ttf: custom (see [files/mygui/DejaVuFontLicense.txt](https://github.com/TES3MP/TES3MP/blob/master/files/mygui/DejaVuFontLicense.txt) for more information)
|
||||
|
|
|
@ -489,7 +489,7 @@ void signalHandler(int signum)
|
|||
{
|
||||
std::cout << "Interrupt signal (" << signum << ") received.\n";
|
||||
//15 is SIGTERM(Normal OS stop call), 2 is SIGINT(Ctrl+C)
|
||||
if(signum == 15 or signum == 2)
|
||||
if(signum == 15 || signum == 2)
|
||||
{
|
||||
killLoop = true;
|
||||
}
|
||||
|
@ -507,7 +507,7 @@ int Networking::mainLoop()
|
|||
sigIntHandler.sa_flags = 0;
|
||||
#endif
|
||||
|
||||
while (running and !killLoop)
|
||||
while (running && !killLoop)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
sigaction(SIGTERM, &sigIntHandler, NULL);
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace mwmp
|
|||
|
||||
void Do(ActorPacket &packet, Player &player, BaseActorList &actorList) override
|
||||
{
|
||||
bool isAccepted = false;
|
||||
Cell *serverCell = CellController::get()->getCell(&actorList.cell);
|
||||
|
||||
if (serverCell != nullptr)
|
||||
|
@ -31,18 +32,27 @@ namespace mwmp
|
|||
}
|
||||
}
|
||||
|
||||
// Only accept regular cell changes from a cell's authority, but accept follower
|
||||
// If the cell is loaded, only accept regular cell changes from a cell's authority, but accept follower
|
||||
// cell changes from other players
|
||||
if (*serverCell->getAuthority() == actorList.guid || isFollowerCellChange)
|
||||
{
|
||||
serverCell->removeActors(&actorList);
|
||||
|
||||
Script::Call<Script::CallbackIdentity("OnActorCellChange")>(player.getId(), actorList.cell.getShortDescription().c_str());
|
||||
|
||||
// Send this to everyone
|
||||
packet.Send(true);
|
||||
isAccepted = true;
|
||||
}
|
||||
}
|
||||
// If the cell isn't loaded, the packet must be from dialogue or a script, so accept it
|
||||
else
|
||||
{
|
||||
isAccepted = true;
|
||||
}
|
||||
|
||||
if (isAccepted)
|
||||
{
|
||||
Script::Call<Script::CallbackIdentity("OnActorCellChange")>(player.getId(), actorList.cell.getShortDescription().c_str());
|
||||
|
||||
// Send this to everyone
|
||||
packet.Send(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -698,7 +698,15 @@ void OMW::Engine::createWindow(Settings::Manager& settings)
|
|||
{
|
||||
while (!mWindow)
|
||||
{
|
||||
mWindow = SDL_CreateWindow("OpenMW", pos_x, pos_y, width, height, flags);
|
||||
/*
|
||||
Start of tes3mp change (major)
|
||||
|
||||
Rename the window into TES3MP
|
||||
*/
|
||||
mWindow = SDL_CreateWindow("TES3MP", pos_x, pos_y, width, height, flags);
|
||||
/*
|
||||
End of tes3mp change (major)
|
||||
*/
|
||||
if (!mWindow)
|
||||
{
|
||||
// Try with a lower AA
|
||||
|
@ -776,7 +784,15 @@ void OMW::Engine::createWindow(Settings::Manager& settings)
|
|||
void OMW::Engine::setWindowIcon()
|
||||
{
|
||||
boost::filesystem::ifstream windowIconStream;
|
||||
std::string windowIcon = (mResDir / "mygui" / "openmw.png").string();
|
||||
/*
|
||||
Start of tes3mp change (major)
|
||||
|
||||
Use TES3MP's logo for the window icon
|
||||
*/
|
||||
std::string windowIcon = (mResDir / "mygui" / "tes3mp_logo.png").string();
|
||||
/*
|
||||
End of tes3mp change (major)
|
||||
*/
|
||||
windowIconStream.open(windowIcon, std::ios_base::in | std::ios_base::binary);
|
||||
if (windowIconStream.fail())
|
||||
Log(Debug::Error) << "Error: Failed to open " << windowIcon;
|
||||
|
|
|
@ -279,11 +279,23 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
|
|||
engine.setCompileAll(variables["script-all"].as<bool>());
|
||||
engine.setCompileAllDialogue(variables["script-all-dialogue"].as<bool>());
|
||||
engine.setScriptConsoleMode (variables["script-console"].as<bool>());
|
||||
|
||||
/*
|
||||
Start of tes3mp change (major)
|
||||
|
||||
Clients should not be allowed to set any of these unilaterally in multiplayer, so
|
||||
disable them
|
||||
*/
|
||||
/*
|
||||
engine.setStartupScript (variables["script-run"].as<Files::EscapeHashString>().toStdString());
|
||||
engine.setWarningsMode (variables["script-warn"].as<int>());
|
||||
engine.setScriptBlacklist (variables["script-blacklist"].as<Files::EscapeStringVector>().toStdStringVector());
|
||||
engine.setScriptBlacklistUse (variables["script-blacklist-use"].as<bool>());
|
||||
engine.setSaveGameFile (variables["load-savegame"].as<Files::EscapePath>().mPath.string());
|
||||
*/
|
||||
/*
|
||||
End of tes3mp change (major)
|
||||
*/
|
||||
|
||||
// other settings
|
||||
Fallback::Map::init(variables["fallback"].as<FallbackMap>().mMap);
|
||||
|
|
|
@ -17,6 +17,17 @@
|
|||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwworld/player.hpp"
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Include additional headers for multiplayer purposes
|
||||
*/
|
||||
#include "../mwmp/Main.hpp"
|
||||
#include "../mwmp/LocalPlayer.hpp"
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
#include "textinput.hpp"
|
||||
#include "race.hpp"
|
||||
#include "class.hpp"
|
||||
|
@ -329,6 +340,16 @@ namespace MWGui
|
|||
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Birth);
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Decrease the character generation stage tracked for the LocalPlayer
|
||||
*/
|
||||
mwmp::Main::get().getLocalPlayer()->charGenState.currentStage--;
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
}
|
||||
|
||||
void CharacterCreation::onReviewActivateDialog(int parDialog)
|
||||
|
@ -381,6 +402,16 @@ namespace MWGui
|
|||
selectPickedClass();
|
||||
|
||||
handleDialogDone(CSE_ClassChosen, GM_Birth);
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Increase the character generation stage tracked for the LocalPlayer
|
||||
*/
|
||||
mwmp::Main::get().getLocalPlayer()->charGenState.currentStage++;
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
}
|
||||
|
||||
void CharacterCreation::onPickClassDialogBack()
|
||||
|
@ -411,6 +442,16 @@ namespace MWGui
|
|||
break;
|
||||
case ClassChoiceDialog::Class_Back:
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Race);
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Decrease the character generation stage tracked for the LocalPlayer
|
||||
*/
|
||||
mwmp::Main::get().getLocalPlayer()->charGenState.currentStage--;
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
break;
|
||||
|
||||
};
|
||||
|
@ -439,6 +480,16 @@ namespace MWGui
|
|||
}
|
||||
|
||||
handleDialogDone(CSE_NameChosen, GM_Race);
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Increase the character generation stage tracked for the LocalPlayer
|
||||
*/
|
||||
mwmp::Main::get().getLocalPlayer()->charGenState.currentStage++;
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
}
|
||||
|
||||
void CharacterCreation::selectRace()
|
||||
|
@ -477,6 +528,16 @@ namespace MWGui
|
|||
selectRace();
|
||||
|
||||
handleDialogDone(CSE_RaceChosen, GM_Class);
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Increase the character generation stage tracked for the LocalPlayer
|
||||
*/
|
||||
mwmp::Main::get().getLocalPlayer()->charGenState.currentStage++;
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
}
|
||||
|
||||
void CharacterCreation::selectBirthSign()
|
||||
|
@ -498,6 +559,16 @@ namespace MWGui
|
|||
selectBirthSign();
|
||||
|
||||
handleDialogDone(CSE_BirthSignChosen, GM_Review);
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Increase the character generation stage tracked for the LocalPlayer
|
||||
*/
|
||||
mwmp::Main::get().getLocalPlayer()->charGenState.currentStage++;
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
}
|
||||
|
||||
void CharacterCreation::onBirthSignDialogBack()
|
||||
|
@ -506,6 +577,16 @@ namespace MWGui
|
|||
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Class);
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Decrease the character generation stage tracked for the LocalPlayer
|
||||
*/
|
||||
mwmp::Main::get().getLocalPlayer()->charGenState.currentStage--;
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
}
|
||||
|
||||
void CharacterCreation::selectCreatedClass()
|
||||
|
@ -547,6 +628,16 @@ namespace MWGui
|
|||
selectCreatedClass();
|
||||
|
||||
handleDialogDone(CSE_ClassChosen, GM_Birth);
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Increase the character generation stage tracked for the LocalPlayer
|
||||
*/
|
||||
mwmp::Main::get().getLocalPlayer()->charGenState.currentStage++;
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
}
|
||||
|
||||
void CharacterCreation::onCreateClassDialogBack()
|
||||
|
@ -556,6 +647,16 @@ namespace MWGui
|
|||
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
MWBase::Environment::get().getWindowManager()->pushGuiMode(GM_Class);
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Decrease the character generation stage tracked for the LocalPlayer
|
||||
*/
|
||||
mwmp::Main::get().getLocalPlayer()->charGenState.currentStage--;
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
}
|
||||
|
||||
void CharacterCreation::onClassQuestionChosen(int _index)
|
||||
|
@ -748,6 +849,16 @@ namespace MWGui
|
|||
selectGeneratedClass();
|
||||
|
||||
handleDialogDone(CSE_ClassChosen, GM_Birth);
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Increase the character generation stage tracked for the LocalPlayer
|
||||
*/
|
||||
mwmp::Main::get().getLocalPlayer()->charGenState.currentStage++;
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
}
|
||||
|
||||
CharacterCreation::~CharacterCreation()
|
||||
|
|
|
@ -301,27 +301,33 @@ namespace MWGui
|
|||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Trigger crimes related to the attempted taking of these items, if applicable
|
||||
|
||||
Send an ID_CONTAINER packet every time the Take All button is used on
|
||||
a container
|
||||
*/
|
||||
for (size_t i = 0; i < mModel->getItemCount(); ++i)
|
||||
{
|
||||
const ItemStack& item = mModel->getItem(i);
|
||||
|
||||
if (!onTakeItem(item, item.mCount))
|
||||
break;
|
||||
}
|
||||
|
||||
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
|
||||
objectList->reset();
|
||||
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY;
|
||||
objectList->cell = *mPtr.getCell()->getCell();
|
||||
objectList->action = mwmp::BaseObjectList::REMOVE;
|
||||
objectList->containerSubAction = mwmp::BaseObjectList::TAKE_ALL;
|
||||
objectList->addEntireContainer(mPtr);
|
||||
objectList->sendContainer();
|
||||
mwmp::BaseObject baseObject = objectList->getBaseObjectFromPtr(mPtr);
|
||||
|
||||
for (size_t i = 0; i < mModel->getItemCount(); ++i)
|
||||
{
|
||||
const ItemStack& item = mModel->getItem(i);
|
||||
|
||||
// Trigger crimes related to the attempted taking of these items, if applicable
|
||||
if (!onTakeItem(item, item.mCount))
|
||||
break;
|
||||
|
||||
objectList->addContainerItem(baseObject, item, item.mCount, item.mCount);
|
||||
}
|
||||
|
||||
if (baseObject.containerItems.size() > 0)
|
||||
{
|
||||
objectList->addBaseObject(baseObject);
|
||||
objectList->sendContainer();
|
||||
}
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
|
|
@ -469,10 +469,6 @@ namespace MWGui
|
|||
{
|
||||
if (dialogueChoiceType == mwmp::DialogueChoiceType::TOPIC)
|
||||
{
|
||||
// If we're using a translated version of Morrowind, translate this topic from English into our language
|
||||
if (MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation())
|
||||
topic = MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().getLocalizedTopicId(topic);
|
||||
|
||||
onTopicActivated(topic);
|
||||
}
|
||||
else if (dialogueChoiceType == mwmp::DialogueChoiceType::PERSUASION)
|
||||
|
|
|
@ -514,22 +514,21 @@ namespace MWGui
|
|||
Instead of unilaterally using an item, send an ID_PLAYER_ITEM_USE packet and let the server
|
||||
decide if the item actually gets used
|
||||
*/
|
||||
/*
|
||||
if (!item.getClass().getEquipmentSlots(item).first.empty() && !store.isEquipped(item))
|
||||
{
|
||||
|
||||
/*
|
||||
MWBase::Environment::get().getWindowManager()->useItem(item);
|
||||
|
||||
// make sure that item was successfully equipped
|
||||
if (!store.isEquipped(item))
|
||||
return;
|
||||
*/
|
||||
|
||||
mwmp::Main::get().getLocalPlayer()->sendItemUse(item, true, MWMechanics::DrawState_Spell);
|
||||
}
|
||||
|
||||
//store.setSelectedEnchantItem(it);
|
||||
//MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell);
|
||||
store.setSelectedEnchantItem(it);
|
||||
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState_Spell);
|
||||
*/
|
||||
|
||||
mwmp::Main::get().getLocalPlayer()->sendItemUse(item, true, MWMechanics::DrawState_Spell);
|
||||
/*
|
||||
End of tes3mp change (major)
|
||||
*/
|
||||
|
|
|
@ -154,9 +154,10 @@ namespace MWGui
|
|||
|
||||
Prevent resting and waiting if they have been disabled by the server for the local player
|
||||
*/
|
||||
else if (canRest == MWBase::World::Rest_Allowed && !mwmp::Main::get().getLocalPlayer()->wildernessRestAllowed)
|
||||
else if (canRest == MWBase::World::Rest_Allowed && !mwmp::Main::get().getLocalPlayer()->wildernessRestAllowed &&
|
||||
!mwmp::Main::get().getLocalPlayer()->isUsingBed)
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("You are not allowed to rest in the wilderness.");
|
||||
MWBase::Environment::get().getWindowManager()->messageBox("You are not allowed to rest without a bed.");
|
||||
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
||||
}
|
||||
else if (canRest == MWBase::World::Rest_OnlyWaiting && !mwmp::Main::get().getLocalPlayer()->waitAllowed &&
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
*/
|
||||
#include "../mwmp/Main.hpp"
|
||||
#include "../mwmp/LocalPlayer.hpp"
|
||||
#include "../mwmp/GUIController.hpp"
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
@ -366,6 +367,19 @@ namespace MWInput
|
|||
|
||||
void ActionManager::toggleMainMenu()
|
||||
{
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Don't allow the main menu to be toggled while TES3MP listboxes are open
|
||||
*/
|
||||
if (MWBase::Environment::get().getWindowManager()->getMode() == mwmp::GUIController::GM_TES3MP_ListBox)
|
||||
{
|
||||
return;
|
||||
}
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
if (MyGUI::InputManager::getInstance().isModalAny())
|
||||
{
|
||||
MWBase::Environment::get().getWindowManager()->exitCurrentModal();
|
||||
|
|
|
@ -2479,24 +2479,24 @@ namespace MWMechanics
|
|||
void Actors::cleanupSummonedCreature (MWMechanics::CreatureStats& casterStats, int creatureActorId)
|
||||
{
|
||||
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->searchPtrViaActorId(creatureActorId);
|
||||
if (!ptr.isEmpty())
|
||||
{
|
||||
/*
|
||||
Start of tes3mp change (major)
|
||||
|
||||
Send an ID_OBJECT_DELETE packet every time a summoned creature despawns
|
||||
*/
|
||||
if (mwmp::Main::get().getCellController()->hasLocalAuthority(*ptr.getCell()->getCell()))
|
||||
{
|
||||
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
|
||||
objectList->reset();
|
||||
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY;
|
||||
objectList->addObjectGeneric(ptr);
|
||||
objectList->sendObjectDelete();
|
||||
}
|
||||
/*
|
||||
End of tes3mp change (major)
|
||||
*/
|
||||
/*
|
||||
Start of tes3mp change (major)
|
||||
|
||||
Do a cleanup here and send an ID_OBJECT_DELETE packet every time a summoned creature
|
||||
despawns for the local player or for a local actor
|
||||
*/
|
||||
if (!ptr.isEmpty() &&
|
||||
(casterStats.getActorId() == getPlayer().getClass().getCreatureStats(getPlayer()).getActorId() || mwmp::Main::get().getCellController()->hasLocalAuthority(*ptr.getCell()->getCell())))
|
||||
{
|
||||
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
|
||||
objectList->reset();
|
||||
objectList->packetOrigin = mwmp::CLIENT_GAMEPLAY;
|
||||
objectList->addObjectGeneric(ptr);
|
||||
objectList->sendObjectDelete();
|
||||
/*
|
||||
End of tes3mp change (major)
|
||||
*/
|
||||
|
||||
const ESM::Static* fx = MWBase::Environment::get().getWorld()->getStore().get<ESM::Static>()
|
||||
.search("VFX_Summon_End");
|
||||
|
|
|
@ -553,8 +553,20 @@ MWMechanics::Alchemy::Result MWMechanics::Alchemy::create (const std::string& na
|
|||
if (readyStatus == Result_NoEffects)
|
||||
removeIngredients();
|
||||
|
||||
/*
|
||||
Start of tes3mp change (minor)
|
||||
|
||||
Set avoidSendingInventoryPackets to false again if this has not been a successful
|
||||
potion creation
|
||||
*/
|
||||
if (readyStatus != Result_Success)
|
||||
{
|
||||
mwmp::Main::get().getLocalPlayer()->avoidSendingInventoryPackets = false;
|
||||
return readyStatus;
|
||||
}
|
||||
/*
|
||||
End of tes3mp change (major)
|
||||
*/
|
||||
|
||||
Result result = Result_RandomFailure;
|
||||
int brewedCount = 0;
|
||||
|
|
|
@ -79,10 +79,24 @@ void Cell::updateLocal(bool forceUpdate)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Forcibly update this local actor if its data has never been sent before;
|
||||
// otherwise, use the current forceUpdate value
|
||||
if (actor->getPtr().getRefData().isEnabled() && !actor->getPtr().getRefData().isDeleted())
|
||||
actor->update(actor->hasSentData ? forceUpdate : true);
|
||||
if (actor->getPtr().getRefData().isEnabled())
|
||||
{
|
||||
if (actor->getPtr().getRefData().isDeleted())
|
||||
{
|
||||
std::string mapIndex = it->first;
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- Deleting LocalActor %s whose reference has been deleted",
|
||||
mapIndex.c_str(), getShortDescription().c_str());
|
||||
cellController->removeLocalActorRecord(mapIndex);
|
||||
delete actor;
|
||||
localActors.erase(it++);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Forcibly update this local actor if its data has never been sent before;
|
||||
// otherwise, use the current forceUpdate value
|
||||
actor->update(actor->hasSentData ? forceUpdate : true);
|
||||
}
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
|
@ -531,7 +545,7 @@ void Cell::initializeDedicatedActors(ActorList& actorList)
|
|||
// If this key doesn't exist, create it
|
||||
if (dedicatedActors.count(mapIndex) == 0)
|
||||
{
|
||||
MWWorld::Ptr ptrFound = store->searchExact(baseActor.refNum, baseActor.mpNum);
|
||||
MWWorld::Ptr ptrFound = store->searchExact(baseActor.refNum, baseActor.mpNum, baseActor.refId, true);
|
||||
|
||||
if (!ptrFound) continue;
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace mwmp
|
|||
|
||||
mHistory->setNeedKeyFocus(false);
|
||||
|
||||
windowState = 0;
|
||||
windowState = CHAT_DISABLED;
|
||||
mCommandLine->setVisible(0);
|
||||
delay = 3; // 3 sec.
|
||||
}
|
||||
|
@ -49,7 +49,9 @@ namespace mwmp
|
|||
// Give keyboard focus to the combo box whenever the console is
|
||||
// turned on
|
||||
setEditState(0);
|
||||
windowState = CHAT_ENABLED;
|
||||
|
||||
if (windowState == CHAT_DISABLED)
|
||||
windowState = CHAT_ENABLED;
|
||||
}
|
||||
|
||||
void GUIChat::onClose()
|
||||
|
@ -114,7 +116,7 @@ namespace mwmp
|
|||
|
||||
void GUIChat::print(const std::string &msg, const std::string &color)
|
||||
{
|
||||
if (windowState == 2 && !isVisible())
|
||||
if (windowState == CHAT_HIDDENMODE && !isVisible())
|
||||
{
|
||||
setVisible(true);
|
||||
}
|
||||
|
|
|
@ -211,6 +211,11 @@ bool mwmp::GUIController::pressedKey(int key)
|
|||
return false;
|
||||
}
|
||||
|
||||
void mwmp::GUIController::changeChatMode()
|
||||
{
|
||||
mChat->pressedChatMode();
|
||||
}
|
||||
|
||||
bool mwmp::GUIController::getChatEditState()
|
||||
{
|
||||
return mChat->editState;
|
||||
|
|
|
@ -45,11 +45,13 @@ namespace mwmp
|
|||
|
||||
void showDialogList(const BasePlayer::GUIMessageBox &guiMessageBox);
|
||||
|
||||
bool getChatEditState();
|
||||
|
||||
/// Returns 0 if there was no events
|
||||
bool pressedKey(int key);
|
||||
|
||||
void changeChatMode();
|
||||
|
||||
bool getChatEditState();
|
||||
|
||||
void update(float dt);
|
||||
|
||||
void processCustomMessageBoxInput(int pressedButton);
|
||||
|
|
|
@ -155,7 +155,6 @@ bool LocalPlayer::processCharGen()
|
|||
}
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_CHARGEN)->setPlayer(this);
|
||||
getNetworking()->getPlayerPacket(ID_PLAYER_CHARGEN)->Send();
|
||||
charGenState.currentStage++;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -112,6 +112,22 @@ void ObjectList::addContainerItem(mwmp::BaseObject& baseObject, const MWWorld::P
|
|||
baseObject.containerItems.push_back(containerItem);
|
||||
}
|
||||
|
||||
void ObjectList::addContainerItem(mwmp::BaseObject& baseObject, const MWGui::ItemStack& itemStack, int itemCount, int actionCount)
|
||||
{
|
||||
mwmp::ContainerItem containerItem;
|
||||
containerItem.refId = itemStack.mBase.getCellRef().getRefId();
|
||||
containerItem.count = itemCount;
|
||||
containerItem.charge = itemStack.mBase.getCellRef().getCharge();
|
||||
containerItem.enchantmentCharge = itemStack.mBase.getCellRef().getEnchantmentCharge();
|
||||
containerItem.soul = itemStack.mBase.getCellRef().getSoul();
|
||||
containerItem.actionCount = actionCount;
|
||||
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "--- Adding container item %s to packet with count %i and actionCount %i",
|
||||
containerItem.refId.c_str(), itemCount, actionCount);
|
||||
|
||||
baseObject.containerItems.push_back(containerItem);
|
||||
}
|
||||
|
||||
void ObjectList::addContainerItem(mwmp::BaseObject& baseObject, const std::string itemId, int itemCount, int actionCount)
|
||||
{
|
||||
mwmp::ContainerItem containerItem;
|
||||
|
@ -163,7 +179,7 @@ void ObjectList::editContainers(MWWorld::CellStore* cellStore)
|
|||
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- container %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -349,14 +365,7 @@ void ObjectList::activateObjects(MWWorld::CellStore* cellStore)
|
|||
else
|
||||
{
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "-- Activated object is %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
|
||||
if (baseObject.refId.empty())
|
||||
{
|
||||
ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptrFound = cellStore->searchExactPlus(baseObject.refId, baseObject.refNum, baseObject.mpNum);
|
||||
}
|
||||
ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
}
|
||||
|
||||
if (ptrFound)
|
||||
|
@ -371,7 +380,7 @@ void ObjectList::activateObjects(MWWorld::CellStore* cellStore)
|
|||
}
|
||||
else
|
||||
{
|
||||
activatingActorPtr = cellStore->searchExact(baseObject.activatingActor.refNum, baseObject.activatingActor.mpNum);
|
||||
activatingActorPtr = cellStore->searchExact(baseObject.activatingActor.refNum, baseObject.activatingActor.mpNum, baseObject.activatingActor.refId);
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "-- Object has been activated by actor %s %i-%i", activatingActorPtr.getCellRef().getRefId().c_str(),
|
||||
activatingActorPtr.getCellRef().getRefNum().mIndex, activatingActorPtr.getCellRef().getMpNum());
|
||||
}
|
||||
|
@ -491,7 +500,7 @@ void ObjectList::spawnObjects(MWWorld::CellStore* cellStore)
|
|||
if (baseObject.master.isPlayer)
|
||||
masterPtr = MechanicsHelper::getPlayerPtr(baseObject.master);
|
||||
else
|
||||
masterPtr = cellStore->searchExact(baseObject.master.refNum, baseObject.master.mpNum);
|
||||
masterPtr = cellStore->searchExact(baseObject.master.refNum, baseObject.master.mpNum, baseObject.master.refId);
|
||||
|
||||
if (masterPtr)
|
||||
{
|
||||
|
@ -541,6 +550,7 @@ void ObjectList::spawnObjects(MWWorld::CellStore* cellStore)
|
|||
foundSummonedCreature = true;
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
// If it is, update its creatureActorId
|
||||
|
@ -570,7 +580,7 @@ void ObjectList::deleteObjects(MWWorld::CellStore* cellStore)
|
|||
{
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -623,7 +633,7 @@ void ObjectList::lockObjects(MWWorld::CellStore* cellStore)
|
|||
{
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -644,7 +654,7 @@ void ObjectList::triggerTrapObjects(MWWorld::CellStore* cellStore)
|
|||
{
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -671,7 +681,7 @@ void ObjectList::scaleObjects(MWWorld::CellStore* cellStore)
|
|||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i, scale: %f", baseObject.refId.c_str(), baseObject.refNum,
|
||||
baseObject.mpNum, baseObject.scale);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -690,7 +700,7 @@ void ObjectList::setObjectStates(MWWorld::CellStore* cellStore)
|
|||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i, state: %s", baseObject.refId.c_str(), baseObject.refNum,
|
||||
baseObject.mpNum, baseObject.objectState ? "true" : "false");
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -720,7 +730,7 @@ void ObjectList::moveObjects(MWWorld::CellStore* cellStore)
|
|||
{
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -739,7 +749,7 @@ void ObjectList::restockObjects(MWWorld::CellStore* cellStore)
|
|||
{
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -765,7 +775,7 @@ void ObjectList::rotateObjects(MWWorld::CellStore* cellStore)
|
|||
{
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -784,7 +794,7 @@ void ObjectList::animateObjects(MWWorld::CellStore* cellStore)
|
|||
{
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -826,7 +836,7 @@ void ObjectList::playObjectSounds(MWWorld::CellStore* cellStore)
|
|||
else
|
||||
{
|
||||
objectDescription = baseObject.refId + " " + std::to_string(baseObject.refNum) + "-" + std::to_string(baseObject.mpNum);
|
||||
ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
}
|
||||
|
||||
if (ptrFound)
|
||||
|
@ -857,7 +867,7 @@ void ObjectList::setGoldPoolsForObjects(MWWorld::CellStore* cellStore)
|
|||
{
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -889,7 +899,7 @@ void ObjectList::activateDoors(MWWorld::CellStore* cellStore)
|
|||
{
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -910,7 +920,7 @@ void ObjectList::setDoorDestinations(MWWorld::CellStore* cellStore)
|
|||
{
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -976,7 +986,7 @@ void ObjectList::runConsoleCommands(MWWorld::CellStore* cellStore)
|
|||
{
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "-- Running on object %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -998,16 +1008,8 @@ void ObjectList::makeDialogueChoices(MWWorld::CellStore* cellStore)
|
|||
for (const auto& baseObject : baseObjects)
|
||||
{
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound;
|
||||
|
||||
if (baseObject.refId.empty())
|
||||
{
|
||||
ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptrFound = cellStore->searchExactPlus(baseObject.refId, baseObject.refNum, baseObject.mpNum);
|
||||
}
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -1036,7 +1038,33 @@ void ObjectList::makeDialogueChoices(MWWorld::CellStore* cellStore)
|
|||
LOG_APPEND(TimedLog::LOG_VERBOSE, "-- topic was %s", baseObject.topicId.c_str());
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->activateDialogueChoice(baseObject.dialogueChoiceType, baseObject.topicId);
|
||||
std::string topic = baseObject.topicId;
|
||||
|
||||
if (MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation())
|
||||
{
|
||||
char delimiter = '|';
|
||||
|
||||
// If we're using a translated version of Morrowind, we may have received a string that had the original
|
||||
// topic delimited from its possible English translation by a | character, in which case we need to use
|
||||
// the original topic here
|
||||
if (topic.find(delimiter) != std::string::npos)
|
||||
{
|
||||
topic = topic.substr(0, topic.find(delimiter));
|
||||
}
|
||||
// Alternatively, we may have received a topic that needs to be translated into the current language's
|
||||
// version of it
|
||||
else
|
||||
{
|
||||
std::string translatedTopic = MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().getLocalizedTopicId(topic);
|
||||
|
||||
if (!translatedTopic.empty())
|
||||
{
|
||||
topic = translatedTopic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->activateDialogueChoice(baseObject.dialogueChoiceType, topic);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1053,7 +1081,7 @@ void ObjectList::setClientLocals(MWWorld::CellStore* cellStore)
|
|||
{
|
||||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i", baseObject.refId.c_str(), baseObject.refNum, baseObject.mpNum);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -1163,7 +1191,7 @@ void ObjectList::addRequestedContainers(MWWorld::CellStore* cellStore, const std
|
|||
LOG_APPEND(TimedLog::LOG_VERBOSE, "- cellRef: %s %i-%i", baseObject.refId.c_str(),
|
||||
baseObject.refNum, baseObject.mpNum);
|
||||
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum);
|
||||
MWWorld::Ptr ptrFound = cellStore->searchExact(baseObject.refNum, baseObject.mpNum, baseObject.refId);
|
||||
|
||||
if (ptrFound)
|
||||
{
|
||||
|
@ -1329,7 +1357,7 @@ void ObjectList::addObjectDialogueChoice(const MWWorld::Ptr& ptr, std::string di
|
|||
|
||||
// For translated versions of the game, make sure we translate the topic back into English first
|
||||
if (MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().hasTranslation())
|
||||
baseObject.topicId = MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().topicID(dialogueChoice);
|
||||
baseObject.topicId = dialogueChoice + "|" + MWBase::Environment::get().getWindowManager()->getTranslationDataStorage().topicID(dialogueChoice);
|
||||
else
|
||||
baseObject.topicId = dialogueChoice;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define OPENMW_OBJECTLIST_HPP
|
||||
|
||||
#include <components/openmw-mp/Base/BaseObject.hpp>
|
||||
#include "../mwgui/itemmodel.hpp"
|
||||
#include "../mwworld/worldimp.hpp"
|
||||
#include <RakNetTypes.h>
|
||||
|
||||
|
@ -20,6 +21,7 @@ namespace mwmp
|
|||
void addBaseObject(BaseObject baseObject);
|
||||
mwmp::BaseObject getBaseObjectFromPtr(const MWWorld::Ptr& ptr);
|
||||
void addContainerItem(mwmp::BaseObject& baseObject, const MWWorld::Ptr& itemPtr, int itemCount, int actionCount);
|
||||
void addContainerItem(mwmp::BaseObject& baseObject, const MWGui::ItemStack& itemStack, int itemCount, int actionCount);
|
||||
void addContainerItem(mwmp::BaseObject& baseObject, const std::string itemId, int itemCount, int actionCount);
|
||||
void addEntireContainer(const MWWorld::Ptr& ptr);
|
||||
|
||||
|
|
|
@ -368,6 +368,18 @@ void RecordHelper::overrideRecord(const mwmp::CellRecord& record)
|
|||
world->unloadCell(finalData);
|
||||
world->clearCellStore(finalData);
|
||||
world->getModifiableStore().overrideRecord(finalData);
|
||||
|
||||
// Create a Pathgrid record for this new Cell based on the base Cell's Pathgrid
|
||||
// Note: This has to be done after the new Cell has been created so the Pathgrid override
|
||||
// can correctly determine whether the Cell is an interior or an exterior
|
||||
const ESM::Pathgrid* basePathgrid = world->getStore().get<ESM::Pathgrid>().search(record.baseId);
|
||||
|
||||
if (basePathgrid)
|
||||
{
|
||||
ESM::Pathgrid finalPathgrid = *basePathgrid;
|
||||
finalPathgrid.mCell = recordData.mName;
|
||||
world->getModifiableStore().overrideRecord(finalPathgrid);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -195,21 +195,23 @@ namespace MWScript
|
|||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Send an ID_OBJECT_STATE packet whenever an object is enabled, as long as
|
||||
the player is logged in on the server, the object is still disabled, and our last
|
||||
packet regarding its state did not already attempt to enable it (to prevent
|
||||
Send an ID_OBJECT_STATE packet whenever an object should be enabled, as long as the
|
||||
player is logged in on the server and — if triggered from a clientside script — our
|
||||
last packet regarding its state did not already attempt to enable it (to prevent
|
||||
packet spam)
|
||||
*/
|
||||
if (mwmp::Main::get().getLocalPlayer()->isLoggedIn())
|
||||
{
|
||||
if (ptr.isInCell() && !ptr.getRefData().isEnabled() &&
|
||||
ptr.getRefData().getLastCommunicatedState() != MWWorld::RefData::StateCommunication::Enabled)
|
||||
unsigned char packetOrigin = ScriptController::getPacketOriginFromContextType(runtime.getContext().getContextType());
|
||||
|
||||
if (packetOrigin == Interpreter::Context::CONSOLE || packetOrigin == Interpreter::Context::DIALOGUE ||
|
||||
(ptr.isInCell() && ptr.getRefData().getLastCommunicatedState() != MWWorld::RefData::StateCommunication::Enabled))
|
||||
{
|
||||
ptr.getRefData().setLastCommunicatedState(MWWorld::RefData::StateCommunication::Enabled);
|
||||
|
||||
mwmp::ObjectList* objectList = mwmp::Main::get().getNetworking()->getObjectList();
|
||||
objectList->reset();
|
||||
objectList->packetOrigin = ScriptController::getPacketOriginFromContextType(runtime.getContext().getContextType());
|
||||
objectList->packetOrigin = packetOrigin;
|
||||
objectList->originClientScript = runtime.getContext().getCurrentScriptName();
|
||||
objectList->addObjectState(ptr, true);
|
||||
objectList->sendObjectState();
|
||||
|
@ -244,21 +246,23 @@ namespace MWScript
|
|||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Send an ID_OBJECT_STATE packet whenever an object should be disabled, as long as
|
||||
the player is logged in on the server, the object is still enabled, and our last
|
||||
packet regarding its state did not already attempt to disable it (to prevent
|
||||
Send an ID_OBJECT_STATE packet whenever an object should be disabled, as long as the
|
||||
player is logged in on the server and — if triggered from a clientside script — our
|
||||
last packet regarding its state did not already attempt to disable it (to prevent
|
||||
packet spam)
|
||||
*/
|
||||
if (mwmp::Main::get().getLocalPlayer()->isLoggedIn())
|
||||
{
|
||||
if (ptr.isInCell() && ptr.getRefData().isEnabled() &&
|
||||
ptr.getRefData().getLastCommunicatedState() != MWWorld::RefData::StateCommunication::Disabled)
|
||||
unsigned char packetOrigin = ScriptController::getPacketOriginFromContextType(runtime.getContext().getContextType());
|
||||
|
||||
if (packetOrigin == Interpreter::Context::CONSOLE || packetOrigin == Interpreter::Context::DIALOGUE ||
|
||||
(ptr.isInCell() && ptr.getRefData().getLastCommunicatedState() != MWWorld::RefData::StateCommunication::Disabled))
|
||||
{
|
||||
ptr.getRefData().setLastCommunicatedState(MWWorld::RefData::StateCommunication::Disabled);
|
||||
|
||||
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
|
||||
objectList->reset();
|
||||
objectList->packetOrigin = ScriptController::getPacketOriginFromContextType(runtime.getContext().getContextType());
|
||||
objectList->packetOrigin = packetOrigin;
|
||||
objectList->originClientScript = runtime.getContext().getCurrentScriptName();
|
||||
objectList->addObjectState(ptr, false);
|
||||
objectList->sendObjectState();
|
||||
|
@ -423,9 +427,10 @@ namespace MWScript
|
|||
Start of tes3mp addition
|
||||
|
||||
Send an ID_OBJECT_LOCK packet every time an object is locked
|
||||
through a script
|
||||
through a script, as long as the lock level being set is not
|
||||
the one it already has
|
||||
*/
|
||||
if (mwmp::Main::get().getLocalPlayer()->isLoggedIn())
|
||||
if (mwmp::Main::get().getLocalPlayer()->isLoggedIn() && ptr.getCellRef().getLockLevel() != lockLevel)
|
||||
{
|
||||
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
|
||||
objectList->reset();
|
||||
|
@ -471,9 +476,9 @@ namespace MWScript
|
|||
Start of tes3mp addition
|
||||
|
||||
Send an ID_OBJECT_LOCK packet every time an object is unlocked
|
||||
through a script
|
||||
through a script, as long as it's not already unlocked
|
||||
*/
|
||||
if (mwmp::Main::get().getLocalPlayer()->isLoggedIn())
|
||||
if (mwmp::Main::get().getLocalPlayer()->isLoggedIn() && ptr.getCellRef().getLockLevel() > 0)
|
||||
{
|
||||
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
|
||||
objectList->reset();
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "../mwmp/LocalPlayer.hpp"
|
||||
#include "../mwmp/PlayerList.hpp"
|
||||
#include "../mwmp/ObjectList.hpp"
|
||||
#include "../mwmp/CellController.hpp"
|
||||
#include "../mwmp/ScriptController.hpp"
|
||||
/*
|
||||
End of tes3mp addition
|
||||
|
@ -443,10 +444,52 @@ namespace MWScript
|
|||
}
|
||||
if(store)
|
||||
{
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Track the original cell of this object in case we need to use it when sending a packet
|
||||
*/
|
||||
ESM::Cell originalCell = *ptr.getCell()->getCell();
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
MWWorld::Ptr base = ptr;
|
||||
ptr = MWBase::Environment::get().getWorld()->moveObject(ptr,store,x,y,z);
|
||||
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(base,ptr);
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Send ActorCellChange packets when actors are moved here, regardless of whether we're
|
||||
the cell authority or not; the server can decide if it wants to comply with them
|
||||
*/
|
||||
if (ptr.getClass().isActor() && !mwmp::Main::get().getCellController()->isSameCell(originalCell, *store->getCell()))
|
||||
{
|
||||
mwmp::BaseActor baseActor;
|
||||
baseActor.refNum = ptr.getCellRef().getRefNum().mIndex;
|
||||
baseActor.mpNum = ptr.getCellRef().getMpNum();
|
||||
baseActor.cell = *store->getCell();
|
||||
baseActor.position = ptr.getRefData().getPosition();
|
||||
baseActor.isFollowerCellChange = true;
|
||||
|
||||
mwmp::ActorList* actorList = mwmp::Main::get().getNetworking()->getActorList();
|
||||
actorList->reset();
|
||||
actorList->cell = originalCell;
|
||||
|
||||
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Sending ID_ACTOR_CELL_CHANGE about %s %i-%i to server",
|
||||
ptr.getCellRef().getRefId().c_str(), baseActor.refNum, baseActor.mpNum);
|
||||
|
||||
LOG_APPEND(TimedLog::LOG_INFO, "- Moved from %s to %s", actorList->cell.getDescription().c_str(),
|
||||
baseActor.cell.getDescription().c_str());
|
||||
|
||||
actorList->addCellChangeActor(baseActor);
|
||||
actorList->sendCellChangeActors();
|
||||
}
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
float ax = ptr.getRefData().getPosition().rot[0];
|
||||
float ay = ptr.getRefData().getPosition().rot[1];
|
||||
// Note that you must specify ZRot in minutes (1 degree = 60 minutes; north = 0, east = 5400, south = 10800, west = 16200)
|
||||
|
|
|
@ -605,8 +605,11 @@ namespace MWWorld
|
|||
{
|
||||
const unsigned int mRefNumToFind;
|
||||
const unsigned int mMpNumToFind;
|
||||
const std::string mRefIdToFind;
|
||||
const bool mActorsOnly;
|
||||
public:
|
||||
SearchExactVisitor(const unsigned int refNum, const unsigned int mpNum) : mRefNumToFind(refNum), mMpNumToFind(mpNum) {}
|
||||
SearchExactVisitor(const unsigned int refNum, const unsigned int mpNum, const std::string refId, const bool actorsOnly) :
|
||||
mRefNumToFind(refNum), mMpNumToFind(mpNum), mRefIdToFind(refId), mActorsOnly(actorsOnly) {}
|
||||
|
||||
Ptr mFound;
|
||||
|
||||
|
@ -614,38 +617,14 @@ namespace MWWorld
|
|||
{
|
||||
if (ptr.getCellRef().getRefNum().mIndex == mRefNumToFind && ptr.getCellRef().getMpNum() == mMpNumToFind)
|
||||
{
|
||||
mFound = ptr;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
A custom type of search visitor used to find objects by their reference numbers
|
||||
while ensuring they have a certain refId
|
||||
*/
|
||||
class SearchExactPlusVisitor
|
||||
{
|
||||
const std::string mRefIdToFind;
|
||||
const unsigned int mRefNumToFind;
|
||||
const unsigned int mMpNumToFind;
|
||||
public:
|
||||
SearchExactPlusVisitor(const std::string refId, const unsigned int refNum, const unsigned int mpNum) : mRefIdToFind(refId), mRefNumToFind(refNum), mMpNumToFind(mpNum) {}
|
||||
|
||||
Ptr mFound;
|
||||
|
||||
bool operator()(const Ptr& ptr)
|
||||
{
|
||||
if (ptr.getCellRef().getRefNum().mIndex == mRefNumToFind && ptr.getCellRef().getMpNum() == mMpNumToFind && Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), mRefIdToFind))
|
||||
{
|
||||
mFound = ptr;
|
||||
return false;
|
||||
if (!mActorsOnly || ptr.getClass().isActor())
|
||||
{
|
||||
if (mRefIdToFind.empty() || Misc::StringUtils::ciEqual(ptr.getCellRef().getRefId(), mRefIdToFind))
|
||||
{
|
||||
mFound = ptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -659,33 +638,13 @@ namespace MWWorld
|
|||
|
||||
Allow the searching of objects by their reference numbers
|
||||
*/
|
||||
Ptr CellStore::searchExact (const unsigned int refNum, const unsigned int mpNum)
|
||||
Ptr CellStore::searchExact (const unsigned int refNum, const unsigned int mpNum, const std::string refId, bool actorsOnly)
|
||||
{
|
||||
// Ensure that all objects searched for have a valid reference number
|
||||
if (refNum == 0 && mpNum == 0)
|
||||
return 0;
|
||||
|
||||
SearchExactVisitor searchVisitor(refNum, mpNum);
|
||||
forEach(searchVisitor);
|
||||
return searchVisitor.mFound;
|
||||
}
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Allow the searching of objects by their reference numbers while ensuring
|
||||
they have a certain refId
|
||||
*/
|
||||
Ptr CellStore::searchExactPlus(const std::string refId, const unsigned int refNum, const unsigned int mpNum)
|
||||
{
|
||||
// Ensure that all objects searched for have a valid reference number
|
||||
if (refNum == 0 && mpNum == 0)
|
||||
return 0;
|
||||
|
||||
SearchExactPlusVisitor searchVisitor(refId, refNum, mpNum);
|
||||
SearchExactVisitor searchVisitor(refNum, mpNum, refId, actorsOnly);
|
||||
forEach(searchVisitor);
|
||||
return searchVisitor.mFound;
|
||||
}
|
||||
|
|
|
@ -262,20 +262,10 @@ namespace MWWorld
|
|||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Allow the searching of objects by their reference numbers
|
||||
Allow the searching of objects by their reference numbers and, optionally,
|
||||
their refIds
|
||||
*/
|
||||
Ptr searchExact (unsigned int refNum, unsigned int mpNum);
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Allow the searching of objects by their reference numbers while ensuring
|
||||
they have a certain refId
|
||||
*/
|
||||
Ptr searchExactPlus (std::string refId, unsigned int refNum, unsigned int mpNum);
|
||||
Ptr searchExact (unsigned int refNum, unsigned int mpNum, std::string refId = "", bool actorsOnly = false);
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
|
|
@ -331,7 +331,7 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStore::add (const Ptr& itemPtr
|
|||
|
||||
Send an ID_PLAYER_INVENTORY packet every time an item gets added for a player here
|
||||
*/
|
||||
if (actorPtr == player && this == &player.getClass().getContainerStore(player))
|
||||
if (this == &player.getClass().getContainerStore(player))
|
||||
{
|
||||
mwmp::LocalPlayer *localPlayer = mwmp::Main::get().getLocalPlayer();
|
||||
|
||||
|
@ -562,7 +562,7 @@ int MWWorld::ContainerStore::remove(const Ptr& item, int count, const Ptr& actor
|
|||
*/
|
||||
Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
|
||||
if (actor == player && this == &player.getClass().getContainerStore(player))
|
||||
if (this == &player.getClass().getContainerStore(player))
|
||||
{
|
||||
mwmp::LocalPlayer *localPlayer = mwmp::Main::get().getLocalPlayer();
|
||||
|
||||
|
|
|
@ -276,7 +276,7 @@ namespace MWWorld
|
|||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Make it possible to override a cell record similarly to how
|
||||
Make it possible to override a Cell record similarly to how
|
||||
other types of records can be overridden
|
||||
*/
|
||||
template <>
|
||||
|
@ -287,6 +287,20 @@ namespace MWWorld
|
|||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Make it possible to override a Pathgrid record similarly to how
|
||||
other types of records can be overridden
|
||||
*/
|
||||
template <>
|
||||
inline const ESM::Pathgrid* ESMStore::overrideRecord<ESM::Pathgrid>(const ESM::Pathgrid& pathgrid) {
|
||||
return mPathgrids.override(pathgrid);
|
||||
}
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
template <>
|
||||
inline const ESM::Cell *ESMStore::insert<ESM::Cell>(const ESM::Cell &cell) {
|
||||
return mCells.insert(cell);
|
||||
|
|
|
@ -796,7 +796,7 @@ namespace MWWorld
|
|||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Make it possible to override a cell record similarly to how
|
||||
Make it possible to override a Cell record similarly to how
|
||||
other types of records can be overridden
|
||||
*/
|
||||
ESM::Cell *Store<ESM::Cell>::override(const ESM::Cell &cell)
|
||||
|
@ -949,6 +949,37 @@ namespace MWWorld
|
|||
|
||||
return RecordId("", isDeleted);
|
||||
}
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Make it possible to override a Pathgrid record similarly to how
|
||||
other types of records can be overridden
|
||||
*/
|
||||
ESM::Pathgrid* Store<ESM::Pathgrid>::override(const ESM::Pathgrid& pathgrid)
|
||||
{
|
||||
bool interior = mCells->search(pathgrid.mCell) != nullptr;
|
||||
|
||||
// Try to overwrite existing record
|
||||
if (interior)
|
||||
{
|
||||
std::pair<Interior::iterator, bool> ret = mInt.insert(std::make_pair(pathgrid.mCell, pathgrid));
|
||||
if (!ret.second)
|
||||
ret.first->second = pathgrid;
|
||||
|
||||
return &ret.first->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::pair<Exterior::iterator, bool> ret = mExt.insert(std::make_pair(std::make_pair(pathgrid.mData.mX, pathgrid.mData.mY), pathgrid));
|
||||
if (!ret.second)
|
||||
ret.first->second = pathgrid;
|
||||
|
||||
return &ret.first->second;
|
||||
}
|
||||
}
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
size_t Store<ESM::Pathgrid>::getSize() const
|
||||
{
|
||||
return mInt.size() + mExt.size();
|
||||
|
|
|
@ -325,7 +325,7 @@ namespace MWWorld
|
|||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Make it possible to override a cell record similarly to how
|
||||
Make it possible to override a Cell record similarly to how
|
||||
other types of records can be overridden
|
||||
*/
|
||||
ESM::Cell *override(const ESM::Cell &cell);
|
||||
|
@ -362,6 +362,17 @@ namespace MWWorld
|
|||
|
||||
void setUp() override;
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Make it possible to override a Pathgrid record similarly to how
|
||||
other types of records can be overridden
|
||||
*/
|
||||
ESM::Pathgrid* override(const ESM::Pathgrid& pathgrid);
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
const ESM::Pathgrid *search(int x, int y) const;
|
||||
const ESM::Pathgrid *search(const std::string& name) const;
|
||||
const ESM::Pathgrid *find(int x, int y) const;
|
||||
|
|
|
@ -3971,6 +3971,12 @@ namespace MWWorld
|
|||
MWWorld::Ptr player = getPlayerPtr();
|
||||
player.getClass().getInventoryStore(player).rechargeItems(duration);
|
||||
|
||||
/*
|
||||
Start of tes3mp change (major)
|
||||
|
||||
Don't unilaterally recharge world items on clients
|
||||
*/
|
||||
/*
|
||||
if (activeOnly)
|
||||
{
|
||||
for (auto &cell : mWorldScene->getActiveCells())
|
||||
|
@ -3980,6 +3986,10 @@ namespace MWWorld
|
|||
}
|
||||
else
|
||||
mCells.recharge(duration);
|
||||
*/
|
||||
/*
|
||||
End of tes3mp change (major)
|
||||
*/
|
||||
}
|
||||
|
||||
void World::teleportToClosestMarker (const MWWorld::Ptr& ptr,
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace mwmp
|
|||
hasStatsDynamicData = false;
|
||||
}
|
||||
|
||||
std::string refId;
|
||||
std::string refId = "";
|
||||
unsigned int refNum;
|
||||
unsigned int mpNum;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace mwmp
|
|||
|
||||
struct BaseObject
|
||||
{
|
||||
std::string refId;
|
||||
std::string refId = "";
|
||||
unsigned int refNum;
|
||||
unsigned int mpNum;
|
||||
int count;
|
||||
|
|
|
@ -106,6 +106,9 @@ set(MYGUI_FILES
|
|||
openmw_windows.skin.xml
|
||||
DejaVuLGCSansMono.ttf
|
||||
../launcher/images/openmw.png
|
||||
# Start of tes3mp addition
|
||||
../tes3mp/tes3mp_logo.png
|
||||
# End of tes3mp addition
|
||||
OpenMWResourcePlugin.xml
|
||||
skins.xml
|
||||
|
||||
|
|
Loading…
Reference in a new issue