remotelyactivateditembehaviour.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. class RemotelyActivatedItemBehaviour
  2. {
  3. protected EntityAI m_Parent;
  4. protected bool m_IsTrigger;
  5. protected EntityAI m_PairDevice;
  6. protected int m_PairDeviceNetIdLow;
  7. protected int m_PairDeviceNetIdHigh;
  8. protected int m_PersistentPairID = int.MIN;
  9. protected static ref map<int,EntityAI> m_RemoteReceivers = new map<int,EntityAI>();
  10. void RemotelyActivatedItemBehaviour(notnull EntityAI pParent)
  11. {
  12. m_Parent = pParent;
  13. m_PairDeviceNetIdLow = -1;
  14. m_PairDeviceNetIdHigh = -1;
  15. }
  16. void ~RemotelyActivatedItemBehaviour()
  17. {
  18. if (m_Parent)
  19. Unpair();
  20. }
  21. void SetTrigger()
  22. {
  23. m_IsTrigger = true;
  24. }
  25. void OnVariableSynchronized()
  26. {
  27. Pair();
  28. }
  29. void OnStoreSave(ParamsWriteContext ctx)
  30. {
  31. ctx.Write(m_PersistentPairID);
  32. }
  33. bool OnStoreLoad(ParamsReadContext ctx, int version)
  34. {
  35. if (!ctx.Read(m_PersistentPairID))
  36. return false;
  37. if (m_PersistentPairID == int.MIN)//default value, no point in going further
  38. return true;
  39. if (m_IsTrigger)//trigger
  40. {
  41. EntityAI receiver = m_RemoteReceivers.Get(m_PersistentPairID);
  42. if (receiver)
  43. Pair(receiver);
  44. }
  45. else // remotely controlled device
  46. {
  47. m_RemoteReceivers.Insert(m_PersistentPairID, m_Parent);//receivers will register themselves upon being loaded from the storage
  48. }
  49. return true;
  50. }
  51. void OnAfterLoad()
  52. {
  53. if (m_IsTrigger && m_PersistentPairID != int.MIN && !m_PairDevice)
  54. {
  55. EntityAI receiver = m_RemoteReceivers.Get(m_PersistentPairID);
  56. if (receiver)
  57. {
  58. //if both the receiver and trigger are somewhere in the world outside of the player inventory, there is no guarantee
  59. //that the pairing is going to be succesful during the 'OnStoreLoad' event as that requires the receiver to already be loaded when the trigger is being loaded
  60. //therefore, it's necessary to also perform pairing in this event, which happens at the end of the storage loading process
  61. //do note that this event is not called when the entity is being loaded as part of the player inventory, therefore, we need to pair both in 'OnStoreLoad' and here to handle both situations
  62. //(when the trigger is in the player's inventory, it always loads correctly after the receiver, which is always in the world)
  63. Pair(receiver);
  64. }
  65. }
  66. }
  67. static int GeneratePersistentID()
  68. {
  69. int randomID = Math.RandomInt(0, int.MAX);
  70. if (m_RemoteReceivers.Contains(randomID))
  71. {
  72. //it's very unlikely to have a collision here, but lets handle it anyway
  73. return GeneratePersistentID();
  74. }
  75. else
  76. return randomID;
  77. }
  78. void SetPersistentPairID(int id)
  79. {
  80. m_PersistentPairID = id;
  81. if (!m_IsTrigger)
  82. m_RemoteReceivers.Insert(id,m_Parent);
  83. }
  84. void Pair()
  85. {
  86. EntityAI device = EntityAI.Cast(GetGame().GetObjectByNetworkId(GetPairDeviceNetIdLow(), GetPairDeviceNetIdHigh()));
  87. if (device)
  88. {
  89. Pair(device);
  90. }
  91. }
  92. void Pair(notnull EntityAI device)
  93. {
  94. m_PairDevice = device;
  95. SetPairDeviceNetIds(device);
  96. if (device != m_Parent && (!m_Parent.GetPairDevice() || m_Parent.GetPairDevice() != m_PairDevice))
  97. m_PairDevice.PairRemote(m_Parent);
  98. m_PairDevice.SetSynchDirty();
  99. m_Parent.SetSynchDirty();
  100. }
  101. void Unpair()
  102. {
  103. m_PairDeviceNetIdLow = -1;
  104. m_PairDeviceNetIdHigh = -1;
  105. if (m_PairDevice)
  106. {
  107. m_PairDevice.SetSynchDirty();
  108. m_PairDevice = null;
  109. }
  110. if (m_PersistentPairID != int.MIN)
  111. {
  112. if (m_RemoteReceivers.Contains(m_PersistentPairID))
  113. m_RemoteReceivers.Remove(m_PersistentPairID);
  114. }
  115. m_PersistentPairID = int.MIN;
  116. m_Parent.SetSynchDirty();
  117. }
  118. EntityAI GetPairDevice()
  119. {
  120. return m_PairDevice;
  121. }
  122. bool IsPaired()
  123. {
  124. return m_PairDevice != null;
  125. }
  126. void SetPairDeviceNetIds(notnull EntityAI device)
  127. {
  128. device.GetNetworkID(m_PairDeviceNetIdLow, m_PairDeviceNetIdHigh);
  129. }
  130. int GetPairDeviceNetIdLow()
  131. {
  132. return m_PairDeviceNetIdLow;
  133. }
  134. int GetPairDeviceNetIdHigh()
  135. {
  136. return m_PairDeviceNetIdHigh;
  137. }
  138. }