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

This commit is contained in:
zicodxx 2011-01-22 17:56:23 +01:00
parent 13faad1855
commit 4b1faafc15
6 changed files with 111 additions and 81 deletions

View file

@ -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
--------

View file

@ -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;

View file

@ -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;
/*

View file

@ -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<MAX_SEGMENTS; i++ )
Segments[i].special = SEGMENT_IS_NOTHING;
Control_center_destroyed = 0;
Num_robot_centers = 0;
}
@ -534,76 +530,6 @@ void robotmaker_proc( FuelCenter * robotcen )
}
}
#define BASE_CONTROL_CENTER_EXPLOSION_TIME 30
#define DIFF_CONTROL_CENTER_EXPLOSION_TIME (BASE_CONTROL_CENTER_EXPLOSION_TIME + (NDL-Difficulty_level-1)*5)
#define COUNTDOWN_VOICE_TIME (i2f(DIFF_CONTROL_CENTER_EXPLOSION_TIME)-fl2f(12.75))
void controlcen_proc( FuelCenter * controlcen )
{
fix old_time;
int fc;
if (!Control_center_destroyed) return;
// Control center destroyed, rock the player's ship.
fc = Countdown_seconds_left;
if (fc > 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;

View file

@ -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);

View file

@ -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);