//called for each level to load & setup the exit sequence load_endlevel_data(int level_num) { char filename[13]; char line[LINE_LEN],*p; CFILE *ifile; int var,segnum,sidenum; int exit_side, i; int have_binary = 0; endlevel_data_loaded = 0; //not loaded yet try_again: ; if (level_num<0) //secret level strcpy(filename,Secret_level_names[-level_num-1]); else //normal level strcpy(filename,Level_names[level_num-1]); if (!convert_ext(filename,"END")) return; ifile = cfopen(filename,"rb"); if (!ifile) { convert_ext(filename,"TXB"); ifile = cfopen(filename,"rb"); if (!ifile) if (level_num==1) { return; //abort //Error("Cannot load file text of binary version of <%s>",filename); } else { level_num = 1; goto try_again; } have_binary = 1; } //ok...this parser is pretty simple. It ignores comments, but //everything else must be in the right place var = 0; while (cfgets(line,LINE_LEN,ifile)) { if (have_binary) { for (i = 0; i < strlen(line) - 1; i++) { encode_rotate_left(&(line[i])); line[i] = line[i] ^ BITMAP_TBL_XOR; encode_rotate_left(&(line[i])); } p = line; } if ((p=strchr(line,';'))!=NULL) *p = 0; //cut off comment for (p=line+strlen(line)-1;p>line && isspace(*p);*p--=0); for (p=line;isspace(*p);p++); if (!*p) //empty line continue; switch (var) { case 0: { //ground terrain int iff_error; ubyte pal[768]; if (terrain_bm_instance.bm_data) free(terrain_bm_instance.bm_data); iff_error = iff_read_bitmap(p,&terrain_bm_instance,BM_LINEAR,pal); if (iff_error != IFF_NO_ERROR) { mprintf((1, "File %s - IFF error: %s",p,iff_errormsg(iff_error))); Error("File %s - IFF error: %s",p,iff_errormsg(iff_error)); } terrain_bitmap = &terrain_bm_instance; gr_remap_bitmap_good( terrain_bitmap, pal, iff_transparent_color, -1); break; } case 1: //height map load_terrain(p); break; case 2: sscanf(p,"%d,%d",&exit_point_bmx,&exit_point_bmy); break; case 3: //exit heading exit_angles.h = i2f(atoi(p))/360; break; case 4: { //planet bitmap int iff_error; ubyte pal[768]; if (satellite_bm_instance.bm_data) free(satellite_bm_instance.bm_data); iff_error = iff_read_bitmap(p,&satellite_bm_instance,BM_LINEAR,pal); if (iff_error != IFF_NO_ERROR) { mprintf((1, "File %s - IFF error: %s",p,iff_errormsg(iff_error))); Error("File %s - IFF error: %s",p,iff_errormsg(iff_error)); } satellite_bitmap = &satellite_bm_instance; gr_remap_bitmap_good( satellite_bitmap, pal, iff_transparent_color, -1); break; } case 5: //earth pos case 7: { //station pos vms_matrix tm; vms_angvec ta; int pitch,head; sscanf(p,"%d,%d",&head,&pitch); ta.h = i2f(head)/360; ta.p = -i2f(pitch)/360; ta.b = 0; vm_angles_2_matrix(&tm,&ta); if (var==5) satellite_pos = tm.fvec; //vm_vec_copy_scale(&satellite_pos,&tm.fvec,SATELLITE_DIST); else station_pos = tm.fvec; break; } case 6: //planet size satellite_size = i2f(atoi(p)); break; } var++; } Assert(var == NUM_VARS); // OK, now the data is loaded. Initialize everything //find the exit sequence by searching all segments for a side with //children == -2 for (segnum=0,exit_segnum=-1;exit_segnum==-1 && segnum<=Highest_segment_index;segnum++) for (sidenum=0;sidenum<6;sidenum++) if (Segments[segnum].children[sidenum] == -2) { exit_segnum = segnum; exit_side = sidenum; break; } Assert(exit_segnum!=-1); compute_segment_center(&mine_exit_point,&Segments[exit_segnum]); extract_orient_from_segment(&mine_exit_orient,&Segments[exit_segnum]); compute_center_point_on_side(&mine_side_exit_point,&Segments[exit_segnum],exit_side); vm_vec_scale_add(&mine_ground_exit_point,&mine_exit_point,&mine_exit_orient.uvec,-i2f(20)); //compute orientation of surface { vms_vector tv; vms_matrix exit_orient,tm; vm_angles_2_matrix(&exit_orient,&exit_angles); vm_transpose_matrix(&exit_orient); vm_matrix_x_matrix(&surface_orient,&mine_exit_orient,&exit_orient); vm_copy_transpose_matrix(&tm,&surface_orient); vm_vec_rotate(&tv,&station_pos,&tm); vm_vec_scale_add(&station_pos,&mine_exit_point,&tv,STATION_DIST); vm_vec_rotate(&tv,&satellite_pos,&tm); vm_vec_scale_add(&satellite_pos,&mine_exit_point,&tv,SATELLITE_DIST); vm_vector_2_matrix(&tm,&tv,&surface_orient.uvec,NULL); vm_vec_copy_scale(&satellite_upvec,&tm.uvec,SATELLITE_HEIGHT); } cfclose(ifile); endlevel_data_loaded = 1; }
// ---------------------------------------------------------------------------------------------------------- void robotmaker_proc( FuelCenter * robotcen ) { fix dist_to_player; vms_vector cur_object_loc; //, direction; int matcen_num, segnum, objnum; object *obj; fix top_time; vms_vector direction; if (robotcen->Enabled == 0) return; if (robotcen->Disable_time > 0) { robotcen->Disable_time -= FrameTime; if (robotcen->Disable_time <= 0) { robotcen->Enabled = 0; } } // No robot making in multiplayer mode. #ifdef NETWORK #ifndef SHAREWARE if ((Game_mode & GM_MULTI) && (!(Game_mode & GM_MULTI_ROBOTS) || !multi_i_am_master())) return; #else if (Game_mode & GM_MULTI) return; #endif #endif // Wait until transmorgafier has capacity to make a robot... if ( robotcen->Capacity <= 0 ) { return; } matcen_num = Segment2s[robotcen->segnum].matcen_num; if ( matcen_num == -1 ) { return; } if (RobotCenters[matcen_num].robot_flags[0]==0 && RobotCenters[matcen_num].robot_flags[1]==0) { return; } // Wait until we have a free slot for this puppy... // <<<<<<<<<<<<<<<< Num robots in mine >>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<< Max robots in mine >>>>>>>>>>>>>>> if ( (Players[Player_num].num_robots_level - Players[Player_num].num_kills_level) >= (Gamesave_num_org_robots + Num_extry_robots ) ) { return; } robotcen->Timer += FrameTime; switch( robotcen->Flag ) { case 0: // Wait until next robot can generate if (Game_mode & GM_MULTI) { top_time = ROBOT_GEN_TIME; } else { dist_to_player = vm_vec_dist_quick( &ConsoleObject->pos, &robotcen->Center ); top_time = dist_to_player/64 + d_rand() * 2 + F1_0*2; if ( top_time > ROBOT_GEN_TIME ) top_time = ROBOT_GEN_TIME + d_rand(); if ( top_time < F1_0*2 ) top_time = F1_0*3/2 + d_rand()*2; } if (robotcen->Timer > top_time ) { int count=0; int i, my_station_num = robotcen-Station; object *obj; // Make sure this robotmaker hasn't put out its max without having any of them killed. for (i=0; i<=Highest_object_index; i++) if (Objects[i].type == OBJ_ROBOT) if ((Objects[i].matcen_creator^0x80) == my_station_num) count++; if (count > Difficulty_level + 3) { robotcen->Timer /= 2; return; } // Whack on any robot or player in the matcen segment. count=0; segnum = robotcen->segnum; for (objnum=Segments[segnum].objects;objnum!=-1;objnum=Objects[objnum].next) { count++; if ( count > MAX_OBJECTS ) { Int3(); return; } if (Objects[objnum].type==OBJ_ROBOT) { collide_robot_and_materialization_center(&Objects[objnum]); robotcen->Timer = top_time/2; return; } else if (Objects[objnum].type==OBJ_PLAYER ) { collide_player_and_materialization_center(&Objects[objnum]); robotcen->Timer = top_time/2; return; } } compute_segment_center(&cur_object_loc, &Segments[robotcen->segnum]); // HACK!!! The 10 under here should be something equal to the 1/2 the size of the segment. obj = object_create_explosion(robotcen->segnum, &cur_object_loc, i2f(10), VCLIP_MORPHING_ROBOT ); if (obj) extract_orient_from_segment(&obj->orient,&Segments[robotcen->segnum]); if ( Vclip[VCLIP_MORPHING_ROBOT].sound_num > -1 ) { digi_link_sound_to_pos( Vclip[VCLIP_MORPHING_ROBOT].sound_num, robotcen->segnum, 0, &cur_object_loc, 0, F1_0 ); } robotcen->Flag = 1; robotcen->Timer = 0; } break; case 1: // Wait until 1/2 second after VCLIP started. if (robotcen->Timer > (Vclip[VCLIP_MORPHING_ROBOT].play_time/2) ) { robotcen->Capacity -= EnergyToCreateOneRobot; robotcen->Flag = 0; robotcen->Timer = 0; compute_segment_center(&cur_object_loc, &Segments[robotcen->segnum]); // If this is the first materialization, set to valid robot. if (RobotCenters[matcen_num].robot_flags[0] != 0 || RobotCenters[matcen_num].robot_flags[1] != 0) { int type; uint flags; sbyte legal_types[64]; // 64 bits, the width of robot_flags[]. int num_types, robot_index, i; num_types = 0; for (i=0;i<2;i++) { robot_index = i*32; flags = RobotCenters[matcen_num].robot_flags[i]; while (flags) { if (flags & 1) legal_types[num_types++] = robot_index; flags >>= 1; robot_index++; } } if (num_types == 1) type = legal_types[0]; else type = legal_types[(d_rand() * num_types) / 32768]; obj = create_morph_robot(&Segments[robotcen->segnum], &cur_object_loc, type ); if (obj != NULL) { #ifndef SHAREWARE #ifdef NETWORK if (Game_mode & GM_MULTI) multi_send_create_robot(robotcen-Station, obj-Objects, type); #endif #endif obj->matcen_creator = (robotcen-Station) | 0x80; // Make object faces player... vm_vec_sub( &direction, &ConsoleObject->pos,&obj->pos ); vm_vector_2_matrix( &obj->orient, &direction, &obj->orient.uvec, NULL); morph_start( obj ); //robotcen->last_created_obj = obj; //robotcen->last_created_sig = robotcen->last_created_obj->signature; } } }