From 54ed9a7ab448ad7054fd599aa38f721e3105353c Mon Sep 17 00:00:00 2001
From: David Cernat <davidcernat@gmail.com>
Date: Tue, 25 Oct 2016 14:07:00 +0300
Subject: [PATCH] Implement ID_OBJECT_MOVE and send it from ingame scripts

---
 apps/openmw/mwmp/Networking.cpp               | 28 ++++++++++++-
 .../mwscript/transformationextensions.cpp     | 40 ++++++++++++++++++-
 components/openmw-mp/Base/WorldEvent.hpp      |  2 +
 .../Packets/World/PacketObjectMove.cpp        | 12 ++++++
 4 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/apps/openmw/mwmp/Networking.cpp b/apps/openmw/mwmp/Networking.cpp
index b70645ea9..0bda6e76e 100644
--- a/apps/openmw/mwmp/Networking.cpp
+++ b/apps/openmw/mwmp/Networking.cpp
@@ -698,8 +698,13 @@ void Networking::ProcessWorldPacket(RakNet::Packet *packet)
     {
     case ID_OBJECT_PLACE:
     {
-        MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), event->cellRef.mRefID, 1);
+        LOG_MESSAGE_SIMPLE(Log::LOG_WARN, "%s", "Received ID_OBJECT_PLACE");
+        LOG_APPEND(Log::LOG_WARN, "- cellRef: %s, %i\n- cell: %s",
+            event->cellRef.mRefID.c_str(),
+            event->cellRef.mRefNum.mIndex,
+            event->cell.getDescription().c_str());
 
+        MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), event->cellRef.mRefID, 1);
         MWBase::Environment::get().getWorld()->placeObject(ref.getPtr(), ptrCellStore, event->cellRef.mPos);
 
         break;
@@ -788,6 +793,27 @@ void Networking::ProcessWorldPacket(RakNet::Packet *packet)
 
         break;
     }
+    case ID_OBJECT_MOVE:
+    {
+        LOG_MESSAGE_SIMPLE(Log::LOG_WARN, "%s", "Received ID_OBJECT_MOVE");
+        LOG_APPEND(Log::LOG_WARN, "- cellRef: %s, %i\n- cell: %s",
+            event->cellRef.mRefID.c_str(),
+            event->cellRef.mRefNum.mIndex,
+            event->cell.getDescription().c_str());
+
+        MWWorld::Ptr ptrFound = ptrCellStore->searchByRefNum(event->cellRef.mRefNum);
+
+        if (ptrFound)
+        {
+            LOG_MESSAGE_SIMPLE(Log::LOG_WARN, "Found %s, %i",
+                ptrFound.getCellRef().getRefId().c_str(),
+                ptrFound.getCellRef().getRefNum());
+
+            MWBase::Environment::get().getWorld()->moveObject(ptrFound, event->pos.pos[0], event->pos.pos[1], event->pos.pos[2]);
+        }
+
+        break;
+    }
     case ID_DOOR_ACTIVATE:
     {
         LOG_MESSAGE_SIMPLE(Log::LOG_WARN, "%s", "Received ID_DOOR_ACTIVATE");
diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp
index cbf514e0f..788efe0bb 100644
--- a/apps/openmw/mwscript/transformationextensions.cpp
+++ b/apps/openmw/mwscript/transformationextensions.cpp
@@ -633,12 +633,21 @@ namespace MWScript
                     float yr = ptr.getCellRef().getPosition().rot[1];
                     float zr = ptr.getCellRef().getPosition().rot[2];
 
+                    // Added by tes3mp
+                    mwmp::WorldEvent *event = mwmp::Main::get().getNetworking()->createWorldEvent();
+                    event->cell = *ptr.getCell()->getCell();
+                    event->cellRef.mRefID = ptr.getCellRef().getRefId();
+                    event->cellRef.mRefNum = ptr.getCellRef().getRefNum();
+                    event->pos.pos[0] = ptr.getCellRef().getPosition().pos[0];
+                    event->pos.pos[1] = ptr.getCellRef().getPosition().pos[1];
+                    event->pos.pos[2] = ptr.getCellRef().getPosition().pos[2];
+                    mwmp::Main::get().getNetworking()->GetWorldPacket(ID_OBJECT_MOVE)->Send(event);
+
                     MWBase::Environment::get().getWorld()->rotateObject(ptr, xr, yr, zr);
 
                     dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(ptr,
                         MWBase::Environment::get().getWorld()->moveObject(ptr, ptr.getCellRef().getPosition().pos[0],
                             ptr.getCellRef().getPosition().pos[1], ptr.getCellRef().getPosition().pos[2]));
-
                 }
         };
 
