undo.pwn 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #define MAX_UNDO_BUFFER 10000
  2. #define UNDO_TYPE_UNUSED 0
  3. #define UNDO_TYPE_CREATED 1
  4. #define UNDO_TYPE_EDIT 2
  5. #define UNDO_TYPE_DELETED 3
  6. #define UNDO_GROUP_NONE 0
  7. // Object information ENUM
  8. enum OBJECTUNDOINFO
  9. {
  10. uoGroup, // Object group
  11. uoModel, // Object Model
  12. Float:uoX, // Position Z
  13. Float:uoY, // Position Z
  14. Float:uoZ, // Position Z
  15. Float:uoRX, // Rotation Z
  16. Float:uoRY, // Rotation Z
  17. Float:uoRZ, // Rotation Z
  18. Float:uoDD, // Draw distance
  19. uoTexIndex[MAX_MATERIALS], // Texture index ref
  20. uoColorIndex[MAX_MATERIALS], // Material List
  21. uousetext, // Use text
  22. uoFontFace, // Font face reference
  23. uoFontSize, // Font size reference
  24. uoFontBold, // Font bold
  25. uoFontColor, // Font color
  26. uoBackColor, // Font back color
  27. uoAlignment, // Font alignment
  28. uoTextFontSize, // Font text size
  29. uoObjectText[MAX_TEXT_LENGTH], // Font text
  30. uoNote[64], // Note
  31. uoAttachedVehicle, // Vehicle object is attached to
  32. uoIndex, // Store indexid object
  33. uoType, // Type of undo
  34. uoGroupTask, // Group
  35. }
  36. static UndoBuffer[MAX_UNDO_BUFFER][OBJECTUNDOINFO];
  37. static CurrBufferIndex;
  38. SaveUndoInfo(index, type, group=0)
  39. {
  40. UndoBuffer[CurrBufferIndex][uoGroup] = ObjectData[index][oGroup];
  41. UndoBuffer[CurrBufferIndex][uoModel] = ObjectData[index][oModel];
  42. UndoBuffer[CurrBufferIndex][uoX] = ObjectData[index][oX];
  43. UndoBuffer[CurrBufferIndex][uoY] = ObjectData[index][oY];
  44. UndoBuffer[CurrBufferIndex][uoZ] = ObjectData[index][oZ];
  45. UndoBuffer[CurrBufferIndex][uoRX] = ObjectData[index][oRX];
  46. UndoBuffer[CurrBufferIndex][uoRY] = ObjectData[index][oRY];
  47. UndoBuffer[CurrBufferIndex][uoRZ] = ObjectData[index][oRZ];
  48. UndoBuffer[CurrBufferIndex][uoDD] = ObjectData[index][oDD];
  49. UndoBuffer[CurrBufferIndex][uousetext] = ObjectData[index][ousetext];
  50. UndoBuffer[CurrBufferIndex][uoFontFace] = ObjectData[index][oFontFace];
  51. UndoBuffer[CurrBufferIndex][uoFontSize] = ObjectData[index][oFontSize];
  52. UndoBuffer[CurrBufferIndex][uoFontBold] = ObjectData[index][oFontBold];
  53. UndoBuffer[CurrBufferIndex][uoFontColor] = ObjectData[index][oFontColor];
  54. UndoBuffer[CurrBufferIndex][uoBackColor] = ObjectData[index][oBackColor];
  55. UndoBuffer[CurrBufferIndex][uoAlignment] = ObjectData[index][oAlignment];
  56. UndoBuffer[CurrBufferIndex][uoTextFontSize] = ObjectData[index][oTextFontSize];
  57. UndoBuffer[CurrBufferIndex][uoAttachedVehicle] = ObjectData[index][oAttachedVehicle];
  58. UndoBuffer[CurrBufferIndex][uoGroupTask] = group;
  59. for(new i = 0; i < MAX_MATERIALS; i++)
  60. {
  61. UndoBuffer[CurrBufferIndex][uoTexIndex][i] = ObjectData[index][oTexIndex][i];
  62. UndoBuffer[CurrBufferIndex][uoColorIndex][i] = ObjectData[index][oColorIndex][i];
  63. }
  64. format(UndoBuffer[CurrBufferIndex][uoNote], 64, "%s", ObjectData[index][oNote]);
  65. format(UndoBuffer[CurrBufferIndex][uoObjectText], MAX_TEXT_LENGTH, "%s", ObjectData[index][oObjectText]);
  66. UndoBuffer[CurrBufferIndex][uoIndex] = index;
  67. UndoBuffer[CurrBufferIndex][uoType] = type;
  68. if(++CurrBufferIndex == MAX_UNDO_BUFFER) CurrBufferIndex = 0;
  69. }
  70. UndoLastAction(lastgroup=0)
  71. {
  72. if(CurrBufferIndex == 0)
  73. {
  74. if(UndoBuffer[MAX_UNDO_BUFFER-1][uoType] == UNDO_TYPE_UNUSED) return 0;
  75. else CurrBufferIndex = MAX_UNDO_BUFFER;
  76. }
  77. CurrBufferIndex--;
  78. // Group deletion is complete
  79. if(lastgroup > 0 && UndoBuffer[CurrBufferIndex][uoGroupTask] != lastgroup)
  80. {
  81. CurrBufferIndex++;
  82. return 1;
  83. }
  84. else
  85. {
  86. switch(UndoBuffer[CurrBufferIndex][uoType])
  87. {
  88. case UNDO_TYPE_CREATED:
  89. {
  90. DeleteDynamicObject(UndoBuffer[CurrBufferIndex][uoIndex]);
  91. // Grouped event keep undoing
  92. ClearUndoInfo(CurrBufferIndex);
  93. if(UndoBuffer[CurrBufferIndex][uoGroupTask] > 0) UndoLastAction(UndoBuffer[CurrBufferIndex][uoGroupTask]);
  94. return 1;
  95. }
  96. case UNDO_TYPE_EDIT, UNDO_TYPE_DELETED:
  97. {
  98. new index = UndoBuffer[CurrBufferIndex][uoIndex];
  99. ObjectData[index][oGroup] = UndoBuffer[CurrBufferIndex][uoGroup];
  100. ObjectData[index][oModel] = UndoBuffer[CurrBufferIndex][uoModel];
  101. ObjectData[index][oX] = UndoBuffer[CurrBufferIndex][uoX];
  102. ObjectData[index][oY] = UndoBuffer[CurrBufferIndex][uoY];
  103. ObjectData[index][oZ] = UndoBuffer[CurrBufferIndex][uoZ];
  104. ObjectData[index][oRX] = UndoBuffer[CurrBufferIndex][uoRX];
  105. ObjectData[index][oRY] = UndoBuffer[CurrBufferIndex][uoRY];
  106. ObjectData[index][oRZ] = UndoBuffer[CurrBufferIndex][uoRZ];
  107. ObjectData[index][oDD] = UndoBuffer[CurrBufferIndex][uoDD];
  108. ObjectData[index][ousetext] = UndoBuffer[CurrBufferIndex][uousetext];
  109. ObjectData[index][oFontFace] = UndoBuffer[CurrBufferIndex][uoFontFace];
  110. ObjectData[index][oFontSize] = UndoBuffer[CurrBufferIndex][uoFontSize];
  111. ObjectData[index][oFontBold] = UndoBuffer[CurrBufferIndex][uoFontBold];
  112. ObjectData[index][oFontColor] = UndoBuffer[CurrBufferIndex][uoFontColor];
  113. ObjectData[index][oBackColor] = UndoBuffer[CurrBufferIndex][uoBackColor];
  114. ObjectData[index][oAlignment] = UndoBuffer[CurrBufferIndex][uoAlignment];
  115. ObjectData[index][oTextFontSize] = UndoBuffer[CurrBufferIndex][uoTextFontSize];
  116. ObjectData[index][oAttachedVehicle] = UndoBuffer[CurrBufferIndex][uoAttachedVehicle];
  117. format(ObjectData[index][oNote], 64, "%s", UndoBuffer[CurrBufferIndex][uoNote]);
  118. for(new i = 0; i < MAX_MATERIALS; i++)
  119. {
  120. ObjectData[index][oTexIndex][i] = UndoBuffer[CurrBufferIndex][uoTexIndex][i];
  121. ObjectData[index][oColorIndex][i] = UndoBuffer[CurrBufferIndex][uoColorIndex][i];
  122. }
  123. format(ObjectData[index][oObjectText], MAX_TEXT_LENGTH, "%s", UndoBuffer[CurrBufferIndex][uoObjectText]);
  124. // Rebuild object
  125. if(UndoBuffer[CurrBufferIndex][uoType] == UNDO_TYPE_DELETED)
  126. {
  127. Iter_Add(Objects, index);
  128. sqlite_InsertObject(index);
  129. }
  130. else DestroyDynamicObject(ObjectData[index][oID]);
  131. // Re-create object
  132. ObjectData[index][oID] = CreateDynamicObject(ObjectData[index][oModel], ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ], ObjectData[index][oRX], ObjectData[index][oRY], ObjectData[index][oRZ], MapSetting[mVirtualWorld], MapSetting[mInterior], -1, 300.0);
  133. Streamer_SetFloatData(STREAMER_TYPE_OBJECT, ObjectData[index][oID], E_STREAMER_DRAW_DISTANCE, 300.0);
  134. // Update the streamer
  135. foreach(new i : Player)
  136. {
  137. if(IsPlayerInRangeOfPoint(i, 300.0, ObjectData[index][oX], ObjectData[index][oY], ObjectData[index][oZ])) Streamer_Update(i);
  138. }
  139. // Update the materials
  140. UpdateMaterial(index);
  141. // Update object text
  142. UpdateObjectText(index);
  143. if(ObjectData[index][oAttachedVehicle] > -1) UpdateAttachedVehicleObject(ObjectData[index][oAttachedVehicle], index, VEHICLE_REATTACH_UPDATE);
  144. UpdateObject3DText(index);
  145. // Save all data
  146. sqlite_UpdateObjectPos(index);
  147. sqlite_SaveMaterialIndex(index);
  148. sqlite_SaveColorIndex(index);
  149. sqlite_SaveAllObjectText(index);
  150. // Grouped event keep undoing
  151. ClearUndoInfo(CurrBufferIndex);
  152. if(UndoBuffer[CurrBufferIndex][uoGroupTask] > 0) UndoLastAction(UndoBuffer[CurrBufferIndex][uoGroupTask]);
  153. return 1;
  154. }
  155. }
  156. }
  157. return 0;
  158. }
  159. ClearAllUndoInfo()
  160. {
  161. CurrBufferIndex = 0;
  162. for(new i = 0; i < MAX_UNDO_BUFFER; i++) ClearUndoInfo(i);
  163. return 1;
  164. }
  165. ClearUndoInfo(index)
  166. {
  167. UndoBuffer[index][uoGroup] = 0;
  168. UndoBuffer[index][uoModel] = 0;
  169. UndoBuffer[index][uoX] = 0.0;
  170. UndoBuffer[index][uoY] = 0.0;
  171. UndoBuffer[index][uoZ] = 0.0;
  172. UndoBuffer[index][uoRX] = 0.0;
  173. UndoBuffer[index][uoRY] = 0.0;
  174. UndoBuffer[index][uoRZ] = 0.0;
  175. UndoBuffer[index][uoDD] = 300.0;
  176. UndoBuffer[index][uousetext] = 0;
  177. UndoBuffer[index][uoFontFace] = 0;
  178. UndoBuffer[index][uoFontSize] = 0;
  179. UndoBuffer[index][uoFontBold] = 0;
  180. UndoBuffer[index][uoFontColor] = 0;
  181. UndoBuffer[index][uoBackColor] = 0;
  182. UndoBuffer[index][uoAlignment] = 0;
  183. UndoBuffer[index][uoTextFontSize] = 20;
  184. for(new i = 0; i < MAX_MATERIALS; i++)
  185. {
  186. UndoBuffer[index][uoTexIndex][i] = 0;
  187. UndoBuffer[index][uoColorIndex][i] = 0;
  188. }
  189. format(UndoBuffer[index][uoObjectText], MAX_TEXT_LENGTH, "None");
  190. UndoBuffer[index][uoNote][0] = EOS;
  191. UndoBuffer[index][uoIndex] = 0;
  192. UndoBuffer[index][uoType] = UNDO_TYPE_UNUSED;
  193. return 1;
  194. }
  195. YCMD:undo(playerid, arg[], help)
  196. {
  197. if(help)
  198. {
  199. SendClientMessage(playerid, STEALTH_ORANGE, "______________________________________________");
  200. SendClientMessage(playerid, STEALTH_GREEN, "Undo last action.");
  201. return 1;
  202. }
  203. MapOpenCheck();
  204. NoEditingMode(playerid);
  205. if(UndoLastAction()) SendClientMessage(playerid, STEALTH_GREEN, "Last action has been undone.");
  206. else SendClientMessage(playerid, STEALTH_YELLOW, "No actions to undo.");
  207. return 1;
  208. }