2018-05-13 01:11:05 +00:00
|
|
|
#ifndef OPENMW_OBJECTAPI_HPP
|
|
|
|
#define OPENMW_OBJECTAPI_HPP
|
2016-08-30 05:24:31 +00:00
|
|
|
|
2018-05-13 01:11:05 +00:00
|
|
|
#define OBJECTAPI \
|
2018-07-12 23:33:50 +00:00
|
|
|
{"ReadReceivedObjectList", ObjectFunctions::ReadReceivedObjectList},\
|
2018-06-05 11:19:06 +00:00
|
|
|
\
|
|
|
|
{"ClearObjectList", ObjectFunctions::ClearObjectList},\
|
|
|
|
{"SetObjectListPid", ObjectFunctions::SetObjectListPid},\
|
|
|
|
\
|
2018-07-12 23:33:50 +00:00
|
|
|
{"CopyReceivedObjectListToStore", ObjectFunctions::CopyReceivedObjectListToStore},\
|
2017-01-28 14:22:30 +00:00
|
|
|
\
|
2018-07-12 23:33:50 +00:00
|
|
|
{"GetObjectListSize", ObjectFunctions::GetObjectListSize},\
|
2018-07-22 15:38:05 +00:00
|
|
|
{"GetObjectListOrigin", ObjectFunctions::GetObjectListOrigin},\
|
|
|
|
{"GetObjectListClientScript", ObjectFunctions::GetObjectListClientScript},\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"GetObjectListAction", ObjectFunctions::GetObjectListAction},\
|
2019-12-07 08:13:10 +00:00
|
|
|
{"GetObjectListConsoleCommand", ObjectFunctions::GetObjectListConsoleCommand},\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"GetObjectListContainerSubAction", ObjectFunctions::GetObjectListContainerSubAction},\
|
2017-01-29 11:21:41 +00:00
|
|
|
\
|
2018-07-15 00:16:04 +00:00
|
|
|
{"IsObjectPlayer", ObjectFunctions::IsObjectPlayer},\
|
|
|
|
{"GetObjectPid", ObjectFunctions::GetObjectPid},\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"GetObjectRefId", ObjectFunctions::GetObjectRefId},\
|
2018-07-13 01:12:03 +00:00
|
|
|
{"GetObjectRefNum", ObjectFunctions::GetObjectRefNum},\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"GetObjectMpNum", ObjectFunctions::GetObjectMpNum},\
|
|
|
|
{"GetObjectCount", ObjectFunctions::GetObjectCount},\
|
|
|
|
{"GetObjectCharge", ObjectFunctions::GetObjectCharge},\
|
|
|
|
{"GetObjectEnchantmentCharge", ObjectFunctions::GetObjectEnchantmentCharge},\
|
2018-07-26 19:37:04 +00:00
|
|
|
{"GetObjectSoul" , ObjectFunctions::GetObjectSoul},\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"GetObjectGoldValue", ObjectFunctions::GetObjectGoldValue},\
|
|
|
|
{"GetObjectScale", ObjectFunctions::GetObjectScale},\
|
2020-02-29 16:15:41 +00:00
|
|
|
{"GetObjectSoundId", ObjectFunctions::GetObjectSoundId},\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"GetObjectState", ObjectFunctions::GetObjectState},\
|
|
|
|
{"GetObjectDoorState", ObjectFunctions::GetObjectDoorState},\
|
|
|
|
{"GetObjectLockLevel", ObjectFunctions::GetObjectLockLevel},\
|
2018-07-02 21:53:52 +00:00
|
|
|
\
|
2018-07-15 00:16:04 +00:00
|
|
|
{"DoesObjectHavePlayerActivating", ObjectFunctions::DoesObjectHavePlayerActivating},\
|
|
|
|
{"GetObjectActivatingPid", ObjectFunctions::GetObjectActivatingPid},\
|
|
|
|
{"GetObjectActivatingRefId", ObjectFunctions::GetObjectActivatingRefId},\
|
|
|
|
{"GetObjectActivatingRefNum", ObjectFunctions::GetObjectActivatingRefNum},\
|
|
|
|
{"GetObjectActivatingMpNum", ObjectFunctions::GetObjectActivatingMpNum},\
|
|
|
|
{"GetObjectActivatingName", ObjectFunctions::GetObjectActivatingName},\
|
|
|
|
\
|
2019-12-13 12:00:51 +00:00
|
|
|
{"GetObjectHitSuccess", ObjectFunctions::GetObjectHitSuccess},\
|
2019-12-19 11:53:18 +00:00
|
|
|
{"GetObjectHitDamage", ObjectFunctions::GetObjectHitDamage},\
|
|
|
|
{"GetObjectHitBlock", ObjectFunctions::GetObjectHitBlock},\
|
|
|
|
{"GetObjectHitKnockdown", ObjectFunctions::GetObjectHitKnockdown},\
|
2019-12-08 14:14:01 +00:00
|
|
|
{"DoesObjectHavePlayerHitting", ObjectFunctions::DoesObjectHavePlayerHitting},\
|
|
|
|
{"GetObjectHittingPid", ObjectFunctions::GetObjectHittingPid},\
|
|
|
|
{"GetObjectHittingRefId", ObjectFunctions::GetObjectHittingRefId},\
|
|
|
|
{"GetObjectHittingRefNum", ObjectFunctions::GetObjectHittingRefNum},\
|
|
|
|
{"GetObjectHittingMpNum", ObjectFunctions::GetObjectHittingMpNum},\
|
|
|
|
{"GetObjectHittingName", ObjectFunctions::GetObjectHittingName},\
|
|
|
|
\
|
2018-07-01 23:25:06 +00:00
|
|
|
{"GetObjectSummonState", ObjectFunctions::GetObjectSummonState},\
|
2019-12-01 11:32:34 +00:00
|
|
|
{"GetObjectSummonEffectId", ObjectFunctions::GetObjectSummonEffectId},\
|
|
|
|
{"GetObjectSummonSpellId", ObjectFunctions::GetObjectSummonSpellId},\
|
2018-06-30 21:43:29 +00:00
|
|
|
{"GetObjectSummonDuration", ObjectFunctions::GetObjectSummonDuration},\
|
2018-07-02 12:54:39 +00:00
|
|
|
{"DoesObjectHavePlayerSummoner", ObjectFunctions::DoesObjectHavePlayerSummoner},\
|
2018-07-04 01:26:44 +00:00
|
|
|
{"GetObjectSummonerPid", ObjectFunctions::GetObjectSummonerPid},\
|
2018-07-02 21:53:52 +00:00
|
|
|
{"GetObjectSummonerRefId", ObjectFunctions::GetObjectSummonerRefId},\
|
2018-07-13 01:12:03 +00:00
|
|
|
{"GetObjectSummonerRefNum", ObjectFunctions::GetObjectSummonerRefNum},\
|
2018-07-02 21:53:52 +00:00
|
|
|
{"GetObjectSummonerMpNum", ObjectFunctions::GetObjectSummonerMpNum},\
|
|
|
|
\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"GetObjectPosX", ObjectFunctions::GetObjectPosX},\
|
|
|
|
{"GetObjectPosY", ObjectFunctions::GetObjectPosY},\
|
|
|
|
{"GetObjectPosZ", ObjectFunctions::GetObjectPosZ},\
|
|
|
|
{"GetObjectRotX", ObjectFunctions::GetObjectRotX},\
|
|
|
|
{"GetObjectRotY", ObjectFunctions::GetObjectRotY},\
|
|
|
|
{"GetObjectRotZ", ObjectFunctions::GetObjectRotZ},\
|
2017-02-14 17:31:56 +00:00
|
|
|
\
|
2018-07-07 14:09:57 +00:00
|
|
|
{"GetVideoFilename", ObjectFunctions::GetVideoFilename},\
|
|
|
|
\
|
2019-09-19 05:46:54 +00:00
|
|
|
{"GetScriptVariableName", ObjectFunctions::GetScriptVariableName},\
|
|
|
|
{"GetScriptVariableShortValue", ObjectFunctions::GetScriptVariableShortValue},\
|
|
|
|
\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"GetContainerChangesSize", ObjectFunctions::GetContainerChangesSize},\
|
|
|
|
{"GetContainerItemRefId", ObjectFunctions::GetContainerItemRefId},\
|
|
|
|
{"GetContainerItemCount", ObjectFunctions::GetContainerItemCount},\
|
|
|
|
{"GetContainerItemCharge", ObjectFunctions::GetContainerItemCharge},\
|
|
|
|
{"GetContainerItemEnchantmentCharge", ObjectFunctions::GetContainerItemEnchantmentCharge},\
|
2018-07-26 19:37:04 +00:00
|
|
|
{"GetContainerItemSoul", ObjectFunctions::GetContainerItemSoul},\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"GetContainerItemActionCount", ObjectFunctions::GetContainerItemActionCount},\
|
2017-02-17 14:24:40 +00:00
|
|
|
\
|
2018-06-26 13:56:08 +00:00
|
|
|
{"DoesObjectHaveContainer", ObjectFunctions::DoesObjectHaveContainer},\
|
2020-02-27 12:53:03 +00:00
|
|
|
{"IsObjectDroppedByPlayer", ObjectFunctions::IsObjectDroppedByPlayer},\
|
2018-06-26 13:56:08 +00:00
|
|
|
\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"SetObjectListCell", ObjectFunctions::SetObjectListCell},\
|
|
|
|
{"SetObjectListAction", ObjectFunctions::SetObjectListAction},\
|
|
|
|
{"SetObjectListConsoleCommand", ObjectFunctions::SetObjectListConsoleCommand},\
|
2017-02-17 14:24:40 +00:00
|
|
|
\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"SetObjectRefId", ObjectFunctions::SetObjectRefId},\
|
2018-07-13 01:12:03 +00:00
|
|
|
{"SetObjectRefNum", ObjectFunctions::SetObjectRefNum},\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"SetObjectMpNum", ObjectFunctions::SetObjectMpNum},\
|
|
|
|
{"SetObjectCount", ObjectFunctions::SetObjectCount},\
|
|
|
|
{"SetObjectCharge", ObjectFunctions::SetObjectCharge},\
|
|
|
|
{"SetObjectEnchantmentCharge", ObjectFunctions::SetObjectEnchantmentCharge},\
|
2018-07-26 19:37:04 +00:00
|
|
|
{"SetObjectSoul", ObjectFunctions::SetObjectSoul},\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"SetObjectGoldValue", ObjectFunctions::SetObjectGoldValue},\
|
|
|
|
{"SetObjectScale", ObjectFunctions::SetObjectScale},\
|
|
|
|
{"SetObjectState", ObjectFunctions::SetObjectState},\
|
|
|
|
{"SetObjectLockLevel", ObjectFunctions::SetObjectLockLevel},\
|
|
|
|
{"SetObjectDisarmState", ObjectFunctions::SetObjectDisarmState},\
|
2020-02-27 12:53:03 +00:00
|
|
|
{"SetObjectDroppedByPlayerState", ObjectFunctions::SetObjectDroppedByPlayerState},\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"SetObjectPosition", ObjectFunctions::SetObjectPosition},\
|
|
|
|
{"SetObjectRotation", ObjectFunctions::SetObjectRotation},\
|
2020-03-14 18:17:00 +00:00
|
|
|
{"SetObjectSound", ObjectFunctions::SetObjectSound},\
|
2018-04-29 19:32:22 +00:00
|
|
|
\
|
2019-11-30 18:44:27 +00:00
|
|
|
{"SetObjectSummonState", ObjectFunctions::SetObjectSummonState},\
|
2019-12-01 11:32:34 +00:00
|
|
|
{"SetObjectSummonEffectId", ObjectFunctions::SetObjectSummonEffectId},\
|
|
|
|
{"SetObjectSummonSpellId", ObjectFunctions::SetObjectSummonSpellId},\
|
2019-11-30 18:44:27 +00:00
|
|
|
{"SetObjectSummonDuration", ObjectFunctions::SetObjectSummonDuration},\
|
2019-12-01 08:12:13 +00:00
|
|
|
{"SetObjectSummonerPid", ObjectFunctions::SetObjectSummonerPid},\
|
|
|
|
{"SetObjectSummonerRefNum", ObjectFunctions::SetObjectSummonerRefNum},\
|
|
|
|
{"SetObjectSummonerMpNum", ObjectFunctions::SetObjectSummonerMpNum},\
|
2019-11-30 18:44:27 +00:00
|
|
|
\
|
2018-10-22 13:25:50 +00:00
|
|
|
{"SetObjectActivatingPid", ObjectFunctions::SetObjectActivatingPid},\
|
|
|
|
\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"SetObjectDoorState", ObjectFunctions::SetObjectDoorState},\
|
|
|
|
{"SetObjectDoorTeleportState", ObjectFunctions::SetObjectDoorTeleportState},\
|
|
|
|
{"SetObjectDoorDestinationCell", ObjectFunctions::SetObjectDoorDestinationCell},\
|
|
|
|
{"SetObjectDoorDestinationPosition", ObjectFunctions::SetObjectDoorDestinationPosition},\
|
|
|
|
{"SetObjectDoorDestinationRotation", ObjectFunctions::SetObjectDoorDestinationRotation},\
|
2018-04-29 19:32:22 +00:00
|
|
|
\
|
2019-09-19 05:46:54 +00:00
|
|
|
{"SetScriptVariableName", ObjectFunctions::SetScriptVariableName},\
|
|
|
|
{"SetScriptVariableShortValue", ObjectFunctions::SetScriptVariableShortValue},\
|
|
|
|
\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"SetPlayerAsObject", ObjectFunctions::SetPlayerAsObject},\
|
2017-01-29 11:21:41 +00:00
|
|
|
\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"SetContainerItemRefId", ObjectFunctions::SetContainerItemRefId},\
|
|
|
|
{"SetContainerItemCount", ObjectFunctions::SetContainerItemCount},\
|
|
|
|
{"SetContainerItemCharge", ObjectFunctions::SetContainerItemCharge},\
|
|
|
|
{"SetContainerItemEnchantmentCharge", ObjectFunctions::SetContainerItemEnchantmentCharge},\
|
2018-07-26 19:37:04 +00:00
|
|
|
{"SetContainerItemSoul", ObjectFunctions::SetContainerItemSoul},\
|
2017-02-17 21:11:38 +00:00
|
|
|
\
|
2018-06-05 11:19:06 +00:00
|
|
|
{"SetContainerItemActionCountByIndex", ObjectFunctions::SetContainerItemActionCountByIndex},\
|
[General] Rework container sync to prevent item duping
A main priority in TES3MP development is to avoid making major changes to OpenMW code, so as to avoid merge conflicts in the future. Whenever avoiding potential conflicts seems especially difficult for the proper implementation of a particular multiplayer feature, that multiplayer feature is often put off until later or partially implemented with the intent of being revisited in the future.
Container sync is the perfect example. Previously, the OpenMW code for container actions was kept exactly as it was, with clients unilaterally accepting their own container changes as per singleplayer-specific code, with only the addition that clients sent container packets every time they made a change in a container, packets which were then forwarded unquestioningly by the server to other players. This meant that two players clicking on the same item in a container at the same time both managed to take it, thus duplicating the item.
Immediately after the packets were already forwarded, server scripts were able to check for incorrect changes, such as the removal of more items than should have existed in a container, but they had to send their own packets that attempted to fix what had already been accepted on the initial client and then forwarded to all clients, which was quite onerous in some scenarios, such as when a player on a slow connection immediately dropped items in the world after taking them from a container (which is why the default TES3MP serverside scripts made no attempt at sending corrective packets at all, preferring to expect the matter to be solved in a later C++ implementation).
This commit fixes item duping in containers by preventing container actions from initially running on clients and by ending the automatic forwarding of container packets by the server. Instead, clients now send container packets that act as requests for container actions, and serverside scripts have to forward these requests themselves. In other words, without a matching Container event in the server's Lua scripts, players are completely unable to affect containers for themselves or for others.
To forward a received Container packet, the following line must be used in a Container event in the Lua scripts:
tes3mp.SendContainer(true, true)
When an invalid action count is used in a container request, the serverside scripts can amend it using the following new function:
tes3mp.SetReceivedContainerItemActionCount(objectIndex, itemIndex, actionCount)
Thus, the serverside scripts are able to allow only container actions that are correct based on their own recorded contents for that container.
The OpenMW code allowing unilateral container actions in mwgui/container.cpp is now prevented from executing. When a player's container request is returned to them, code in mwmp/WorldEvent.cpp simulates those container actions instead.
2018-03-26 16:27:36 +00:00
|
|
|
\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"AddObject", ObjectFunctions::AddObject},\
|
|
|
|
{"AddContainerItem", ObjectFunctions::AddContainerItem},\
|
2017-01-28 14:22:30 +00:00
|
|
|
\
|
2018-07-15 00:16:04 +00:00
|
|
|
{"SendObjectActivate", ObjectFunctions::SendObjectActivate},\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"SendObjectPlace", ObjectFunctions::SendObjectPlace},\
|
|
|
|
{"SendObjectSpawn", ObjectFunctions::SendObjectSpawn},\
|
|
|
|
{"SendObjectDelete", ObjectFunctions::SendObjectDelete},\
|
|
|
|
{"SendObjectLock", ObjectFunctions::SendObjectLock},\
|
2020-01-23 10:50:34 +00:00
|
|
|
{"SendObjectRestock", ObjectFunctions::SendObjectRestock},\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"SendObjectTrap", ObjectFunctions::SendObjectTrap},\
|
|
|
|
{"SendObjectScale", ObjectFunctions::SendObjectScale},\
|
2020-02-29 16:15:41 +00:00
|
|
|
{"SendObjectSound", ObjectFunctions::SendObjectSound},\
|
2018-05-13 01:11:05 +00:00
|
|
|
{"SendObjectState", ObjectFunctions::SendObjectState},\
|
|
|
|
{"SendDoorState", ObjectFunctions::SendDoorState},\
|
|
|
|
{"SendDoorDestination", ObjectFunctions::SendDoorDestination},\
|
|
|
|
{"SendContainer", ObjectFunctions::SendContainer},\
|
2018-07-07 14:09:57 +00:00
|
|
|
{"SendVideoPlay", ObjectFunctions::SendVideoPlay},\
|
2019-09-19 05:46:54 +00:00
|
|
|
{"SendScriptGlobalShort", ObjectFunctions::SendScriptGlobalShort},\
|
2018-05-15 23:16:27 +00:00
|
|
|
{"SendConsoleCommand", ObjectFunctions::SendConsoleCommand},\
|
|
|
|
\
|
2018-07-12 23:33:50 +00:00
|
|
|
{"ReadLastObjectList", ObjectFunctions::ReadLastObjectList},\
|
2018-05-15 23:16:27 +00:00
|
|
|
{"ReadLastEvent", ObjectFunctions::ReadLastEvent},\
|
2018-06-05 11:19:06 +00:00
|
|
|
{"InitializeObjectList", ObjectFunctions::InitializeObjectList},\
|
2018-05-15 23:16:27 +00:00
|
|
|
{"InitializeEvent", ObjectFunctions::InitializeEvent},\
|
2018-07-12 23:33:50 +00:00
|
|
|
{"CopyLastObjectListToStore", ObjectFunctions::CopyLastObjectListToStore},\
|
|
|
|
{"GetObjectChangesSize", ObjectFunctions::GetObjectChangesSize},\
|
2018-05-15 23:16:27 +00:00
|
|
|
{"GetEventAction", ObjectFunctions::GetEventAction},\
|
|
|
|
{"GetEventContainerSubAction", ObjectFunctions::GetEventContainerSubAction},\
|
2018-07-13 01:12:03 +00:00
|
|
|
{"GetObjectRefNumIndex", ObjectFunctions::GetObjectRefNumIndex},\
|
|
|
|
{"GetObjectSummonerRefNumIndex", ObjectFunctions::GetObjectSummonerRefNumIndex},\
|
2018-05-15 23:16:27 +00:00
|
|
|
{"SetEventCell", ObjectFunctions::SetEventCell},\
|
|
|
|
{"SetEventAction", ObjectFunctions::SetEventAction},\
|
|
|
|
{"SetEventConsoleCommand", ObjectFunctions::SetEventConsoleCommand},\
|
2018-07-13 01:12:03 +00:00
|
|
|
{"SetObjectRefNumIndex", ObjectFunctions::SetObjectRefNumIndex},\
|
2018-05-15 23:16:27 +00:00
|
|
|
{"AddWorldObject", ObjectFunctions::AddWorldObject}
|
2016-08-30 05:24:31 +00:00
|
|
|
|
2018-05-13 01:11:05 +00:00
|
|
|
class ObjectFunctions
|
2016-08-30 05:24:31 +00:00
|
|
|
{
|
|
|
|
public:
|
2017-01-28 14:22:30 +00:00
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Use the last object list received by the server as the one being read.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \return void
|
|
|
|
*/
|
2018-07-12 23:33:50 +00:00
|
|
|
static void ReadReceivedObjectList() noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-26 19:37:04 +00:00
|
|
|
* \brief Clear the data from the object list stored on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-06-05 11:19:06 +00:00
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void ClearObjectList() noexcept;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Set the pid attached to the ObjectList.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-05-12 21:42:24 +00:00
|
|
|
* \param pid The player ID to whom the object list should be attached.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return void
|
|
|
|
*/
|
2018-06-05 11:19:06 +00:00
|
|
|
static void SetObjectListPid(unsigned short pid) noexcept;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Take the contents of the read-only object list last received by the
|
|
|
|
* server from a player and move its contents to the stored object list
|
|
|
|
* that can be sent by the server.
|
|
|
|
*
|
|
|
|
* \return void
|
|
|
|
*/
|
2018-07-12 23:33:50 +00:00
|
|
|
static void CopyReceivedObjectListToStore() noexcept;
|
2017-01-28 14:22:30 +00:00
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
2018-07-12 23:33:50 +00:00
|
|
|
* \brief Get the number of indexes in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \return The number of indexes.
|
|
|
|
*/
|
2018-07-12 23:33:50 +00:00
|
|
|
static unsigned int GetObjectListSize() noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
2018-07-22 15:38:05 +00:00
|
|
|
/**
|
|
|
|
* \brief Get the origin of the read object list.
|
|
|
|
*
|
2018-07-22 20:08:32 +00:00
|
|
|
* \return The origin (0 for CLIENT_GAMEPLAY, 1 for CLIENT_CONSOLE, 2 for
|
|
|
|
* CLIENT_DIALOGUE, 3 for CLIENT_SCRIPT_LOCAL, 4 for CLIENT_SCRIPT_GLOBAL,
|
|
|
|
* 5 for SERVER_SCRIPT).
|
2018-07-22 15:38:05 +00:00
|
|
|
*/
|
|
|
|
static unsigned char GetObjectListOrigin() noexcept;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the client script that the read object list originated from.
|
|
|
|
*
|
2018-07-22 20:08:32 +00:00
|
|
|
* Note: This is not yet implemented.
|
|
|
|
*
|
2018-07-22 15:38:05 +00:00
|
|
|
* \return The ID of the client script.
|
|
|
|
*/
|
|
|
|
static const char *GetObjectListClientScript() noexcept;
|
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Get the action type used in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \return The action type (0 for SET, 1 for ADD, 2 for REMOVE, 3 for REQUEST).
|
|
|
|
*/
|
2018-05-12 21:42:24 +00:00
|
|
|
static unsigned char GetObjectListAction() noexcept;
|
2017-01-29 11:21:41 +00:00
|
|
|
|
2019-12-07 08:13:10 +00:00
|
|
|
/**
|
|
|
|
* \brief Get the console command used in the read object list.
|
|
|
|
*
|
|
|
|
* \return The console command.
|
|
|
|
*/
|
|
|
|
static const char *GetObjectListConsoleCommand() noexcept;
|
|
|
|
|
[General] Rework container sync to prevent item duping
A main priority in TES3MP development is to avoid making major changes to OpenMW code, so as to avoid merge conflicts in the future. Whenever avoiding potential conflicts seems especially difficult for the proper implementation of a particular multiplayer feature, that multiplayer feature is often put off until later or partially implemented with the intent of being revisited in the future.
Container sync is the perfect example. Previously, the OpenMW code for container actions was kept exactly as it was, with clients unilaterally accepting their own container changes as per singleplayer-specific code, with only the addition that clients sent container packets every time they made a change in a container, packets which were then forwarded unquestioningly by the server to other players. This meant that two players clicking on the same item in a container at the same time both managed to take it, thus duplicating the item.
Immediately after the packets were already forwarded, server scripts were able to check for incorrect changes, such as the removal of more items than should have existed in a container, but they had to send their own packets that attempted to fix what had already been accepted on the initial client and then forwarded to all clients, which was quite onerous in some scenarios, such as when a player on a slow connection immediately dropped items in the world after taking them from a container (which is why the default TES3MP serverside scripts made no attempt at sending corrective packets at all, preferring to expect the matter to be solved in a later C++ implementation).
This commit fixes item duping in containers by preventing container actions from initially running on clients and by ending the automatic forwarding of container packets by the server. Instead, clients now send container packets that act as requests for container actions, and serverside scripts have to forward these requests themselves. In other words, without a matching Container event in the server's Lua scripts, players are completely unable to affect containers for themselves or for others.
To forward a received Container packet, the following line must be used in a Container event in the Lua scripts:
tes3mp.SendContainer(true, true)
When an invalid action count is used in a container request, the serverside scripts can amend it using the following new function:
tes3mp.SetReceivedContainerItemActionCount(objectIndex, itemIndex, actionCount)
Thus, the serverside scripts are able to allow only container actions that are correct based on their own recorded contents for that container.
The OpenMW code allowing unilateral container actions in mwgui/container.cpp is now prevented from executing. When a player's container request is returned to them, code in mwmp/WorldEvent.cpp simulates those container actions instead.
2018-03-26 16:27:36 +00:00
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Get the container subaction type used in the read object list.
|
[General] Rework container sync to prevent item duping
A main priority in TES3MP development is to avoid making major changes to OpenMW code, so as to avoid merge conflicts in the future. Whenever avoiding potential conflicts seems especially difficult for the proper implementation of a particular multiplayer feature, that multiplayer feature is often put off until later or partially implemented with the intent of being revisited in the future.
Container sync is the perfect example. Previously, the OpenMW code for container actions was kept exactly as it was, with clients unilaterally accepting their own container changes as per singleplayer-specific code, with only the addition that clients sent container packets every time they made a change in a container, packets which were then forwarded unquestioningly by the server to other players. This meant that two players clicking on the same item in a container at the same time both managed to take it, thus duplicating the item.
Immediately after the packets were already forwarded, server scripts were able to check for incorrect changes, such as the removal of more items than should have existed in a container, but they had to send their own packets that attempted to fix what had already been accepted on the initial client and then forwarded to all clients, which was quite onerous in some scenarios, such as when a player on a slow connection immediately dropped items in the world after taking them from a container (which is why the default TES3MP serverside scripts made no attempt at sending corrective packets at all, preferring to expect the matter to be solved in a later C++ implementation).
This commit fixes item duping in containers by preventing container actions from initially running on clients and by ending the automatic forwarding of container packets by the server. Instead, clients now send container packets that act as requests for container actions, and serverside scripts have to forward these requests themselves. In other words, without a matching Container event in the server's Lua scripts, players are completely unable to affect containers for themselves or for others.
To forward a received Container packet, the following line must be used in a Container event in the Lua scripts:
tes3mp.SendContainer(true, true)
When an invalid action count is used in a container request, the serverside scripts can amend it using the following new function:
tes3mp.SetReceivedContainerItemActionCount(objectIndex, itemIndex, actionCount)
Thus, the serverside scripts are able to allow only container actions that are correct based on their own recorded contents for that container.
The OpenMW code allowing unilateral container actions in mwgui/container.cpp is now prevented from executing. When a player's container request is returned to them, code in mwmp/WorldEvent.cpp simulates those container actions instead.
2018-03-26 16:27:36 +00:00
|
|
|
*
|
|
|
|
* \return The action type (0 for NONE, 1 for DRAG, 2 for DROP, 3 for TAKE_ALL).
|
|
|
|
*/
|
2018-05-12 21:42:24 +00:00
|
|
|
static unsigned char GetObjectListContainerSubAction() noexcept;
|
[General] Rework container sync to prevent item duping
A main priority in TES3MP development is to avoid making major changes to OpenMW code, so as to avoid merge conflicts in the future. Whenever avoiding potential conflicts seems especially difficult for the proper implementation of a particular multiplayer feature, that multiplayer feature is often put off until later or partially implemented with the intent of being revisited in the future.
Container sync is the perfect example. Previously, the OpenMW code for container actions was kept exactly as it was, with clients unilaterally accepting their own container changes as per singleplayer-specific code, with only the addition that clients sent container packets every time they made a change in a container, packets which were then forwarded unquestioningly by the server to other players. This meant that two players clicking on the same item in a container at the same time both managed to take it, thus duplicating the item.
Immediately after the packets were already forwarded, server scripts were able to check for incorrect changes, such as the removal of more items than should have existed in a container, but they had to send their own packets that attempted to fix what had already been accepted on the initial client and then forwarded to all clients, which was quite onerous in some scenarios, such as when a player on a slow connection immediately dropped items in the world after taking them from a container (which is why the default TES3MP serverside scripts made no attempt at sending corrective packets at all, preferring to expect the matter to be solved in a later C++ implementation).
This commit fixes item duping in containers by preventing container actions from initially running on clients and by ending the automatic forwarding of container packets by the server. Instead, clients now send container packets that act as requests for container actions, and serverside scripts have to forward these requests themselves. In other words, without a matching Container event in the server's Lua scripts, players are completely unable to affect containers for themselves or for others.
To forward a received Container packet, the following line must be used in a Container event in the Lua scripts:
tes3mp.SendContainer(true, true)
When an invalid action count is used in a container request, the serverside scripts can amend it using the following new function:
tes3mp.SetReceivedContainerItemActionCount(objectIndex, itemIndex, actionCount)
Thus, the serverside scripts are able to allow only container actions that are correct based on their own recorded contents for that container.
The OpenMW code allowing unilateral container actions in mwgui/container.cpp is now prevented from executing. When a player's container request is returned to them, code in mwmp/WorldEvent.cpp simulates those container actions instead.
2018-03-26 16:27:36 +00:00
|
|
|
|
2018-07-15 00:16:04 +00:00
|
|
|
/**
|
|
|
|
* \brief Check whether the object at a certain index in the read object list is a
|
|
|
|
* player.
|
|
|
|
*
|
|
|
|
* Note: Although most player data and events are dealt with in Player packets,
|
|
|
|
* object activation is general enough for players themselves to be included
|
|
|
|
* as objects in ObjectActivate packets.
|
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-07-15 00:16:04 +00:00
|
|
|
* \return Whether the object is a player.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static bool IsObjectPlayer(unsigned int index) noexcept;
|
2018-07-15 00:16:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the player ID of the object at a certain index in the read object list,
|
|
|
|
* only valid if the object is a player.
|
|
|
|
*
|
|
|
|
* Note: Currently, players can only be objects in ObjectActivate and ConsoleCommand
|
|
|
|
* packets.
|
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-07-15 00:16:04 +00:00
|
|
|
* \return The player ID of the object.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static int GetObjectPid(unsigned int index) noexcept;
|
2018-07-15 00:16:04 +00:00
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the refId of the object at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The refId.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static const char *GetObjectRefId(unsigned int index) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the refNum of the object at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-07-13 01:12:03 +00:00
|
|
|
* \return The refNum.
|
2017-07-23 18:59:33 +00:00
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static unsigned int GetObjectRefNum(unsigned int index) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the mpNum of the object at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The mpNum.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static unsigned int GetObjectMpNum(unsigned int index) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the count of the object at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The object count.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static int GetObjectCount(unsigned int index) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the charge of the object at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The charge.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static int GetObjectCharge(unsigned int index) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
2017-12-23 11:16:38 +00:00
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the enchantment charge of the object at a certain index in the read object list.
|
2017-12-23 11:16:38 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-12-23 11:16:38 +00:00
|
|
|
* \return The enchantment charge.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static double GetObjectEnchantmentCharge(unsigned int index) noexcept;
|
2017-12-23 11:16:38 +00:00
|
|
|
|
2018-07-26 19:37:04 +00:00
|
|
|
/**
|
|
|
|
* \brief Get the soul of the object at a certain index in the read object list.
|
|
|
|
*
|
|
|
|
* \param index The index of the object.
|
|
|
|
* \return The soul.
|
|
|
|
*/
|
|
|
|
static const char *GetObjectSoul(unsigned int index) noexcept;
|
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the gold value of the object at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* This is used solely to get the gold value of gold. It is not used for other objects.
|
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The gold value.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static int GetObjectGoldValue(unsigned int index) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the object scale of the object at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The object scale.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static double GetObjectScale(unsigned int index) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
2020-02-29 16:15:41 +00:00
|
|
|
/**
|
|
|
|
* \brief Get the object sound ID of the object at a certain index in the read object list.
|
|
|
|
*
|
|
|
|
* \param index The index of the object.
|
|
|
|
* \return The object sound ID.
|
|
|
|
*/
|
|
|
|
static const char *GetObjectSoundId(unsigned int index) noexcept;
|
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the object state of the object at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The object state.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static bool GetObjectState(unsigned int index) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the door state of the object at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The door state.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static int GetObjectDoorState(unsigned int index) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the lock level of the object at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The lock level.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static int GetObjectLockLevel(unsigned int index) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
2018-07-15 00:16:04 +00:00
|
|
|
/**
|
|
|
|
* \brief Check whether the object at a certain index in the read object list has been
|
|
|
|
* activated by a player.
|
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-07-15 00:16:04 +00:00
|
|
|
* \return Whether the object has been activated by a player.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static bool DoesObjectHavePlayerActivating(unsigned int index) noexcept;
|
2018-07-15 00:16:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the player ID of the player activating the object at a certain index in the
|
|
|
|
* read object list.
|
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-07-15 00:16:04 +00:00
|
|
|
* \return The player ID of the activating player.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static int GetObjectActivatingPid(unsigned int index) noexcept;
|
2018-07-15 00:16:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the refId of the actor activating the object at a certain index in the read
|
|
|
|
* object list.
|
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-07-15 00:16:04 +00:00
|
|
|
* \return The refId of the activating actor.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static const char *GetObjectActivatingRefId(unsigned int index) noexcept;
|
2018-07-15 00:16:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the refNum of the actor activating the object at a certain index in the read
|
|
|
|
* object list.
|
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-07-15 00:16:04 +00:00
|
|
|
* \return The refNum of the activating actor.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static unsigned int GetObjectActivatingRefNum(unsigned int index) noexcept;
|
2018-07-15 00:16:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the mpNum of the actor activating the object at a certain index in the read
|
|
|
|
* object list.
|
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-07-15 00:16:04 +00:00
|
|
|
* \return The mpNum of the activating actor.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static unsigned int GetObjectActivatingMpNum(unsigned int index) noexcept;
|
2018-07-15 00:16:04 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the name of the actor activating the object at a certain index in the read
|
|
|
|
* object list.
|
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-07-15 00:16:04 +00:00
|
|
|
* \return The name of the activating actor.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static const char *GetObjectActivatingName(unsigned int index) noexcept;
|
2018-07-15 00:16:04 +00:00
|
|
|
|
2019-12-13 12:00:51 +00:00
|
|
|
/**
|
|
|
|
* \brief Check whether the object at a certain index in the read object list has been
|
|
|
|
* hit successfully.
|
|
|
|
*
|
|
|
|
* \param index The index of the object.
|
|
|
|
* \return The success state.
|
|
|
|
*/
|
|
|
|
static bool GetObjectHitSuccess(unsigned int index) noexcept;
|
|
|
|
|
2019-12-19 11:53:18 +00:00
|
|
|
/**
|
|
|
|
* \brief Get the damage caused to the object at a certain index in the read object list
|
|
|
|
* in a hit.
|
|
|
|
*
|
|
|
|
* \param index The index of the object.
|
|
|
|
* \return The damage.
|
|
|
|
*/
|
|
|
|
static double GetObjectHitDamage(unsigned int index) noexcept;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Check whether the object at a certain index in the read object list has
|
|
|
|
* blocked the hit on it.
|
|
|
|
*
|
|
|
|
* \param index The index of the object.
|
|
|
|
* \return The block state.
|
|
|
|
*/
|
|
|
|
static bool GetObjectHitBlock(unsigned int index) noexcept;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Check whether the object at a certain index in the read object list has been
|
|
|
|
* knocked down.
|
|
|
|
*
|
|
|
|
* \param index The index of the object.
|
|
|
|
* \return The knockdown state.
|
|
|
|
*/
|
|
|
|
static bool GetObjectHitKnockdown(unsigned int index) noexcept;
|
|
|
|
|
2018-07-01 23:25:06 +00:00
|
|
|
/**
|
2019-12-08 14:14:01 +00:00
|
|
|
* \brief Check whether the object at a certain index in the read object list has been
|
|
|
|
* hit by a player.
|
|
|
|
*
|
|
|
|
* \param index The index of the object.
|
|
|
|
* \return Whether the object has been hit by a player.
|
|
|
|
*/
|
|
|
|
static bool DoesObjectHavePlayerHitting(unsigned int index) noexcept;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the player ID of the player hitting the object at a certain index in the
|
|
|
|
* read object list.
|
|
|
|
*
|
|
|
|
* \param index The index of the object.
|
|
|
|
* \return The player ID of the hitting player.
|
|
|
|
*/
|
|
|
|
static int GetObjectHittingPid(unsigned int index) noexcept;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the refId of the actor hitting the object at a certain index in the read
|
|
|
|
* object list.
|
|
|
|
*
|
|
|
|
* \param index The index of the object.
|
|
|
|
* \return The refId of the hitting actor.
|
|
|
|
*/
|
|
|
|
static const char *GetObjectHittingRefId(unsigned int index) noexcept;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the refNum of the actor hitting the object at a certain index in the read
|
|
|
|
* object list.
|
|
|
|
*
|
|
|
|
* \param index The index of the object.
|
|
|
|
* \return The refNum of the hitting actor.
|
|
|
|
*/
|
|
|
|
static unsigned int GetObjectHittingRefNum(unsigned int index) noexcept;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the mpNum of the actor hitting the object at a certain index in the read
|
|
|
|
* object list.
|
|
|
|
*
|
|
|
|
* \param index The index of the object.
|
|
|
|
* \return The mpNum of the hitting actor.
|
|
|
|
*/
|
|
|
|
static unsigned int GetObjectHittingMpNum(unsigned int index) noexcept;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the name of the actor hitting the object at a certain index in the read
|
|
|
|
* object list.
|
|
|
|
*
|
|
|
|
* \param index The index of the object.
|
|
|
|
* \return The name of the hitting actor.
|
|
|
|
*/
|
|
|
|
static const char *GetObjectHittingName(unsigned int index) noexcept;
|
|
|
|
|
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Check whether the object at a certain index in the read object list is a
|
|
|
|
* summon.
|
2018-07-01 23:25:06 +00:00
|
|
|
*
|
2018-07-02 12:54:39 +00:00
|
|
|
* Only living actors can be summoned.
|
2018-07-01 23:25:06 +00:00
|
|
|
*
|
|
|
|
* \return The summon state.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static bool GetObjectSummonState(unsigned int index) noexcept;
|
2018-07-01 23:25:06 +00:00
|
|
|
|
2019-12-01 11:32:34 +00:00
|
|
|
/**
|
|
|
|
* \brief Get the summon effect ID of the object at a certain index in the read object list.
|
|
|
|
*
|
|
|
|
* \param index The index of the object.
|
|
|
|
* \return The summon effect ID.
|
|
|
|
*/
|
|
|
|
static double GetObjectSummonEffectId(unsigned int index) noexcept;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the summon spell ID of the object at a certain index in the read object list.
|
|
|
|
*
|
|
|
|
* \param index The index of the object.
|
|
|
|
* \return The summon spell ID.
|
|
|
|
*/
|
|
|
|
static const char *GetObjectSummonSpellId(unsigned int index) noexcept;
|
|
|
|
|
2018-06-30 21:43:29 +00:00
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the summon duration of the object at a certain index in the read object list.
|
2018-06-30 21:43:29 +00:00
|
|
|
*
|
|
|
|
* Note: Returns -1 if indefinite.
|
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-06-30 21:43:29 +00:00
|
|
|
* \return The summon duration.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static double GetObjectSummonDuration(unsigned int index) noexcept;
|
2018-06-30 21:43:29 +00:00
|
|
|
|
2018-07-02 12:54:39 +00:00
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Check whether the object at a certain index in the read object list has a player
|
|
|
|
* as its summoner.
|
2018-07-02 12:54:39 +00:00
|
|
|
*
|
|
|
|
* Only living actors can be summoned.
|
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-07-02 21:53:52 +00:00
|
|
|
* \return Whether a player is the summoner of the object.
|
2018-07-02 12:54:39 +00:00
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static bool DoesObjectHavePlayerSummoner(unsigned int index) noexcept;
|
2018-07-02 12:54:39 +00:00
|
|
|
|
2018-07-04 01:26:44 +00:00
|
|
|
/**
|
|
|
|
* \brief Get the player ID of the summoner of the object at a certain index in the read object
|
2018-07-13 01:55:05 +00:00
|
|
|
* list.
|
2018-07-04 01:26:44 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-07-04 01:26:44 +00:00
|
|
|
* \return The player ID of the summoner.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static int GetObjectSummonerPid(unsigned int index) noexcept;
|
2018-07-02 21:53:52 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-05 17:26:23 +00:00
|
|
|
* \brief Get the refId of the actor summoner of the object at a certain index in the read object
|
2018-07-13 01:55:05 +00:00
|
|
|
* list.
|
2018-07-02 21:53:52 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-07-04 01:26:44 +00:00
|
|
|
* \return The refId of the summoner.
|
2018-07-02 21:53:52 +00:00
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static const char *GetObjectSummonerRefId(unsigned int index) noexcept;
|
2018-07-02 21:53:52 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-13 01:12:03 +00:00
|
|
|
* \brief Get the refNum of the actor summoner of the object at a certain index in the read object
|
2018-07-13 01:55:05 +00:00
|
|
|
* list.
|
2018-07-02 21:53:52 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-07-13 01:12:03 +00:00
|
|
|
* \return The refNum of the summoner.
|
2018-07-02 21:53:52 +00:00
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static unsigned int GetObjectSummonerRefNum(unsigned int index) noexcept;
|
2018-07-02 21:53:52 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the mpNum of the actor summoner of the object at a certain index in the read object list.
|
2018-07-02 21:53:52 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-07-04 01:26:44 +00:00
|
|
|
* \return The mpNum of the summoner.
|
2018-07-02 21:53:52 +00:00
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static unsigned int GetObjectSummonerMpNum(unsigned int index) noexcept;
|
2018-07-02 21:53:52 +00:00
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the X position of the object at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The X position.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static double GetObjectPosX(unsigned int index) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the Y position of the object at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The Y position.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static double GetObjectPosY(unsigned int index) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the Z position at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The Z position.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static double GetObjectPosZ(unsigned int index) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the X rotation of the object at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The X rotation.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static double GetObjectRotX(unsigned int index) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the Y rotation of the object at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The Y rotation.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static double GetObjectRotY(unsigned int index) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the Z rotation of the object at a certain index in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The Z rotation.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static double GetObjectRotZ(unsigned int index) noexcept;
|
2017-01-29 11:21:41 +00:00
|
|
|
|
2018-07-07 14:09:57 +00:00
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Get the videoFilename of the object at a certain index in the read object list.
|
2018-07-07 14:09:57 +00:00
|
|
|
*
|
|
|
|
* \return The videoFilename.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static const char *GetVideoFilename(unsigned int index) noexcept;
|
2018-07-07 14:09:57 +00:00
|
|
|
|
2019-09-19 05:46:54 +00:00
|
|
|
static const char *GetScriptVariableName(unsigned int index) noexcept;
|
|
|
|
static int GetScriptVariableShortValue(unsigned int index) noexcept;
|
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
|
|
|
* \brief Get the number of container item indexes of the object at a certain index in the
|
2018-07-13 01:55:05 +00:00
|
|
|
* read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return The number of container item indexes.
|
|
|
|
*/
|
2017-02-17 16:33:20 +00:00
|
|
|
static unsigned int GetContainerChangesSize(unsigned int objectIndex) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the refId of the container item at a certain itemIndex in the container changes
|
2018-07-13 01:55:05 +00:00
|
|
|
* of the object at a certain objectIndex in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \param objectIndex The index of the object.
|
|
|
|
* \param itemIndex The index of the container item.
|
|
|
|
* \return The refId.
|
|
|
|
*/
|
2017-02-17 16:33:20 +00:00
|
|
|
static const char *GetContainerItemRefId(unsigned int objectIndex, unsigned int itemIndex) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the item count of the container item at a certain itemIndex in the container
|
2018-07-13 01:55:05 +00:00
|
|
|
* changes of the object at a certain objectIndex in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \param objectIndex The index of the object.
|
|
|
|
* \param itemIndex The index of the container item.
|
|
|
|
* \return The item count.
|
|
|
|
*/
|
2017-02-17 16:33:20 +00:00
|
|
|
static int GetContainerItemCount(unsigned int objectIndex, unsigned int itemIndex) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Get the charge of the container item at a certain itemIndex in the container changes
|
2018-07-13 01:55:05 +00:00
|
|
|
* of the object at a certain objectIndex in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \param objectIndex The index of the object.
|
|
|
|
* \param itemIndex The index of the container item.
|
|
|
|
* \return The charge.
|
|
|
|
*/
|
2017-02-17 16:33:20 +00:00
|
|
|
static int GetContainerItemCharge(unsigned int objectIndex, unsigned int itemIndex) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
2017-12-23 11:16:38 +00:00
|
|
|
/**
|
|
|
|
* \brief Get the enchantment charge of the container item at a certain itemIndex in the container changes
|
2018-07-13 01:55:05 +00:00
|
|
|
* of the object at a certain objectIndex in the read object list.
|
2017-12-23 11:16:38 +00:00
|
|
|
*
|
|
|
|
* \param objectIndex The index of the object.
|
|
|
|
* \param itemIndex The index of the container item.
|
|
|
|
* \return The enchantment charge.
|
|
|
|
*/
|
2018-01-17 06:09:57 +00:00
|
|
|
static double GetContainerItemEnchantmentCharge(unsigned int objectIndex, unsigned int itemIndex) noexcept;
|
2017-12-23 11:16:38 +00:00
|
|
|
|
2018-07-26 19:37:04 +00:00
|
|
|
/**
|
|
|
|
* \brief Get the soul of the container item at a certain itemIndex in the container changes
|
|
|
|
* of the object at a certain objectIndex in the read object list.
|
|
|
|
*
|
|
|
|
* \param objectIndex The index of the object.
|
|
|
|
* \param itemIndex The index of the container item.
|
|
|
|
* \return The soul.
|
|
|
|
*/
|
|
|
|
static const char *GetContainerItemSoul(unsigned int objectIndex, unsigned int itemIndex) noexcept;
|
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
|
|
|
* \brief Get the action count of the container item at a certain itemIndex in the container
|
2018-07-13 01:55:05 +00:00
|
|
|
* changes of the object at a certain objectIndex in the read object list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \param objectIndex The index of the object.
|
|
|
|
* \param itemIndex The index of the container item.
|
|
|
|
* \return The action count.
|
|
|
|
*/
|
2017-02-18 22:11:09 +00:00
|
|
|
static int GetContainerItemActionCount(unsigned int objectIndex, unsigned int itemIndex) noexcept;
|
2017-02-17 16:33:20 +00:00
|
|
|
|
2018-06-26 13:56:08 +00:00
|
|
|
/**
|
2018-07-13 01:55:05 +00:00
|
|
|
* \brief Check whether the object at a certain index in the read object list has a container.
|
2018-06-26 13:56:08 +00:00
|
|
|
*
|
|
|
|
* Note: Only ObjectLists from ObjectPlace packets contain this information. Objects from
|
|
|
|
* received ObjectSpawn packets can always be assumed to have a container.
|
|
|
|
*
|
2018-07-24 17:14:51 +00:00
|
|
|
* \param index The index of the object.
|
2018-06-26 13:56:08 +00:00
|
|
|
* \return Whether the object has a container.
|
|
|
|
*/
|
2018-07-24 17:14:51 +00:00
|
|
|
static bool DoesObjectHaveContainer(unsigned int index) noexcept;
|
2018-06-26 13:56:08 +00:00
|
|
|
|
2020-02-27 12:53:03 +00:00
|
|
|
/**
|
|
|
|
* \brief Check whether the object at a certain index in the read object list has been
|
|
|
|
* dropped by a player.
|
|
|
|
*
|
|
|
|
* Note: Only ObjectLists from ObjectPlace packets contain this information.
|
|
|
|
*
|
|
|
|
* \param index The index of the object.
|
|
|
|
* \return Whether the object has been dropped by a player.
|
|
|
|
*/
|
|
|
|
static bool IsObjectDroppedByPlayer(unsigned int index) noexcept;
|
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the cell of the temporary object list stored on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* The cell is determined to be an exterior cell if it fits the pattern of a number followed
|
|
|
|
* by a comma followed by another number.
|
|
|
|
*
|
2017-07-25 15:07:09 +00:00
|
|
|
* \param cellDescription The description of the cell.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return void
|
|
|
|
*/
|
2018-05-12 21:42:24 +00:00
|
|
|
static void SetObjectListCell(const char* cellDescription) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the action type of the temporary object list stored on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \param action The action type (0 for SET, 1 for ADD, 2 for REMOVE, 3 for REQUEST).
|
|
|
|
* \return void
|
|
|
|
*/
|
2018-05-12 21:42:24 +00:00
|
|
|
static void SetObjectListAction(unsigned char action) noexcept;
|
2017-02-17 14:24:40 +00:00
|
|
|
|
2017-11-22 22:21:47 +00:00
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the console command of the temporary object list stored on the server.
|
2017-11-22 22:21:47 +00:00
|
|
|
*
|
2018-05-12 21:42:24 +00:00
|
|
|
* When sent, the command will run once on every object added to the object list. If no objects
|
2017-11-22 22:21:47 +00:00
|
|
|
* have been added, it will run once without any object reference.
|
|
|
|
*
|
|
|
|
* \param consoleCommand The console command.
|
|
|
|
* \return void
|
|
|
|
*/
|
2018-05-12 21:42:24 +00:00
|
|
|
static void SetObjectListConsoleCommand(const char* consoleCommand) noexcept;
|
2017-11-22 22:21:47 +00:00
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the refId of the temporary object stored on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \param refId The refId.
|
|
|
|
* \return void
|
|
|
|
*/
|
2017-02-17 14:24:40 +00:00
|
|
|
static void SetObjectRefId(const char* refId) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-07-13 01:12:03 +00:00
|
|
|
* \brief Set the refNum of the temporary object stored on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-07-13 01:12:03 +00:00
|
|
|
* Every object loaded from .ESM and .ESP data files has a unique refNum which needs to be
|
2017-07-23 18:59:33 +00:00
|
|
|
* retained to refer to it in packets.
|
|
|
|
*
|
2018-07-13 01:12:03 +00:00
|
|
|
* On the other hand, objects placed or spawned via the server should always have a refNum
|
2017-07-23 18:59:33 +00:00
|
|
|
* of 0.
|
|
|
|
*
|
2018-07-13 01:12:03 +00:00
|
|
|
* \param refNum The refNum.
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return void
|
|
|
|
*/
|
2018-07-13 01:12:03 +00:00
|
|
|
static void SetObjectRefNum(int refNum) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the mpNum of the temporary object stored on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* Every object placed or spawned via the server is assigned an mpNum by incrementing the last
|
|
|
|
* mpNum stored on the server. Scripts should take care to ensure that mpNums are kept unique
|
|
|
|
* for these objects.
|
|
|
|
*
|
|
|
|
* Objects loaded from .ESM and .ESP data files should always have an mpNum of 0, because they
|
2018-07-13 01:12:03 +00:00
|
|
|
* have unique refNumes instead.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \param mpNum The mpNum.
|
|
|
|
* \return void
|
|
|
|
*/
|
2017-04-04 06:30:17 +00:00
|
|
|
static void SetObjectMpNum(int mpNum) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the object count of the temporary object stored on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* This determines the quantity of an object, with the exception of gold.
|
|
|
|
*
|
|
|
|
* \param count The object count.
|
|
|
|
* \return void
|
|
|
|
*/
|
2017-02-17 14:24:40 +00:00
|
|
|
static void SetObjectCount(int count) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the charge of the temporary object stored on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* Object durabilities are set through this value.
|
|
|
|
*
|
|
|
|
* \param charge The charge.
|
|
|
|
* \return void
|
|
|
|
*/
|
2017-02-17 21:11:38 +00:00
|
|
|
static void SetObjectCharge(int charge) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
2017-12-23 11:16:38 +00:00
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the enchantment charge of the temporary object stored on the server.
|
2017-12-23 11:16:38 +00:00
|
|
|
*
|
|
|
|
* Object durabilities are set through this value.
|
|
|
|
*
|
|
|
|
* \param charge The enchantment charge.
|
|
|
|
* \return void
|
|
|
|
*/
|
2018-01-17 06:09:57 +00:00
|
|
|
static void SetObjectEnchantmentCharge(double enchantmentCharge) noexcept;
|
2017-12-23 11:16:38 +00:00
|
|
|
|
2018-07-26 19:37:04 +00:00
|
|
|
/**
|
|
|
|
* \brief Set the soul of the temporary object stored on the server.
|
|
|
|
*
|
|
|
|
* \param refId The soul.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetObjectSoul(const char* soul) noexcept;
|
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the gold value of the temporary object stored on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* This is used solely to set the gold value for gold. It has no effect on other objects.
|
|
|
|
*
|
|
|
|
* \param goldValue The gold value.
|
|
|
|
* \return void
|
|
|
|
*/
|
2017-02-17 14:24:40 +00:00
|
|
|
static void SetObjectGoldValue(int goldValue) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the scale of the temporary object stored on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* Objects are smaller or larger than their default size based on their scale.
|
|
|
|
*
|
|
|
|
* \param scale The scale.
|
|
|
|
* \return void
|
|
|
|
*/
|
2017-02-17 14:24:40 +00:00
|
|
|
static void SetObjectScale(double scale) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the object state of the temporary object stored on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* Objects are enabled or disabled based on their object state.
|
|
|
|
*
|
|
|
|
* \param objectState The object state.
|
|
|
|
* \return void
|
|
|
|
*/
|
2017-07-13 06:46:30 +00:00
|
|
|
static void SetObjectState(bool objectState) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the lock level of the temporary object stored on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \param lockLevel The lock level.
|
|
|
|
* \return void
|
|
|
|
*/
|
2017-02-17 14:24:40 +00:00
|
|
|
static void SetObjectLockLevel(int lockLevel) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the disarm state of the temporary object stored on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \param disarmState The disarmState.
|
|
|
|
* \return void
|
|
|
|
*/
|
2017-05-25 22:28:43 +00:00
|
|
|
static void SetObjectDisarmState(bool disarmState) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
2020-02-27 12:53:03 +00:00
|
|
|
/**
|
|
|
|
* \brief Set the droppedByPlayer state of the temporary object stored on the server.
|
|
|
|
*
|
|
|
|
* \param droppedByPlayer Whether the object has been dropped by a player or not.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetObjectDroppedByPlayerState(bool dropedByPlayerState) noexcept;
|
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the position of the temporary object stored on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \param x The X position.
|
|
|
|
* \param y The Y position.
|
|
|
|
* \param z The Z position.
|
|
|
|
* \return void
|
|
|
|
*/
|
2017-02-17 14:24:40 +00:00
|
|
|
static void SetObjectPosition(double x, double y, double z) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the rotation of the temporary object stored on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \param x The X rotation.
|
|
|
|
* \param y The Y rotation.
|
|
|
|
* \param z The Z rotation.
|
|
|
|
* \return void
|
|
|
|
*/
|
2017-02-17 14:24:40 +00:00
|
|
|
static void SetObjectRotation(double x, double y, double z) noexcept;
|
|
|
|
|
2020-03-14 18:17:00 +00:00
|
|
|
static void SetObjectSound(const char* soundId, double volume, double pitch) noexcept;
|
|
|
|
|
2019-11-30 18:44:27 +00:00
|
|
|
/**
|
|
|
|
* \brief Set the summon state of the temporary object stored on the server.
|
|
|
|
*
|
|
|
|
* This only affects living actors and determines whether they are summons of another
|
|
|
|
* living actor.
|
|
|
|
*
|
|
|
|
* \param summonState The summon state.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetObjectSummonState(bool summonState) noexcept;
|
|
|
|
|
2019-12-01 11:32:34 +00:00
|
|
|
/**
|
|
|
|
* \brief Set the summon effect ID of the temporary object stored on the server.
|
|
|
|
*
|
|
|
|
* \param summonEffectId The summon effect ID.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetObjectSummonEffectId(int summonEffectId) noexcept;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Set the summon spell ID of the temporary object stored on the server.
|
|
|
|
*
|
|
|
|
* \param summonSpellId The summon spell ID.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetObjectSummonSpellId(const char* summonSpellId) noexcept;
|
|
|
|
|
2019-11-30 18:44:27 +00:00
|
|
|
/**
|
|
|
|
* \brief Set the summon duration of the temporary object stored on the server.
|
|
|
|
*
|
|
|
|
* \param summonDuration The summon duration.
|
|
|
|
* \return void
|
|
|
|
*/
|
2019-12-01 08:41:07 +00:00
|
|
|
static void SetObjectSummonDuration(double summonDuration) noexcept;
|
2019-11-30 18:44:27 +00:00
|
|
|
|
2019-12-01 08:12:13 +00:00
|
|
|
/**
|
|
|
|
* \brief Set the player ID of the summoner of the temporary object stored on the server.
|
|
|
|
*
|
|
|
|
* \param pid The player ID of the summoner.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetObjectSummonerPid(unsigned short pid) noexcept;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Set the refNum of the actor summoner of the temporary object stored on the server.
|
|
|
|
*
|
|
|
|
* \param refNum The refNum of the summoner.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetObjectSummonerRefNum(int refNum) noexcept;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Set the mpNum of the actor summoner of the temporary object stored on the server.
|
|
|
|
*
|
|
|
|
* \param mpNum The mpNum of the summoner.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetObjectSummonerMpNum(int mpNum) noexcept;
|
|
|
|
|
2018-10-22 13:25:50 +00:00
|
|
|
/**
|
|
|
|
* \brief Set the player ID of the player activating the temporary object stored on the
|
|
|
|
* server. Currently only used for ObjectActivate packets.
|
|
|
|
*
|
|
|
|
* \param pid The pid of the player.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetObjectActivatingPid(unsigned short pid) noexcept;
|
|
|
|
|
2018-04-29 19:32:22 +00:00
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the door state of the temporary object stored on the server.
|
2018-04-29 19:32:22 +00:00
|
|
|
*
|
|
|
|
* Doors are open or closed based on their door state.
|
|
|
|
*
|
|
|
|
* \param doorState The door state.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetObjectDoorState(int doorState) noexcept;
|
|
|
|
|
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the teleport state of the temporary object stored on the server.
|
2018-04-29 19:32:22 +00:00
|
|
|
*
|
|
|
|
* If a door's teleport state is true, interacting with the door teleports a player to its
|
|
|
|
* destination. If it's false, it opens and closes like a regular door.
|
|
|
|
*
|
|
|
|
* \param teleportState The teleport state.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetObjectDoorTeleportState(bool teleportState) noexcept;
|
|
|
|
|
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the door destination cell of the temporary object stored on the server.
|
2018-04-29 19:32:22 +00:00
|
|
|
*
|
|
|
|
* The cell is determined to be an exterior cell if it fits the pattern of a number followed
|
|
|
|
* by a comma followed by another number.
|
|
|
|
*
|
|
|
|
* \param cellDescription The description of the cell.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetObjectDoorDestinationCell(const char* cellDescription) noexcept;
|
|
|
|
|
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the door destination position of the temporary object stored on the server.
|
2018-04-29 19:32:22 +00:00
|
|
|
*
|
|
|
|
* \param x The X position.
|
|
|
|
* \param y The Y position.
|
|
|
|
* \param z The Z position.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetObjectDoorDestinationPosition(double x, double y, double z) noexcept;
|
|
|
|
|
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set the door destination rotation of the temporary object stored on the server.
|
2018-04-29 19:32:22 +00:00
|
|
|
*
|
|
|
|
* Note: Because this sets the rotation a player will have upon using the door, and rotation
|
|
|
|
* on the Y axis has no effect on players, the Y value has been omitted as an argument.
|
|
|
|
*
|
|
|
|
* \param x The X rotation.
|
|
|
|
* \param z The Z rotation.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetObjectDoorDestinationRotation(double x, double z) noexcept;
|
|
|
|
|
2019-09-19 05:46:54 +00:00
|
|
|
static void SetScriptVariableName(const char* varName) noexcept;
|
|
|
|
static void SetScriptVariableShortValue(int shortVal) noexcept;
|
|
|
|
|
2017-11-22 22:21:47 +00:00
|
|
|
/**
|
2018-05-12 21:42:24 +00:00
|
|
|
* \brief Set a player as the object in the temporary object stored on the server.
|
2017-11-22 22:21:47 +00:00
|
|
|
* Currently only used for ConsoleCommand packets.
|
|
|
|
*
|
|
|
|
* \param pid The pid of the player.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetPlayerAsObject(unsigned short pid) noexcept;
|
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
|
|
|
* \brief Set the refId of the temporary container item stored on the server.
|
|
|
|
*
|
|
|
|
* \param refId The refId.
|
|
|
|
* \return void
|
|
|
|
*/
|
2017-02-17 21:11:38 +00:00
|
|
|
static void SetContainerItemRefId(const char* refId) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Set the item count of the temporary container item stored on the server.
|
|
|
|
*
|
|
|
|
* \param count The item count.
|
|
|
|
* \return void
|
|
|
|
*/
|
2017-02-17 21:11:38 +00:00
|
|
|
static void SetContainerItemCount(int count) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Set the charge of the temporary container item stored on the server.
|
|
|
|
*
|
|
|
|
* \param charge The charge.
|
|
|
|
* \return void
|
|
|
|
*/
|
2017-02-17 21:11:38 +00:00
|
|
|
static void SetContainerItemCharge(int charge) noexcept;
|
|
|
|
|
2017-12-23 11:16:38 +00:00
|
|
|
/**
|
|
|
|
* \brief Set the enchantment charge of the temporary container item stored on the server.
|
|
|
|
*
|
|
|
|
* \param charge The enchantment charge.
|
|
|
|
* \return void
|
|
|
|
*/
|
2018-01-17 06:09:57 +00:00
|
|
|
static void SetContainerItemEnchantmentCharge(double enchantmentCharge) noexcept;
|
2017-12-23 11:16:38 +00:00
|
|
|
|
2018-07-26 19:37:04 +00:00
|
|
|
/**
|
|
|
|
* \brief Set the soul of the temporary container item stored on the server.
|
|
|
|
*
|
|
|
|
* \param refId The soul.
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SetContainerItemSoul(const char* soul) noexcept;
|
|
|
|
|
[General] Rework container sync to prevent item duping
A main priority in TES3MP development is to avoid making major changes to OpenMW code, so as to avoid merge conflicts in the future. Whenever avoiding potential conflicts seems especially difficult for the proper implementation of a particular multiplayer feature, that multiplayer feature is often put off until later or partially implemented with the intent of being revisited in the future.
Container sync is the perfect example. Previously, the OpenMW code for container actions was kept exactly as it was, with clients unilaterally accepting their own container changes as per singleplayer-specific code, with only the addition that clients sent container packets every time they made a change in a container, packets which were then forwarded unquestioningly by the server to other players. This meant that two players clicking on the same item in a container at the same time both managed to take it, thus duplicating the item.
Immediately after the packets were already forwarded, server scripts were able to check for incorrect changes, such as the removal of more items than should have existed in a container, but they had to send their own packets that attempted to fix what had already been accepted on the initial client and then forwarded to all clients, which was quite onerous in some scenarios, such as when a player on a slow connection immediately dropped items in the world after taking them from a container (which is why the default TES3MP serverside scripts made no attempt at sending corrective packets at all, preferring to expect the matter to be solved in a later C++ implementation).
This commit fixes item duping in containers by preventing container actions from initially running on clients and by ending the automatic forwarding of container packets by the server. Instead, clients now send container packets that act as requests for container actions, and serverside scripts have to forward these requests themselves. In other words, without a matching Container event in the server's Lua scripts, players are completely unable to affect containers for themselves or for others.
To forward a received Container packet, the following line must be used in a Container event in the Lua scripts:
tes3mp.SendContainer(true, true)
When an invalid action count is used in a container request, the serverside scripts can amend it using the following new function:
tes3mp.SetReceivedContainerItemActionCount(objectIndex, itemIndex, actionCount)
Thus, the serverside scripts are able to allow only container actions that are correct based on their own recorded contents for that container.
The OpenMW code allowing unilateral container actions in mwgui/container.cpp is now prevented from executing. When a player's container request is returned to them, code in mwmp/WorldEvent.cpp simulates those container actions instead.
2018-03-26 16:27:36 +00:00
|
|
|
/**
|
|
|
|
* \brief Set the action count of the container item at a certain itemIndex in the container
|
2018-06-05 11:19:06 +00:00
|
|
|
* changes of the object at a certain objectIndex in the object list stored on the server.
|
[General] Rework container sync to prevent item duping
A main priority in TES3MP development is to avoid making major changes to OpenMW code, so as to avoid merge conflicts in the future. Whenever avoiding potential conflicts seems especially difficult for the proper implementation of a particular multiplayer feature, that multiplayer feature is often put off until later or partially implemented with the intent of being revisited in the future.
Container sync is the perfect example. Previously, the OpenMW code for container actions was kept exactly as it was, with clients unilaterally accepting their own container changes as per singleplayer-specific code, with only the addition that clients sent container packets every time they made a change in a container, packets which were then forwarded unquestioningly by the server to other players. This meant that two players clicking on the same item in a container at the same time both managed to take it, thus duplicating the item.
Immediately after the packets were already forwarded, server scripts were able to check for incorrect changes, such as the removal of more items than should have existed in a container, but they had to send their own packets that attempted to fix what had already been accepted on the initial client and then forwarded to all clients, which was quite onerous in some scenarios, such as when a player on a slow connection immediately dropped items in the world after taking them from a container (which is why the default TES3MP serverside scripts made no attempt at sending corrective packets at all, preferring to expect the matter to be solved in a later C++ implementation).
This commit fixes item duping in containers by preventing container actions from initially running on clients and by ending the automatic forwarding of container packets by the server. Instead, clients now send container packets that act as requests for container actions, and serverside scripts have to forward these requests themselves. In other words, without a matching Container event in the server's Lua scripts, players are completely unable to affect containers for themselves or for others.
To forward a received Container packet, the following line must be used in a Container event in the Lua scripts:
tes3mp.SendContainer(true, true)
When an invalid action count is used in a container request, the serverside scripts can amend it using the following new function:
tes3mp.SetReceivedContainerItemActionCount(objectIndex, itemIndex, actionCount)
Thus, the serverside scripts are able to allow only container actions that are correct based on their own recorded contents for that container.
The OpenMW code allowing unilateral container actions in mwgui/container.cpp is now prevented from executing. When a player's container request is returned to them, code in mwmp/WorldEvent.cpp simulates those container actions instead.
2018-03-26 16:27:36 +00:00
|
|
|
*
|
|
|
|
* When resending a received Container packet, this allows you to correct the amount of items
|
|
|
|
* removed from a container by a player when it conflicts with what other players have already
|
|
|
|
* taken.
|
|
|
|
*
|
|
|
|
* \param objectIndex The index of the object.
|
|
|
|
* \param itemIndex The index of the container item.
|
|
|
|
* \param actionCount The action count.
|
|
|
|
* \return void
|
|
|
|
*/
|
2018-06-05 11:19:06 +00:00
|
|
|
static void SetContainerItemActionCountByIndex(unsigned int objectIndex, unsigned int itemIndex, int actionCount) noexcept;
|
[General] Rework container sync to prevent item duping
A main priority in TES3MP development is to avoid making major changes to OpenMW code, so as to avoid merge conflicts in the future. Whenever avoiding potential conflicts seems especially difficult for the proper implementation of a particular multiplayer feature, that multiplayer feature is often put off until later or partially implemented with the intent of being revisited in the future.
Container sync is the perfect example. Previously, the OpenMW code for container actions was kept exactly as it was, with clients unilaterally accepting their own container changes as per singleplayer-specific code, with only the addition that clients sent container packets every time they made a change in a container, packets which were then forwarded unquestioningly by the server to other players. This meant that two players clicking on the same item in a container at the same time both managed to take it, thus duplicating the item.
Immediately after the packets were already forwarded, server scripts were able to check for incorrect changes, such as the removal of more items than should have existed in a container, but they had to send their own packets that attempted to fix what had already been accepted on the initial client and then forwarded to all clients, which was quite onerous in some scenarios, such as when a player on a slow connection immediately dropped items in the world after taking them from a container (which is why the default TES3MP serverside scripts made no attempt at sending corrective packets at all, preferring to expect the matter to be solved in a later C++ implementation).
This commit fixes item duping in containers by preventing container actions from initially running on clients and by ending the automatic forwarding of container packets by the server. Instead, clients now send container packets that act as requests for container actions, and serverside scripts have to forward these requests themselves. In other words, without a matching Container event in the server's Lua scripts, players are completely unable to affect containers for themselves or for others.
To forward a received Container packet, the following line must be used in a Container event in the Lua scripts:
tes3mp.SendContainer(true, true)
When an invalid action count is used in a container request, the serverside scripts can amend it using the following new function:
tes3mp.SetReceivedContainerItemActionCount(objectIndex, itemIndex, actionCount)
Thus, the serverside scripts are able to allow only container actions that are correct based on their own recorded contents for that container.
The OpenMW code allowing unilateral container actions in mwgui/container.cpp is now prevented from executing. When a player's container request is returned to them, code in mwmp/WorldEvent.cpp simulates those container actions instead.
2018-03-26 16:27:36 +00:00
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
2018-07-26 19:37:04 +00:00
|
|
|
* \brief Add a copy of the server's temporary object to the server's currently stored object
|
|
|
|
* list.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
2018-05-12 21:42:24 +00:00
|
|
|
* In the process, the server's temporary object will automatically be cleared so a new
|
2017-07-23 18:59:33 +00:00
|
|
|
* one can be set up.
|
|
|
|
*
|
|
|
|
* \return void
|
|
|
|
*/
|
2018-05-12 21:42:24 +00:00
|
|
|
static void AddObject() noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Add a copy of the server's temporary container item to the container changes of the
|
2018-05-12 21:42:24 +00:00
|
|
|
* server's temporary object.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* In the process, the server's temporary container item will automatically be cleared so a new
|
|
|
|
* one can be set up.
|
|
|
|
*
|
|
|
|
* \return void
|
|
|
|
*/
|
2017-02-17 21:11:38 +00:00
|
|
|
static void AddContainerItem() noexcept;
|
2017-02-14 17:31:56 +00:00
|
|
|
|
2018-07-15 00:16:04 +00:00
|
|
|
/**
|
|
|
|
* \brief Send an ObjectActivate packet.
|
|
|
|
*
|
|
|
|
* \param sendToOtherPlayers Whether this packet should be sent to players other than the
|
|
|
|
* player attached to the packet (false by default).
|
|
|
|
* \param skipAttachedPlayer Whether the packet should skip being sent to the player attached
|
|
|
|
* to the packet (false by default).
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SendObjectActivate(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
|
|
|
* \brief Send an ObjectPlace packet.
|
|
|
|
*
|
2018-07-07 15:29:31 +00:00
|
|
|
* \param sendToOtherPlayers Whether this packet should be sent to players other than the
|
|
|
|
* player attached to the packet (false by default).
|
2018-07-07 17:16:36 +00:00
|
|
|
* \param skipAttachedPlayer Whether the packet should skip being sent to the player attached
|
|
|
|
* to the packet (false by default).
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return void
|
|
|
|
*/
|
2018-07-07 17:08:59 +00:00
|
|
|
static void SendObjectPlace(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Send an ObjectSpawn packet.
|
|
|
|
*
|
2018-07-07 15:29:31 +00:00
|
|
|
* \param sendToOtherPlayers Whether this packet should be sent to players other than the
|
|
|
|
* player attached to the packet (false by default).
|
2018-07-07 17:16:36 +00:00
|
|
|
* \param skipAttachedPlayer Whether the packet should skip being sent to the player attached
|
|
|
|
* to the packet (false by default).
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return void
|
|
|
|
*/
|
2018-07-07 17:08:59 +00:00
|
|
|
static void SendObjectSpawn(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Send an ObjectDelete packet.
|
|
|
|
*
|
2017-12-30 19:52:30 +00:00
|
|
|
* \param broadcast Whether this packet should be sent only to the player for whom the current
|
2018-05-12 21:42:24 +00:00
|
|
|
* object list was initialized or to everyone on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \return void
|
|
|
|
*/
|
2018-07-07 17:08:59 +00:00
|
|
|
static void SendObjectDelete(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Send an ObjectLock packet.
|
|
|
|
*
|
2018-07-07 15:29:31 +00:00
|
|
|
* \param sendToOtherPlayers Whether this packet should be sent to players other than the
|
|
|
|
* player attached to the packet (false by default).
|
2018-07-07 17:16:36 +00:00
|
|
|
* \param skipAttachedPlayer Whether the packet should skip being sent to the player attached
|
|
|
|
* to the packet (false by default).
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return void
|
|
|
|
*/
|
2018-07-07 17:08:59 +00:00
|
|
|
static void SendObjectLock(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
2020-01-23 10:50:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Send an ObjectRestock packet.
|
|
|
|
*
|
|
|
|
* \param sendToOtherPlayers Whether this packet should be sent to players other than the
|
|
|
|
* player attached to the packet (false by default).
|
|
|
|
* \param skipAttachedPlayer Whether the packet should skip being sent to the player attached
|
|
|
|
* to the packet (false by default).
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SendObjectRestock(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Send an ObjectTrap packet.
|
|
|
|
*
|
2017-12-30 19:52:30 +00:00
|
|
|
* \param broadcast Whether this packet should be sent only to the player for whom the current
|
2018-05-12 21:42:24 +00:00
|
|
|
* object list was initialized or to everyone on the server.
|
2017-07-23 18:59:33 +00:00
|
|
|
*
|
|
|
|
* \return void
|
|
|
|
*/
|
2018-07-07 17:08:59 +00:00
|
|
|
static void SendObjectTrap(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Send an ObjectScale packet.
|
|
|
|
*
|
2018-07-07 15:29:31 +00:00
|
|
|
* \param sendToOtherPlayers Whether this packet should be sent to players other than the
|
|
|
|
* player attached to the packet (false by default).
|
2018-07-07 17:16:36 +00:00
|
|
|
* \param skipAttachedPlayer Whether the packet should skip being sent to the player attached
|
|
|
|
* to the packet (false by default).
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return void
|
|
|
|
*/
|
2018-07-07 17:08:59 +00:00
|
|
|
static void SendObjectScale(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
2020-02-29 16:15:41 +00:00
|
|
|
/**
|
|
|
|
* \brief Send an ObjectSound packet.
|
|
|
|
*
|
|
|
|
* \param sendToOtherPlayers Whether this packet should be sent to players other than the
|
|
|
|
* player attached to the packet (false by default).
|
|
|
|
* \param skipAttachedPlayer Whether the packet should skip being sent to the player attached
|
|
|
|
* to the packet (false by default).
|
|
|
|
* \return void
|
|
|
|
*/
|
|
|
|
static void SendObjectSound(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
|
|
|
* \brief Send an ObjectState packet.
|
|
|
|
*
|
2018-07-07 15:29:31 +00:00
|
|
|
* \param sendToOtherPlayers Whether this packet should be sent to players other than the
|
|
|
|
* player attached to the packet (false by default).
|
2018-07-07 17:16:36 +00:00
|
|
|
* \param skipAttachedPlayer Whether the packet should skip being sent to the player attached
|
|
|
|
* to the packet (false by default).
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return void
|
|
|
|
*/
|
2018-07-07 17:08:59 +00:00
|
|
|
static void SendObjectState(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Send a DoorState packet.
|
|
|
|
*
|
2018-07-07 15:29:31 +00:00
|
|
|
* \param sendToOtherPlayers Whether this packet should be sent to players other than the
|
|
|
|
* player attached to the packet (false by default).
|
2018-07-07 17:16:36 +00:00
|
|
|
* \param skipAttachedPlayer Whether the packet should skip being sent to the player attached
|
|
|
|
* to the packet (false by default).
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return void
|
|
|
|
*/
|
2018-07-07 17:08:59 +00:00
|
|
|
static void SendDoorState(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
2017-07-23 18:59:33 +00:00
|
|
|
|
2018-04-29 19:32:22 +00:00
|
|
|
/**
|
|
|
|
* \brief Send a DoorDestination packet.
|
|
|
|
*
|
2018-07-07 15:29:31 +00:00
|
|
|
* \param sendToOtherPlayers Whether this packet should be sent to players other than the
|
|
|
|
* player attached to the packet (false by default).
|
2018-07-07 17:16:36 +00:00
|
|
|
* \param skipAttachedPlayer Whether the packet should skip being sent to the player attached
|
|
|
|
* to the packet (false by default).
|
2018-04-29 19:32:22 +00:00
|
|
|
* \return void
|
|
|
|
*/
|
2018-07-07 17:08:59 +00:00
|
|
|
static void SendDoorDestination(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
2018-04-29 19:32:22 +00:00
|
|
|
|
2017-07-23 18:59:33 +00:00
|
|
|
/**
|
|
|
|
* \brief Send a Container packet.
|
|
|
|
*
|
2018-07-07 15:29:31 +00:00
|
|
|
* \param sendToOtherPlayers Whether this packet should be sent to players other than the
|
|
|
|
* player attached to the packet (false by default).
|
2018-07-07 17:16:36 +00:00
|
|
|
* \param skipAttachedPlayer Whether the packet should skip being sent to the player attached
|
|
|
|
* to the packet (false by default).
|
2017-07-23 18:59:33 +00:00
|
|
|
* \return void
|
|
|
|
*/
|
2018-07-07 17:08:59 +00:00
|
|
|
static void SendContainer(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
2017-01-28 14:22:30 +00:00
|
|
|
|
2018-07-07 14:09:57 +00:00
|
|
|
/**
|
|
|
|
* \brief Send a VideoPlay packet.
|
|
|
|
*
|
2018-07-07 15:29:31 +00:00
|
|
|
* \param sendToOtherPlayers Whether this packet should be sent to players other than the
|
|
|
|
* player attached to the packet (false by default).
|
2018-07-07 17:16:36 +00:00
|
|
|
* \param skipAttachedPlayer Whether the packet should skip being sent to the player attached
|
|
|
|
* to the packet (false by default).
|
2018-07-07 14:09:57 +00:00
|
|
|
* \return void
|
|
|
|
*/
|
2018-07-07 17:08:59 +00:00
|
|
|
static void SendVideoPlay(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
2018-07-07 14:09:57 +00:00
|
|
|
|
2019-09-19 05:46:54 +00:00
|
|
|
static void SendScriptGlobalShort(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
|
|
|
|
2017-11-22 22:21:47 +00:00
|
|
|
/**
|
|
|
|
* \brief Send a ConsoleCommand packet.
|
|
|
|
*
|
2018-07-07 15:29:31 +00:00
|
|
|
* \param sendToOtherPlayers Whether this packet should be sent to players other than the
|
|
|
|
* player attached to the packet (false by default).
|
2018-07-07 17:16:36 +00:00
|
|
|
* \param skipAttachedPlayer Whether the packet should skip being sent to the player attached
|
|
|
|
* to the packet (false by default).
|
2017-11-22 22:21:47 +00:00
|
|
|
* \return void
|
|
|
|
*/
|
2018-07-07 17:08:59 +00:00
|
|
|
static void SendConsoleCommand(bool sendToOtherPlayers, bool skipAttachedPlayer) noexcept;
|
2017-11-22 22:21:47 +00:00
|
|
|
|
2018-05-15 23:16:27 +00:00
|
|
|
|
|
|
|
// All methods below are deprecated versions of methods from above
|
|
|
|
|
2018-07-12 23:33:50 +00:00
|
|
|
static void ReadLastObjectList() noexcept;
|
2018-05-15 23:16:27 +00:00
|
|
|
static void ReadLastEvent() noexcept;
|
2018-06-05 11:19:06 +00:00
|
|
|
static void InitializeObjectList(unsigned short pid) noexcept;
|
2018-05-15 23:16:27 +00:00
|
|
|
static void InitializeEvent(unsigned short pid) noexcept;
|
2018-07-12 23:33:50 +00:00
|
|
|
static void CopyLastObjectListToStore() noexcept;
|
|
|
|
static unsigned int GetObjectChangesSize() noexcept;
|
2018-05-15 23:16:27 +00:00
|
|
|
static unsigned char GetEventAction() noexcept;
|
|
|
|
static unsigned char GetEventContainerSubAction() noexcept;
|
2018-07-24 17:14:51 +00:00
|
|
|
static unsigned int GetObjectRefNumIndex(unsigned int index) noexcept;
|
|
|
|
static unsigned int GetObjectSummonerRefNumIndex(unsigned int index) noexcept;
|
2018-05-15 23:16:27 +00:00
|
|
|
static void SetEventCell(const char* cellDescription) noexcept;
|
|
|
|
static void SetEventAction(unsigned char action) noexcept;
|
|
|
|
static void SetEventConsoleCommand(const char* consoleCommand) noexcept;
|
2018-07-13 01:12:03 +00:00
|
|
|
static void SetObjectRefNumIndex(int refNum) noexcept;
|
2018-05-15 23:16:27 +00:00
|
|
|
static void AddWorldObject() noexcept;
|
|
|
|
|
2016-08-30 05:24:31 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2018-05-13 01:11:05 +00:00
|
|
|
#endif //OPENMW_OBJECTAPI_HPP
|