mirror of
https://github.com/TES3MP/TES3MP.git
synced 2025-09-24 05:00:31 -04:00
Merge branch '0.7.1' into 0.7.1-cell-records
This commit is contained in:
commit
ea25b994df
@ -25,6 +25,8 @@
|
||||
#include "processors/ObjectProcessor.hpp"
|
||||
#include "processors/WorldstateProcessor.hpp"
|
||||
|
||||
#include "handleInput.cpp"
|
||||
|
||||
using namespace mwmp;
|
||||
using namespace std;
|
||||
|
||||
@ -496,6 +498,20 @@ void signalHandler(int signum)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
BOOL WINAPI sigIntHandler(_In_ DWORD dwCtrlType) {
|
||||
switch (dwCtrlType)
|
||||
{
|
||||
case CTRL_C_EVENT:
|
||||
signalHandler(15);
|
||||
return TRUE;
|
||||
default:
|
||||
// Pass signal on to the next handler
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int Networking::mainLoop()
|
||||
{
|
||||
RakNet::Packet *packet;
|
||||
@ -506,16 +522,15 @@ int Networking::mainLoop()
|
||||
sigIntHandler.sa_handler = signalHandler;
|
||||
sigemptyset(&sigIntHandler.sa_mask);
|
||||
sigIntHandler.sa_flags = 0;
|
||||
sigaction(SIGTERM, &sigIntHandler, NULL);
|
||||
sigaction(SIGINT, &sigIntHandler, NULL);
|
||||
#else
|
||||
SetConsoleCtrlHandler(sigIntHandler, TRUE);
|
||||
#endif
|
||||
|
||||
while (running and !killLoop)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
sigaction(SIGTERM, &sigIntHandler, NULL);
|
||||
sigaction(SIGINT, &sigIntHandler, NULL);
|
||||
#endif
|
||||
if (kbhit() && getch() == '\n')
|
||||
break;
|
||||
mwmp_input::handler();
|
||||
for (packet=peer->Receive(); packet; peer->DeallocatePacket(packet), packet=peer->Receive())
|
||||
{
|
||||
if (getMasterClient()->Process(packet))
|
||||
|
@ -484,6 +484,13 @@ void ObjectFunctions::SetObjectRotation(double x, double y, double z) noexcept
|
||||
tempObject.position.rot[2] = z;
|
||||
}
|
||||
|
||||
void ObjectFunctions::SetObjectSound(const char* soundId, double volume, double pitch) noexcept
|
||||
{
|
||||
tempObject.soundId = soundId;
|
||||
tempObject.volume = volume;
|
||||
tempObject.pitch = pitch;
|
||||
}
|
||||
|
||||
void ObjectFunctions::SetObjectSummonState(bool summonState) noexcept
|
||||
{
|
||||
tempObject.isSummon = summonState;
|
||||
|
@ -102,6 +102,7 @@
|
||||
{"SetObjectDroppedByPlayerState", ObjectFunctions::SetObjectDroppedByPlayerState},\
|
||||
{"SetObjectPosition", ObjectFunctions::SetObjectPosition},\
|
||||
{"SetObjectRotation", ObjectFunctions::SetObjectRotation},\
|
||||
{"SetObjectSound", ObjectFunctions::SetObjectSound},\
|
||||
\
|
||||
{"SetObjectSummonState", ObjectFunctions::SetObjectSummonState},\
|
||||
{"SetObjectSummonEffectId", ObjectFunctions::SetObjectSummonEffectId},\
|
||||
@ -934,6 +935,8 @@ public:
|
||||
*/
|
||||
static void SetObjectRotation(double x, double y, double z) noexcept;
|
||||
|
||||
static void SetObjectSound(const char* soundId, double volume, double pitch) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the summon state of the temporary object stored on the server.
|
||||
*
|
||||
|
@ -36,6 +36,7 @@ ProbeRecord tempProbe;
|
||||
RepairRecord tempRepair;
|
||||
ScriptRecord tempScript;
|
||||
StaticRecord tempStatic;
|
||||
SoundRecord tempSound;
|
||||
|
||||
BaseOverrides tempOverrides;
|
||||
|
||||
@ -85,6 +86,7 @@ void RecordsDynamicFunctions::ClearRecords() noexcept
|
||||
WorldstateFunctions::writeWorldstate.repairRecords.clear();
|
||||
WorldstateFunctions::writeWorldstate.scriptRecords.clear();
|
||||
WorldstateFunctions::writeWorldstate.staticRecords.clear();
|
||||
WorldstateFunctions::writeWorldstate.soundRecords.clear();
|
||||
}
|
||||
|
||||
unsigned short RecordsDynamicFunctions::GetRecordType() noexcept
|
||||
@ -399,6 +401,8 @@ void RecordsDynamicFunctions::SetRecordId(const char* id) noexcept
|
||||
tempScript.data.mId = id;
|
||||
else if (writeRecordsType == mwmp::RECORD_TYPE::STATIC)
|
||||
tempStatic.data.mId = id;
|
||||
else if (writeRecordsType == mwmp::RECORD_TYPE::SOUND)
|
||||
tempSound.data.mId = id;
|
||||
else
|
||||
LOG_MESSAGE_SIMPLE(TimedLog::LOG_ERROR, "Tried to set id for record type %i which lacks that property", writeRecordsType);
|
||||
}
|
||||
@ -453,6 +457,8 @@ void RecordsDynamicFunctions::SetRecordBaseId(const char* baseId) noexcept
|
||||
tempScript.baseId = baseId;
|
||||
else if (writeRecordsType == mwmp::RECORD_TYPE::STATIC)
|
||||
tempStatic.baseId = baseId;
|
||||
else if (writeRecordsType == mwmp::RECORD_TYPE::SOUND)
|
||||
tempSound.baseId = baseId;
|
||||
else
|
||||
LOG_MESSAGE_SIMPLE(TimedLog::LOG_ERROR, "Tried to set baseId for record type %i which lacks that property", writeRecordsType);
|
||||
}
|
||||
@ -1407,6 +1413,8 @@ void RecordsDynamicFunctions::SetRecordSound(const char* sound) noexcept
|
||||
|
||||
if (writeRecordsType == mwmp::RECORD_TYPE::LIGHT)
|
||||
tempLight.data.mSound = sound;
|
||||
else if (writeRecordsType == mwmp::RECORD_TYPE::SOUND)
|
||||
tempSound.data.mSound = sound;
|
||||
else
|
||||
{
|
||||
LOG_MESSAGE_SIMPLE(TimedLog::LOG_ERROR, "Tried to set sound for record type %i which lacks that property", writeRecordsType);
|
||||
@ -1416,6 +1424,51 @@ void RecordsDynamicFunctions::SetRecordSound(const char* sound) noexcept
|
||||
tempOverrides.hasSound = true;
|
||||
}
|
||||
|
||||
void RecordsDynamicFunctions::SetRecordVolume(double volume) noexcept
|
||||
{
|
||||
unsigned short writeRecordsType = WorldstateFunctions::writeWorldstate.recordsType;
|
||||
|
||||
if (writeRecordsType == mwmp::RECORD_TYPE::SOUND)
|
||||
tempSound.data.mData.mVolume = volume;
|
||||
else
|
||||
{
|
||||
LOG_MESSAGE_SIMPLE(TimedLog::LOG_ERROR, "Tried to set sound for record type %i which lacks that property", writeRecordsType);
|
||||
return;
|
||||
}
|
||||
|
||||
tempOverrides.hasVolume = true;
|
||||
}
|
||||
|
||||
void RecordsDynamicFunctions::SetRecordMinRange(double minRange) noexcept
|
||||
{
|
||||
unsigned short writeRecordsType = WorldstateFunctions::writeWorldstate.recordsType;
|
||||
|
||||
if (writeRecordsType == mwmp::RECORD_TYPE::SOUND)
|
||||
tempSound.data.mData.mMinRange = minRange;
|
||||
else
|
||||
{
|
||||
LOG_MESSAGE_SIMPLE(TimedLog::LOG_ERROR, "Tried to set sound for record type %i which lacks that property", writeRecordsType);
|
||||
return;
|
||||
}
|
||||
|
||||
tempOverrides.hasMinRange = true;
|
||||
}
|
||||
|
||||
void RecordsDynamicFunctions::SetRecordMaxRange(double maxRange) noexcept
|
||||
{
|
||||
unsigned short writeRecordsType = WorldstateFunctions::writeWorldstate.recordsType;
|
||||
|
||||
if (writeRecordsType == mwmp::RECORD_TYPE::SOUND)
|
||||
tempSound.data.mData.mMinRange = maxRange;
|
||||
else
|
||||
{
|
||||
LOG_MESSAGE_SIMPLE(TimedLog::LOG_ERROR, "Tried to set sound for record type %i which lacks that property", writeRecordsType);
|
||||
return;
|
||||
}
|
||||
|
||||
tempOverrides.hasMaxRange = true;
|
||||
}
|
||||
|
||||
void RecordsDynamicFunctions::SetRecordOpenSound(const char* sound) noexcept
|
||||
{
|
||||
unsigned short writeRecordsType = WorldstateFunctions::writeWorldstate.recordsType;
|
||||
@ -1860,6 +1913,12 @@ void RecordsDynamicFunctions::AddRecord() noexcept
|
||||
WorldstateFunctions::writeWorldstate.staticRecords.push_back(tempStatic);
|
||||
tempStatic = {};
|
||||
}
|
||||
else if (writeRecordsType == mwmp::RECORD_TYPE::SOUND)
|
||||
{
|
||||
tempSound.baseOverrides = tempOverrides;
|
||||
WorldstateFunctions::writeWorldstate.soundRecords.push_back(tempSound);
|
||||
tempSound = {};
|
||||
}
|
||||
|
||||
effectCount = 0;
|
||||
tempOverrides = {};
|
||||
|
@ -99,6 +99,8 @@
|
||||
{"SetRecordAIServices", RecordsDynamicFunctions::SetRecordAIServices},\
|
||||
\
|
||||
{"SetRecordSound", RecordsDynamicFunctions::SetRecordSound},\
|
||||
{"SetRecordMinRange", RecordsDynamicFunctions::SetRecordMinRange},\
|
||||
{"SetRecordMaxRange", RecordsDynamicFunctions::SetRecordMaxRange},\
|
||||
{"SetRecordOpenSound", RecordsDynamicFunctions::SetRecordOpenSound},\
|
||||
{"SetRecordCloseSound", RecordsDynamicFunctions::SetRecordCloseSound},\
|
||||
\
|
||||
@ -859,6 +861,33 @@ public:
|
||||
*/
|
||||
static void SetRecordSound(const char* sound) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the volume of the temporary record stored on the server for the currently
|
||||
* specified record type.
|
||||
*
|
||||
* \param volume The volume of the record.
|
||||
* \return void
|
||||
*/
|
||||
static void SetRecordVolume(double volume) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the minimum range of the temporary record stored on the server for the currently
|
||||
* specified record type.
|
||||
*
|
||||
* \param volume The minimum range of the record.
|
||||
* \return void
|
||||
*/
|
||||
static void SetRecordMinRange(double minRange) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the maximum range of the temporary record stored on the server for the currently
|
||||
* specified record type.
|
||||
*
|
||||
* \param volume The maximum range of the record.
|
||||
* \return void
|
||||
*/
|
||||
static void SetRecordMaxRange(double maxRange) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the opening sound of the temporary record stored on the server for the
|
||||
* currently specified record type.
|
||||
|
@ -214,7 +214,8 @@ public:
|
||||
{"OnWorldWeather", Callback<unsigned short>()},
|
||||
{"OnClientScriptGlobal", Callback<unsigned short>()},
|
||||
{"OnMpNumIncrement", Callback<int>()},
|
||||
{"OnRequestDataFileList", Callback<>()}
|
||||
{"OnRequestDataFileList", Callback<>()},
|
||||
{"OnServerWindowInput", Callback<const char *>()}
|
||||
};
|
||||
};
|
||||
|
||||
|
27
apps/openmw-mp/handleInput.cpp
Normal file
27
apps/openmw-mp/handleInput.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
using namespace std;
|
||||
namespace mwmp_input {
|
||||
string windowInputBuffer;
|
||||
void handler() {
|
||||
char c;
|
||||
#ifndef WIN32
|
||||
while (kbhit()) {
|
||||
c = getch();
|
||||
#else // on Windows conio.h getch() and kbhit() are deprecated, use _getch() and _kbhit() instead
|
||||
while (_kbhit()) {
|
||||
c = _getch();
|
||||
#endif
|
||||
cout << c << flush;
|
||||
if (c == '\n' || c == '\r') { // handle carriage return as new line on Windows
|
||||
cout << endl;
|
||||
Script::Call<Script::CallbackIdentity("OnServerWindowInput")>(windowInputBuffer.c_str());
|
||||
windowInputBuffer.assign("");
|
||||
}
|
||||
else if (c == '\b') {
|
||||
auto size = windowInputBuffer.size();
|
||||
if (size > 0)
|
||||
windowInputBuffer.erase(size - 1);
|
||||
}
|
||||
else windowInputBuffer += c;
|
||||
}
|
||||
}
|
||||
}
|
@ -1497,3 +1497,49 @@ void RecordHelper::overrideRecord(const mwmp::WeaponRecord& record)
|
||||
if (isExistingId)
|
||||
world->updatePtrsWithRefId(recordData.mId);
|
||||
}
|
||||
|
||||
void RecordHelper::overrideRecord(const mwmp::SoundRecord& record) {
|
||||
const ESM::Sound& recordData = record.data;
|
||||
|
||||
if (recordData.mId.empty())
|
||||
{
|
||||
LOG_APPEND(TimedLog::LOG_INFO, "-- Ignoring record override with no id provided");
|
||||
return;
|
||||
}
|
||||
|
||||
bool isExistingId = doesRecordIdExist<ESM::Sound>(recordData.mId);
|
||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||
|
||||
if (record.baseId.empty())
|
||||
{
|
||||
world->getModifiableStore().overrideRecord(recordData);
|
||||
}
|
||||
else if (doesRecordIdExist<ESM::Sound>(record.baseId))
|
||||
{
|
||||
const ESM::Sound* baseData = world->getStore().get<ESM::Sound>().search(record.baseId);
|
||||
ESM::Sound finalData = *baseData;
|
||||
finalData.mId = recordData.mId;
|
||||
|
||||
if (record.baseOverrides.hasSound)
|
||||
finalData.mSound = recordData.mSound;
|
||||
|
||||
if (record.baseOverrides.hasVolume)
|
||||
finalData.mData.mVolume = recordData.mData.mVolume;
|
||||
|
||||
if (record.baseOverrides.hasMinRange)
|
||||
finalData.mData.mMinRange = recordData.mData.mMinRange;
|
||||
|
||||
if (record.baseOverrides.hasMaxRange)
|
||||
finalData.mData.mMaxRange = recordData.mData.mMaxRange;
|
||||
|
||||
world->getModifiableStore().overrideRecord(finalData);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_APPEND(TimedLog::LOG_INFO, "-- Ignoring record override with invalid baseId %s", record.baseId.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (isExistingId)
|
||||
world->updatePtrsWithRefId(recordData.mId);
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ namespace RecordHelper
|
||||
void overrideRecord(const mwmp::SpellRecord& record);
|
||||
void overrideRecord(const mwmp::StaticRecord& record);
|
||||
void overrideRecord(const mwmp::WeaponRecord& record);
|
||||
void overrideRecord(const mwmp::SoundRecord& record);
|
||||
|
||||
template<class RecordType>
|
||||
void overrideRecord(const RecordType &record)
|
||||
|
@ -316,6 +316,18 @@ void Worldstate::addRecords()
|
||||
RecordHelper::overrideRecord(record);
|
||||
}
|
||||
}
|
||||
else if (recordsType == mwmp::RECORD_TYPE::SOUND)
|
||||
{
|
||||
for (auto&& record : soundRecords)
|
||||
{
|
||||
bool hasBaseId = !record.baseId.empty();
|
||||
|
||||
LOG_APPEND(TimedLog::LOG_INFO, "- sound record %s\n-- baseId is %s", record.data.mId.c_str(),
|
||||
hasBaseId ? record.baseId.c_str() : "empty");
|
||||
|
||||
RecordHelper::overrideRecord(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Worldstate::containsExploredMapTile(int cellX, int cellY)
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <components/esm/loadspel.hpp>
|
||||
#include <components/esm/loadstat.hpp>
|
||||
#include <components/esm/loadweap.hpp>
|
||||
#include <components/esm/loadsoun.hpp>
|
||||
|
||||
#include <components/openmw-mp/Base/BaseStructs.hpp>
|
||||
|
||||
@ -57,7 +58,8 @@ namespace mwmp
|
||||
SCRIPT,
|
||||
SPELL,
|
||||
STATIC,
|
||||
WEAPON
|
||||
WEAPON,
|
||||
SOUND
|
||||
};
|
||||
|
||||
// When using an existing record as a base, this struct tracks which changes
|
||||
@ -149,6 +151,9 @@ namespace mwmp
|
||||
bool hasQuasiEx = false;
|
||||
bool hasRegion = false;
|
||||
|
||||
bool hasVolume = false;
|
||||
bool hasMinRange = false;
|
||||
bool hasMaxRange = false;
|
||||
};
|
||||
|
||||
struct ActivatorRecord
|
||||
@ -318,6 +323,13 @@ namespace mwmp
|
||||
BaseOverrides baseOverrides;
|
||||
};
|
||||
|
||||
struct SoundRecord
|
||||
{
|
||||
ESM::Sound data;
|
||||
std::string baseId;
|
||||
BaseOverrides baseOverrides;
|
||||
};
|
||||
|
||||
static const int maxImageDataSize = 1800;
|
||||
|
||||
struct MapTile
|
||||
@ -404,6 +416,7 @@ namespace mwmp
|
||||
std::vector<ProbeRecord> probeRecords;
|
||||
std::vector<RepairRecord> repairRecords;
|
||||
std::vector<ScriptRecord> scriptRecords;
|
||||
std::vector<SoundRecord> soundRecords;
|
||||
std::vector<SpellRecord> spellRecords;
|
||||
std::vector<StaticRecord> staticRecords;
|
||||
std::vector<WeaponRecord> weaponRecords;
|
||||
|
@ -68,6 +68,8 @@ void PacketRecordDynamic::Packet(RakNet::BitStream *newBitstream, bool send)
|
||||
worldstate->recordsCount = Utils::getVectorSize(worldstate->scriptRecords);
|
||||
else if (worldstate->recordsType == mwmp::RECORD_TYPE::STATIC)
|
||||
worldstate->recordsCount = Utils::getVectorSize(worldstate->staticRecords);
|
||||
else if (worldstate->recordsType == mwmp::RECORD_TYPE::SOUND)
|
||||
worldstate->recordsCount = Utils::getVectorSize(worldstate->soundRecords);
|
||||
else
|
||||
{
|
||||
LOG_MESSAGE_SIMPLE(TimedLog::LOG_ERROR, "Processed invalid ID_RECORD_DYNAMIC packet about unimplemented recordsType %i",
|
||||
@ -134,6 +136,8 @@ void PacketRecordDynamic::Packet(RakNet::BitStream *newBitstream, bool send)
|
||||
Utils::resetVector(worldstate->scriptRecords, worldstate->recordsCount);
|
||||
else if (worldstate->recordsType == mwmp::RECORD_TYPE::STATIC)
|
||||
Utils::resetVector(worldstate->staticRecords, worldstate->recordsCount);
|
||||
else if (worldstate->recordsType == mwmp::RECORD_TYPE::SOUND)
|
||||
Utils::resetVector(worldstate->soundRecords, worldstate->recordsCount);
|
||||
}
|
||||
|
||||
if (worldstate->recordsType == mwmp::RECORD_TYPE::SPELL)
|
||||
@ -868,6 +872,29 @@ void PacketRecordDynamic::Packet(RakNet::BitStream *newBitstream, bool send)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (worldstate->recordsType == mwmp::RECORD_TYPE::SOUND)
|
||||
{
|
||||
for (auto&& record : worldstate->soundRecords)
|
||||
{
|
||||
auto& recordData = record.data;
|
||||
|
||||
RW(record.baseId, send, true);
|
||||
RW(recordData.mId, send, true);
|
||||
RW(recordData.mSound, send, true);
|
||||
RW(recordData.mData.mVolume, send);
|
||||
RW(recordData.mData.mMinRange, send);
|
||||
RW(recordData.mData.mMaxRange, send);
|
||||
|
||||
if (!record.baseId.empty())
|
||||
{
|
||||
auto&& overrides = record.baseOverrides;
|
||||
RW(overrides.hasSound, send);
|
||||
RW(overrides.hasVolume, send);
|
||||
RW(overrides.hasMinRange, send);
|
||||
RW(overrides.hasMaxRange, send);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PacketRecordDynamic::ProcessEffects(ESM::EffectList &effectList, bool send)
|
||||
|
Loading…
x
Reference in New Issue
Block a user