2017-01-28 14:22:30 +00:00
|
|
|
#include <regex>
|
2016-08-30 05:24:31 +00:00
|
|
|
|
|
|
|
#include <apps/openmw-mp/Player.hpp>
|
|
|
|
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
|
|
|
#include <apps/openmw-mp/Networking.hpp>
|
|
|
|
#include <components/openmw-mp/NetworkMessages.hpp>
|
2017-02-06 10:53:41 +00:00
|
|
|
#include <components/openmw-mp/Base/BaseEvent.hpp>
|
2016-08-30 05:24:31 +00:00
|
|
|
#include "World.hpp"
|
|
|
|
|
2017-01-28 14:22:30 +00:00
|
|
|
using namespace mwmp;
|
|
|
|
|
2017-02-23 06:36:35 +00:00
|
|
|
BaseEvent scriptEvent;
|
2017-04-09 23:37:43 +00:00
|
|
|
|
2017-02-23 05:47:00 +00:00
|
|
|
WorldObject tempWorldObject;
|
2017-04-09 23:37:43 +00:00
|
|
|
const WorldObject emptyWorldObject = {};
|
|
|
|
|
2017-02-23 05:47:00 +00:00
|
|
|
ContainerItem tempContainerItem;
|
2017-04-09 23:37:43 +00:00
|
|
|
const ContainerItem emptyContainerItem = {};
|
2017-01-28 14:22:30 +00:00
|
|
|
|
|
|
|
std::regex exteriorCellPattern("^(-?\\d+), (-?\\d+)$");
|
|
|
|
|
2017-02-23 06:23:46 +00:00
|
|
|
void WorldFunctions::InitScriptEvent(unsigned short pid) noexcept
|
2017-01-28 14:22:30 +00:00
|
|
|
{
|
2017-02-23 06:23:46 +00:00
|
|
|
Player *player;
|
|
|
|
GET_PLAYER(pid, player, );
|
|
|
|
|
2017-02-23 05:47:00 +00:00
|
|
|
scriptEvent.cell.blank();
|
|
|
|
scriptEvent.objectChanges.objects.clear();
|
2017-02-23 06:23:46 +00:00
|
|
|
scriptEvent.guid = player->guid;
|
2017-01-28 14:22:30 +00:00
|
|
|
}
|
|
|
|
|
2017-02-17 14:24:40 +00:00
|
|
|
unsigned int WorldFunctions::GetObjectChangesSize() noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.count;
|
|
|
|
}
|
|
|
|
|
2017-02-23 07:17:00 +00:00
|
|
|
unsigned char WorldFunctions::GetLastEventAction() noexcept
|
2017-02-17 14:24:40 +00:00
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->action;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *WorldFunctions::GetObjectRefId(unsigned int i) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(i).refId.c_str();
|
|
|
|
}
|
|
|
|
|
|
|
|
int WorldFunctions::GetObjectRefNumIndex(unsigned int i) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(i).refNumIndex;
|
|
|
|
}
|
|
|
|
|
2017-04-04 06:30:17 +00:00
|
|
|
int WorldFunctions::GetObjectMpNum(unsigned int i) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(i).mpNum;
|
|
|
|
}
|
|
|
|
|
2017-02-17 16:33:20 +00:00
|
|
|
int WorldFunctions::GetObjectCount(unsigned int i) noexcept
|
2017-02-17 14:24:40 +00:00
|
|
|
{
|
2017-02-17 16:33:20 +00:00
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(i).count;
|
2017-02-17 14:24:40 +00:00
|
|
|
}
|
|
|
|
|
2017-02-17 16:33:20 +00:00
|
|
|
int WorldFunctions::GetObjectCharge(unsigned int i) noexcept
|
2017-02-17 14:24:40 +00:00
|
|
|
{
|
2017-02-17 16:33:20 +00:00
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(i).charge;
|
2017-02-17 14:24:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int WorldFunctions::GetObjectGoldValue(unsigned int i) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(i).goldValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
double WorldFunctions::GetObjectScale(unsigned int i) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(i).scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
int WorldFunctions::GetObjectDoorState(unsigned int i) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(i).doorState;
|
|
|
|
}
|
|
|
|
|
|
|
|
int WorldFunctions::GetObjectLockLevel(unsigned int i) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(i).lockLevel;
|
|
|
|
}
|
|
|
|
|
|
|
|
double WorldFunctions::GetObjectPosX(unsigned int i) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(i).pos.pos[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
double WorldFunctions::GetObjectPosY(unsigned int i) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(i).pos.pos[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
double WorldFunctions::GetObjectPosZ(unsigned int i) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(i).pos.pos[2];
|
|
|
|
}
|
|
|
|
|
|
|
|
double WorldFunctions::GetObjectRotX(unsigned int i) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(i).pos.rot[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
double WorldFunctions::GetObjectRotY(unsigned int i) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(i).pos.rot[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
double WorldFunctions::GetObjectRotZ(unsigned int i) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(i).pos.rot[2];
|
|
|
|
}
|
|
|
|
|
2017-02-17 16:33:20 +00:00
|
|
|
unsigned int WorldFunctions::GetContainerChangesSize(unsigned int objectIndex) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(objectIndex).containerChanges.count;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *WorldFunctions::GetContainerItemRefId(unsigned int objectIndex, unsigned int itemIndex) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(objectIndex)
|
|
|
|
.containerChanges.items.at(itemIndex).refId.c_str();
|
|
|
|
}
|
|
|
|
|
|
|
|
int WorldFunctions::GetContainerItemCount(unsigned int objectIndex, unsigned int itemIndex) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(objectIndex)
|
|
|
|
.containerChanges.items.at(itemIndex).count;
|
|
|
|
}
|
|
|
|
|
|
|
|
int WorldFunctions::GetContainerItemCharge(unsigned int objectIndex, unsigned int itemIndex) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(objectIndex)
|
|
|
|
.containerChanges.items.at(itemIndex).charge;
|
|
|
|
}
|
|
|
|
|
2017-02-18 22:11:09 +00:00
|
|
|
int WorldFunctions::GetContainerItemActionCount(unsigned int objectIndex, unsigned int itemIndex) noexcept
|
|
|
|
{
|
|
|
|
return mwmp::Networking::getPtr()->getLastEvent()->objectChanges.objects.at(objectIndex)
|
|
|
|
.containerChanges.items.at(itemIndex).actionCount;
|
|
|
|
}
|
|
|
|
|
2017-02-23 05:47:00 +00:00
|
|
|
void WorldFunctions::SetScriptEventCell(const char* cellDescription) noexcept
|
2017-01-28 14:22:30 +00:00
|
|
|
{
|
|
|
|
std::string description = cellDescription;
|
|
|
|
std::smatch baseMatch;
|
|
|
|
|
|
|
|
if (std::regex_match(description, baseMatch, exteriorCellPattern))
|
|
|
|
{
|
2017-02-23 05:47:00 +00:00
|
|
|
scriptEvent.cell.mData.mFlags &= ~ESM::Cell::Interior;
|
2017-01-28 14:22:30 +00:00
|
|
|
|
|
|
|
// The first sub match is the whole string, so check for a length of 3
|
2017-01-30 15:09:14 +00:00
|
|
|
if (baseMatch.size() == 3)
|
|
|
|
{
|
2017-02-23 05:47:00 +00:00
|
|
|
scriptEvent.cell.mData.mX = stoi(baseMatch[1].str());
|
|
|
|
scriptEvent.cell.mData.mY = stoi(baseMatch[2].str());
|
2017-01-28 14:22:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-02-23 05:47:00 +00:00
|
|
|
scriptEvent.cell.mData.mFlags |= ESM::Cell::Interior;
|
|
|
|
scriptEvent.cell.mName = description;
|
2017-01-28 14:22:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-23 07:17:00 +00:00
|
|
|
void WorldFunctions::SetScriptEventAction(unsigned char action) noexcept
|
2017-02-14 17:31:56 +00:00
|
|
|
{
|
2017-02-23 05:47:00 +00:00
|
|
|
scriptEvent.action = action;
|
2017-02-14 17:31:56 +00:00
|
|
|
}
|
|
|
|
|
2017-01-30 15:42:29 +00:00
|
|
|
void WorldFunctions::SetObjectRefId(const char* refId) noexcept
|
2017-01-28 14:22:30 +00:00
|
|
|
{
|
2017-01-30 10:26:45 +00:00
|
|
|
tempWorldObject.refId = refId;
|
2017-01-28 14:22:30 +00:00
|
|
|
}
|
|
|
|
|
2017-01-30 15:42:29 +00:00
|
|
|
void WorldFunctions::SetObjectRefNumIndex(int refNumIndex) noexcept
|
2017-01-28 14:22:30 +00:00
|
|
|
{
|
2017-01-30 10:26:45 +00:00
|
|
|
tempWorldObject.refNumIndex = refNumIndex;
|
2017-01-28 14:22:30 +00:00
|
|
|
}
|
|
|
|
|
2017-04-04 06:30:17 +00:00
|
|
|
void WorldFunctions::SetObjectMpNum(int mpNum) noexcept
|
|
|
|
{
|
|
|
|
tempWorldObject.mpNum = mpNum;
|
|
|
|
}
|
|
|
|
|
2017-02-17 21:11:38 +00:00
|
|
|
void WorldFunctions::SetObjectCount(int count) noexcept
|
2017-02-05 11:45:12 +00:00
|
|
|
{
|
2017-02-17 21:11:38 +00:00
|
|
|
tempWorldObject.count = count;
|
2017-02-05 11:45:12 +00:00
|
|
|
}
|
|
|
|
|
2017-02-17 21:11:38 +00:00
|
|
|
void WorldFunctions::SetObjectCharge(int charge) noexcept
|
2017-01-29 14:16:01 +00:00
|
|
|
{
|
2017-02-17 21:11:38 +00:00
|
|
|
tempWorldObject.charge = charge;
|
2017-01-29 14:16:01 +00:00
|
|
|
}
|
|
|
|
|
2017-01-30 15:42:29 +00:00
|
|
|
void WorldFunctions::SetObjectGoldValue(int goldValue) noexcept
|
2017-01-29 14:16:01 +00:00
|
|
|
{
|
2017-01-30 10:26:45 +00:00
|
|
|
tempWorldObject.goldValue = goldValue;
|
2017-01-29 14:16:01 +00:00
|
|
|
}
|
|
|
|
|
2017-02-01 10:53:51 +00:00
|
|
|
void WorldFunctions::SetObjectScale(double scale) noexcept
|
2017-01-31 20:54:05 +00:00
|
|
|
{
|
|
|
|
tempWorldObject.scale = scale;
|
|
|
|
}
|
|
|
|
|
2017-02-06 21:09:50 +00:00
|
|
|
void WorldFunctions::SetObjectDoorState(int doorState) noexcept
|
2017-02-01 10:43:19 +00:00
|
|
|
{
|
2017-02-06 21:09:50 +00:00
|
|
|
tempWorldObject.doorState = doorState;
|
2017-02-01 10:43:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void WorldFunctions::SetObjectLockLevel(int lockLevel) noexcept
|
|
|
|
{
|
|
|
|
tempWorldObject.lockLevel = lockLevel;
|
|
|
|
}
|
|
|
|
|
2017-01-30 15:42:29 +00:00
|
|
|
void WorldFunctions::SetObjectPosition(double x, double y, double z) noexcept
|
2017-01-28 14:22:30 +00:00
|
|
|
{
|
2017-01-30 10:26:45 +00:00
|
|
|
tempWorldObject.pos.pos[0] = x;
|
|
|
|
tempWorldObject.pos.pos[1] = y;
|
|
|
|
tempWorldObject.pos.pos[2] = z;
|
2017-01-28 14:22:30 +00:00
|
|
|
}
|
|
|
|
|
2017-01-30 15:42:29 +00:00
|
|
|
void WorldFunctions::SetObjectRotation(double x, double y, double z) noexcept
|
2017-01-29 15:38:29 +00:00
|
|
|
{
|
2017-01-30 10:26:45 +00:00
|
|
|
tempWorldObject.pos.rot[0] = x;
|
|
|
|
tempWorldObject.pos.rot[1] = y;
|
|
|
|
tempWorldObject.pos.rot[2] = z;
|
2017-01-29 15:38:29 +00:00
|
|
|
}
|
|
|
|
|
2017-02-17 21:11:38 +00:00
|
|
|
void WorldFunctions::SetContainerItemRefId(const char* refId) noexcept
|
2017-02-14 17:31:56 +00:00
|
|
|
{
|
2017-02-17 21:11:38 +00:00
|
|
|
tempContainerItem.refId = refId;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WorldFunctions::SetContainerItemCount(int count) noexcept
|
|
|
|
{
|
|
|
|
tempContainerItem.count = count;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WorldFunctions::SetContainerItemCharge(int charge) noexcept
|
|
|
|
{
|
|
|
|
tempContainerItem.charge = charge;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WorldFunctions::AddWorldObject() noexcept
|
|
|
|
{
|
2017-04-09 23:37:43 +00:00
|
|
|
scriptEvent.objectChanges.objects.push_back(tempWorldObject);
|
2017-02-17 21:11:38 +00:00
|
|
|
|
2017-04-09 23:37:43 +00:00
|
|
|
tempWorldObject = emptyWorldObject;
|
2017-02-17 21:11:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void WorldFunctions::AddContainerItem() noexcept
|
|
|
|
{
|
2017-04-09 23:37:43 +00:00
|
|
|
tempWorldObject.containerChanges.items.push_back(tempContainerItem);
|
2017-02-17 21:11:38 +00:00
|
|
|
|
2017-04-09 23:37:43 +00:00
|
|
|
tempContainerItem = emptyContainerItem;
|
2017-02-14 17:31:56 +00:00
|
|
|
}
|
|
|
|
|
2017-02-23 06:23:46 +00:00
|
|
|
void WorldFunctions::SendObjectDelete() noexcept
|
2017-01-28 14:22:30 +00:00
|
|
|
{
|
2017-04-09 05:51:28 +00:00
|
|
|
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_DELETE)->setEvent(&scriptEvent);
|
|
|
|
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_DELETE)->Send(scriptEvent.guid);
|
2017-01-28 14:22:30 +00:00
|
|
|
}
|
|
|
|
|
2017-02-23 06:23:46 +00:00
|
|
|
void WorldFunctions::SendObjectPlace() noexcept
|
2017-01-28 14:22:30 +00:00
|
|
|
{
|
2017-04-09 05:51:28 +00:00
|
|
|
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_PLACE)->setEvent(&scriptEvent);
|
|
|
|
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_PLACE)->Send(scriptEvent.guid);
|
2017-01-28 14:22:30 +00:00
|
|
|
}
|
|
|
|
|
2017-02-23 06:23:46 +00:00
|
|
|
void WorldFunctions::SendObjectScale() noexcept
|
2017-01-31 21:07:02 +00:00
|
|
|
{
|
2017-04-09 05:51:28 +00:00
|
|
|
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_SCALE)->setEvent(&scriptEvent);
|
|
|
|
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_SCALE)->Send(scriptEvent.guid);
|
2017-01-31 21:07:02 +00:00
|
|
|
}
|
|
|
|
|
2017-02-23 06:23:46 +00:00
|
|
|
void WorldFunctions::SendObjectLock() noexcept
|
2017-02-01 10:43:19 +00:00
|
|
|
{
|
2017-04-09 05:51:28 +00:00
|
|
|
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_LOCK)->setEvent(&scriptEvent);
|
|
|
|
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_LOCK)->Send(scriptEvent.guid);
|
2017-02-01 10:43:19 +00:00
|
|
|
}
|
|
|
|
|
2017-02-23 06:23:46 +00:00
|
|
|
void WorldFunctions::SendObjectUnlock() noexcept
|
2017-02-01 10:43:19 +00:00
|
|
|
{
|
2017-04-09 05:51:28 +00:00
|
|
|
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_UNLOCK)->setEvent(&scriptEvent);
|
|
|
|
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_UNLOCK)->Send(scriptEvent.guid);
|
2017-02-01 10:43:19 +00:00
|
|
|
}
|
|
|
|
|
2017-02-23 06:23:46 +00:00
|
|
|
void WorldFunctions::SendDoorState() noexcept
|
2017-02-01 10:43:19 +00:00
|
|
|
{
|
2017-04-09 05:51:28 +00:00
|
|
|
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_DOOR_STATE)->setEvent(&scriptEvent);
|
|
|
|
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_DOOR_STATE)->Send(scriptEvent.guid);
|
2017-02-01 10:43:19 +00:00
|
|
|
}
|
|
|
|
|
2017-02-23 06:23:46 +00:00
|
|
|
void WorldFunctions::SendContainer() noexcept
|
2017-02-17 21:11:38 +00:00
|
|
|
{
|
2017-04-09 05:51:28 +00:00
|
|
|
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_CONTAINER)->setEvent(&scriptEvent);
|
|
|
|
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_CONTAINER)->Send(scriptEvent.guid);
|
2017-02-17 21:11:38 +00:00
|
|
|
}
|
|
|
|
|
2016-11-16 17:28:22 +00:00
|
|
|
void WorldFunctions::SetHour(unsigned short pid, double hour) noexcept
|
2016-08-30 05:24:31 +00:00
|
|
|
{
|
|
|
|
Player *player;
|
|
|
|
GET_PLAYER(pid, player,);
|
|
|
|
|
|
|
|
player->hour = hour;
|
|
|
|
player->month = -1;
|
|
|
|
player->day = -1;
|
|
|
|
|
2017-04-09 05:51:28 +00:00
|
|
|
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->setPlayer(player);
|
|
|
|
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->Send(false);
|
2016-08-30 05:24:31 +00:00
|
|
|
}
|
|
|
|
|
2016-11-16 17:28:22 +00:00
|
|
|
void WorldFunctions::SetMonth(unsigned short pid, int month) noexcept
|
2016-08-30 05:24:31 +00:00
|
|
|
{
|
|
|
|
Player *player;
|
|
|
|
GET_PLAYER(pid, player,);
|
|
|
|
|
|
|
|
player->hour = -1;
|
|
|
|
player->month = month;
|
|
|
|
player->day = -1;
|
|
|
|
|
2017-04-09 05:51:28 +00:00
|
|
|
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->setPlayer(player);
|
|
|
|
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->Send(false);
|
2016-08-30 05:24:31 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-11-16 17:28:22 +00:00
|
|
|
void WorldFunctions::SetDay(unsigned short pid, int day) noexcept
|
2016-08-30 05:24:31 +00:00
|
|
|
{
|
|
|
|
Player *player;
|
|
|
|
GET_PLAYER(pid, player,);
|
|
|
|
|
|
|
|
player->hour = -1;
|
|
|
|
player->month = -1;
|
|
|
|
player->day = day;
|
|
|
|
|
2017-04-09 05:51:28 +00:00
|
|
|
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->setPlayer(player);
|
|
|
|
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->Send(false);
|
2016-08-30 05:24:31 +00:00
|
|
|
}
|