1 /* $Id: eswitch.c,v 1.3 2004-12-19 15:21:11 btb Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
17 * Editor switch functions.
22 static char rcsid[] = "$Id: eswitch.c,v 1.3 2004-12-19 15:21:11 btb Exp $";
55 //-------------------------------------------------------------------------
56 // Variables for this module...
57 //-------------------------------------------------------------------------
58 #define NUM_TRIGGER_FLAGS 10
60 static UI_WINDOW *MainWindow = NULL;
61 static UI_GADGET_USERBOX *WallViewBox;
62 static UI_GADGET_BUTTON *QuitButton;
63 static UI_GADGET_CHECKBOX *TriggerFlag[NUM_TRIGGER_FLAGS];
65 static int old_trigger_num;
67 //-----------------------------------------------------------------
68 // Adds a trigger to wall, and returns the trigger number.
69 // If there is a trigger already present, it returns the trigger number. (To be replaced)
70 int add_trigger(segment *seg, short side)
72 int trigger_num = Num_triggers;
73 int wall_num = seg->sides[side].wall_num;
75 Assert(trigger_num < MAX_TRIGGERS);
76 if (trigger_num>=MAX_TRIGGERS) return -1;
79 wall_add_to_markedside(WALL_OPEN);
80 wall_num = seg->sides[side].wall_num;
81 Walls[wall_num].trigger = trigger_num;
83 // Set default values first time trigger is added
84 Triggers[trigger_num].flags = 0;
85 Triggers[trigger_num].value = F1_0*5;
86 Triggers[trigger_num].num_links = 0;
87 Triggers[trigger_num].flags &= TRIGGER_ON;
92 if (Walls[wall_num].trigger != -1)
93 return Walls[wall_num].trigger;
95 // Create new trigger.
96 Walls[wall_num].trigger = trigger_num;
98 // Set default values first time trigger is added
99 Triggers[trigger_num].flags = 0;
100 Triggers[trigger_num].value = F1_0*5;
101 Triggers[trigger_num].num_links = 0;
102 Triggers[trigger_num].flags &= TRIGGER_ON;
109 //-----------------------------------------------------------------
110 // Adds a specific trigger flag to Markedsegp/Markedside if it is possible.
111 // Automatically adds flag to Connectside if possible unless it is a control trigger.
112 // Returns 1 if trigger flag added.
113 // Returns 0 if trigger flag cannot be added.
114 int trigger_add_to_Markedside(short flag) {
115 int trigger_num; //, ctrigger_num;
118 editor_status("No Markedside.");
122 // If no child on Markedside return
123 if (!IS_CHILD(Markedsegp->children[Markedside])) return 0;
125 trigger_num = add_trigger(Markedsegp, Markedside);
127 if (trigger_num == -1) {
128 editor_status("Cannot add trigger at Markedside.");
132 Triggers[trigger_num].flags |= flag;
137 int trigger_remove_flag_from_Markedside(short flag) {
138 int trigger_num; //, ctrigger_num;
142 editor_status("No Markedside.");
146 // If no child on Markedside return
147 if (!IS_CHILD(Markedsegp->children[Markedside])) return 0;
149 // If no wall just return
150 wall_num = Markedsegp->sides[Markedside].wall_num;
151 if (wall_num == -1) return 0;
153 trigger_num = Walls[wall_num].trigger;
155 // If flag is already cleared, then don't change anything.
156 if ( trigger_num == -1 ) {
157 editor_status("No trigger at Markedside.");
161 if (!Triggers[trigger_num].flags & flag)
164 Triggers[trigger_num].flags &= ~flag;
170 int bind_matcen_to_trigger() {
172 int wall_num, trigger_num, link_num;
176 editor_status("No marked segment.");
180 wall_num = Markedsegp->sides[Markedside].wall_num;
181 if (wall_num == -1) {
182 editor_status("No wall at Markedside.");
186 trigger_num = Walls[wall_num].trigger;
188 if (trigger_num == -1) {
189 editor_status("No trigger at Markedside.");
193 if (!(Cursegp->special & SEGMENT_IS_ROBOTMAKER)) {
194 editor_status("No Matcen at Cursegp.");
198 link_num = Triggers[trigger_num].num_links;
199 for (i=0;i<link_num;i++)
200 if (Cursegp-Segments == Triggers[trigger_num].seg[i]) {
201 editor_status("Matcen already bound to Markedside.");
205 // Error checking completed, actual binding begins
206 Triggers[trigger_num].seg[link_num] = Cursegp - Segments;
207 Triggers[trigger_num].num_links++;
209 mprintf((0, "seg %d linked to link_num %d\n",
210 Triggers[trigger_num].seg[link_num], link_num));
212 editor_status("Matcen linked to trigger");
218 int bind_wall_to_trigger() {
220 int wall_num, trigger_num, link_num;
224 editor_status("No marked segment.");
228 wall_num = Markedsegp->sides[Markedside].wall_num;
229 if (wall_num == -1) {
230 editor_status("No wall at Markedside.");
234 trigger_num = Walls[wall_num].trigger;
236 if (trigger_num == -1) {
237 editor_status("No trigger at Markedside.");
241 if (Cursegp->sides[Curside].wall_num == -1) {
242 editor_status("No wall at Curside.");
246 if ((Cursegp==Markedsegp) && (Curside==Markedside)) {
247 editor_status("Cannot bind wall to itself.");
251 link_num = Triggers[trigger_num].num_links;
252 for (i=0;i<link_num;i++)
253 if ((Cursegp-Segments == Triggers[trigger_num].seg[i]) && (Curside == Triggers[trigger_num].side[i])) {
254 editor_status("Curside already bound to Markedside.");
258 // Error checking completed, actual binding begins
259 Triggers[trigger_num].seg[link_num] = Cursegp - Segments;
260 Triggers[trigger_num].side[link_num] = Curside;
261 Triggers[trigger_num].num_links++;
263 mprintf((0, "seg %d:side %d linked to link_num %d\n",
264 Triggers[trigger_num].seg[link_num], Triggers[trigger_num].side[link_num], link_num));
266 editor_status("Wall linked to trigger");
271 int remove_trigger(segment *seg, short side)
273 int trigger_num, t, w;
275 if (seg->sides[side].wall_num == -1) {
276 mprintf((0, "Can't remove trigger from wall_num -1\n"));
280 trigger_num = Walls[seg->sides[side].wall_num].trigger;
282 if (trigger_num != -1) {
283 Walls[seg->sides[side].wall_num].trigger = -1;
284 for (t=trigger_num;t<Num_triggers-1;t++)
285 Triggers[t] = Triggers[t+1];
287 for (w=0; w<Num_walls; w++) {
288 if (Walls[w].trigger > trigger_num)
293 for (t=0;t<Num_walls;t++)
294 if (Walls[seg->sides[side].wall_num].trigger > trigger_num)
295 Walls[seg->sides[side].wall_num].trigger--;
300 editor_status("No trigger to remove");
305 int add_trigger_control()
307 trigger_add_to_Markedside(TRIGGER_CONTROL_DOORS);
308 Update_flags = UF_WORLD_CHANGED;
314 remove_trigger(Markedsegp, Markedside);
315 Update_flags = UF_WORLD_CHANGED;
319 int trigger_turn_all_ON()
323 for (t=0;t<Num_triggers;t++)
324 Triggers[t].flags &= TRIGGER_ON;
328 //-------------------------------------------------------------------------
329 // Called from the editor... does one instance of the trigger dialog box
330 //-------------------------------------------------------------------------
331 int do_trigger_dialog()
336 editor_status("Trigger requires Marked Segment & Side.");
340 // Only open 1 instance of this window...
341 if ( MainWindow != NULL ) return 0;
343 // Close other windows.
344 robot_close_window();
346 close_centers_window();
347 hostage_close_window();
349 // Open a window with a quit button
350 MainWindow = ui_open_window( TMAPBOX_X+20, TMAPBOX_Y+20, 765-TMAPBOX_X, 545-TMAPBOX_Y, WIN_DIALOG );
352 // These are the checkboxes for each door flag.
354 TriggerFlag[0] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Door Control" ); i+=22;
355 TriggerFlag[1] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Shield damage" ); i+=22;
356 TriggerFlag[2] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Energy drain" ); i+=22;
357 TriggerFlag[3] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Exit" ); i+=22;
358 TriggerFlag[4] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "One-shot" ); i+=22;
359 TriggerFlag[5] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Illusion ON" ); i+=22;
360 TriggerFlag[6] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Illusion OFF" ); i+=22;
361 TriggerFlag[7] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Trigger ON" ); i+=22;
362 TriggerFlag[8] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Matcen Trigger" ); i+=22;
363 TriggerFlag[9] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Secret Exit" ); i+=22;
365 QuitButton = ui_add_gadget_button( MainWindow, 20, i, 48, 40, "Done", NULL );
367 // The little box the wall will appear in.
368 WallViewBox = ui_add_gadget_userbox( MainWindow, 155, 5, 64, 64 );
370 // A bunch of buttons...
372 // ui_add_gadget_button( MainWindow,155,i,140, 26, "Add Door Control", add_trigger_control ); i += 29;
373 ui_add_gadget_button( MainWindow,155,i,140, 26, "Remove Trigger", trigger_remove ); i += 29;
374 ui_add_gadget_button( MainWindow,155,i,140, 26, "Bind Wall", bind_wall_to_trigger ); i += 29;
375 ui_add_gadget_button( MainWindow,155,i,140, 26, "Bind Matcen", bind_matcen_to_trigger ); i += 29;
376 ui_add_gadget_button( MainWindow,155,i,140, 26, "All Triggers ON", trigger_turn_all_ON ); i += 29;
378 old_trigger_num = -2; // Set to some dummy value so everything works ok on the first frame.
383 void close_trigger_window()
385 if ( MainWindow!=NULL ) {
386 ui_close_window( MainWindow );
391 void do_trigger_window()
394 short Markedwall, trigger_num;
396 if ( MainWindow == NULL ) return;
398 close_trigger_window();
402 //------------------------------------------------------------
403 // Call the ui code..
404 //------------------------------------------------------------
405 ui_button_any_drawn = 0;
406 ui_window_do_gadgets(MainWindow);
408 //------------------------------------------------------------
409 // If we change walls, we need to reset the ui code for all
410 // of the checkboxes that control the wall flags.
411 //------------------------------------------------------------
412 Markedwall = Markedsegp->sides[Markedside].wall_num;
413 if (Markedwall != -1)
414 trigger_num = Walls[Markedwall].trigger;
415 else trigger_num = -1;
417 if (old_trigger_num != trigger_num ) {
418 for ( i=0; i < NUM_TRIGGER_FLAGS; i++ ) {
419 TriggerFlag[i]->flag = 0; // Tells ui that this button isn't checked
420 TriggerFlag[i]->status = 1; // Tells ui to redraw button
423 if (trigger_num != -1) {
424 if (Triggers[trigger_num].flags & TRIGGER_CONTROL_DOORS)
425 TriggerFlag[0]->flag = 1;
426 if (Triggers[trigger_num].flags & TRIGGER_SHIELD_DAMAGE)
427 TriggerFlag[1]->flag = 1;
428 if (Triggers[trigger_num].flags & TRIGGER_ENERGY_DRAIN)
429 TriggerFlag[2]->flag = 1;
430 if (Triggers[trigger_num].flags & TRIGGER_EXIT)
431 TriggerFlag[3]->flag = 1;
432 if (Triggers[trigger_num].flags & TRIGGER_ONE_SHOT)
433 TriggerFlag[4]->flag = 1;
434 if (Triggers[trigger_num].flags & TRIGGER_ILLUSION_ON)
435 TriggerFlag[5]->flag = 1;
436 if (Triggers[trigger_num].flags & TRIGGER_ILLUSION_OFF)
437 TriggerFlag[6]->flag = 1;
438 if (Triggers[trigger_num].flags & TRIGGER_ON)
439 TriggerFlag[7]->flag = 1;
440 if (Triggers[trigger_num].flags & TRIGGER_MATCEN)
441 TriggerFlag[8]->flag = 1;
442 if (Triggers[trigger_num].flags & TRIGGER_SECRET_EXIT)
443 TriggerFlag[9]->flag = 1;
447 //------------------------------------------------------------
448 // If any of the checkboxes that control the wallflags are set, then
449 // update the cooresponding wall flag.
450 //------------------------------------------------------------
451 if (IS_CHILD(Markedsegp->children[Markedside])) {
452 if (TriggerFlag[0]->flag == 1)
453 trigger_add_to_Markedside(TRIGGER_CONTROL_DOORS);
455 trigger_remove_flag_from_Markedside(TRIGGER_CONTROL_DOORS);
456 if (TriggerFlag[1]->flag == 1)
457 trigger_add_to_Markedside(TRIGGER_SHIELD_DAMAGE);
459 trigger_remove_flag_from_Markedside(TRIGGER_SHIELD_DAMAGE);
460 if (TriggerFlag[2]->flag == 1)
461 trigger_add_to_Markedside(TRIGGER_ENERGY_DRAIN);
463 trigger_remove_flag_from_Markedside(TRIGGER_ENERGY_DRAIN);
464 if (TriggerFlag[3]->flag == 1)
465 trigger_add_to_Markedside(TRIGGER_EXIT);
467 trigger_remove_flag_from_Markedside(TRIGGER_EXIT);
468 if (TriggerFlag[4]->flag == 1)
469 trigger_add_to_Markedside(TRIGGER_ONE_SHOT);
471 trigger_remove_flag_from_Markedside(TRIGGER_ONE_SHOT);
472 if (TriggerFlag[5]->flag == 1)
473 trigger_add_to_Markedside(TRIGGER_ILLUSION_ON);
475 trigger_remove_flag_from_Markedside(TRIGGER_ILLUSION_ON);
476 if (TriggerFlag[6]->flag == 1)
477 trigger_add_to_Markedside(TRIGGER_ILLUSION_OFF);
479 trigger_remove_flag_from_Markedside(TRIGGER_ILLUSION_OFF);
480 if (TriggerFlag[7]->flag == 1)
481 trigger_add_to_Markedside(TRIGGER_ON);
483 trigger_remove_flag_from_Markedside(TRIGGER_ON);
485 if (TriggerFlag[8]->flag == 1)
486 trigger_add_to_Markedside(TRIGGER_MATCEN);
488 trigger_remove_flag_from_Markedside(TRIGGER_MATCEN);
490 if (TriggerFlag[9]->flag == 1)
491 trigger_add_to_Markedside(TRIGGER_SECRET_EXIT);
493 trigger_remove_flag_from_Markedside(TRIGGER_SECRET_EXIT);
496 for ( i=0; i < NUM_TRIGGER_FLAGS; i++ )
497 if (TriggerFlag[i]->flag == 1) {
498 TriggerFlag[i]->flag = 0; // Tells ui that this button isn't checked
499 TriggerFlag[i]->status = 1; // Tells ui to redraw button
502 //------------------------------------------------------------
503 // Draw the wall in the little 64x64 box
504 //------------------------------------------------------------
505 gr_set_current_canvas( WallViewBox->canvas );
507 if ((Markedsegp->sides[Markedside].wall_num == -1) || (Walls[Markedsegp->sides[Markedside].wall_num].trigger) == -1)
508 gr_clear_canvas( CBLACK );
510 if (Markedsegp->sides[Markedside].tmap_num2 > 0) {
511 gr_ubitmap(0,0, texmerge_get_cached_bitmap( Markedsegp->sides[Markedside].tmap_num, Markedsegp->sides[Markedside].tmap_num2));
513 if (Markedsegp->sides[Markedside].tmap_num > 0) {
514 PIGGY_PAGE_IN(Textures[Markedsegp->sides[Markedside].tmap_num]);
515 gr_ubitmap(0,0, &GameBitmaps[Textures[Markedsegp->sides[Markedside].tmap_num].index]);
517 gr_clear_canvas( CGREY );
521 //------------------------------------------------------------
522 // If anything changes in the ui system, redraw all the text that
523 // identifies this robot.
524 //------------------------------------------------------------
525 if (ui_button_any_drawn || (old_trigger_num != trigger_num) ) {
526 if ( Markedsegp->sides[Markedside].wall_num > -1 ) {
527 ui_wprintf_at( MainWindow, 12, 6, "Trigger: %d ", trigger_num);
529 ui_wprintf_at( MainWindow, 12, 6, "Trigger: none ");
531 Update_flags |= UF_WORLD_CHANGED;
534 if ( QuitButton->pressed || (last_keypress==KEY_ESC)) {
535 close_trigger_window();
539 old_trigger_num = trigger_num;