@@ -682,6 +691,21 @@ namespace MWScript
                     osg::Vec3f diff = ptr.getRefData().getBaseNode()->getAttitude() * posChange;
                     osg::Vec3f worldPos(ptr.getRefData().getPosition().asVec3());
                     worldPos += diff;
+
+                    // Added by tes3mp
+                    mwmp::WorldEvent *event = mwmp::Main::get().getNetworking()->createWorldEvent();
+                    event->cell = *ptr.getCell()->getCell();
+                    event->cellRef.mRefID = ptr.getCellRef().getRefId();
+                    event->cellRef.mRefNum = ptr.getCellRef().getRefNum();
+                    event->pos.pos[0] = worldPos.x();
+                    event->pos.pos[1] = worldPos.y();
+                    event->pos.pos[2] = worldPos.z();
+                    mwmp::Main::get().getNetworking()->GetWorldPacket(ID_OBJECT_MOVE)->Send(event);
+
+                    printf("Sending ID_OBJECT_MOVE about %s\n%i\n",
+                        event->cellRef.mRefID.c_str(),
+                        event->cellRef.mRefNum.mIndex);
+
                     MWBase::Environment::get().getWorld()->moveObject(ptr, worldPos.x(), worldPos.y(), worldPos.z());
                 }
         };
@@ -720,6 +744,20 @@ namespace MWScript
                     }
                     else
                         throw std::runtime_error ("invalid movement axis: " + axis);
+
+                    // Added by tes3mp
+                    mwmp::WorldEvent *event = mwmp::Main::get().getNetworking()->createWorldEvent();
+                    event->cell = *ptr.getCell()->getCell();
+                    event->cellRef.mRefID = ptr.getCellRef().getRefId();
+                    event->cellRef.mRefNum = ptr.getCellRef().getRefNum();
+                    event->pos.pos[0] = updated.getRefData().getPosition().pos[0];
+                    event->pos.pos[1] = updated.getRefData().getPosition().pos[1];
+                    event->pos.pos[2] = updated.getRefData().getPosition().pos[2];
+                    mwmp::Main::get().getNetworking()->GetWorldPacket(ID_OBJECT_MOVE)->Send(event);
+
+                    printf("Sending ID_OBJECT_MOVE about %s\n%i\n",
+                        event->cellRef.mRefID.c_str(),
+                        event->cellRef.mRefNum.mIndex);
                 }
         };
 
diff --git a/components/openmw-mp/Base/WorldEvent.hpp b/components/openmw-mp/Base/WorldEvent.hpp
index 4b84c48a2..4961cf1a2 100644
--- a/components/openmw-mp/Base/WorldEvent.hpp
+++ b/components/openmw-mp/Base/WorldEvent.hpp
@@ -25,6 +25,8 @@ namespace mwmp
 
         ESM::Cell cell;
         ESM::CellRef cellRef;
+
+        ESM::Position pos;
         
         int state;
         int lockLevel;
diff --git a/components/openmw-mp/Packets/World/PacketObjectMove.cpp b/components/openmw-mp/Packets/World/PacketObjectMove.cpp
index 9173410c4..69df9ad38 100644
--- a/components/openmw-mp/Packets/World/PacketObjectMove.cpp
+++ b/components/openmw-mp/Packets/World/PacketObjectMove.cpp
@@ -11,4 +11,16 @@ PacketObjectMove::PacketObjectMove(RakNet::RakPeerInterface *peer) : WorldPacket
 void PacketObjectMove::Packet(RakNet::BitStream *bs, WorldEvent *event, bool send)
 {
     WorldPacket::Packet(bs, event, send);
+
+    RW(event->cellRef.mRefID, send);
+    RW(event->cellRef.mRefNum.mIndex, send);
+
+    RW(event->cell.mData.mFlags, send);
+    RW(event->cell.mData.mX, send);
+    RW(event->cell.mData.mY, send);
+    RW(event->cell.mName, send);
+
+    RW(event->pos.pos[0], send);
+    RW(event->pos.pos[1], send);
+    RW(event->pos.pos[2], send);
 }