home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / main / ehostage.c < prev    next >
Text File  |  1998-06-08  |  16KB  |  549 lines

  1. /*
  2.  * $Source: f:/miner/source/main/editor/rcs/ehostage.c $
  3.  * $Revision: 2.0 $
  4.  * $Author: john $
  5.  * $Date: 1995/02/27 11:35:45 $
  6.  * 
  7.  * Routines for placing hostages, etc...
  8.  * 
  9.  * $Log: ehostage.c $
  10.  * Revision 2.0  1995/02/27  11:35:45  john
  11.  * Version 2.0! No anonymous unions, Watcom 10.0, with no need
  12.  * for bitmaps.tbl.
  13.  * 
  14.  * Revision 1.17  1995/01/14  19:18:05  john
  15.  * First version of object paging.
  16.  * 
  17.  * Revision 1.16  1994/11/20  14:11:41  matt
  18.  * Show object number in hostage window
  19.  * 
  20.  * Revision 1.15  1994/11/19  19:55:46  matt
  21.  * Added code to full support different hostage head clip & message for
  22.  * each hostage.
  23.  * 
  24.  * 
  25.  * Revision 1.14  1994/10/28  15:03:27  john
  26.  * Made digi_play_sample use volume.
  27.  * 
  28.  * 
  29.  * Revision 1.13  1994/10/23  02:11:39  matt
  30.  * Got rid of obsolete hostage_info stuff
  31.  * 
  32.  * Revision 1.12  1994/10/04  13:15:44  john
  33.  * Changed PLAY_SOUND to digi_play_sample.
  34.  * 
  35.  * Revision 1.11  1994/08/02  14:17:28  mike
  36.  * Clean up dialog boxes.
  37.  * 
  38.  * Revision 1.10  1994/07/22  17:19:17  yuan
  39.  * Working on dialog box for refuel/repair/material/control centers.
  40.  * 
  41.  * Revision 1.9  1994/07/06  15:22:34  john
  42.  * Added new sound.
  43.  * 
  44.  * 
  45.  * Revision 1.8  1994/07/06  14:26:07  john
  46.  * Added vclip.
  47.  * 
  48.  * Revision 1.7  1994/07/06  13:25:52  john
  49.  * Added compress hostages functions.
  50.  * 
  51.  * Revision 1.6  1994/07/06  12:52:27  john
  52.  * Fixed warnings.
  53.  * 
  54.  * Revision 1.5  1994/07/06  12:43:04  john
  55.  * Made generic messages for hostages.
  56.  * 
  57.  * Revision 1.4  1994/07/06  11:49:01  john
  58.  * Made adding hostage update current object.
  59.  * 
  60.  * Revision 1.3  1994/07/06  10:56:00  john
  61.  * New structures for hostages.
  62.  * 
  63.  * Revision 1.2  1994/07/01  17:57:13  john
  64.  * First version of not-working hostage system
  65.  * 
  66.  * 
  67.  * Revision 1.1  1994/07/01  14:21:44  john
  68.  * Initial revision
  69.  * 
  70.  * 
  71.  */
  72.  
  73.  
  74. #pragma off (unreferenced)
  75. static char rcsid[] = "$Id: ehostage.c 2.0 1995/02/27 11:35:45 john Exp $";
  76. #pragma on (unreferenced)
  77.  
  78. #include <stdlib.h>
  79. #include <stdio.h>
  80. #include <conio.h>
  81. #include <math.h>
  82. #include <dos.h>
  83. #include <string.h>
  84. #include <direct.h>
  85.  
  86. #include "screens.h"
  87. #include "inferno.h"
  88. #include "segment.h"
  89. #include "editor.h"
  90.  
  91. #include "timer.h"
  92. #include "objpage.h"
  93. #include "fix.h"
  94. #include "mono.h"
  95. #include "error.h"
  96. #include "kdefs.h"
  97. #include    "object.h"
  98. #include "polyobj.h"
  99. #include "game.h"
  100. #include "powerup.h"
  101. #include "ai.h"
  102. #include "hostage.h"
  103. #include "eobject.h"
  104. #include "medwall.h"
  105. #include "eswitch.h"
  106. #include "medrobot.h"
  107. #include "key.h"
  108. #include "bm.h"
  109. #include "sounds.h"
  110. #include "centers.h"
  111. #include "piggy.h"
  112.  
  113. //-------------------------------------------------------------------------
  114. // Variables for this module...
  115. //-------------------------------------------------------------------------
  116. static UI_WINDOW                 *MainWindow = NULL;
  117. static UI_GADGET_USERBOX    *HostageViewBox;
  118. static UI_GADGET_INPUTBOX    *HostageText;
  119. static UI_GADGET_BUTTON     *QuitButton;
  120. static int                        CurrentHostageIndex=-1;
  121. static int                        LastHostageIndex=-1;
  122.  
  123. static fix             Vclip_animation_time=0;            // How long the rescue sequence has been playing
  124. static fix             Vclip_playback_speed=0;                // Calculated internally.  Frames/second of vclip.
  125. static vclip         *Vclip_ptr = NULL;                // Used for the vclip on monitor
  126.  
  127. void vclip_play( vclip * vc, fix frame_time )    
  128. {
  129.     int bitmapnum;
  130.  
  131.     if ( vc == NULL )
  132.         return;
  133.  
  134.     if ( vc != Vclip_ptr )    {
  135.         // Start new vclip
  136.         Vclip_ptr = vc;
  137.         Vclip_animation_time = 1;
  138.  
  139.         // Calculate the frame/second of the playback
  140.         Vclip_playback_speed = fixdiv(i2f(Vclip_ptr->num_frames),Vclip_ptr->play_time);
  141.     }
  142.  
  143.     if ( Vclip_animation_time <= 0 )
  144.         return;
  145.  
  146.     // Find next bitmap in the vclip
  147.     bitmapnum = f2i(Vclip_animation_time);
  148.  
  149.     // Check if vclip is done playing.
  150.     if (bitmapnum >= Vclip_ptr->num_frames)        {
  151.         Vclip_animation_time    = 1;                                            // Restart this vclip
  152.         bitmapnum = 0;
  153.     }
  154.  
  155.     PIGGY_PAGE_IN( Vclip_ptr->frames[bitmapnum] );
  156.     gr_bitmap(0,0,&GameBitmaps[Vclip_ptr->frames[bitmapnum].index] );
  157.     
  158.     Vclip_animation_time += fixmul(frame_time, Vclip_playback_speed );
  159. }
  160.  
  161.  
  162.  
  163. static char HostageMessage[]  = "  ";
  164.  
  165. static fix Time;
  166.  
  167. int SelectPrevHostage()    {
  168.     int start=0;
  169.  
  170.     do    {
  171.         CurrentHostageIndex--;
  172.         if ( CurrentHostageIndex < 0 ) CurrentHostageIndex = MAX_HOSTAGES-1;
  173.         start++;
  174.         if ( start > MAX_HOSTAGES ) break;
  175.     } while ( !hostage_is_valid( CurrentHostageIndex ) );
  176.  
  177.     if (hostage_is_valid( CurrentHostageIndex ) )    {
  178.         Cur_object_index = Hostages[CurrentHostageIndex].objnum;
  179.     } else {
  180.         CurrentHostageIndex =-1;
  181.     }
  182.     
  183.     return CurrentHostageIndex;
  184. }
  185.  
  186.  
  187. int SelectNextHostage()    {
  188.     int start=0;
  189.  
  190.     do    {
  191.         CurrentHostageIndex++;
  192.         if ( CurrentHostageIndex >= MAX_HOSTAGES ) CurrentHostageIndex = 0;
  193.         start++;
  194.         if ( start > MAX_HOSTAGES ) break;
  195.     } while ( !hostage_is_valid( CurrentHostageIndex ) );
  196.  
  197.     if (hostage_is_valid( CurrentHostageIndex ) )    {
  198.         Cur_object_index = Hostages[CurrentHostageIndex].objnum;
  199.     } else {
  200.         CurrentHostageIndex =-1;
  201.     }
  202.     
  203.     return CurrentHostageIndex;
  204. }
  205.  
  206.  
  207. int SelectClosestHostage()    {
  208.     int start=0;
  209.  
  210.     while ( !hostage_is_valid( CurrentHostageIndex ) )    {
  211.         CurrentHostageIndex++;
  212.         if ( CurrentHostageIndex >= MAX_HOSTAGES ) CurrentHostageIndex = 0;
  213.         start++;
  214.         if ( start > MAX_HOSTAGES ) break;
  215.     }
  216.  
  217.     if (hostage_is_valid( CurrentHostageIndex ) )    {
  218.         Cur_object_index = Hostages[CurrentHostageIndex].objnum;
  219.     } else {
  220.         CurrentHostageIndex =-1;
  221.     }
  222.     
  223.     return CurrentHostageIndex;
  224. }
  225.  
  226.  
  227. int PlaceHostage()    {
  228.     int ctype,i;
  229.     vms_vector    cur_object_loc;
  230.  
  231.     //update_due_to_new_segment();
  232.     compute_segment_center(&cur_object_loc, Cursegp);
  233.  
  234.     ctype = -1;
  235.     for (i=0; i<Num_total_object_types; i++ )    {
  236.         if (ObjType[i] == OL_HOSTAGE )    {
  237.             ctype = i;    
  238.             break;
  239.         }
  240.     }
  241.  
  242.     Assert( ctype != -1 );
  243.  
  244.     if (place_object(Cursegp, &cur_object_loc, ctype )==0)    {
  245.         Int3();        // Debug below
  246.         i=place_object(Cursegp, &cur_object_loc, ctype );
  247.         return 1;
  248.     }
  249.  
  250.     if (hostage_object_is_valid( Cur_object_index ) )    {
  251.         CurrentHostageIndex    = Objects[Cur_object_index].id;
  252.     } else {
  253.         Int3();        // Get John! (Object should be valid)
  254.         i=hostage_object_is_valid( Cur_object_index );    // For debugging only
  255.     }
  256.  
  257.     return 0;
  258. }
  259.  
  260. int CompressHostages()
  261. {
  262.     hostage_compress_all();
  263.  
  264.     return 0;
  265. }
  266.  
  267. //@@int SelectPrevVclip()    {
  268. //@@    if (!hostage_is_valid( CurrentHostageIndex ) )    
  269. //@@        return 0;
  270. //@@
  271. //@@    if ( Hostages[CurrentHostageIndex].type == 0 )
  272. //@@        Hostages[CurrentHostageIndex].type = N_hostage_types-1;
  273. //@@    else
  274. //@@        Hostages[CurrentHostageIndex].type--;
  275. //@@    
  276. //@@    if ( Hostages[CurrentHostageIndex].type >= N_hostage_types )
  277. //@@        Hostages[CurrentHostageIndex].type = 0;
  278. //@@    
  279. //@@    return 1;
  280. //@@}
  281. //@@
  282. //@@int SelectNextVclip()    {
  283. //@@    if (!hostage_is_valid( CurrentHostageIndex ) )    
  284. //@@        return 0;
  285. //@@
  286. //@@    Hostages[CurrentHostageIndex].type++;
  287. //@@    if ( Hostages[CurrentHostageIndex].type >= N_hostage_types )
  288. //@@        Hostages[CurrentHostageIndex].type = 0;
  289. //@@
  290. //@@    return 1;
  291. //@@}
  292.  
  293. int SelectNextFace()
  294. {
  295.     int start = Hostages[CurrentHostageIndex].vclip_num;
  296.     
  297.     if (!hostage_is_valid( CurrentHostageIndex ) )    
  298.         return 0;
  299.  
  300.     do {
  301.         Hostages[CurrentHostageIndex].vclip_num++;
  302.         if ( Hostages[CurrentHostageIndex].vclip_num >= MAX_HOSTAGES)
  303.             Hostages[CurrentHostageIndex].vclip_num = 0;
  304.  
  305.         if (Hostages[CurrentHostageIndex].vclip_num == start)
  306.             return 0;
  307.  
  308.     } while (Hostage_face_clip[Hostages[CurrentHostageIndex].vclip_num].num_frames == 0);
  309.  
  310.     return 1;
  311. }
  312.  
  313. int SelectPrevFace()
  314. {
  315.     int start = Hostages[CurrentHostageIndex].vclip_num;
  316.     
  317.     if (!hostage_is_valid( CurrentHostageIndex ) )    
  318.         return 0;
  319.  
  320.     do {
  321.         Hostages[CurrentHostageIndex].vclip_num--;
  322.         if ( Hostages[CurrentHostageIndex].vclip_num < 0)
  323.             Hostages[CurrentHostageIndex].vclip_num = MAX_HOSTAGES-1;
  324.  
  325.         if (Hostages[CurrentHostageIndex].vclip_num == start)
  326.             return 0;
  327.  
  328.     } while (Hostage_face_clip[Hostages[CurrentHostageIndex].vclip_num].num_frames == 0);
  329.  
  330.     return 1;
  331. }
  332.  
  333. int PlayHostageSound()    {
  334.     int sound_num;
  335.  
  336.     if (!hostage_is_valid( CurrentHostageIndex ) )    
  337.         return 0;
  338.  
  339.     sound_num = Hostage_face_clip[Hostages[CurrentHostageIndex].vclip_num].sound_num;
  340.  
  341.     if ( sound_num > -1 )    {
  342.         digi_play_sample( sound_num, F1_0 );
  343.     }
  344.  
  345.     return 1;    
  346. }
  347.  
  348. //@@int find_next_hostage_sound()    {
  349. //@@    int start=0,n;
  350. //@@
  351. //@@    n = Hostages[CurrentHostageIndex].sound_num;
  352. //@@    do    {
  353. //@@        n++;
  354. //@@        if ( n < SOUND_HOSTAGE_VOICES ) n = SOUND_HOSTAGE_VOICES+MAX_HOSTAGE_SOUNDS-1;
  355. //@@        if ( n >= SOUND_HOSTAGE_VOICES+MAX_HOSTAGE_SOUNDS ) n = SOUND_HOSTAGE_VOICES;
  356. //@@        start++;
  357. //@@        if ( start > MAX_HOSTAGE_SOUNDS ) break;
  358. //@@    } while ( Sounds[n] == NULL );
  359. //@@
  360. //@@    if ( Sounds[n] == NULL )
  361. //@@        Hostages[CurrentHostageIndex].sound_num = -1;
  362. //@@    else    {
  363. //@@        Hostages[CurrentHostageIndex].sound_num = n;
  364. //@@        PlayHostageSound();
  365. //@@    }
  366. //@@    return 1;
  367. //@@}
  368. //@@
  369. //@@int find_prev_hostage_sound()    {
  370. //@@    int start=0,n;
  371. //@@
  372. //@@    n = Hostages[CurrentHostageIndex].sound_num;
  373. //@@    do    {
  374. //@@        n--;
  375. //@@        if ( n < SOUND_HOSTAGE_VOICES ) n = SOUND_HOSTAGE_VOICES+MAX_HOSTAGE_SOUNDS-1;
  376. //@@        if ( n >= SOUND_HOSTAGE_VOICES+MAX_HOSTAGE_SOUNDS ) n = SOUND_HOSTAGE_VOICES;
  377. //@@        start++;
  378. //@@        if ( start > MAX_HOSTAGE_SOUNDS ) break;
  379. //@@    } while ( Sounds[n] == NULL );
  380. //@@
  381. //@@    if ( Sounds[n] == NULL )
  382. //@@        Hostages[CurrentHostageIndex].sound_num = -1;
  383. //@@    else    {
  384. //@@        Hostages[CurrentHostageIndex].sound_num = n;
  385. //@@        PlayHostageSound();
  386. //@@    }
  387. //@@    return 1;
  388. //@@}
  389.  
  390.  
  391. //-------------------------------------------------------------------------
  392. // Called from the editor... does one instance of the hostage dialog box
  393. //-------------------------------------------------------------------------
  394. int do_hostage_dialog()
  395. {
  396.     int i;
  397.  
  398.     // Only open 1 instance of this window...
  399.     if ( MainWindow != NULL ) return 0;
  400.     
  401.     // Close other windows
  402.     close_all_windows();
  403.  
  404.     CurrentHostageIndex = 0;
  405.     SelectClosestHostage();
  406.  
  407.     // Open a window with a quit button
  408.     MainWindow = ui_open_window( TMAPBOX_X+10, TMAPBOX_Y+20, 765-TMAPBOX_X, 545-TMAPBOX_Y, WIN_DIALOG );
  409.     QuitButton = ui_add_gadget_button( MainWindow, 20, 222, 48, 40, "Done", NULL );
  410.  
  411.     ui_wprintf_at( MainWindow, 10, 32,"&Message:" );
  412.     HostageText = ui_add_gadget_inputbox( MainWindow, 10, 50, HOSTAGE_MESSAGE_LEN, HOSTAGE_MESSAGE_LEN, HostageMessage );
  413.  
  414.     // The little box the hostage vclip will play in.
  415.     HostageViewBox = ui_add_gadget_userbox( MainWindow,10, 90+10, 64, 64 );
  416.  
  417.     // A bunch of buttons...
  418.     i = 90;
  419. //@@    ui_add_gadget_button( MainWindow,155,i,70, 26, "<< Type", SelectPrevVclip );
  420. //@@    ui_add_gadget_button( MainWindow,155+70,i,70, 26, "Type >>", SelectNextVclip );i += 29;        
  421. //@@    ui_add_gadget_button( MainWindow,155,i,70, 26, "<< Sound",  find_prev_hostage_sound );
  422. //@@    ui_add_gadget_button( MainWindow,155+70,i,70, 26, "Sound >>", find_next_hostage_sound );i += 29;        
  423.  
  424.     ui_add_gadget_button( MainWindow,155,i,70, 26, "<< Face", SelectPrevFace );
  425.     ui_add_gadget_button( MainWindow,155+70,i,70, 26, "Face >>", SelectNextFace );i += 29;        
  426.     ui_add_gadget_button( MainWindow,155,i,140, 26, "Play sound", PlayHostageSound );i += 29;        
  427.     ui_add_gadget_button( MainWindow,155,i,140, 26, "Next Hostage", SelectNextHostage );    i += 29;        
  428.     ui_add_gadget_button( MainWindow,155,i,140, 26, "Prev Hostage", SelectPrevHostage ); i += 29;        
  429.     ui_add_gadget_button( MainWindow,155,i,140, 26, "Compress All", CompressHostages ); i += 29;        
  430.     ui_add_gadget_button( MainWindow,155,i,140, 26, "Delete", ObjectDelete );    i += 29;        
  431.     ui_add_gadget_button( MainWindow,155,i,140, 26, "Create New", PlaceHostage );    i += 29;        
  432.     
  433.     Time = timer_get_fixed_seconds();
  434.  
  435.     LastHostageIndex = -2;        // Set to some dummy value so everything works ok on the first frame.
  436.     
  437. //    if ( CurrentHostageIndex == -1 )
  438. //        SelectNextHostage();
  439.  
  440.     return 1;
  441.  
  442. }
  443.  
  444. void hostage_close_window()
  445. {
  446.     if ( MainWindow!=NULL )    {
  447.         ui_close_window( MainWindow );
  448.         MainWindow = NULL;
  449.     }
  450. }
  451.  
  452. void do_hostage_window()
  453. {
  454.     fix DeltaTime, Temp;
  455.  
  456.     if ( MainWindow == NULL ) return;
  457.  
  458.     SelectClosestHostage();
  459.  
  460.     //------------------------------------------------------------
  461.     // Call the ui code..
  462.     //------------------------------------------------------------
  463.     ui_button_any_drawn = 0;
  464.     ui_window_do_gadgets(MainWindow);
  465.  
  466.     //------------------------------------------------------------
  467.     // If we change objects, we need to reset the ui code for all
  468.     // of the radio buttons that control the ai mode.  Also makes
  469.     // the current AI mode button be flagged as pressed down.
  470.     //------------------------------------------------------------
  471.     if (LastHostageIndex != CurrentHostageIndex )    {
  472.  
  473.         if ( CurrentHostageIndex > -1 )    
  474.             strcpy( HostageText->text, Hostages[CurrentHostageIndex].text );
  475.         else
  476.             strcpy(HostageText->text, " " );
  477.  
  478.         HostageText->position = strlen(HostageText->text);
  479.         HostageText->oldposition = HostageText->position;
  480.         HostageText->status=1;
  481.         HostageText->first_time = 1;
  482.  
  483.     }
  484.  
  485.     //------------------------------------------------------------
  486.     // If any of the radio buttons that control the mode are set, then
  487.     // update the cooresponding AI state.
  488.     //------------------------------------------------------------
  489.     if ( CurrentHostageIndex > -1 )    
  490.         strcpy( Hostages[CurrentHostageIndex].text, HostageText->text );
  491.  
  492.     //------------------------------------------------------------
  493.     // A simple frame time counter for spinning the objects...
  494.     //------------------------------------------------------------
  495.     Temp = timer_get_fixed_seconds();
  496.     DeltaTime = Temp - Time;
  497.     Time = Temp;
  498.  
  499.     //------------------------------------------------------------
  500.     // Redraw the object in the little 64x64 box
  501.     //------------------------------------------------------------
  502.     if (CurrentHostageIndex > -1 )    {
  503.         int vclip_num;
  504.         
  505.         vclip_num = Hostages[CurrentHostageIndex].vclip_num;
  506.  
  507.         Assert(vclip_num != -1);
  508.  
  509.         gr_set_current_canvas( HostageViewBox->canvas );
  510.  
  511.         if ( vclip_num > -1 )    {
  512.             vclip_play( &Hostage_face_clip[vclip_num], DeltaTime );    
  513.         } else {
  514.             gr_clear_canvas( CGREY );
  515.         }
  516.     } else {
  517.         // no hostage, so just blank out
  518.         gr_set_current_canvas( HostageViewBox->canvas );
  519.         gr_clear_canvas( CGREY );
  520.     }
  521.  
  522.     //------------------------------------------------------------
  523.     // If anything changes in the ui system, redraw all the text that
  524.     // identifies this robot.
  525.     //------------------------------------------------------------
  526.     if (ui_button_any_drawn || (LastHostageIndex != CurrentHostageIndex) )    {
  527.         if ( CurrentHostageIndex > -1 )    {
  528.             ui_wprintf_at( MainWindow, 10, 15, "Hostage: %d   Object: %d", CurrentHostageIndex, Hostages[CurrentHostageIndex].objnum );
  529.             //@@ui_wprintf_at( MainWindow, 10, 73, "Type: %d   Sound: %d   ", Hostages[CurrentHostageIndex].type, Hostages[CurrentHostageIndex].sound_num );
  530.             ui_wprintf_at( MainWindow, 10, 73, "Face: %d   ", Hostages[CurrentHostageIndex].vclip_num);
  531.         }    else {
  532.             ui_wprintf_at( MainWindow, 10, 15, "Hostage: none " );
  533.             //@@ui_wprintf_at( MainWindow, 10, 73, "Type:    Sound:       " );
  534.             ui_wprintf_at( MainWindow, 10, 73, "Face:         " );
  535.         }
  536.         Update_flags |= UF_WORLD_CHANGED;
  537.     }
  538.  
  539.     if ( QuitButton->pressed || (last_keypress==KEY_ESC))    {
  540.         hostage_close_window();
  541.         return;
  542.     }        
  543.  
  544.     LastHostageIndex = CurrentHostageIndex;
  545. }
  546.  
  547.  
  548.  
  549.