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

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