MEDROBOT.C 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919
  1. /*
  2. * $Source: f:/miner/source/main/editor/rcs/medrobot.c $
  3. * $Revision: 2.0 $
  4. * $Author: john $
  5. * $Date: 1995/02/27 11:35:59 $
  6. *
  7. * Dialog box to edit robot properties.
  8. *
  9. * $Log: medrobot.c $
  10. * Revision 2.0 1995/02/27 11:35:59 john
  11. * Version 2.0! No anonymous unions, Watcom 10.0, with no need
  12. * for bitmaps.tbl.
  13. *
  14. * Revision 1.46 1995/02/22 15:22:03 allender
  15. * remove anonyous unions from object structure
  16. *
  17. * Revision 1.45 1994/11/27 23:17:32 matt
  18. * Made changes for new mprintf calling convention
  19. *
  20. * Revision 1.44 1994/11/14 11:39:57 mike
  21. * fix default robot behavior
  22. *
  23. * Revision 1.43 1994/11/02 16:18:47 matt
  24. * Moved draw_model_picture() out of editor, and cleaned up code
  25. *
  26. * Revision 1.42 1994/10/10 17:23:23 mike
  27. * Verify that not placing too many player objects.
  28. *
  29. * Revision 1.41 1994/10/09 22:04:38 mike
  30. * Maybe improve, maybe not, robot selection in shift-R menu.
  31. *
  32. * Revision 1.40 1994/09/30 21:49:01 mike
  33. * Fix stupid shift-R dialog bug which caused lots of mprintf and selecting of object and frustration.
  34. *
  35. * Revision 1.39 1994/09/30 11:51:33 mike
  36. * Fix boolean logic on an error trap.
  37. *
  38. * Revision 1.38 1994/09/20 14:36:32 mike
  39. * Clean up Robot dialog.
  40. *
  41. * Revision 1.37 1994/09/12 19:11:56 mike
  42. * Fix stupid bugs in selecting objects.
  43. *
  44. * Revision 1.36 1994/09/01 17:05:51 matt
  45. * Don't force redraw if object select fails
  46. *
  47. * Revision 1.35 1994/08/31 19:24:40 mike
  48. * Fix hang bug when only objects in mine are not robots.
  49. *
  50. * Revision 1.34 1994/08/25 21:56:38 mike
  51. * IS_CHILD stuff.
  52. *
  53. * Revision 1.33 1994/08/23 16:39:29 mike
  54. * mode replaced by behavior in ai_info.
  55. *
  56. * Revision 1.32 1994/08/15 23:47:16 mike
  57. * fix bugs.
  58. *
  59. * Revision 1.31 1994/08/13 17:32:45 mike
  60. * set to still function.
  61. *
  62. * Revision 1.30 1994/08/09 16:06:02 john
  63. * Added the ability to place players. Made old
  64. * Player variable be ConsoleObject.
  65. *
  66. * Revision 1.29 1994/08/02 16:22:48 matt
  67. * Finished object editor dialog
  68. *
  69. */
  70. #pragma off (unreferenced)
  71. static char rcsid[] = "$Id: medrobot.c 2.0 1995/02/27 11:35:59 john Exp $";
  72. #pragma on (unreferenced)
  73. #include <stdlib.h>
  74. #include <stdio.h>
  75. #include <conio.h>
  76. #include <math.h>
  77. #include <dos.h>
  78. #include <string.h>
  79. #include <direct.h>
  80. #include "screens.h"
  81. #include "inferno.h"
  82. #include "segment.h"
  83. #include "editor.h"
  84. #include "timer.h"
  85. #include "objpage.h"
  86. #include "fix.h"
  87. #include "mono.h"
  88. #include "error.h"
  89. #include "kdefs.h"
  90. #include "object.h"
  91. #include "polyobj.h"
  92. #include "game.h"
  93. #include "powerup.h"
  94. #include "ai.h"
  95. #include "hostage.h"
  96. #include "eobject.h"
  97. #include "medwall.h"
  98. #include "eswitch.h"
  99. #include "ehostage.h"
  100. #include "key.h"
  101. #include "centers.h"
  102. #include "bm.h"
  103. #define NUM_BOXES 6 // Number of boxes, AI modes
  104. //-------------------------------------------------------------------------
  105. // Variables for this module...
  106. //-------------------------------------------------------------------------
  107. static UI_WINDOW *MainWindow = NULL;
  108. static UI_GADGET_USERBOX *RobotViewBox;
  109. static UI_GADGET_USERBOX *ContainsViewBox;
  110. static UI_GADGET_BUTTON *QuitButton;
  111. static UI_GADGET_RADIO *InitialMode[NUM_BOXES];
  112. static int old_object;
  113. static fix Time;
  114. static vms_angvec angles={0,0,0}, goody_angles={0,0,0};
  115. //-------------------------------------------------------------------------
  116. // Given a pointer to an object, returns a number that cooresponds to the
  117. // object id as used in the objpage stuff.
  118. //-------------------------------------------------------------------------
  119. int get_object_id( object * obj )
  120. {
  121. int i;
  122. int goal_type;
  123. switch( obj->type ) {
  124. case OBJ_PLAYER: goal_type=OL_PLAYER; break;
  125. case OBJ_ROBOT: goal_type=OL_ROBOT; break;
  126. case OBJ_POWERUP: goal_type=OL_POWERUP; break;
  127. case OBJ_CNTRLCEN: goal_type=OL_CONTROL_CENTER; break;
  128. case OBJ_HOSTAGE: goal_type=OL_HOSTAGE; break;
  129. case OBJ_CLUTTER: goal_type=OL_CLUTTER; break;
  130. default:
  131. Int3(); // Invalid object type
  132. return -1;
  133. }
  134. // Find first object with the same type as this
  135. // one and then add the object id to that to find
  136. // the offset into the list.
  137. for (i=0; i< Num_total_object_types; i++ ) {
  138. if ( ObjType[i]==goal_type)
  139. return obj->id + i;
  140. }
  141. return -1;
  142. }
  143. void call_init_ai_object(object *objp, int behavior)
  144. {
  145. int hide_segment;
  146. if (behavior == AIB_STATION)
  147. hide_segment = Cursegp-Segments;
  148. else {
  149. if (Markedsegp != NULL)
  150. hide_segment = Markedsegp-Segments;
  151. else
  152. hide_segment = Cursegp-Segments;
  153. }
  154. mprintf((0, "Initializing AI object with hide segment = %i\n", hide_segment));
  155. init_ai_object(objp-Objects, behavior, hide_segment);
  156. if (behavior == AIB_STATION) {
  157. int cseg, mseg;
  158. cseg = 0;
  159. mseg = 0;
  160. if (Cursegp != NULL)
  161. cseg = Cursegp-Segments;
  162. if (Markedsegp != NULL) {
  163. mseg = Markedsegp-Segments;
  164. }
  165. objp->ctype.ai_info.follow_path_start_seg = Cursegp-Segments;
  166. objp->ctype.ai_info.follow_path_end_seg = Markedsegp-Segments;
  167. }
  168. }
  169. //-------------------------------------------------------------------------
  170. // Called when user presses "Next Type" button. This only works for polygon
  171. // objects and it just selects the next polygon model for the current object.
  172. //-------------------------------------------------------------------------
  173. int RobotNextType()
  174. {
  175. if (Cur_object_index > -1 ) {
  176. if ( Objects[Cur_object_index].type == OBJ_ROBOT ) {
  177. object * obj = &Objects[Cur_object_index];
  178. obj->id++;
  179. if (obj->id >= N_robot_types )
  180. obj->id = 0;
  181. //Set polygon-object-specific data
  182. obj->rtype.pobj_info.model_num = Robot_info[obj->id].model_num;
  183. obj->rtype.pobj_info.subobj_flags = 0;
  184. //set Physics info
  185. obj->mtype.phys_info.flags |= (PF_LEVELLING);
  186. obj->shields = Robot_info[obj->id].strength;
  187. call_init_ai_object(obj, AIB_NORMAL);
  188. Cur_robot_type = obj->id;
  189. }
  190. }
  191. Update_flags |= UF_WORLD_CHANGED;
  192. return 1;
  193. }
  194. //-------------------------------------------------------------------------
  195. // Called when user presses "Prev Type" button. This only works for polygon
  196. // objects and it just selects the prev polygon model for the current object.
  197. //-------------------------------------------------------------------------
  198. int RobotPrevType()
  199. {
  200. if (Cur_object_index > -1 ) {
  201. if ( Objects[Cur_object_index].type == OBJ_ROBOT ) {
  202. object * obj = &Objects[Cur_object_index];
  203. if (obj->id == 0 )
  204. obj->id = N_robot_types-1;
  205. else
  206. obj->id--;
  207. //Set polygon-object-specific data
  208. obj->rtype.pobj_info.model_num = Robot_info[obj->id].model_num;
  209. obj->rtype.pobj_info.subobj_flags = 0;
  210. //set Physics info
  211. obj->mtype.phys_info.flags |= (PF_LEVELLING);
  212. obj->shields = Robot_info[obj->id].strength;
  213. call_init_ai_object(obj, AIB_NORMAL);
  214. Cur_robot_type = obj->id;
  215. }
  216. }
  217. Update_flags |= UF_WORLD_CHANGED;
  218. return 1;
  219. }
  220. //-------------------------------------------------------------------------
  221. // Dummy function for Mike to write.
  222. //-------------------------------------------------------------------------
  223. int med_set_ai_path()
  224. {
  225. mprintf( (0, "med-set-ai-path called -- it does nothing, paths automatically set!\n" ));
  226. return 1;
  227. }
  228. // #define OBJ_NONE 255 //unused object
  229. // #define OBJ_WALL 0 //A wall... not really an object, but used for collisions
  230. // #define OBJ_FIREBALL 1 //a fireball, part of an explosion
  231. // #define OBJ_ROBOT 2 //an evil enemy
  232. // #define OBJ_HOSTAGE 3 //a hostage you need to rescue
  233. // #define OBJ_PLAYER 4 //the player on the console
  234. // #define OBJ_WEAPON 5 //a laser, missile, etc
  235. // #define OBJ_CAMERA 6 //a camera to slew around with
  236. // #define OBJ_POWERUP 7 //a powerup you can pick up
  237. // #define OBJ_DEBRIS 8 //a piece of robot
  238. // #define OBJ_CNTRLCEN 9 //the control center
  239. // #define OBJ_FLARE 10 //the control center
  240. // #define MAX_OBJECT_TYPES 11
  241. #define GOODY_TYPE_MAX MAX_OBJECT_TYPES
  242. #define GOODY_X 6
  243. #define GOODY_Y 132
  244. //#define GOODY_ID_MAX_ROBOT 6
  245. //#define GOODY_ID_MAX_POWERUP 9
  246. #define GOODY_COUNT_MAX 4
  247. int Cur_goody_type = OBJ_POWERUP;
  248. int Cur_goody_id = 0;
  249. int Cur_goody_count = 0;
  250. void update_goody_info(void)
  251. {
  252. if (Cur_object_index > -1 ) {
  253. if ( Objects[Cur_object_index].type == OBJ_ROBOT ) {
  254. object * obj = &Objects[Cur_object_index];
  255. obj->contains_type = Cur_goody_type;
  256. obj->contains_id = Cur_goody_id;
  257. obj->contains_count = Cur_goody_count;
  258. }
  259. }
  260. }
  261. // #define OBJ_WALL 0 //A wall... not really an object, but used for collisions
  262. // #define OBJ_FIREBALL 1 //a fireball, part of an explosion
  263. // #define OBJ_ROBOT 2 //an evil enemy
  264. // #define OBJ_HOSTAGE 3 //a hostage you need to rescue
  265. // #define OBJ_PLAYER 4 //the player on the console
  266. // #define OBJ_WEAPON 5 //a laser, missile, etc
  267. // #define OBJ_CAMERA 6 //a camera to slew around with
  268. // #define OBJ_POWERUP 7 //a powerup you can pick up
  269. // #define OBJ_DEBRIS 8 //a piece of robot
  270. // #define OBJ_CNTRLCEN 9 //the control center
  271. // #define OBJ_FLARE 10 //the control center
  272. // #define MAX_OBJECT_TYPES 11
  273. int GoodyNextType()
  274. {
  275. Cur_goody_type++;
  276. while (!((Cur_goody_type == OBJ_ROBOT) || (Cur_goody_type == OBJ_POWERUP))) {
  277. if (Cur_goody_type > GOODY_TYPE_MAX)
  278. Cur_goody_type=0;
  279. else
  280. Cur_goody_type++;
  281. }
  282. GoodyNextID();
  283. GoodyPrevID();
  284. update_goody_info();
  285. return 1;
  286. }
  287. int GoodyPrevType()
  288. {
  289. Cur_goody_type--;
  290. while (!((Cur_goody_type == OBJ_ROBOT) || (Cur_goody_type == OBJ_POWERUP))) {
  291. if (Cur_goody_type < 0)
  292. Cur_goody_type = GOODY_TYPE_MAX;
  293. else
  294. Cur_goody_type--;
  295. }
  296. GoodyNextID();
  297. GoodyPrevID();
  298. update_goody_info();
  299. return 1;
  300. }
  301. int GoodyNextID()
  302. {
  303. Cur_goody_id++;
  304. if (Cur_goody_type == OBJ_ROBOT) {
  305. if (Cur_goody_id >= N_robot_types)
  306. Cur_goody_id=0;
  307. } else {
  308. if (Cur_goody_id >= N_powerup_types)
  309. Cur_goody_id=0;
  310. }
  311. update_goody_info();
  312. return 1;
  313. }
  314. int GoodyPrevID()
  315. {
  316. Cur_goody_id--;
  317. if (Cur_goody_type == OBJ_ROBOT) {
  318. if (Cur_goody_id < 0)
  319. Cur_goody_id = N_robot_types-1;
  320. } else {
  321. if (Cur_goody_id < 0)
  322. Cur_goody_id = N_powerup_types-1;
  323. }
  324. update_goody_info();
  325. return 1;
  326. }
  327. int GoodyNextCount()
  328. {
  329. Cur_goody_count++;
  330. if (Cur_goody_count > GOODY_COUNT_MAX)
  331. Cur_goody_count=0;
  332. update_goody_info();
  333. return 1;
  334. }
  335. int GoodyPrevCount()
  336. {
  337. Cur_goody_count--;
  338. if (Cur_goody_count < 0)
  339. Cur_goody_count=GOODY_COUNT_MAX;
  340. update_goody_info();
  341. return 1;
  342. }
  343. int is_legal_type(int the_type)
  344. {
  345. return (the_type == OBJ_ROBOT) || (the_type == OBJ_CLUTTER);
  346. }
  347. int is_legal_type_for_this_window(int objnum)
  348. {
  349. if (objnum == -1)
  350. return 1;
  351. else
  352. return is_legal_type(Objects[objnum].type);
  353. }
  354. int LocalObjectSelectNextinSegment(void)
  355. {
  356. int rval, first_obj;
  357. rval = ObjectSelectNextinSegment();
  358. first_obj = Cur_object_index;
  359. if (Cur_object_index != -1) {
  360. while (!is_legal_type_for_this_window(Cur_object_index)) {
  361. //mprintf((0, "Skipping object #%i of type %i\n", Cur_object_index, Objects[Cur_object_index].type));
  362. rval = ObjectSelectNextinSegment();
  363. if (first_obj == Cur_object_index)
  364. break;
  365. }
  366. Cur_goody_type = Objects[Cur_object_index].contains_type;
  367. Cur_goody_id = Objects[Cur_object_index].contains_id;
  368. if (Objects[Cur_object_index].contains_count < 0)
  369. Objects[Cur_object_index].contains_count = 0;
  370. Cur_goody_count = Objects[Cur_object_index].contains_count;
  371. }
  372. if (Cur_object_index != first_obj)
  373. set_view_target_from_segment(Cursegp);
  374. return rval;
  375. }
  376. int LocalObjectSelectNextinMine(void)
  377. {
  378. int rval, first_obj;
  379. rval = ObjectSelectNextInMine();
  380. first_obj = Cur_object_index;
  381. if (Cur_object_index != -1) {
  382. while (!is_legal_type_for_this_window(Cur_object_index)) {
  383. //mprintf((0, "Skipping object #%i of type %i\n", Cur_object_index, Objects[Cur_object_index].type));
  384. ObjectSelectNextInMine();
  385. if (Cur_object_index == first_obj)
  386. break;
  387. }
  388. Cur_goody_type = Objects[Cur_object_index].contains_type;
  389. Cur_goody_id = Objects[Cur_object_index].contains_id;
  390. if (Objects[Cur_object_index].contains_count < 0)
  391. Objects[Cur_object_index].contains_count = 0;
  392. Cur_goody_count = Objects[Cur_object_index].contains_count;
  393. }
  394. if (Cur_object_index != first_obj)
  395. set_view_target_from_segment(Cursegp);
  396. return rval;
  397. }
  398. int LocalObjectSelectPrevinMine(void)
  399. {
  400. int rval, first_obj;
  401. rval = ObjectSelectPrevInMine();
  402. first_obj = Cur_object_index;
  403. if (Cur_object_index != -1) {
  404. while (!is_legal_type_for_this_window(Cur_object_index)) {
  405. //mprintf((0, "Skipping object #%i of type %i\n", Cur_object_index, Objects[Cur_object_index].type));
  406. ObjectSelectPrevInMine();
  407. if (first_obj == Cur_object_index)
  408. break;
  409. }
  410. Cur_goody_type = Objects[Cur_object_index].contains_type;
  411. Cur_goody_id = Objects[Cur_object_index].contains_id;
  412. if (Objects[Cur_object_index].contains_count < 0)
  413. Objects[Cur_object_index].contains_count = 0;
  414. Cur_goody_count = Objects[Cur_object_index].contains_count;
  415. }
  416. if (Cur_object_index != first_obj)
  417. set_view_target_from_segment(Cursegp);
  418. return rval;
  419. }
  420. int LocalObjectDelete(void)
  421. {
  422. int rval;
  423. rval = ObjectDelete();
  424. if (Cur_object_index != -1) {
  425. Cur_goody_type = Objects[Cur_object_index].contains_type;
  426. Cur_goody_id = Objects[Cur_object_index].contains_id;
  427. Cur_goody_count = Objects[Cur_object_index].contains_count;
  428. }
  429. set_view_target_from_segment(Cursegp);
  430. return rval;
  431. }
  432. int LocalObjectPlaceObject(void)
  433. {
  434. int rval;
  435. Cur_goody_count = 0;
  436. while (ObjType[Cur_robot_type] != OL_ROBOT) { // && (ObjType[Cur_robot_type] != OL_POWERUP)) {
  437. Cur_robot_type++;
  438. if (Cur_robot_type >= N_robot_types)
  439. Cur_robot_type = 0;
  440. }
  441. rval = ObjectPlaceObject();
  442. if (rval == -1)
  443. return -1;
  444. Objects[Cur_object_index].contains_type = Cur_goody_type;
  445. Objects[Cur_object_index].contains_id = Cur_goody_id;
  446. Objects[Cur_object_index].contains_count = Cur_goody_count;
  447. set_view_target_from_segment(Cursegp);
  448. return rval;
  449. }
  450. void close_all_windows(void)
  451. {
  452. close_trigger_window();
  453. close_wall_window();
  454. close_centers_window();
  455. hostage_close_window();
  456. robot_close_window();
  457. }
  458. //-------------------------------------------------------------------------
  459. // Called from the editor... does one instance of the robot dialog box
  460. //-------------------------------------------------------------------------
  461. int do_robot_dialog()
  462. {
  463. int i;
  464. // Only open 1 instance of this window...
  465. if ( MainWindow != NULL ) return 0;
  466. // Close other windows
  467. close_all_windows();
  468. Cur_goody_count = 0;
  469. // Open a window with a quit button
  470. MainWindow = ui_open_window( TMAPBOX_X+20, TMAPBOX_Y+20, 765-TMAPBOX_X, 545-TMAPBOX_Y, WIN_DIALOG );
  471. QuitButton = ui_add_gadget_button( MainWindow, 20, 286, 40, 32, "Done", NULL );
  472. ui_add_gadget_button( MainWindow, GOODY_X+50, GOODY_Y-3, 25, 22, "<<", GoodyPrevType );
  473. ui_add_gadget_button( MainWindow, GOODY_X+80, GOODY_Y-3, 25, 22, ">>", GoodyNextType );
  474. ui_add_gadget_button( MainWindow, GOODY_X+50, GOODY_Y+21, 25, 22, "<<", GoodyPrevID );
  475. ui_add_gadget_button( MainWindow, GOODY_X+80, GOODY_Y+21, 25, 22, ">>", GoodyNextID );
  476. ui_add_gadget_button( MainWindow, GOODY_X+50, GOODY_Y+45, 25, 22, "<<", GoodyPrevCount );
  477. ui_add_gadget_button( MainWindow, GOODY_X+80, GOODY_Y+45, 25, 22, ">>", GoodyNextCount );
  478. InitialMode[0] = ui_add_gadget_radio( MainWindow, 6, 58, 16, 16, 0, "Hover" );
  479. InitialMode[1] = ui_add_gadget_radio( MainWindow, 76, 58, 16, 16, 0, "Normal" );
  480. InitialMode[2] = ui_add_gadget_radio( MainWindow, 6, 78, 16, 16, 0, "(hide)" );
  481. InitialMode[3] = ui_add_gadget_radio( MainWindow, 76, 78, 16, 16, 0, "Avoid" );
  482. InitialMode[4] = ui_add_gadget_radio( MainWindow, 6, 98, 16, 16, 0, "Follow" );
  483. InitialMode[5] = ui_add_gadget_radio( MainWindow, 76, 98, 16, 16, 0, "Station" );
  484. // The little box the robots will spin in.
  485. RobotViewBox = ui_add_gadget_userbox( MainWindow,155, 5, 150, 125 );
  486. // The little box the robots will spin in.
  487. ContainsViewBox = ui_add_gadget_userbox( MainWindow,10, 202, 100, 80 );
  488. // A bunch of buttons...
  489. i = 135;
  490. ui_add_gadget_button( MainWindow,190,i,53, 26, "<<Typ", RobotPrevType );
  491. ui_add_gadget_button( MainWindow,247,i,53, 26, "Typ>>", RobotNextType ); i += 29;
  492. ui_add_gadget_button( MainWindow,190,i,110, 26, "Next in Seg", LocalObjectSelectNextinSegment ); i += 29;
  493. ui_add_gadget_button( MainWindow,190,i,53, 26, "<<Obj", LocalObjectSelectPrevinMine );
  494. ui_add_gadget_button( MainWindow,247,i,53, 26, ">>Obj", LocalObjectSelectNextinMine ); i += 29;
  495. ui_add_gadget_button( MainWindow,190,i,110, 26, "Delete", LocalObjectDelete ); i += 29;
  496. ui_add_gadget_button( MainWindow,190,i,110, 26, "Create New", LocalObjectPlaceObject ); i += 29;
  497. ui_add_gadget_button( MainWindow,190,i,110, 26, "Set Path", med_set_ai_path );
  498. Time = timer_get_fixed_seconds();
  499. old_object = -2; // Set to some dummy value so everything works ok on the first frame.
  500. if ( Cur_object_index == -1 )
  501. LocalObjectSelectNextinMine();
  502. return 1;
  503. }
  504. void robot_close_window()
  505. {
  506. if ( MainWindow!=NULL ) {
  507. ui_close_window( MainWindow );
  508. MainWindow = NULL;
  509. }
  510. }
  511. #define STRING_LENGTH 8
  512. void do_robot_window()
  513. {
  514. int i;
  515. fix DeltaTime, Temp;
  516. int first_object_index;
  517. if ( MainWindow == NULL ) return;
  518. first_object_index = Cur_object_index;
  519. while (!is_legal_type_for_this_window(Cur_object_index)) {
  520. LocalObjectSelectNextinMine();
  521. if (first_object_index == Cur_object_index) {
  522. break;
  523. }
  524. }
  525. //------------------------------------------------------------
  526. // Call the ui code..
  527. //------------------------------------------------------------
  528. ui_button_any_drawn = 0;
  529. ui_window_do_gadgets(MainWindow);
  530. //------------------------------------------------------------
  531. // If we change objects, we need to reset the ui code for all
  532. // of the radio buttons that control the ai mode. Also makes
  533. // the current AI mode button be flagged as pressed down.
  534. //------------------------------------------------------------
  535. if (old_object != Cur_object_index ) {
  536. for ( i=0; i < NUM_BOXES; i++ ) {
  537. InitialMode[i]->flag = 0; // Tells ui that this button isn't checked
  538. InitialMode[i]->status = 1; // Tells ui to redraw button
  539. }
  540. if ( Cur_object_index > -1 ) {
  541. int behavior = Objects[Cur_object_index].ctype.ai_info.behavior;
  542. if ( !((behavior >= MIN_BEHAVIOR) && (behavior <= MAX_BEHAVIOR))) {
  543. mprintf((0, "Object #%i behavior id (%i) out of bounds, setting to AIB_NORMAL.\n", Cur_object_index, behavior));
  544. Objects[Cur_object_index].ctype.ai_info.behavior = AIB_NORMAL;
  545. behavior = AIB_NORMAL;
  546. }
  547. InitialMode[behavior - MIN_BEHAVIOR]->flag = 1; // Mark this button as checked
  548. }
  549. }
  550. //------------------------------------------------------------
  551. // If any of the radio buttons that control the mode are set, then
  552. // update the cooresponding AI state.
  553. //------------------------------------------------------------
  554. for ( i=0; i < NUM_BOXES; i++ ) {
  555. if ( InitialMode[i]->flag == 1 )
  556. if (Objects[Cur_object_index].ctype.ai_info.behavior != MIN_BEHAVIOR+i) {
  557. Objects[Cur_object_index].ctype.ai_info.behavior = MIN_BEHAVIOR+i; // Set the ai_state to the cooresponding radio button
  558. call_init_ai_object(&Objects[Cur_object_index], MIN_BEHAVIOR+i);
  559. }
  560. }
  561. //------------------------------------------------------------
  562. // A simple frame time counter for spinning the objects...
  563. //------------------------------------------------------------
  564. Temp = timer_get_fixed_seconds();
  565. DeltaTime = Temp - Time;
  566. Time = Temp;
  567. //------------------------------------------------------------
  568. // Redraw the object in the little 64x64 box
  569. //------------------------------------------------------------
  570. if (Cur_object_index > -1 ) {
  571. int id;
  572. gr_set_current_canvas( RobotViewBox->canvas );
  573. id = get_object_id(&Objects[Cur_object_index]);
  574. if ( id > -1 )
  575. draw_robot_picture(id, &angles, -1 );
  576. else
  577. gr_clear_canvas( CGREY );
  578. angles.h += fixmul(0x1000, DeltaTime );
  579. } else {
  580. // no object, so just blank out
  581. gr_set_current_canvas( RobotViewBox->canvas );
  582. gr_clear_canvas( CGREY );
  583. // LocalObjectSelectNextInMine();
  584. }
  585. //------------------------------------------------------------
  586. // Redraw the contained object in the other little box
  587. //------------------------------------------------------------
  588. if ((Cur_object_index > -1 ) && (Cur_goody_count > 0)) {
  589. int id;
  590. gr_set_current_canvas( ContainsViewBox->canvas );
  591. id = Cur_goody_id;
  592. if ( id > -1 ) {
  593. int ol_type;
  594. if (Cur_goody_type == OBJ_ROBOT)
  595. ol_type = OL_ROBOT;
  596. else if (Cur_goody_type == OBJ_POWERUP)
  597. ol_type = OL_POWERUP;
  598. else
  599. Int3(); // Error? Unknown goody type!
  600. draw_robot_picture(id, &goody_angles, ol_type );
  601. } else
  602. gr_clear_canvas( CGREY );
  603. goody_angles.h += fixmul(0x1000, DeltaTime );
  604. } else {
  605. // no object, so just blank out
  606. gr_set_current_canvas( ContainsViewBox->canvas );
  607. gr_clear_canvas( CGREY );
  608. // LocalObjectSelectNextInMine();
  609. }
  610. //------------------------------------------------------------
  611. // If anything changes in the ui system, redraw all the text that
  612. // identifies this robot.
  613. //------------------------------------------------------------
  614. if (ui_button_any_drawn || (old_object != Cur_object_index) ) {
  615. int i;
  616. char type_text[STRING_LENGTH+1],id_text[STRING_LENGTH+1];
  617. if (Cur_object_index != -1) {
  618. Cur_goody_type = Objects[Cur_object_index].contains_type;
  619. Cur_goody_id = Objects[Cur_object_index].contains_id;
  620. if (Objects[Cur_object_index].contains_count < 0)
  621. Objects[Cur_object_index].contains_count = 0;
  622. Cur_goody_count = Objects[Cur_object_index].contains_count;
  623. }
  624. ui_wprintf_at( MainWindow, GOODY_X, GOODY_Y, " Type:");
  625. ui_wprintf_at( MainWindow, GOODY_X, GOODY_Y+24, " ID:");
  626. ui_wprintf_at( MainWindow, GOODY_X, GOODY_Y+48, "Count:");
  627. for (i=0; i<STRING_LENGTH; i++)
  628. id_text[i] = ' ';
  629. id_text[i] = 0;
  630. switch (Cur_goody_type) {
  631. case OBJ_ROBOT:
  632. strcpy(type_text, "Robot ");
  633. strncpy(id_text, Robot_names[Cur_goody_id], strlen(Robot_names[Cur_goody_id]));
  634. break;
  635. case OBJ_POWERUP:
  636. strcpy(type_text, "Powerup");
  637. strncpy(id_text, Powerup_names[Cur_goody_id], strlen(Powerup_names[Cur_goody_id]));
  638. break;
  639. default:
  640. editor_status("Illegal contained object type (%i), changing to powerup.", Cur_goody_type);
  641. Cur_goody_type = OBJ_POWERUP;
  642. Cur_goody_id = 0;
  643. strcpy(type_text, "Powerup");
  644. strncpy(id_text, Powerup_names[Cur_goody_id], strlen(Powerup_names[Cur_goody_id]));
  645. break;
  646. }
  647. ui_wprintf_at( MainWindow, GOODY_X+108, GOODY_Y, type_text);
  648. ui_wprintf_at( MainWindow, GOODY_X+108, GOODY_Y+24, id_text);
  649. ui_wprintf_at( MainWindow, GOODY_X+108, GOODY_Y+48, "%i", Cur_goody_count);
  650. if ( Cur_object_index > -1 ) {
  651. int id = Objects[Cur_object_index].id;
  652. char id_text[12];
  653. int i;
  654. for (i=0; i<STRING_LENGTH; i++)
  655. id_text[i] = ' ';
  656. id_text[i] = 0;
  657. strncpy(id_text, Robot_names[id], strlen(Robot_names[id]));
  658. ui_wprintf_at( MainWindow, 12, 6, "Robot: %3d ", Cur_object_index );
  659. ui_wprintf_at( MainWindow, 12, 22, " Id: %3d", id);
  660. ui_wprintf_at( MainWindow, 12, 38, " Name: %8s", id_text);
  661. } else {
  662. ui_wprintf_at( MainWindow, 12, 6, "Robot: none" );
  663. ui_wprintf_at( MainWindow, 12, 22, " Type: ? " );
  664. ui_wprintf_at( MainWindow, 12, 38, " Name: ________" );
  665. }
  666. Update_flags |= UF_WORLD_CHANGED;
  667. }
  668. if ( QuitButton->pressed || (last_keypress==KEY_ESC)) {
  669. robot_close_window();
  670. return;
  671. }
  672. old_object = Cur_object_index;
  673. }
  674. // --------------------------------------------------------------------------------------------------------------------------
  675. #define NUM_MATT_THINGS 2
  676. #define MATT_LEN 20
  677. static UI_WINDOW *MattWindow = NULL;
  678. void object_close_window()
  679. {
  680. if ( MattWindow!=NULL ) {
  681. ui_close_window( MattWindow );
  682. MattWindow = NULL;
  683. }
  684. }
  685. UI_GADGET_INPUTBOX *Xtext, *Ytext, *Ztext;
  686. //-------------------------------------------------------------------------
  687. // Called from the editor... does one instance of the object dialog box
  688. //-------------------------------------------------------------------------
  689. int do_object_dialog()
  690. {
  691. char Xmessage[MATT_LEN], Ymessage[MATT_LEN], Zmessage[MATT_LEN];
  692. object *obj=&Objects[Cur_object_index];
  693. if (obj->type == OBJ_ROBOT) //don't do this for robots
  694. return 0;
  695. // Only open 1 instance of this window...
  696. if ( MattWindow != NULL )
  697. return 0;
  698. Cur_goody_count = 0;
  699. // Open a window with a quit button
  700. MattWindow = ui_open_window( TMAPBOX_X+20, TMAPBOX_Y+20, 765-TMAPBOX_X, 545-TMAPBOX_Y, WIN_DIALOG );
  701. QuitButton = ui_add_gadget_button( MattWindow, 20, 286, 40, 32, "Done", NULL );
  702. QuitButton->hotkey = KEY_ENTER;
  703. // These are the radio buttons for each mode
  704. InitialMode[0] = ui_add_gadget_radio( MattWindow, 10, 50, 16, 16, 0, "None" );
  705. InitialMode[1] = ui_add_gadget_radio( MattWindow, 80, 50, 16, 16, 0, "Spinning" );
  706. InitialMode[obj->movement_type == MT_SPINNING?1:0]->flag = 1;
  707. sprintf(Xmessage,"%.2f",f2fl(obj->mtype.spin_rate.x));
  708. sprintf(Ymessage,"%.2f",f2fl(obj->mtype.spin_rate.y));
  709. sprintf(Zmessage,"%.2f",f2fl(obj->mtype.spin_rate.z));
  710. ui_wprintf_at( MattWindow, 10, 132,"&X:" );
  711. Xtext = ui_add_gadget_inputbox( MattWindow, 30, 132, MATT_LEN, MATT_LEN, Xmessage );
  712. ui_wprintf_at( MattWindow, 10, 162,"&Y:" );
  713. Ytext = ui_add_gadget_inputbox( MattWindow, 30, 162, MATT_LEN, MATT_LEN, Ymessage );
  714. ui_wprintf_at( MattWindow, 10, 192,"&Z:" );
  715. Ztext = ui_add_gadget_inputbox( MattWindow, 30, 192, MATT_LEN, MATT_LEN, Zmessage );
  716. ui_gadget_calc_keys(MattWindow);
  717. MattWindow->keyboard_focus_gadget = (UI_GADGET *) InitialMode[0];
  718. mprintf((0, "X = %08x, Y = %08x, Z = %08x\n", atoi(Xmessage), atoi(Ymessage), atoi(Zmessage)));
  719. return 1;
  720. }
  721. void do_object_window()
  722. {
  723. object *obj=&Objects[Cur_object_index];
  724. if ( MattWindow == NULL ) return;
  725. //------------------------------------------------------------
  726. // Call the ui code..
  727. //------------------------------------------------------------
  728. ui_button_any_drawn = 0;
  729. ui_window_do_gadgets(MattWindow);
  730. if ( QuitButton->pressed || (last_keypress==KEY_ESC)) {
  731. if (InitialMode[0]->flag) obj->movement_type = MT_NONE;
  732. if (InitialMode[1]->flag) obj->movement_type = MT_SPINNING;
  733. obj->mtype.spin_rate.x = fl2f(atof(Xtext->text));
  734. obj->mtype.spin_rate.y = fl2f(atof(Ytext->text));
  735. obj->mtype.spin_rate.z = fl2f(atof(Ztext->text));
  736. object_close_window();
  737. return;
  738. }
  739. old_object = Cur_object_index;
  740. }
  741. void set_all_modes_to_hover(void)
  742. {
  743. int i;
  744. for (i=0; i<=Highest_object_index; i++)
  745. if (Objects[i].control_type == CT_AI)
  746. Objects[i].ctype.ai_info.behavior = AIB_STILL;
  747. }
  748.