2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
14 * $Source: /cvs/cvsroot/d2x/main/editor/eswitch.c,v $
17 * $Date: 2004-12-19 13:54:27 $
19 * Editor switch functions.
21 * $Log: not supported by cvs2svn $
22 * Revision 1.1.1.1 1999/06/14 22:03:03 donut
23 * Import of d1x 1.37 source.
25 * Revision 2.0 1995/02/27 11:35:18 john
26 * Version 2.0! No anonymous unions, Watcom 10.0, with no need
29 * Revision 1.33 1995/01/14 19:18:04 john
30 * First version of object paging.
32 * Revision 1.32 1994/11/27 23:18:01 matt
33 * Made changes for new mprintf calling convention
35 * Revision 1.31 1994/11/07 10:55:42 yuan
36 * *** empty log message ***
38 * Revision 1.30 1994/10/13 13:15:06 yuan
39 * Fixed trigger removal bug.
41 * Revision 1.29 1994/10/06 21:24:16 matt
42 * Added switch for exit to secret level
44 * Revision 1.28 1994/09/29 17:06:10 matt
45 * Took out references to obsolete external triggers
47 * Revision 1.27 1994/09/28 13:40:34 yuan
48 * Fixed control center trigger bug.
50 * Revision 1.26 1994/09/26 16:25:04 yuan
51 * Only allow one binding of each matcen .
53 * Revision 1.25 1994/09/24 17:10:19 yuan
54 * Added Matcen triggers.
56 * Revision 1.24 1994/09/20 18:23:58 yuan
57 * Killed the BOGIFYING WALL DRAGON...
59 * There was a problem with triggers being created that had bogus
60 * pointers back to their segments.
62 * Revision 1.23 1994/08/25 21:56:33 mike
65 * Revision 1.22 1994/08/15 18:06:54 yuan
66 * Added external trigger.
68 * Revision 1.21 1994/07/22 17:18:47 yuan
69 * Working on dialog box for refuel/repair/material/control centers.
71 * Revision 1.20 1994/07/06 10:55:55 john
72 * New structures for hostages.
74 * Revision 1.19 1994/07/01 16:36:20 yuan
75 * Working on triggers that aren't always on.
77 * Revision 1.18 1994/06/21 18:50:14 john
78 * Made ESC key exit dialog.
80 * Revision 1.17 1994/06/20 22:30:36 yuan
81 * Fixed crazy runaway trigger bug that Adam found
83 * Revision 1.16 1994/05/31 10:03:48 yuan
84 * Fixed compiler warnings...
87 * Revision 1.15 1994/05/30 20:22:30 yuan
90 * Revision 1.14 1994/05/27 12:33:50 yuan
91 * Fixed some bugs when adding trigger.
93 * Revision 1.13 1994/05/27 10:34:29 yuan
94 * Added new Dialog boxes for Walls and Triggers.
96 * Revision 1.12 1994/05/25 18:15:02 yuan
97 * Fixed make warnings to save 10 cents!
99 * Revision 1.11 1994/05/25 18:08:03 yuan
100 * Revamping walls and triggers interface.
101 * Wall interface complete, but triggers are still in progress.
103 * Revision 1.10 1994/04/29 15:05:50 yuan
104 * Trigger/Link removing stuff still needs to be fixed.
106 * Revision 1.9 1994/04/28 23:25:34 yuan
107 * Obliterated warnings.
109 * Revision 1.8 1994/04/28 18:08:06 yuan
116 static char rcsid[] = "$Id: eswitch.c,v 1.1 2004-12-19 13:54:27 btb Exp $";
136 #include "textures.h"
137 #include "texmerge.h"
138 #include "medrobot.h"
141 #include "ehostage.h"
145 //-------------------------------------------------------------------------
146 // Variables for this module...
147 //-------------------------------------------------------------------------
148 #define NUM_TRIGGER_FLAGS 10
150 static UI_WINDOW *MainWindow = NULL;
151 static UI_GADGET_USERBOX *WallViewBox;
152 static UI_GADGET_BUTTON *QuitButton;
153 static UI_GADGET_CHECKBOX *TriggerFlag[NUM_TRIGGER_FLAGS];
155 static int old_trigger_num;
157 //-----------------------------------------------------------------
158 // Adds a trigger to wall, and returns the trigger number.
159 // If there is a trigger already present, it returns the trigger number. (To be replaced)
160 int add_trigger(segment *seg, short side)
162 int trigger_num = Num_triggers;
163 int wall_num = seg->sides[side].wall_num;
165 Assert(trigger_num < MAX_TRIGGERS);
166 if (trigger_num>=MAX_TRIGGERS) return -1;
168 if (wall_num == -1) {
169 wall_add_to_markedside(WALL_OPEN);
170 wall_num = seg->sides[side].wall_num;
171 Walls[wall_num].trigger = trigger_num;
173 // Set default values first time trigger is added
174 Triggers[trigger_num].flags = 0;
175 Triggers[trigger_num].value = F1_0*5;
176 Triggers[trigger_num].num_links = 0;
177 Triggers[trigger_num].flags &= TRIGGER_ON;
182 if (Walls[wall_num].trigger != -1)
183 return Walls[wall_num].trigger;
185 // Create new trigger.
186 Walls[wall_num].trigger = trigger_num;
188 // Set default values first time trigger is added
189 Triggers[trigger_num].flags = 0;
190 Triggers[trigger_num].value = F1_0*5;
191 Triggers[trigger_num].num_links = 0;
192 Triggers[trigger_num].flags &= TRIGGER_ON;
199 //-----------------------------------------------------------------
200 // Adds a specific trigger flag to Markedsegp/Markedside if it is possible.
201 // Automatically adds flag to Connectside if possible unless it is a control trigger.
202 // Returns 1 if trigger flag added.
203 // Returns 0 if trigger flag cannot be added.
204 int trigger_add_to_Markedside(short flag) {
205 int trigger_num; //, ctrigger_num;
208 editor_status("No Markedside.");
212 // If no child on Markedside return
213 if (!IS_CHILD(Markedsegp->children[Markedside])) return 0;
215 trigger_num = add_trigger(Markedsegp, Markedside);
217 if (trigger_num == -1) {
218 editor_status("Cannot add trigger at Markedside.");
222 Triggers[trigger_num].flags |= flag;
227 int trigger_remove_flag_from_Markedside(short flag) {
228 int trigger_num; //, ctrigger_num;
232 editor_status("No Markedside.");
236 // If no child on Markedside return
237 if (!IS_CHILD(Markedsegp->children[Markedside])) return 0;
239 // If no wall just return
240 wall_num = Markedsegp->sides[Markedside].wall_num;
241 if (wall_num == -1) return 0;
243 trigger_num = Walls[wall_num].trigger;
245 // If flag is already cleared, then don't change anything.
246 if ( trigger_num == -1 ) {
247 editor_status("No trigger at Markedside.");
251 if (!Triggers[trigger_num].flags & flag)
254 Triggers[trigger_num].flags &= ~flag;
260 int bind_matcen_to_trigger() {
262 int wall_num, trigger_num, link_num;
266 editor_status("No marked segment.");
270 wall_num = Markedsegp->sides[Markedside].wall_num;
271 if (wall_num == -1) {
272 editor_status("No wall at Markedside.");
276 trigger_num = Walls[wall_num].trigger;
278 if (trigger_num == -1) {
279 editor_status("No trigger at Markedside.");
283 if (!(Cursegp->special & SEGMENT_IS_ROBOTMAKER)) {
284 editor_status("No Matcen at Cursegp.");
288 link_num = Triggers[trigger_num].num_links;
289 for (i=0;i<link_num;i++)
290 if (Cursegp-Segments == Triggers[trigger_num].seg[i]) {
291 editor_status("Matcen already bound to Markedside.");
295 // Error checking completed, actual binding begins
296 Triggers[trigger_num].seg[link_num] = Cursegp - Segments;
297 Triggers[trigger_num].num_links++;
299 mprintf((0, "seg %d linked to link_num %d\n",
300 Triggers[trigger_num].seg[link_num], link_num));
302 editor_status("Matcen linked to trigger");
308 int bind_wall_to_trigger() {
310 int wall_num, trigger_num, link_num;
314 editor_status("No marked segment.");
318 wall_num = Markedsegp->sides[Markedside].wall_num;
319 if (wall_num == -1) {
320 editor_status("No wall at Markedside.");
324 trigger_num = Walls[wall_num].trigger;
326 if (trigger_num == -1) {
327 editor_status("No trigger at Markedside.");
331 if (Cursegp->sides[Curside].wall_num == -1) {
332 editor_status("No wall at Curside.");
336 if ((Cursegp==Markedsegp) && (Curside==Markedside)) {
337 editor_status("Cannot bind wall to itself.");
341 link_num = Triggers[trigger_num].num_links;
342 for (i=0;i<link_num;i++)
343 if ((Cursegp-Segments == Triggers[trigger_num].seg[i]) && (Curside == Triggers[trigger_num].side[i])) {
344 editor_status("Curside already bound to Markedside.");
348 // Error checking completed, actual binding begins
349 Triggers[trigger_num].seg[link_num] = Cursegp - Segments;
350 Triggers[trigger_num].side[link_num] = Curside;
351 Triggers[trigger_num].num_links++;
353 mprintf((0, "seg %d:side %d linked to link_num %d\n",
354 Triggers[trigger_num].seg[link_num], Triggers[trigger_num].side[link_num], link_num));
356 editor_status("Wall linked to trigger");
361 int remove_trigger(segment *seg, short side)
363 int trigger_num, t, w;
365 if (seg->sides[side].wall_num == -1) {
366 mprintf((0, "Can't remove trigger from wall_num -1\n"));
370 trigger_num = Walls[seg->sides[side].wall_num].trigger;
372 if (trigger_num != -1) {
373 Walls[seg->sides[side].wall_num].trigger = -1;
374 for (t=trigger_num;t<Num_triggers-1;t++)
375 Triggers[t] = Triggers[t+1];
377 for (w=0; w<Num_walls; w++) {
378 if (Walls[w].trigger > trigger_num)
383 for (t=0;t<Num_walls;t++)
384 if (Walls[seg->sides[side].wall_num].trigger > trigger_num)
385 Walls[seg->sides[side].wall_num].trigger--;
390 editor_status("No trigger to remove");
395 int add_trigger_control()
397 trigger_add_to_Markedside(TRIGGER_CONTROL_DOORS);
398 Update_flags = UF_WORLD_CHANGED;
404 remove_trigger(Markedsegp, Markedside);
405 Update_flags = UF_WORLD_CHANGED;
409 int trigger_turn_all_ON()
413 for (t=0;t<Num_triggers;t++)
414 Triggers[t].flags &= TRIGGER_ON;
418 //-------------------------------------------------------------------------
419 // Called from the editor... does one instance of the trigger dialog box
420 //-------------------------------------------------------------------------
421 int do_trigger_dialog()
426 editor_status("Trigger requires Marked Segment & Side.");
430 // Only open 1 instance of this window...
431 if ( MainWindow != NULL ) return 0;
433 // Close other windows.
434 robot_close_window();
436 close_centers_window();
437 hostage_close_window();
439 // Open a window with a quit button
440 MainWindow = ui_open_window( TMAPBOX_X+20, TMAPBOX_Y+20, 765-TMAPBOX_X, 545-TMAPBOX_Y, WIN_DIALOG );
442 // These are the checkboxes for each door flag.
444 TriggerFlag[0] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Door Control" ); i+=22;
445 TriggerFlag[1] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Shield damage" ); i+=22;
446 TriggerFlag[2] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Energy drain" ); i+=22;
447 TriggerFlag[3] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Exit" ); i+=22;
448 TriggerFlag[4] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "One-shot" ); i+=22;
449 TriggerFlag[5] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Illusion ON" ); i+=22;
450 TriggerFlag[6] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Illusion OFF" ); i+=22;
451 TriggerFlag[7] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Trigger ON" ); i+=22;
452 TriggerFlag[8] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Matcen Trigger" ); i+=22;
453 TriggerFlag[9] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Secret Exit" ); i+=22;
455 QuitButton = ui_add_gadget_button( MainWindow, 20, i, 48, 40, "Done", NULL );
457 // The little box the wall will appear in.
458 WallViewBox = ui_add_gadget_userbox( MainWindow, 155, 5, 64, 64 );
460 // A bunch of buttons...
462 // ui_add_gadget_button( MainWindow,155,i,140, 26, "Add Door Control", add_trigger_control ); i += 29;
463 ui_add_gadget_button( MainWindow,155,i,140, 26, "Remove Trigger", trigger_remove ); i += 29;
464 ui_add_gadget_button( MainWindow,155,i,140, 26, "Bind Wall", bind_wall_to_trigger ); i += 29;
465 ui_add_gadget_button( MainWindow,155,i,140, 26, "Bind Matcen", bind_matcen_to_trigger ); i += 29;
466 ui_add_gadget_button( MainWindow,155,i,140, 26, "All Triggers ON", trigger_turn_all_ON ); i += 29;
468 old_trigger_num = -2; // Set to some dummy value so everything works ok on the first frame.
473 void close_trigger_window()
475 if ( MainWindow!=NULL ) {
476 ui_close_window( MainWindow );
481 void do_trigger_window()
484 short Markedwall, trigger_num;
486 if ( MainWindow == NULL ) return;
488 close_trigger_window();
492 //------------------------------------------------------------
493 // Call the ui code..
494 //------------------------------------------------------------
495 ui_button_any_drawn = 0;
496 ui_window_do_gadgets(MainWindow);
498 //------------------------------------------------------------
499 // If we change walls, we need to reset the ui code for all
500 // of the checkboxes that control the wall flags.
501 //------------------------------------------------------------
502 Markedwall = Markedsegp->sides[Markedside].wall_num;
503 if (Markedwall != -1)
504 trigger_num = Walls[Markedwall].trigger;
505 else trigger_num = -1;
507 if (old_trigger_num != trigger_num ) {
508 for ( i=0; i < NUM_TRIGGER_FLAGS; i++ ) {
509 TriggerFlag[i]->flag = 0; // Tells ui that this button isn't checked
510 TriggerFlag[i]->status = 1; // Tells ui to redraw button
513 if (trigger_num != -1) {
514 if (Triggers[trigger_num].flags & TRIGGER_CONTROL_DOORS)
515 TriggerFlag[0]->flag = 1;
516 if (Triggers[trigger_num].flags & TRIGGER_SHIELD_DAMAGE)
517 TriggerFlag[1]->flag = 1;
518 if (Triggers[trigger_num].flags & TRIGGER_ENERGY_DRAIN)
519 TriggerFlag[2]->flag = 1;
520 if (Triggers[trigger_num].flags & TRIGGER_EXIT)
521 TriggerFlag[3]->flag = 1;
522 if (Triggers[trigger_num].flags & TRIGGER_ONE_SHOT)
523 TriggerFlag[4]->flag = 1;
524 if (Triggers[trigger_num].flags & TRIGGER_ILLUSION_ON)
525 TriggerFlag[5]->flag = 1;
526 if (Triggers[trigger_num].flags & TRIGGER_ILLUSION_OFF)
527 TriggerFlag[6]->flag = 1;
528 if (Triggers[trigger_num].flags & TRIGGER_ON)
529 TriggerFlag[7]->flag = 1;
530 if (Triggers[trigger_num].flags & TRIGGER_MATCEN)
531 TriggerFlag[8]->flag = 1;
532 if (Triggers[trigger_num].flags & TRIGGER_SECRET_EXIT)
533 TriggerFlag[9]->flag = 1;
537 //------------------------------------------------------------
538 // If any of the checkboxes that control the wallflags are set, then
539 // update the cooresponding wall flag.
540 //------------------------------------------------------------
541 if (IS_CHILD(Markedsegp->children[Markedside])) {
542 if (TriggerFlag[0]->flag == 1)
543 trigger_add_to_Markedside(TRIGGER_CONTROL_DOORS);
545 trigger_remove_flag_from_Markedside(TRIGGER_CONTROL_DOORS);
546 if (TriggerFlag[1]->flag == 1)
547 trigger_add_to_Markedside(TRIGGER_SHIELD_DAMAGE);
549 trigger_remove_flag_from_Markedside(TRIGGER_SHIELD_DAMAGE);
550 if (TriggerFlag[2]->flag == 1)
551 trigger_add_to_Markedside(TRIGGER_ENERGY_DRAIN);
553 trigger_remove_flag_from_Markedside(TRIGGER_ENERGY_DRAIN);
554 if (TriggerFlag[3]->flag == 1)
555 trigger_add_to_Markedside(TRIGGER_EXIT);
557 trigger_remove_flag_from_Markedside(TRIGGER_EXIT);
558 if (TriggerFlag[4]->flag == 1)
559 trigger_add_to_Markedside(TRIGGER_ONE_SHOT);
561 trigger_remove_flag_from_Markedside(TRIGGER_ONE_SHOT);
562 if (TriggerFlag[5]->flag == 1)
563 trigger_add_to_Markedside(TRIGGER_ILLUSION_ON);
565 trigger_remove_flag_from_Markedside(TRIGGER_ILLUSION_ON);
566 if (TriggerFlag[6]->flag == 1)
567 trigger_add_to_Markedside(TRIGGER_ILLUSION_OFF);
569 trigger_remove_flag_from_Markedside(TRIGGER_ILLUSION_OFF);
570 if (TriggerFlag[7]->flag == 1)
571 trigger_add_to_Markedside(TRIGGER_ON);
573 trigger_remove_flag_from_Markedside(TRIGGER_ON);
575 if (TriggerFlag[8]->flag == 1)
576 trigger_add_to_Markedside(TRIGGER_MATCEN);
578 trigger_remove_flag_from_Markedside(TRIGGER_MATCEN);
580 if (TriggerFlag[9]->flag == 1)
581 trigger_add_to_Markedside(TRIGGER_SECRET_EXIT);
583 trigger_remove_flag_from_Markedside(TRIGGER_SECRET_EXIT);
586 for ( i=0; i < NUM_TRIGGER_FLAGS; i++ )
587 if (TriggerFlag[i]->flag == 1) {
588 TriggerFlag[i]->flag = 0; // Tells ui that this button isn't checked
589 TriggerFlag[i]->status = 1; // Tells ui to redraw button
592 //------------------------------------------------------------
593 // Draw the wall in the little 64x64 box
594 //------------------------------------------------------------
595 gr_set_current_canvas( WallViewBox->canvas );
597 if ((Markedsegp->sides[Markedside].wall_num == -1) || (Walls[Markedsegp->sides[Markedside].wall_num].trigger) == -1)
598 gr_clear_canvas( CBLACK );
600 if (Markedsegp->sides[Markedside].tmap_num2 > 0) {
601 gr_ubitmap(0,0, texmerge_get_cached_bitmap( Markedsegp->sides[Markedside].tmap_num, Markedsegp->sides[Markedside].tmap_num2));
603 if (Markedsegp->sides[Markedside].tmap_num > 0) {
604 PIGGY_PAGE_IN(Textures[Markedsegp->sides[Markedside].tmap_num]);
605 gr_ubitmap(0,0, &GameBitmaps[Textures[Markedsegp->sides[Markedside].tmap_num].index]);
607 gr_clear_canvas( CGREY );
611 //------------------------------------------------------------
612 // If anything changes in the ui system, redraw all the text that
613 // identifies this robot.
614 //------------------------------------------------------------
615 if (ui_button_any_drawn || (old_trigger_num != trigger_num) ) {
616 if ( Markedsegp->sides[Markedside].wall_num > -1 ) {
617 ui_wprintf_at( MainWindow, 12, 6, "Trigger: %d ", trigger_num);
619 ui_wprintf_at( MainWindow, 12, 6, "Trigger: none ");
621 Update_flags |= UF_WORLD_CHANGED;
624 if ( QuitButton->pressed || (last_keypress==KEY_ESC)) {
625 close_trigger_window();
629 old_trigger_num = trigger_num;