Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Portions of this file are copyright Rebirth contributors and licensed as
  3.  * described in COPYING.txt.
  4.  * Portions of this file are copyright Parallax Software and licensed
  5.  * according to the Parallax license below.
  6.  * See COPYING.txt for license details.
  7.  
  8. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  9. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  10. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  11. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  12. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  13. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  14. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  15. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  16. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  17. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  18. */
  19.  
  20. /*
  21.  *
  22.  * Editor switch functions.
  23.  *
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <math.h>
  29. #include <string.h>
  30.  
  31. #include "inferno.h"
  32. #include "editor.h"
  33. #include "editor/esegment.h"
  34. #include "editor/kdefs.h"
  35. #include "eswitch.h"
  36. #include "segment.h"
  37. #include "dxxerror.h"
  38. #include "event.h"
  39. #include "gameseg.h"
  40. #include "wall.h"
  41. #include "medwall.h"
  42. #include "screens.h"
  43. #include "textures.h"
  44. #include "texmerge.h"
  45. #include "medrobot.h"
  46. #include "timer.h"
  47. #include "key.h"
  48. #include "ehostage.h"
  49. #include "centers.h"
  50. #include "piggy.h"
  51. #include "u_mem.h"
  52.  
  53. #include "compiler-range_for.h"
  54. #include "partial_range.h"
  55. #include <memory>
  56.  
  57. //-------------------------------------------------------------------------
  58. // Variables for this module...
  59. //-------------------------------------------------------------------------
  60. #define NUM_TRIGGER_FLAGS 10
  61.  
  62. static UI_DIALOG                                *MainWindow = NULL;
  63.  
  64. namespace {
  65.  
  66. struct trigger_dialog
  67. {
  68.         std::unique_ptr<UI_GADGET_USERBOX> wallViewBox;
  69.         std::unique_ptr<UI_GADGET_BUTTON> quitButton, remove_trigger, bind_wall, bind_matcen, enable_all_triggers;
  70. #if defined(DXX_BUILD_DESCENT_I)
  71.         std::array<std::unique_ptr<UI_GADGET_CHECKBOX>, NUM_TRIGGER_FLAGS> triggerFlag;
  72. #endif
  73.         int old_trigger_num;
  74. };
  75.  
  76. }
  77.  
  78. #if defined(DXX_BUILD_DESCENT_I)
  79. //-----------------------------------------------------------------
  80. // Adds a trigger to wall, and returns the trigger number.
  81. // If there is a trigger already present, it returns the trigger number. (To be replaced)
  82. static trgnum_t add_trigger(trigger_array &Triggers, fvcvertptr &vcvertptr, wall_array &Walls, const shared_segment &seg, const unsigned side)
  83. {
  84.         trgnum_t trigger_num = Triggers.get_count();
  85.  
  86.         Assert(trigger_num < MAX_TRIGGERS);
  87.         if (trigger_num>=MAX_TRIGGERS) return trigger_none;
  88.  
  89.         auto wall_num = seg.sides[side].wall_num;
  90.         wall *wp;
  91.         auto &vmwallptr = Walls.vmptr;
  92.         if (wall_num == wall_none) {
  93.                 wall_add_to_markedside(vcvertptr, Walls, WALL_OPEN);
  94.                 wall_num = seg.sides[side].wall_num;
  95.                 wp = vmwallptr(wall_num);
  96.                 // Set default values first time trigger is added
  97.         } else {
  98.                 auto &w = *vmwallptr(wall_num);
  99.                 if (w.trigger != trigger_none)
  100.                         return w.trigger;
  101.  
  102.                 wp = &w;
  103.                 // Create new trigger.
  104.         }
  105.         wp->trigger = trigger_num;
  106.         auto &t = *Triggers.vmptr(trigger_num);
  107.         t.flags = {};
  108.         t.value = F1_0*5;
  109.         t.num_links = 0;
  110.         Triggers.set_count(trigger_num + 1);
  111.         return trigger_num;
  112. }              
  113.  
  114. //-----------------------------------------------------------------
  115. // Adds a specific trigger flag to Markedsegp/Markedside if it is possible.
  116. // Automatically adds flag to Connectside if possible unless it is a control trigger.
  117. // Returns 1 if trigger flag added.
  118. // Returns 0 if trigger flag cannot be added.
  119. static int trigger_flag_Markedside(const TRIGGER_FLAG flag, const int value)
  120. {
  121.         auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state();
  122.         auto &Vertices = LevelSharedVertexState.get_vertices();
  123.         if (!Markedsegp) {
  124.                 editor_status("No Markedside.");
  125.                 return 0;
  126.         }
  127.  
  128.         // If no child on Markedside return
  129.         if (!IS_CHILD(Markedsegp->children[Markedside])) return 0;
  130.  
  131.         // If no wall just return
  132.         const auto wall_num = Markedsegp->shared_segment::sides[Markedside].wall_num;
  133.         if (!value && wall_num == wall_none) return 0;
  134.         auto &Triggers = LevelUniqueWallSubsystemState.Triggers;
  135.         auto &vcvertptr = Vertices.vcptr;
  136.         auto &Walls = LevelUniqueWallSubsystemState.Walls;
  137.         auto &vcwallptr = Walls.vcptr;
  138.         const auto trigger_num = value ? add_trigger(Triggers, vcvertptr, Walls, Markedsegp, Markedside) : vcwallptr(wall_num)->trigger;
  139.  
  140.         if (trigger_num == trigger_none) {
  141.                 editor_status(value ? "Cannot add trigger at Markedside." : "No trigger at Markedside.");
  142.                 return 0;
  143.         }
  144.  
  145.         auto &vmtrgptr = Triggers.vmptr;
  146.         auto &flags = vmtrgptr(trigger_num)->flags;
  147.         if (value)
  148.                 flags |= flag;
  149.         else
  150.                 flags &= ~flag;
  151.  
  152.         return 1;
  153. }
  154. #endif
  155.  
  156. static int bind_matcen_to_trigger() {
  157.  
  158.         if (!Markedsegp) {
  159.                 editor_status("No marked segment.");
  160.                 return 0;
  161.         }
  162.  
  163.         const auto wall_num = Markedsegp->shared_segment::sides[Markedside].wall_num;
  164.         if (wall_num == wall_none) {
  165.                 editor_status("No wall at Markedside.");
  166.                 return 0;
  167.         }
  168.         auto &Walls = LevelUniqueWallSubsystemState.Walls;
  169.         auto &vcwallptr = Walls.vcptr;
  170.         const auto trigger_num = vcwallptr(wall_num)->trigger;
  171.         if (trigger_num == trigger_none) {
  172.                 editor_status("No trigger at Markedside.");
  173.                 return 0;
  174.         }
  175.  
  176.         if (!(Cursegp->special & SEGMENT_IS_ROBOTMAKER))
  177.         {
  178.                 editor_status("No Matcen at Cursegp.");
  179.                 return 0;
  180.         }
  181.  
  182.         auto &Triggers = LevelUniqueWallSubsystemState.Triggers;
  183.         auto &vmtrgptr = Triggers.vmptr;
  184.         const auto &&t = vmtrgptr(trigger_num);
  185.         const auto link_num = t->num_links;
  186.         for (int i=0;i<link_num;i++)
  187.                 if (Cursegp == t->seg[i])
  188.                 {
  189.                         editor_status("Matcen already bound to Markedside.");
  190.                         return 0;
  191.                 }
  192.  
  193.         // Error checking completed, actual binding begins
  194.         t->seg[link_num] = Cursegp;
  195.         t->num_links++;
  196.  
  197.         editor_status("Matcen linked to trigger");
  198.  
  199.         return 1;
  200. }
  201.  
  202.  
  203. int bind_wall_to_trigger() {
  204.  
  205.         if (!Markedsegp) {
  206.                 editor_status("No marked segment.");
  207.                 return 0;
  208.         }
  209.  
  210.         const auto wall_num = Markedsegp->shared_segment::sides[Markedside].wall_num;
  211.         if (wall_num == wall_none) {
  212.                 editor_status("No wall at Markedside.");
  213.                 return 0;
  214.         }
  215.         auto &Walls = LevelUniqueWallSubsystemState.Walls;
  216.         auto &vcwallptr = Walls.vcptr;
  217.         const auto trigger_num = vcwallptr(wall_num)->trigger;
  218.         if (trigger_num == trigger_none) {
  219.                 editor_status("No trigger at Markedside.");
  220.                 return 0;
  221.         }
  222.  
  223.         if (Cursegp->shared_segment::sides[Curside].wall_num == wall_none)
  224.         {
  225.                 editor_status("No wall at Curside.");
  226.                 return 0;
  227.         }
  228.  
  229.         if ((Cursegp==Markedsegp) && (Curside==Markedside)) {
  230.                 editor_status("Cannot bind wall to itself.");
  231.                 return 0;
  232.         }
  233.  
  234.         auto &Triggers = LevelUniqueWallSubsystemState.Triggers;
  235.         auto &vmtrgptr = Triggers.vmptr;
  236.         const auto &&t = vmtrgptr(trigger_num);
  237.         const auto link_num = t->num_links;
  238.         for (int i=0;i<link_num;i++)
  239.                 if (Cursegp == t->seg[i] && Curside == t->side[i])
  240.                 {
  241.                         editor_status("Curside already bound to Markedside.");
  242.                         return 0;
  243.                 }
  244.  
  245.         // Error checking completed, actual binding begins
  246.         t->seg[link_num] = Cursegp;
  247.         t->side[link_num] = Curside;
  248.         t->num_links++;
  249.  
  250.         editor_status("Wall linked to trigger");
  251.  
  252.         return 1;
  253. }
  254.  
  255. int remove_trigger_num(int trigger_num)
  256. {
  257.         if (trigger_num != trigger_none)
  258.         {
  259.                 auto &Triggers = LevelUniqueWallSubsystemState.Triggers;
  260.                 auto r = partial_range(Triggers, static_cast<unsigned>(trigger_num), Triggers.get_count());
  261.                 Triggers.set_count(Triggers.get_count() - 1);
  262.                 std::move(std::next(r.begin()), r.end(), r.begin());
  263.        
  264.                 auto &Walls = LevelUniqueWallSubsystemState.Walls;
  265.                 auto &vmwallptr = Walls.vmptr;
  266.                 range_for (const auto &&w, vmwallptr)
  267.                 {
  268.                         auto &trigger = w->trigger;
  269.                         if (trigger == trigger_num)
  270.                                 trigger = trigger_none; // a trigger can be shared by multiple walls
  271.                         else if (trigger > trigger_num && trigger != trigger_none)
  272.                                 --trigger;
  273.                 }
  274.  
  275.                 return 1;
  276.         }
  277.  
  278.         editor_status("No trigger to remove");
  279.         return 0;
  280. }
  281.  
  282. unsigned remove_trigger(shared_segment &seg, const unsigned side)
  283. {      
  284.         const auto wall_num = seg.sides[side].wall_num;
  285.         if (wall_num == wall_none)
  286.         {
  287.                 return 0;
  288.         }
  289.  
  290.         auto &Walls = LevelUniqueWallSubsystemState.Walls;
  291.         auto &vcwallptr = Walls.vcptr;
  292.         return remove_trigger_num(vcwallptr(wall_num)->trigger);
  293. }
  294.  
  295. static int trigger_remove()
  296. {
  297.         remove_trigger(Markedsegp, Markedside);
  298.         Update_flags = UF_WORLD_CHANGED;
  299.         return 1;
  300. }
  301.  
  302. #if defined(DXX_BUILD_DESCENT_II)
  303. static int trigger_turn_all_ON()
  304. {
  305.         auto &Triggers = LevelUniqueWallSubsystemState.Triggers;
  306.         auto &vmtrgptr = Triggers.vmptr;
  307.         range_for (const auto t, vmtrgptr)
  308.                 t->flags &= ~trigger_behavior_flags::disabled;
  309.         return 1;
  310. }
  311. #endif
  312.  
  313. static window_event_result trigger_dialog_handler(UI_DIALOG *dlg,const d_event &event, trigger_dialog *t);
  314.  
  315. //-------------------------------------------------------------------------
  316. // Called from the editor... does one instance of the trigger dialog box
  317. //-------------------------------------------------------------------------
  318. int do_trigger_dialog()
  319. {
  320.         if (!Markedsegp) {
  321.                 editor_status("Trigger requires Marked Segment & Side.");
  322.                 return 0;
  323.         }
  324.  
  325.         // Only open 1 instance of this window...
  326.         if ( MainWindow != NULL ) return 0;
  327.        
  328.         auto t = std::make_unique<trigger_dialog>();
  329.         // Close other windows.
  330.         robot_close_window();
  331.         close_wall_window();
  332.         close_centers_window();
  333.         hostage_close_window();
  334.  
  335.         // Open a window with a quit button
  336.         MainWindow = ui_create_dialog(TMAPBOX_X+20, TMAPBOX_Y+20, 765-TMAPBOX_X, 545-TMAPBOX_Y, DF_DIALOG, trigger_dialog_handler, std::move(t));
  337.         return 1;
  338. }
  339.  
  340. static window_event_result trigger_dialog_created(UI_DIALOG *const w, trigger_dialog *const t)
  341. {
  342.         // These are the checkboxes for each door flag.
  343.         int i = 44;
  344. #if defined(DXX_BUILD_DESCENT_I)
  345.         t->triggerFlag[0] = ui_add_gadget_checkbox(w, 22, i, 16, 16, 0, "Door Control");        i+=22;
  346.         t->triggerFlag[1] = ui_add_gadget_checkbox(w, 22, i, 16, 16, 0, "Shield damage");       i+=22;
  347.         t->triggerFlag[2] = ui_add_gadget_checkbox(w, 22, i, 16, 16, 0, "Energy drain");                i+=22;
  348.         t->triggerFlag[3] = ui_add_gadget_checkbox(w, 22, i, 16, 16, 0, "Exit");                                        i+=22;
  349.         t->triggerFlag[4] = ui_add_gadget_checkbox(w, 22, i, 16, 16, 0, "One-shot");                    i+=22;
  350.         t->triggerFlag[5] = ui_add_gadget_checkbox(w, 22, i, 16, 16, 0, "Illusion ON");         i+=22;
  351.         t->triggerFlag[6] = ui_add_gadget_checkbox(w, 22, i, 16, 16, 0, "Illusion OFF");                i+=22;
  352.         t->triggerFlag[7] = ui_add_gadget_checkbox(w, 22, i, 16, 16, 0, "Unused");                      i+=22;
  353.         t->triggerFlag[8] = ui_add_gadget_checkbox(w, 22, i, 16, 16, 0, "Matcen Trigger");      i+=22;
  354.         t->triggerFlag[9] = ui_add_gadget_checkbox(w, 22, i, 16, 16, 0, "Secret Exit");                 i+=22;
  355. #endif
  356.  
  357.         t->quitButton = ui_add_gadget_button( w, 20, i, 48, 40, "Done", NULL );
  358.                                                                                                                                                                  
  359.         // The little box the wall will appear in.
  360.         t->wallViewBox = ui_add_gadget_userbox( w, 155, 5, 64, 64 );
  361.  
  362.         // A bunch of buttons...
  363.         i = 80;
  364.         t->remove_trigger = ui_add_gadget_button(w, 155, i, 140, 26, "Remove Trigger", trigger_remove); i += 29;
  365.         t->bind_wall = ui_add_gadget_button(w, 155, i, 140, 26, "Bind Wall", bind_wall_to_trigger); i += 29;
  366.         t->bind_matcen = ui_add_gadget_button(w, 155, i, 140, 26, "Bind Matcen", bind_matcen_to_trigger); i += 29;
  367. #if defined(DXX_BUILD_DESCENT_II)
  368.         t->enable_all_triggers = ui_add_gadget_button(w, 155, i, 140, 26, "All Triggers ON", trigger_turn_all_ON); i += 29;
  369. #endif
  370.  
  371.         t->old_trigger_num = -2;                // Set to some dummy value so everything works ok on the first frame.
  372.         return window_event_result::handled;
  373. }
  374.  
  375. void close_trigger_window()
  376. {
  377.         if ( MainWindow!=NULL ) {
  378.                 ui_close_dialog( MainWindow );
  379.                 MainWindow = NULL;
  380.         }
  381. }
  382.  
  383. window_event_result trigger_dialog_handler(UI_DIALOG *dlg,const d_event &event, trigger_dialog *t)
  384. {
  385.         switch(event.type)
  386.         {
  387.                 case EVENT_WINDOW_CREATED:
  388.                         return trigger_dialog_created(dlg, t);
  389.                 case EVENT_WINDOW_CLOSE:
  390.                         std::default_delete<trigger_dialog>()(t);
  391.                         MainWindow = NULL;
  392.                         return window_event_result::ignored;
  393.                 default:
  394.                         break;
  395.         }
  396.         int keypress = 0;
  397.         window_event_result rval = window_event_result::ignored;
  398.  
  399.         Assert(MainWindow != NULL);
  400.         if (!Markedsegp) {
  401.                 return window_event_result::close;
  402.         }
  403.  
  404.         //------------------------------------------------------------
  405.         // Call the ui code..
  406.         //------------------------------------------------------------
  407.         ui_button_any_drawn = 0;
  408.        
  409.         if (event.type == EVENT_KEY_COMMAND)
  410.                 keypress = event_key_get(event);
  411.        
  412.         //------------------------------------------------------------
  413.         // If we change walls, we need to reset the ui code for all
  414.         // of the checkboxes that control the wall flags.  
  415.         //------------------------------------------------------------
  416.         const auto Markedwall = Markedsegp->shared_segment::sides[Markedside].wall_num;
  417.         auto &Walls = LevelUniqueWallSubsystemState.Walls;
  418.         auto &vcwallptr = Walls.vcptr;
  419.         const auto trigger_num = (Markedwall != wall_none) ? vcwallptr(Markedwall)->trigger : trigger_none;
  420.  
  421.         if (t->old_trigger_num != trigger_num)
  422.         {
  423.                 if (trigger_num != trigger_none)
  424.                 {
  425. #if defined(DXX_BUILD_DESCENT_I)
  426.                         auto &Triggers = LevelUniqueWallSubsystemState.Triggers;
  427.                         auto &vctrgptr = Triggers.vcptr;
  428.                         const auto &&trig = vctrgptr(trigger_num);
  429.  
  430.                         ui_checkbox_check(t->triggerFlag[0].get(), trig->flags & TRIGGER_CONTROL_DOORS);
  431.                         ui_checkbox_check(t->triggerFlag[1].get(), trig->flags & TRIGGER_SHIELD_DAMAGE);
  432.                         ui_checkbox_check(t->triggerFlag[2].get(), trig->flags & TRIGGER_ENERGY_DRAIN);
  433.                         ui_checkbox_check(t->triggerFlag[3].get(), trig->flags & TRIGGER_EXIT);
  434.                         ui_checkbox_check(t->triggerFlag[4].get(), trig->flags & TRIGGER_ONE_SHOT);
  435.                         ui_checkbox_check(t->triggerFlag[5].get(), trig->flags & TRIGGER_ILLUSION_ON);
  436.                         ui_checkbox_check(t->triggerFlag[6].get(), trig->flags & TRIGGER_ILLUSION_OFF);
  437.                         ui_checkbox_check(t->triggerFlag[7].get(), 0);
  438.                         ui_checkbox_check(t->triggerFlag[8].get(), trig->flags & TRIGGER_MATCEN);
  439.                         ui_checkbox_check(t->triggerFlag[9].get(), trig->flags & TRIGGER_SECRET_EXIT);
  440. #endif
  441.                 }
  442.         }
  443.        
  444.         //------------------------------------------------------------
  445.         // If any of the checkboxes that control the wallflags are set, then
  446.         // update the cooresponding wall flag.
  447.         //------------------------------------------------------------
  448.         if (IS_CHILD(Markedsegp->children[Markedside]))
  449.         {
  450. #if defined(DXX_BUILD_DESCENT_I)
  451.                 rval = window_event_result::handled;
  452.                 if (GADGET_PRESSED(t->triggerFlag[0].get()))
  453.                         trigger_flag_Markedside(TRIGGER_CONTROL_DOORS, t->triggerFlag[0]->flag);
  454.                 else if (GADGET_PRESSED(t->triggerFlag[1].get()))
  455.                         trigger_flag_Markedside(TRIGGER_SHIELD_DAMAGE, t->triggerFlag[1]->flag);
  456.                 else if (GADGET_PRESSED(t->triggerFlag[2].get()))
  457.                         trigger_flag_Markedside(TRIGGER_ENERGY_DRAIN, t->triggerFlag[2]->flag);
  458.                 else if (GADGET_PRESSED(t->triggerFlag[3].get()))
  459.                         trigger_flag_Markedside(TRIGGER_EXIT, t->triggerFlag[3]->flag);
  460.                 else if (GADGET_PRESSED(t->triggerFlag[4].get()))
  461.                         trigger_flag_Markedside(TRIGGER_ONE_SHOT, t->triggerFlag[4]->flag);
  462.                 else if (GADGET_PRESSED(t->triggerFlag[5].get()))
  463.                         trigger_flag_Markedside(TRIGGER_ILLUSION_ON, t->triggerFlag[5]->flag);
  464.                 else if (GADGET_PRESSED(t->triggerFlag[6].get()))
  465.                         trigger_flag_Markedside(TRIGGER_ILLUSION_OFF, t->triggerFlag[6]->flag);
  466.                 else if (GADGET_PRESSED(t->triggerFlag[7].get()))
  467.                 {
  468.                 }
  469.                 else if (GADGET_PRESSED(t->triggerFlag[8].get()))
  470.                         trigger_flag_Markedside(TRIGGER_MATCEN, t->triggerFlag[8]->flag);
  471.                 else if (GADGET_PRESSED(t->triggerFlag[9].get()))
  472.                         trigger_flag_Markedside(TRIGGER_SECRET_EXIT, t->triggerFlag[9]->flag);
  473.                 else
  474. #endif
  475.                         rval = window_event_result::ignored;
  476.  
  477.         } else
  478.         {
  479. #if defined(DXX_BUILD_DESCENT_I)
  480.                 range_for (auto &i, t->triggerFlag)
  481.                         ui_checkbox_check(i.get(), 0);
  482. #endif
  483.         }
  484.  
  485.         //------------------------------------------------------------
  486.         // Draw the wall in the little 64x64 box
  487.         //------------------------------------------------------------
  488.         if (event.type == EVENT_UI_DIALOG_DRAW)
  489.         {
  490.                 gr_set_current_canvas( t->wallViewBox->canvas );
  491.                 auto &canvas = *grd_curcanv;
  492.  
  493.                 const auto wall_num = Markedsegp->shared_segment::sides[Markedside].wall_num;
  494.                 if (wall_num == wall_none || vcwallptr(wall_num)->trigger == trigger_none)
  495.                         gr_clear_canvas(canvas, CBLACK);
  496.                 else {
  497.                         auto &us = Markedsegp->unique_segment::sides[Markedside];
  498.                         if (us.tmap_num2 > 0)
  499.                         {
  500.                                 gr_ubitmap(canvas, texmerge_get_cached_bitmap(us.tmap_num, us.tmap_num2));
  501.                         } else {
  502.                                 const auto tmap_num = us.tmap_num;
  503.                                 if (tmap_num > 0)
  504.                                 {
  505.                                         auto &t = Textures[tmap_num];
  506.                                         PIGGY_PAGE_IN(t);
  507.                                         gr_ubitmap(canvas, GameBitmaps[t.index]);
  508.                                 } else
  509.                                         gr_clear_canvas(canvas, CGREY);
  510.                         }
  511.                 }
  512.         }
  513.  
  514.         //------------------------------------------------------------
  515.         // If anything changes in the ui system, redraw all the text that
  516.         // identifies this robot.
  517.         //------------------------------------------------------------
  518.         if (event.type == EVENT_UI_DIALOG_DRAW)
  519.         {
  520.                 if (Markedsegp->shared_segment::sides[Markedside].wall_num != wall_none)
  521.                 {
  522.                         ui_dprintf_at( MainWindow, 12, 6, "Trigger: %d    ", trigger_num);
  523.                 }       else {
  524.                         ui_dprintf_at( MainWindow, 12, 6, "Trigger: none ");
  525.                 }
  526.         }
  527.        
  528.         if (ui_button_any_drawn || (t->old_trigger_num != trigger_num) )
  529.                 Update_flags |= UF_WORLD_CHANGED;
  530.         if (GADGET_PRESSED(t->quitButton.get()) || keypress == KEY_ESC)
  531.         {
  532.                 return window_event_result::close;
  533.         }              
  534.  
  535.         t->old_trigger_num = trigger_num;
  536.        
  537.         return rval;
  538. }
  539.  
  540.  
  541.  
  542.  
  543.  
  544.