From 4b1faafc15b19185b1303b5f977d32d14f6b1a7c Mon Sep 17 00:00:00 2001 From: zicodxx Date: Sat, 22 Jan 2011 17:56:23 +0100 Subject: [PATCH] Handling Controlcen countdown Descent2-way to make code more similar but more importantly to avoid issues in Multiplayer levels which do not even have a Controlcen type Station causing the game get stuck in an infinite loop; Fixed small issue parsing killreactor command in Multiplayer --- CHANGELOG.txt | 1 + main/cntrlcen.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++-- main/cntrlcen.h | 1 + main/fuelcen.c | 80 ++---------------------------------------- main/multi.c | 2 +- main/state.c | 16 ++++++++- 6 files changed, 111 insertions(+), 81 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index ce664b561..6193eb6f9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -3,6 +3,7 @@ D1X-Rebirth Changelog 20110122 -------- main/console.c, main/game.c, main/gamerend.c, main/gauges.c: Added timer_update() to stop/start/reset_time() functions so resumed last_timer_value will be precise; Added new FPS counter which actually does count the frames rendered per second and is less irritating; Added timer_dleay2 call to console to not stress CPU too much; Imporoved placement for show_time(), multi messages +main/cntrlcen.c, main/cntrlcen.h, main/fuelcen.c, main/multi.c, main/state.c: Handling Controlcen countdown Descent2-way to make code more similar but more importantly to avoid issues in Multiplayer levels which do not even have a Controlcen type Station causing the game get stuck in an infinite loop; Fixed small issue parsing killreactor command in Multiplayer 20110121 -------- diff --git a/main/cntrlcen.c b/main/cntrlcen.c index ac87037be..a65866a09 100644 --- a/main/cntrlcen.c +++ b/main/cntrlcen.c @@ -29,6 +29,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #include "wall.h" #include "object.h" #include "robot.h" +#include "endlevel.h" #include "byteswap.h" vms_vector controlcen_gun_points[MAX_CONTROLCEN_GUNS]; @@ -44,6 +45,8 @@ int Control_center_present; vms_vector Gun_pos[MAX_CONTROLCEN_GUNS], Gun_dir[MAX_CONTROLCEN_GUNS]; +void do_countdown_frame(); + // ----------------------------------------------------------------------------- //return the position & orientation of a gun on the control center object void calc_controlcen_gun_point(vms_vector *gun_point,vms_vector *gun_dir,object *obj,int gun_num) @@ -102,16 +105,98 @@ int calc_best_gun(int num_guns, vms_vector *gun_pos, vms_vector *gun_dir, vms_ve int Dead_controlcen_object_num=-1; +int Control_center_destroyed = 0; +fix Countdown_timer=0; +int Countdown_seconds_left=0, Total_countdown_time=0; //in whole seconds + +int Alan_pavlish_reactor_times[NDL] = {50, 45, 40, 35, 30}; + // ----------------------------------------------------------------------------- // Called every frame. If control center been destroyed, then actually do something. void do_controlcen_dead_frame(void) { - if (!Control_center_present) - return; +// if (!Control_center_present) +// return; if ((Dead_controlcen_object_num != -1) && (Countdown_seconds_left > 0)) if (d_rand() < FrameTime*4) create_small_fireball_on_object(&Objects[Dead_controlcen_object_num], F1_0*3, 1); + + if (Control_center_destroyed && !Endlevel_sequence) + do_countdown_frame(); +} + +#define COUNTDOWN_VOICE_TIME fl2f(12.75) + +void do_countdown_frame() +{ + fix old_time; + int fc, div_scale; + + if (!Control_center_destroyed) return; + + // Control center destroyed, rock the player's ship. + fc = Countdown_seconds_left; + if (fc > 16) + fc = 16; + + // At Trainee, decrease rocking of ship by 4x. + div_scale = 1; + if (Difficulty_level == 0) + div_scale = 4; + + if (FixedStep & EPS20) + { + ConsoleObject->mtype.phys_info.rotvel.x += (fixmul(d_rand() - 16384, 3*F1_0/16 + (F1_0*(16-fc))/32))/div_scale; + ConsoleObject->mtype.phys_info.rotvel.z += (fixmul(d_rand() - 16384, 3*F1_0/16 + (F1_0*(16-fc))/32))/div_scale; + } + // Hook in the rumble sound effect here. + + old_time = Countdown_timer; + Countdown_timer -= FrameTime; + Countdown_seconds_left = f2i(Countdown_timer + F1_0*7/8); + + if ( (old_time > COUNTDOWN_VOICE_TIME ) && (Countdown_timer <= COUNTDOWN_VOICE_TIME) ) { + digi_play_sample( SOUND_COUNTDOWN_13_SECS, F3_0 ); + } + if ( f2i(old_time + F1_0*7/8) != Countdown_seconds_left ) { + if ( (Countdown_seconds_left>=0) && (Countdown_seconds_left<10) ) + digi_play_sample( SOUND_COUNTDOWN_0_SECS+Countdown_seconds_left, F3_0 ); + if ( Countdown_seconds_left==Total_countdown_time-1) + digi_play_sample( SOUND_COUNTDOWN_29_SECS, F3_0 ); + } + + if (Countdown_timer > 0) { + fix size,old_size; + size = (i2f(Total_countdown_time)-Countdown_timer) / fl2f(0.65); + old_size = (i2f(Total_countdown_time)-old_time) / fl2f(0.65); + if (size != old_size && (Countdown_seconds_left < (Total_countdown_time-5) )) { // Every 2 seconds! + //@@if (Dead_controlcen_object_num != -1) { + //@@ vms_vector vp; //,v,c; + //@@ compute_segment_center(&vp, &Segments[Objects[Dead_controlcen_object_num].segnum]); + //@@ object_create_explosion( Objects[Dead_controlcen_object_num].segnum, &vp, size*10, VCLIP_SMALL_EXPLOSION); + //@@} + + digi_play_sample( SOUND_CONTROL_CENTER_WARNING_SIREN, F3_0 ); + } + } else { + int flash_value; + + if (old_time > 0) + digi_play_sample( SOUND_MINE_BLEW_UP, F1_0 ); + + flash_value = f2i(-Countdown_timer * (64 / 4)); // 4 seconds to total whiteness + PALETTE_FLASH_SET(flash_value,flash_value,flash_value); + + if (PaletteBlueAdd > 64 ) { + gr_set_current_canvas( NULL ); + gr_clear_canvas(BM_XRGB(31,31,31)); //make screen all white to match palette effect + reset_palette_add(); //restore palette for death message + //controlcen->MaxCapacity = Fuelcen_max_amount; + //gauge_message( "Control Center Reset" ); + DoPlayerDead(); //kill_player(); + } + } } // ----------------------------------------------------------------------------- @@ -130,6 +215,9 @@ void do_controlcen_destroyed_stuff(object *objp) // And start the countdown stuff. Control_center_destroyed = 1; + Total_countdown_time = Alan_pavlish_reactor_times[Difficulty_level]; + + Countdown_timer = i2f(Total_countdown_time); if (!Control_center_present) return; diff --git a/main/cntrlcen.h b/main/cntrlcen.h index d1ac4c94b..14809b262 100644 --- a/main/cntrlcen.h +++ b/main/cntrlcen.h @@ -64,6 +64,7 @@ extern void init_controlcen_for_level(void); extern void do_controlcen_destroyed_stuff(object *objp); extern void do_controlcen_dead_frame(void); +extern fix Countdown_timer; extern int Control_center_destroyed, Countdown_seconds_left; /* diff --git a/main/fuelcen.c b/main/fuelcen.c index 49791ede5..1de3d1fa9 100644 --- a/main/fuelcen.c +++ b/main/fuelcen.c @@ -61,9 +61,6 @@ fix Fuelcen_max_amount = i2f(100); // by this amount... when capacity gets to 0, no more morphers... fix EnergyToCreateOneRobot = i2f(1); -int Control_center_destroyed = 0; -int Countdown_seconds_left = 0; - #define MATCEN_HP_DEFAULT F1_0*500; // Hitpoints #define MATCEN_INTERVAL_DEFAULT F1_0*5; // 5 seconds @@ -95,7 +92,6 @@ void fuelcen_reset() for(i=0; i 16) - fc = 16; - if (FixedStep & EPS20) - { - ConsoleObject->mtype.phys_info.rotvel.x += fixmul(d_rand() - 16384, 3*F1_0/16 + (F1_0*(16-fc))/32); - ConsoleObject->mtype.phys_info.rotvel.z += fixmul(d_rand() - 16384, 3*F1_0/16 + (F1_0*(16-fc))/32); - } - // Hook in the rumble sound effect here. - - old_time = controlcen->Timer; - controlcen->Timer += FrameTime; //timer_get_approx_seconds - Countdown_seconds_left = DIFF_CONTROL_CENTER_EXPLOSION_TIME - f2i(controlcen->Timer); - if ( (old_time < COUNTDOWN_VOICE_TIME ) && (controlcen->Timer >= COUNTDOWN_VOICE_TIME) ) { - digi_play_sample( SOUND_COUNTDOWN_13_SECS, F3_0 ); - } - if ( f2i(old_time) != f2i(controlcen->Timer) ) { - if ( (Countdown_seconds_left>=0) && (Countdown_seconds_left<10) ) - digi_play_sample( SOUND_COUNTDOWN_0_SECS+Countdown_seconds_left, F3_0 ); - if ( Countdown_seconds_left==DIFF_CONTROL_CENTER_EXPLOSION_TIME-1) - digi_play_sample( SOUND_COUNTDOWN_29_SECS, F3_0 ); - } - - if (controlcen->Timer < i2f(DIFF_CONTROL_CENTER_EXPLOSION_TIME)) { - vms_vector vp; //,v,c; - fix size; - compute_segment_center(&vp, &Segments[controlcen->segnum]); - size = (0x50000*f2i(controlcen->Timer)*(FrameTime & 0xF))/16; - size = controlcen->Timer / (fl2f(0.65)); - old_time = old_time / (fl2f(0.65)); - if (size != old_time && (controlcen->Timer > (5*F1_0) )) { // Every 2 seconds! - //@@object_create_explosion( controlcen->segnum, &vp, size*10, FrameTime & 7); - object_create_explosion( controlcen->segnum, &vp, size*10, VCLIP_SMALL_EXPLOSION); - digi_play_sample( SOUND_CONTROL_CENTER_WARNING_SIREN, F3_0 ); - } - } else { - int flash_value; - - if (old_time < i2f(DIFF_CONTROL_CENTER_EXPLOSION_TIME)) - digi_play_sample( SOUND_MINE_BLEW_UP, F1_0 ); - - flash_value = f2i( (controlcen->Timer-i2f(DIFF_CONTROL_CENTER_EXPLOSION_TIME))*(64/4)); // 4 seconds to total whiteness - PALETTE_FLASH_SET(flash_value,flash_value,flash_value); - - //gauge_message( "YOU'RE TOO SLOW! THE MINE BLEW UP!" ); - if (PaletteBlueAdd > 64 ) { - gr_set_current_canvas( NULL ); - gr_clear_canvas(BM_XRGB(31,31,31)); //make screen all white to match palette effect - reset_palette_add(); //restore palette for death message - controlcen->Timer = -1; - controlcen->MaxCapacity = Fuelcen_max_amount; - //gauge_message( "Control Center Reset" ); - DoPlayerDead(); //kill_player(); - } - } -} - #ifndef M_PI #define M_PI 3.14159 #endif @@ -621,9 +547,9 @@ void fuelcen_update_all() if ( Station[i].Type == SEGMENT_IS_ROBOTMAKER ) { if (! (Game_suspended & SUSP_ROBOTS)) robotmaker_proc( &Station[i] ); - } else if ( Station[i].Type == SEGMENT_IS_CONTROLCEN ) { - controlcen_proc( &Station[i] ); - +// } else if ( Station[i].Type == SEGMENT_IS_CONTROLCEN ) { +// controlcen_proc( &Station[i] ); +// } else if ( (Station[i].MaxCapacity > 0) && (PlayerSegment!=&Segments[Station[i].segnum]) ) { if ( Station[i].Capacity < Station[i].MaxCapacity ) { Station[i].Capacity += AmountToreplenish; diff --git a/main/multi.c b/main/multi.c index ff2b6c5d5..c44db9d62 100644 --- a/main/multi.c +++ b/main/multi.c @@ -1219,7 +1219,7 @@ void multi_send_message_end() } } - else if (!strnicmp (Network_message,"KillReactor",11) && (Game_mode & GM_NETWORK) && !Control_center_destroyed) + else if (!strnicmp (Network_message,"killreactor",11) && (Game_mode & GM_NETWORK) && !Control_center_destroyed) { if (!multi_i_am_master()) HUD_init_message(HM_MULTI, "Only %s can kill the reactor this way!",Players[multi_who_is_master()].callsign); diff --git a/main/state.c b/main/state.c index 8beaeccd9..82877fc4b 100644 --- a/main/state.c +++ b/main/state.c @@ -989,7 +989,14 @@ int state_save_all_sub(char *filename, char *desc, int between_levels) PHYSFS_write(fp, RobotCenters, sizeof(matcen_info), Num_robot_centers); PHYSFS_write(fp, &ControlCenterTriggers, sizeof(control_center_triggers), 1); PHYSFS_write(fp, &Num_fuelcenters, sizeof(int), 1); - PHYSFS_write(fp, Station, sizeof(FuelCenter), Num_fuelcenters); + for (i = 0; i < Num_fuelcenters; i++) + { + // NOTE: Usually Descent1 handles countdown by Timer value of the Reactor Station. Since we now use Descent2 code to handle countdown (which we do in case there IS NO Reactor Station which causes potential trouble in Multiplayer), let's find the Reactor here and store the timer in it. + if (Station[i].Type == SEGMENT_IS_CONTROLCEN) + Station[i].Timer = Countdown_timer; + PHYSFS_write(fp, &Station[i], sizeof(FuelCenter), 1); + } +// PHYSFS_write(fp, Station, sizeof(FuelCenter), Num_fuelcenters); // Save the control cen info PHYSFS_write(fp, &Control_center_been_hit, sizeof(int), 1); @@ -1291,6 +1298,13 @@ RetryObjectLoading: control_center_triggers_read_n_swap(&ControlCenterTriggers, 1, swap, fp); Num_fuelcenters = PHYSFSX_readSXE32(fp, swap); fuelcen_read_n_swap(Station, Num_fuelcenters, swap, fp); + Countdown_timer = 0; + for (i = 0; i < Num_fuelcenters; i++) + { + // NOTE: Usually Descent1 handles countdown by Timer value of the Reactor Station. Since we now use Descent2 code to handle countdown (which we do in case there IS NO Reactor Station which causes potential trouble in Multiplayer), let's find the Reactor here and read the timer from it. + if (Station[i].Type == SEGMENT_IS_CONTROLCEN) + Countdown_timer = Station[i].Timer; + } // Restore the control cen info Control_center_been_hit = PHYSFSX_readSXE32(fp, swap);