Toolkit_Broadcaster.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /******************************************************************************
  19. *
  20. * FILE
  21. * Toolkit_Broadcaster.cpp
  22. *
  23. * DESCRIPTION
  24. * Designer Toolkit for Mission Construction - Broadcaster Subset
  25. *
  26. * PROGRAMMER
  27. * Design Team
  28. *
  29. * VERSION INFO
  30. * $Author: Rich_d $
  31. * $Revision: 2 $
  32. * $Modtime: 9/26/00 11:52a $
  33. * $Archive: /Commando/Code/Scripts/Toolkit_Broadcaster.cpp $
  34. *
  35. ******************************************************************************/
  36. #include "toolkit.h"
  37. /*
  38. Editor Script - M00_Broadcaster_Register_RAD
  39. This script registers an object with a terminal.
  40. Parameters:
  41. Terminal_ID = The ID of the terminal you wish to register with.
  42. Send_Attempts = The number of attempts to send to the terminal this will make before failing.
  43. Send_Delay = The delay between attempts to send.
  44. Debug_Mode = Turn this on if debug information is needed.
  45. Custom:
  46. M00_CUSTOM_BROADCASTER_REGISTRATION
  47. Script activates upon creation.
  48. */
  49. DECLARE_SCRIPT (M00_Broadcaster_Register_RAD, "Terminal_ID:int, Send_Attempts=3:int, Send_Delay=1:int, Debug_Mode=0:int")
  50. {
  51. int send_attempts;
  52. int terminal_id;
  53. int current_send;
  54. int send_delay;
  55. int item_id;
  56. bool debug_mode;
  57. void Created (GameObject* obj)
  58. {
  59. debug_mode = (Get_Int_Parameter("Debug_Mode") == 1) ? true : false;
  60. send_attempts = Get_Int_Parameter("Send_Attempts");
  61. terminal_id = Get_Int_Parameter("Terminal_ID");
  62. send_delay = Get_Int_Parameter("Send_Delay");
  63. item_id = Commands->Get_ID(obj);
  64. current_send = 0;
  65. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Register_RAD ACTIVATED.\n"));
  66. Commands->Start_Timer (obj, this, 0.1f, 0);
  67. //DEBUG Timer may not work here without proper ID later.
  68. }
  69. void Timer_Expired (GameObject* obj, int timer_id)
  70. {
  71. GameObject* terminal_obj;
  72. if (!timer_id)
  73. {
  74. current_send++;
  75. if (current_send > send_attempts)
  76. {
  77. DebugPrint("ERROR - M00_Broadcaster_Registry_RAD - Object %d cannot find Terminal %d to register with!\n", item_id, terminal_id);
  78. }
  79. else
  80. {
  81. terminal_obj = Commands->Find_Object(terminal_id);
  82. if (terminal_obj)
  83. {
  84. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Registry_RAD is sending custom type M00_CUSTOM_BROADCASTER_REGISTRATION, param %d.\n", item_id));
  85. Commands->Send_Custom_Event (obj, terminal_obj, M00_CUSTOM_BROADCASTER_REGISTRATION, item_id);
  86. }
  87. else
  88. {
  89. Commands->Start_Timer (obj, this, send_delay, 0);
  90. }
  91. }
  92. }
  93. }
  94. virtual void Custom (GameObject* obj, int type, int param, GameObject* sender)
  95. {
  96. if (type == M00_CUSTOM_BROADCASTER_REGISTRY_ERROR)
  97. {
  98. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Registry_RAD received custom type M00_CUSTOM_BROADCASTER_REGISTRY_ERROR, param %d.\n", param));
  99. Commands->Start_Timer (obj, this, send_delay, 0);
  100. }
  101. else
  102. {
  103. SCRIPT_DEBUG_MESSAGE(("ERROR - M00_Broadcaster_Registry_RAD received custom type %d, param %d - unknown!\n", type, param));
  104. }
  105. }
  106. void Destroyed (GameObject* obj)
  107. {
  108. GameObject* terminal_obj;
  109. terminal_obj = Commands->Find_Object(terminal_id);
  110. if (terminal_obj)
  111. {
  112. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Registry_RAD is sending custom type M00_CUSTOM_BROADCASTER_REGISTRATION, param 0.\n"));
  113. Commands->Send_Custom_Event (obj, terminal_obj, M00_CUSTOM_BROADCASTER_REGISTRATION, 0);
  114. }
  115. }
  116. };
  117. /*
  118. Editor Script - M00_Broadcaster_Terminal_RAD
  119. This script is a terminal, which transfers customs to other objects. It can store
  120. up to 100 objects before returning an error.
  121. Values:
  122. object_specific_record = Storage of each registry item one at a time.
  123. object_random_record = Storage of any registry item as many times as desired.
  124. object_prompts = Storage of any sent prompts from objects.
  125. 0 = Object ID that is prompting.
  126. 1 = custom type to send with next regular custom.
  127. Parameters:
  128. Random_Percentage = Number from 1 to 99 to determine chance of sending the custom.
  129. Random_Param_Min = Minimum random parameter for random sends.
  130. Random_Param_Max = Maximum random parameter for random sends.
  131. M00_CUSTOM_BROADCASTER_REGISTRATION
  132. M00_CUSTOM_BROADCASTER_PROMPTER
  133. Prompt Parameters:
  134. 0 = Object is sending a custom that should be sent to everyone with one parameter.
  135. 1 = Object is sending a custom that should be sent to random objects with one parameter.
  136. 2 = Object is sending a custom that should be sent to everyone with random parameter.
  137. 3 = Object is sending a custom that should be sent to random objects with random parameter.
  138. Script activates upon receipt of a custom.
  139. */
  140. DECLARE_SCRIPT (M00_Broadcaster_Terminal_RAD, "Random_Percentage=100.0:float, Random_Param_Min=0:int, Random_Param_Max=0:int, Debug_Mode=0:int")
  141. {
  142. int object_specific_record [M00_BROADCASTER_TERMINAL_SIZE_RAD];
  143. int object_random_record [M00_BROADCASTER_TERMINAL_SIZE_RAD];
  144. int object_prompts [M00_BROADCASTER_TERMINAL_PROMPT_SIZE_RAD][2];
  145. bool ready_for_objects;
  146. bool debug_mode;
  147. void Created (GameObject* obj)
  148. {
  149. debug_mode = (Get_Int_Parameter("Debug_Mode") == 1) ? true : false;
  150. int object_count;
  151. ready_for_objects = false;
  152. for (object_count = 0; object_count < M00_BROADCASTER_TERMINAL_SIZE_RAD; object_count++)
  153. {
  154. object_specific_record [object_count] = 0;
  155. object_specific_record [object_count] = 0;
  156. object_random_record [object_count] = 0;
  157. }
  158. for (object_count = 0; object_count < M00_BROADCASTER_TERMINAL_PROMPT_SIZE_RAD; object_count++)
  159. {
  160. object_prompts [object_count][0] = 0;
  161. }
  162. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Terminal_RAD ACTIVATED.\n"));
  163. ready_for_objects = true;
  164. }
  165. void Custom (GameObject* obj, int type, int param, GameObject* sender)
  166. {
  167. int my_id;
  168. int sender_id;
  169. int object_count;
  170. int last_empty;
  171. int obj_id;
  172. int prompt_value;
  173. int random_value;
  174. int random_value2;
  175. int parameter_low;
  176. int parameter_high;
  177. bool found_object;
  178. GameObject* target_obj;
  179. // Check if the sender still exists, just an error catch routine.
  180. if (sender)
  181. {
  182. sender_id = Commands->Get_ID (sender);
  183. }
  184. else
  185. {
  186. sender_id = 0;
  187. }
  188. if (ready_for_objects)
  189. {
  190. my_id = Commands->Get_ID (obj);
  191. if (my_id == sender_id)
  192. {
  193. DebugPrint ("ERROR - M00_Broadcaster_Terminal_RAD - Broadcaster sent a custom to itself!\n");
  194. }
  195. else
  196. {
  197. // Check which type of custom was just sent.
  198. switch (type)
  199. {
  200. case (M00_CUSTOM_BROADCASTER_REGISTRATION):
  201. {
  202. // Object is attempting to register or unregister itself.
  203. if (param)
  204. {
  205. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Terminal_RAD received custom type M00_CUSTOM_BROADCASTER_REGISTRATION, param %d.\n", param));
  206. // Object is attempting to register itself.
  207. // Check if the object is already in the specific list.
  208. found_object = false;
  209. last_empty = -1;
  210. for (object_count = 0; object_count < M00_BROADCASTER_TERMINAL_SIZE_RAD; object_count++)
  211. {
  212. if (object_specific_record [object_count] == sender_id)
  213. {
  214. // Object already exists in the specific record, skip entry.
  215. object_count = M00_BROADCASTER_TERMINAL_SIZE_RAD;
  216. found_object = true;
  217. }
  218. else
  219. {
  220. if ((!object_specific_record [object_count]) && (last_empty == -1))
  221. {
  222. last_empty = object_count;
  223. }
  224. }
  225. }
  226. if (!found_object)
  227. {
  228. // Enter the object into the list in the next available slot.
  229. if (last_empty >= 0)
  230. {
  231. object_specific_record [last_empty] = sender_id;
  232. }
  233. else
  234. {
  235. obj_id = Commands->Get_ID (obj);
  236. DebugPrint ("ERROR - M00_Broadcaster_Terminal_RAD - Broadcaster Terminal %d is full!\n", obj_id);
  237. }
  238. }
  239. // Now, insert the object into the random list regardless of number of entries.
  240. for (object_count = 0; object_count < M00_BROADCASTER_TERMINAL_SIZE_RAD; object_count++)
  241. {
  242. if (!object_random_record [object_count])
  243. {
  244. object_random_record [object_count] = sender_id;
  245. object_count = M00_BROADCASTER_TERMINAL_SIZE_RAD;
  246. }
  247. }
  248. }
  249. else
  250. {
  251. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Terminal_RAD received custom type M00_CUSTOM_BROADCASTER_REGISTRATION, param 0.\n"));
  252. // Object is attempting to unregister itself.
  253. for (object_count = 0; object_count < M00_BROADCASTER_TERMINAL_SIZE_RAD; object_count++)
  254. {
  255. if (object_specific_record [object_count] == sender_id)
  256. {
  257. object_specific_record [object_count] = 0;
  258. }
  259. if (object_random_record [object_count] == sender_id)
  260. {
  261. object_random_record [object_count] = 0;
  262. }
  263. }
  264. }
  265. break;
  266. }
  267. case (M00_CUSTOM_BROADCASTER_PROMPTER):
  268. {
  269. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Terminal_RAD received custom type M00_CUSTOM_BROADCASTER_PROMPTER, param %d.\n", param));
  270. // Check if the object is already in the prompt list, or if there is a blank slot.
  271. prompt_value = M00_BROADCASTER_TERMINAL_PROMPT_SIZE_RAD;
  272. for (object_count = 0;object_count < M00_BROADCASTER_TERMINAL_PROMPT_SIZE_RAD; object_count++)
  273. {
  274. if (object_prompts [object_count][0] == sender_id)
  275. {
  276. prompt_value = M00_BROADCASTER_TERMINAL_PROMPT_SIZE_RAD;
  277. object_count = M00_BROADCASTER_TERMINAL_PROMPT_SIZE_RAD;
  278. }
  279. if (!object_prompts [object_count][0])
  280. {
  281. prompt_value = object_count;
  282. object_count = M00_BROADCASTER_TERMINAL_PROMPT_SIZE_RAD;
  283. }
  284. }
  285. if (prompt_value < M00_BROADCASTER_TERMINAL_PROMPT_SIZE_RAD)
  286. {
  287. // Object is attempting to prompt another custom send.
  288. object_prompts [prompt_value][0] = sender_id;
  289. object_prompts [prompt_value][1] = param;
  290. }
  291. break;
  292. }
  293. default:
  294. {
  295. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Terminal_RAD received custom type %d, param %d.\n", type, param));
  296. // Object is sending a custom that should be already prompted.
  297. // If it is not prompted, default to non-random send.
  298. prompt_value = 0;
  299. for (object_count = 0;object_count < M00_BROADCASTER_TERMINAL_PROMPT_SIZE_RAD; object_count++)
  300. {
  301. if (object_prompts [object_count][0] == sender_id)
  302. {
  303. prompt_value = object_prompts [object_count][1];
  304. object_prompts [object_count][0] = 0;
  305. object_prompts [object_count][1] = 0;
  306. }
  307. }
  308. switch ( prompt_value )
  309. {
  310. case (1): // Object is sending a custom that should be sent to random objects with one parameter.
  311. {
  312. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Terminal_RAD is sending a custom to random objects with one parameter.\n"));
  313. for (object_count = 0;object_count < M00_BROADCASTER_TERMINAL_SIZE_RAD; object_count++)
  314. {
  315. random_value = Commands->Get_Random (0.0f, 100.0f);
  316. if (random_value <= Get_Float_Parameter ("Random_Percentage"))
  317. {
  318. if (object_random_record [object_count])
  319. {
  320. target_obj = Commands->Find_Object (object_random_record [object_count]);
  321. if (target_obj)
  322. {
  323. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Terminal_RAD is sending custom type %d, param %d.\n", type, param));
  324. Commands->Send_Custom_Event (obj, target_obj, type, param);
  325. }
  326. else
  327. {
  328. object_random_record [object_count] = 0;
  329. }
  330. }
  331. }
  332. }
  333. break;
  334. }
  335. case (2): // Object is sending a custom that should be sent to everyone with random parameter.
  336. {
  337. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Terminal_RAD is sending a custom to everyone with random parameter.\n"));
  338. parameter_low = Get_Int_Parameter("Random_Param_Min");
  339. parameter_high = Get_Int_Parameter("Random_Param_Max");
  340. for (object_count = 0;object_count < M00_BROADCASTER_TERMINAL_SIZE_RAD; object_count++)
  341. {
  342. if (object_specific_record [object_count])
  343. {
  344. target_obj = Commands->Find_Object (object_specific_record [object_count]);
  345. if (target_obj)
  346. {
  347. random_value = int(Commands->Get_Random (float(parameter_low), float(parameter_high)));
  348. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Terminal_RAD is sending custom type %d, param %d.\n", type, random_value));
  349. Commands->Send_Custom_Event (obj, target_obj, type, random_value);
  350. }
  351. else
  352. {
  353. object_specific_record [object_count] = 0;
  354. }
  355. }
  356. }
  357. break;
  358. }
  359. case (3): // Object is sending a custom that should be sent to random objects with random parameter.
  360. {
  361. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Terminal_RAD is sending a custom to random objects with random parameter.\n"));
  362. parameter_low = Get_Int_Parameter("Random_Param_Min");
  363. parameter_high = Get_Int_Parameter("Random_Param_Max");
  364. for (object_count = 0;object_count < M00_BROADCASTER_TERMINAL_SIZE_RAD; object_count++)
  365. {
  366. if (object_random_record [object_count])
  367. {
  368. random_value = Commands->Get_Random (0.0f, 100.0f);
  369. if (random_value <= Get_Float_Parameter ("Random_Percentage"))
  370. {
  371. target_obj = Commands->Find_Object (object_random_record [object_count]);
  372. if (target_obj)
  373. {
  374. random_value2 = int(Commands->Get_Random (float(parameter_low), float(parameter_high)));
  375. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Terminal_RAD is sending custom type %d, param %d.\n", type, random_value2));
  376. Commands->Send_Custom_Event (obj, target_obj, type, random_value2);
  377. }
  378. else
  379. {
  380. object_random_record [object_count] = 0;
  381. }
  382. }
  383. }
  384. }
  385. break;
  386. }
  387. default: // Object is sending a custom that should be sent to everyone with one parameter.
  388. {
  389. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Terminal_RAD is sending a custom to everyone with one parameter.\n"));
  390. for (object_count = 0;object_count < M00_BROADCASTER_TERMINAL_SIZE_RAD; object_count++)
  391. {
  392. if (object_specific_record [object_count])
  393. {
  394. target_obj = Commands->Find_Object(object_specific_record [object_count]);
  395. if (target_obj)
  396. {
  397. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Terminal_RAD is sending custom type %d, param %d.\n", type, param));
  398. Commands->Send_Custom_Event (obj, target_obj, type, param);
  399. }
  400. else
  401. {
  402. object_specific_record [object_count] = 0;
  403. }
  404. }
  405. }
  406. break;
  407. }
  408. }
  409. break;
  410. }
  411. }
  412. }
  413. }
  414. else
  415. {
  416. // Terminal is not ready for customs. Send an error message.
  417. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Terminal_RAD is sending custom type M00_CUSTOM_BROADCASTER_REGISTRY_ERROR, param 0.\n"));
  418. Commands->Send_Custom_Event (obj, sender, M00_CUSTOM_BROADCASTER_REGISTRY_ERROR, 0);
  419. }
  420. }
  421. };
  422. /*
  423. Editor Script - M00_Broadcaster_Activator_RAD
  424. This script is an easy way to activate terminals through the Level Editor.
  425. Parameters:
  426. Terminal_ID = The ID of the terminal you wish to register with.
  427. Prompt_Value = The prompt value you wish to send to the terminal before the custom.
  428. 0 = Object is sending a custom that should be sent to everyone with one parameter.
  429. 1 = Object is sending a custom that should be sent to random objects with one parameter.
  430. 2 = Object is sending a custom that should be sent to everyone with random parameter.
  431. 3 = Object is sending a custom that should be sent to random objects with random parameter.
  432. Script activates upon receipt of a custom. Defaults to constant send, 0.
  433. */
  434. DECLARE_SCRIPT (M00_Broadcaster_Activator_RAD, "Terminal_ID:int, Prompt_Value=0:int, Debug_Mode=0:int")
  435. {
  436. int terminal_id;
  437. int prompt_value;
  438. bool debug_mode;
  439. void Created (GameObject* obj)
  440. {
  441. debug_mode = (Get_Int_Parameter("Debug_Mode") == 1) ? true : false;
  442. terminal_id = Get_Int_Parameter ("Terminal_ID");
  443. prompt_value = Get_Int_Parameter ("Prompt_Value");
  444. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Activator_RAD ACTIVATED.\n"));
  445. }
  446. void Custom (GameObject* obj, int type, int param, GameObject* sender)
  447. {
  448. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Activator_RAD received custom type %d, param %d.\n", type, param));
  449. GameObject* terminal_obj;
  450. terminal_obj = Commands->Find_Object(terminal_id);
  451. if (terminal_obj)
  452. {
  453. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Activator_RAD is sending custom type M00_CUSTOM_BROADCASTER_PROMPTER, param %d.\n", prompt_value));
  454. SCRIPT_DEBUG_MESSAGE(("M00_Broadcaster_Activator_RAD is sending custom type %d, param %d.\n", type, param));
  455. Commands->Send_Custom_Event (obj, terminal_obj, M00_CUSTOM_BROADCASTER_PROMPTER, prompt_value);
  456. Commands->Send_Custom_Event (obj, terminal_obj, type, param);
  457. }
  458. else
  459. {
  460. DebugPrint ("ERROR - M00_Broadcaster_Activator_RAD - Cannot find Terminal %d!\n", terminal_id);
  461. }
  462. }
  463. };