Ejemplo n.º 1
0
//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;

}
Ejemplo n.º 2
0
//	----------------------------------------------------------------------------------------------------------
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;
				}
			}
 
		}