Beispiel #1
0
int RestoreGameState() {
	load_level("GAMESAVE.LVL");
	gamestate_not_restored = 0;

	editor_status("Gamestate restored.\n");

	Update_flags |= UF_WORLD_CHANGED;
	return 0;
}
Beispiel #2
0
void RestoreGameState() {
	load_level("GAMESAVE.LVL");
	gamestate_not_restored = 0;

	mprintf((0, "Gamestate restored.\n"));
	editor_status("Gamestate restored.\n");

	Update_flags |= UF_WORLD_CHANGED;
}
Beispiel #3
0
// -----------------------------------------------------------------------------
//	Increase the size of Cursegp in dimension dimension by amount
int segsize_common(int dimension, fix amount)
{
    int	i;
    int	propagated[MAX_SIDES_PER_SEGMENT];
    vms_vector	uvec, rvec, fvec, scalevec;

    Degenerate_segment_found = 0;

    med_scale_segment_new(Cursegp, dimension, amount);

    med_extract_up_vector_from_segment_side(Cursegp, Curside, &uvec);
    med_extract_right_vector_from_segment_side(Cursegp, Curside, &rvec);
    extract_forward_vector_from_segment(Cursegp, &fvec);

    scalevec.x = vm_vec_mag(&rvec);
    scalevec.y = vm_vec_mag(&uvec);
    scalevec.z = vm_vec_mag(&fvec);

    if (Degenerate_segment_found) {
        Degenerate_segment_found = 0;
        // mprintf(0, "Applying scale would create degenerate segments.  Aborting scale.\n");
        editor_status("Applying scale would create degenerate segments.  Aborting scale.");
        med_scale_segment_new(Cursegp, dimension, -amount);
        return 1;
    }

    med_create_new_segment(&scalevec);

    //	For all segments to which Cursegp is connected, propagate tmap (uv coordinates) from the connected
    //	segment back to Cursegp.  This will meaningfully propagate uv coordinates to all sides which havve
    //	an incident edge.  It will also do some sides more than once.  And it is probably just not what you want.
    for (i=0; i<MAX_SIDES_PER_SEGMENT; i++)
        propagated[i] = 0;

    for (i=0; i<MAX_SIDES_PER_SEGMENT; i++)
        if (IS_CHILD(Cursegp->children[i])) {
            int	s;
            for (s=0; s<MAX_SIDES_PER_SEGMENT; s++)
                propagated[s]++;
            propagated[Side_opposite[i]]--;
            med_propagate_tmaps_to_segments(&Segments[Cursegp->children[i]],Cursegp,1);
        }

    //	Now, for all sides that were not adjacent to another side, and therefore did not get tmaps
    //	propagated to them, treat as a back side.
    for (i=0; i<MAX_SIDES_PER_SEGMENT; i++)
        if (!propagated[i]) {
            med_propagate_tmaps_to_back_side(Cursegp, i, 1);
        }

    //	New stuff, assign default texture to all affected sides.

    Update_flags |= UF_WORLD_CHANGED;
    mine_changed = 1;
    return 1;
}
Beispiel #4
0
//-------------------------------------------------------------------------
// Called from the editor... does one instance of the trigger dialog box
//-------------------------------------------------------------------------
int do_trigger_dialog()
{
	int i;
	trigger_dialog *t;

	if (!Markedsegp) {
		editor_status("Trigger requires Marked Segment & Side.");
		return 0;
	}

	// Only open 1 instance of this window...
	if ( MainWindow != NULL ) return 0;
	
	MALLOC(t, trigger_dialog, 1);
	if (!t)
		return 0;

	// Close other windows.	
	robot_close_window();
	close_wall_window();
	close_centers_window();
	hostage_close_window();

	// Open a window with a quit button
	MainWindow = ui_create_dialog( TMAPBOX_X+20, TMAPBOX_Y+20, 765-TMAPBOX_X, 545-TMAPBOX_Y, DF_DIALOG, (int (*)(UI_DIALOG *, d_event *, void *))trigger_dialog_handler, t );

	// These are the checkboxes for each door flag.
	i = 44;
	t->triggerFlag[0] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Door Control" );  	i+=22;
	t->triggerFlag[1] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Shield damage" ); 	i+=22;
	t->triggerFlag[2] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Energy drain" );		i+=22;
	t->triggerFlag[3] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Exit" );					i+=22;
	t->triggerFlag[4] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "One-shot" );			i+=22;
	t->triggerFlag[5] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Illusion ON" );		i+=22;
	t->triggerFlag[6] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Illusion OFF" );		i+=22;
	t->triggerFlag[7] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Trigger ON" );			i+=22;
	t->triggerFlag[8] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Matcen Trigger" ); 	i+=22;
	t->triggerFlag[9] = ui_add_gadget_checkbox( MainWindow, 22, i, 16, 16, 0, "Secret Exit" ); 		i+=22;

	t->quitButton = ui_add_gadget_button( MainWindow, 20, i, 48, 40, "Done", NULL );
																				 
	// The little box the wall will appear in.
	t->wallViewBox = ui_add_gadget_userbox( MainWindow, 155, 5, 64, 64 );

	// A bunch of buttons...
	i = 80;
//	ui_add_gadget_button( MainWindow,155,i,140, 26, "Add Door Control", add_trigger_control ); i += 29;
	ui_add_gadget_button( MainWindow,155,i,140, 26, "Remove Trigger", trigger_remove ); i += 29;
	ui_add_gadget_button( MainWindow,155,i,140, 26, "Bind Wall", bind_wall_to_trigger ); i += 29;
	ui_add_gadget_button( MainWindow,155,i,140, 26, "Bind Matcen", bind_matcen_to_trigger ); i += 29;
	ui_add_gadget_button( MainWindow,155,i,140, 26, "All Triggers ON", trigger_turn_all_ON ); i += 29;

	t->old_trigger_num = -2;		// Set to some dummy value so everything works ok on the first frame.

	return 1;
}
Beispiel #5
0
//	------------------------------------------------------------------------------------------------------
//	Place current object at center of current segment.
int ObjectPlaceObject(void)
{
	int	old_cur_object_index;
	int	rval;

	vms_vector	cur_object_loc;

#ifdef SHAREWARE
	if (ObjType[Cur_robot_type] == OL_PLAYER) {
		int num_players = compute_num_players();
		Assert(num_players <= MAX_PLAYERS);
		if (num_players == MAX_PLAYERS) {
			editor_status("Can't place player object.  Already %i players.", MAX_PLAYERS);
			return -1;
		}
	}
#endif

#ifndef SHAREWARE
	if (ObjType[Cur_robot_type] == OL_PLAYER) {
		int num_players = compute_num_players();
		Assert(num_players <= MAX_MULTI_PLAYERS);
		if (num_players > MAX_PLAYERS)
			editor_status("You just placed a cooperative player object");
		if (num_players == MAX_MULTI_PLAYERS) {
			editor_status("Can't place player object.  Already %i players.", MAX_MULTI_PLAYERS);
			return -1;
		}
	}
#endif

	//update_due_to_new_segment();
	compute_segment_center(&cur_object_loc, Cursegp);

	old_cur_object_index = Cur_object_index;
	rval = place_object(Cursegp, &cur_object_loc, Cur_robot_type);

	if (old_cur_object_index != Cur_object_index)
		Objects[Cur_object_index].rtype.pobj_info.tmap_override = -1;

	return rval;

}
Beispiel #6
0
//---------------------------------------------------------------------
// Add a wall to markedside
int wall_add_to_markedside(sbyte type)
{
	int Connectside;
	segment *csegp;

	if (add_wall(Markedsegp, Markedside)) {
		int	wall_num, cwall_num;
		csegp = &Segments[Markedsegp->children[Markedside]];

		Connectside = find_connect_side(Markedsegp, csegp);

		wall_num = Markedsegp->sides[Markedside].wall_num;
		cwall_num = csegp->sides[Connectside].wall_num;

		Walls[wall_num].segnum = Markedsegp-Segments;
		Walls[cwall_num].segnum = csegp-Segments;

		Walls[wall_num].sidenum = Markedside;
		Walls[cwall_num].sidenum = Connectside;

  		Walls[wall_num].flags = 0;
		Walls[cwall_num].flags = 0;

  		Walls[wall_num].type = type;
		Walls[cwall_num].type = type;

		Walls[wall_num].trigger = -1;
		Walls[cwall_num].trigger = -1;

		Walls[wall_num].clip_num = -1;
		Walls[cwall_num].clip_num = -1;

		Walls[wall_num].keys = KEY_NONE;
		Walls[cwall_num].keys = KEY_NONE;

		if (type == WALL_BLASTABLE) {
	  		Walls[wall_num].hps = WALL_HPS;
			Walls[cwall_num].hps = WALL_HPS;
			
	  		Walls[wall_num].clip_num = 0;
			Walls[cwall_num].clip_num = 0;
			}	

		if (type != WALL_DOOR) {
			Markedsegp->sides[Markedside].tmap_num2 = 0;
			csegp->sides[Connectside].tmap_num2 = 0;
			}

		Update_flags |= UF_WORLD_CHANGED;
		return 1;
	} else {
		editor_status( "Cannot add wall here, no children" );
		return 0;
	}
}
Beispiel #7
0
Datei: med.c Projekt: paud/d2x-xl
void diagnostic_message( const char *format, ... )
{
	char diag_line[DIAGNOSTIC_MESSAGE_MAX];

	va_list ap;

	va_start(ap, format);
	vsprintf(diag_line, format, ap);
	va_end(ap);

	editor_status(diag_line);
}
Beispiel #8
0
//  ---------- Create a bridge segment between current segment:side adjacent segment:side ----------
int CreateAdjacentJoint()
{
    int		adj_side;
    segment	*adj_sp;

    if (med_find_adjacent_segment_side(Cursegp, Curside, &adj_sp, &adj_side)) {
        if (Cursegp->children[Curside] != adj_sp-Segments) {
            med_form_joint(Cursegp,Curside,adj_sp,adj_side);
            Update_flags |= UF_WORLD_CHANGED;
            mine_changed = 1;
            autosave_mine(mine_filename);
            diagnostic_message("Joint segment formed.");
            strcpy(undo_status[Autosave_count], "Joint segment undone.");
            warn_if_concave_segments();
        } else
            editor_status("Attempted to form joint through connected side -- joint segment not formed (you bozo).");
    } else
        editor_status("Could not find adjacent segment -- joint segment not formed.");

    return 1;
}
Beispiel #9
0
//-----------------------------------------------------------------
// Adds a specific trigger flag to Markedsegp/Markedside if it is possible.
// Automatically adds flag to Connectside if possible unless it is a control trigger.
// Returns 1 if trigger flag added.
// Returns 0 if trigger flag cannot be added.
int trigger_add_to_Markedside(short flag) {
	int trigger_num; //, ctrigger_num;

	if (!Markedsegp) {
		editor_status("No Markedside.");
		return 0;
	}

	// If no child on Markedside return
	if (!IS_CHILD(Markedsegp->children[Markedside])) return 0;

	trigger_num = add_trigger(Markedsegp, Markedside);

	if (trigger_num == -1) {
		editor_status("Cannot add trigger at Markedside.");
		return 0;
	}

 	Triggers[trigger_num].flags |= flag;

	return 1;
}
Beispiel #10
0
int wall_unlink_door()
{
	wall *w1=NULL;

	if (Cursegp->sides[Curside].wall_num != -1)
		w1 = &Walls[Cursegp->sides[Curside].wall_num];

	if (!w1 || w1->type != WALL_DOOR) {
		editor_status("Curseg/curside is not a door");
		return 0;
	}

	if (w1->linked_wall == -1)
		editor_status("Curseg/curside is not linked");

	Assert(Walls[w1->linked_wall].linked_wall == w1-Walls);

	Walls[w1->linked_wall].linked_wall = -1;
	w1->linked_wall = -1;

	return 1;

}
Beispiel #11
0
int bind_wall_to_trigger() {

	int wall_num, trigger_num, link_num;
	int i;

	if (!Markedsegp) {
		editor_status("No marked segment.");
		return 0;
	}

	wall_num = Markedsegp->sides[Markedside].wall_num;
	if (wall_num == -1) {
		editor_status("No wall at Markedside.");
		return 0;
	}

	trigger_num = Walls[wall_num].trigger;	

	if (trigger_num == -1) {
		editor_status("No trigger at Markedside.");
		return 0;
	}

	if (Cursegp->sides[Curside].wall_num == -1) {
		editor_status("No wall at Curside.");
		return 0;
	}

	if ((Cursegp==Markedsegp) && (Curside==Markedside)) {
		editor_status("Cannot bind wall to itself.");
		return 0;
	}

	link_num = Triggers[trigger_num].num_links;
	for (i=0;i<link_num;i++)
		if ((Cursegp-Segments == Triggers[trigger_num].seg[i]) && (Curside == Triggers[trigger_num].side[i])) {
			editor_status("Curside already bound to Markedside.");
			return 0;
		}

	// Error checking completed, actual binding begins
	Triggers[trigger_num].seg[link_num] = Cursegp - Segments;
	Triggers[trigger_num].side[link_num] = Curside;
	Triggers[trigger_num].num_links++;

	mprintf((0, "seg %d:side %d linked to link_num %d\n",
				Triggers[trigger_num].seg[link_num], Triggers[trigger_num].side[link_num], link_num)); 

	editor_status("Wall linked to trigger");

	return 1;
}
Beispiel #12
0
int wall_assign_door(int door_type)
{
	int Connectside;
	segment *csegp;

	if (Cursegp->sides[Curside].wall_num == -1) {
		editor_status("Cannot assign door. No wall at Curside.");
		return 0;
	}

	if (Walls[Cursegp->sides[Curside].wall_num].type != WALL_DOOR  &&  Walls[Cursegp->sides[Curside].wall_num].type != WALL_BLASTABLE) {
		editor_status("Cannot assign door. No door at Curside.");
		return 0;
	}

	Current_door_type = door_type;

 	csegp = &Segments[Cursegp->children[Curside]];
 	Connectside = find_connect_side(Cursegp, csegp);
	
 	Walls[Cursegp->sides[Curside].wall_num].clip_num = door_type;
  	Walls[csegp->sides[Connectside].wall_num].clip_num = door_type;

	if (WallAnims[door_type].flags & WCF_TMAP1) {
		Cursegp->sides[Curside].tmap_num = WallAnims[door_type].frames[0];
		csegp->sides[Connectside].tmap_num = WallAnims[door_type].frames[0];
		Cursegp->sides[Curside].tmap_num2 = 0;
		csegp->sides[Connectside].tmap_num2 = 0;
	}
	else {
		Cursegp->sides[Curside].tmap_num2 = WallAnims[door_type].frames[0];
		csegp->sides[Connectside].tmap_num2 = WallAnims[door_type].frames[0];
	}

	Update_flags |= UF_WORLD_CHANGED;
	return 1;
}
Beispiel #13
0
//	------------------------------------------------------------------------------------------------------
int	ObjectSetDefault(void)
{
	//update_due_to_new_segment();

	if (Cur_object_index == -1) {
		editor_status("No current object, cannot move.");
		return 1;
	}

	compute_segment_center(&Objects[Cur_object_index].pos, &Segments[Objects[Cur_object_index].segnum]);

	Update_flags |= UF_WORLD_CHANGED;

	return 1;
}
Beispiel #14
0
//	------------------------------------------------------------------------------------------------------
//	Place current object at center of current segment.
int ObjectPlaceObjectTmap(void)
{
	int	rval, old_cur_object_index;
	//update_due_to_new_segment();
	const auto cur_object_loc = compute_segment_center(Cursegp);

	old_cur_object_index = Cur_object_index;
	rval = place_object(Cursegp, cur_object_loc, Cur_object_type, Cur_object_id);

	if ((Cur_object_index != old_cur_object_index) && (Objects[Cur_object_index].render_type == RT_POLYOBJ))
		Objects[Cur_object_index].rtype.pobj_info.tmap_override = CurrentTexture;
	else
		editor_status("Unable to apply current texture map to this object.");
	
	return rval;
}
Beispiel #15
0
// ------------------------------------------------------------------------------------------------
void copy_old_wall_data_to_new(int owall, int nwall)
{
	Walls[nwall].flags = Walls[owall].flags;
	Walls[nwall].type = Walls[owall].type;
	Walls[nwall].clip_num = Walls[owall].clip_num;
	Walls[nwall].keys = Walls[owall].keys;
	Walls[nwall].hps = Walls[owall].hps;
	Walls[nwall].state = Walls[owall].state;
	Walls[nwall].linked_wall = -1;

	Walls[nwall].trigger = -1;

	if (Walls[owall].trigger != -1) {
		editor_status("Warning: Trigger not copied in group copy.");
	}
}
Beispiel #16
0
//	------------------------------------------------------------------------------------------------------
int	ObjectSetDefault(void)
{
	//update_due_to_new_segment();

	if (Cur_object_index == object_none) {
		editor_status("No current object, cannot move.");
		return 1;
	}

	const auto &&objp = vobjptr(Cur_object_index);
	compute_segment_center(objp->pos, vcsegptr(objp->segnum));

	Update_flags |= UF_WORLD_CHANGED;

	return 1;
}
Beispiel #17
0
int NextWall() {
	int wall_type;

	if (Cursegp->sides[Curside].wall_num == -1) {
		editor_status("Cannot assign new wall. No wall on curside.");
		return 0;
	}

	wall_type = Walls[Cursegp->sides[Curside].wall_num].clip_num;

	if (Walls[Cursegp->sides[Curside].wall_num].type == WALL_DOOR) {

	 	do {

			wall_type++;

			if (wall_type >= Num_wall_anims) {
				wall_type = 0;
				if (Walls[Cursegp->sides[Curside].wall_num].clip_num==-1)
					Error("Cannot find clip for door."); 
			}

		} while (WallAnims[wall_type].num_frames == -1 || WallAnims[wall_type].flags & WCF_BLASTABLE);

	}
	else if (Walls[Cursegp->sides[Curside].wall_num].type == WALL_BLASTABLE) {

	 	do {

			wall_type++;

			if (wall_type >= Num_wall_anims) {
				wall_type = 0;
				if (Walls[Cursegp->sides[Curside].wall_num].clip_num==-1)
					Error("Cannot find clip for blastable wall."); 
			}

		} while (WallAnims[wall_type].num_frames == -1 || !(WallAnims[wall_type].flags & WCF_BLASTABLE));

	}

	wall_assign_door(wall_type);	

	Update_flags |= UF_WORLD_CHANGED;
	return 1;

}
Beispiel #18
0
int SelectNextFoundSeg(void)
{
	if (++Found_seg_index >= Found_segs.count())
		Found_seg_index = 0;

	Cursegp = segptridx(Found_segs[Found_seg_index]);
	med_create_new_segment_from_cursegp();

	Update_flags |= UF_WORLD_CHANGED;

	if (Lock_view_to_cursegp)
		set_view_target_from_segment(Cursegp);

	editor_status("Curseg assigned to next found segment.");

	return 1;
}
Beispiel #19
0
//  ---------- Create a bridge segment between current segment/side and marked segment/side ----------
int CreateBridge()
{
	if (!Markedsegp) {
		editor_status("No marked side.");
		return 0;
	}
	
    if (!med_form_bridge_segment(Cursegp,Curside,Markedsegp,Markedside)) {
		Update_flags |= UF_WORLD_CHANGED;
		mine_changed = 1;
    	autosave_mine(mine_filename);
    	diagnostic_message("Bridge segment formed.");
		undo_status[Autosave_count] = "Bridge segment UNDONE.";
    	warn_if_concave_segments();
	}
    return 1;
}
Beispiel #20
0
int	ObjectMoveFurther(void)
{
	vms_vector	result;

	if (Cur_object_index == -1) {
		editor_status("Cur_object_index == -1, cannot move that peculiar object...aborting!");
		return 1;
	}

//	move_object_to_mouse_click_delta(+4*F1_0);		//	Move four units further from eye

	vm_vec_sub(&result, &Objects[Cur_object_index].pos, &Viewer->pos);
	vm_vec_normalize(&result);
	move_object_to_vector(&result, 4*F1_0);

	return 1;	
}
Beispiel #21
0
int SelectPreviousFoundSeg(void)
{
	if (Found_seg_index > 0)
		Found_seg_index--;
	else
		Found_seg_index = Found_segs.count()-1;

	Cursegp = segptridx(Found_segs[Found_seg_index]);
	med_create_new_segment_from_cursegp();

	Update_flags |= UF_WORLD_CHANGED;

	if (Lock_view_to_cursegp)
		set_view_target_from_segment(Cursegp);

	editor_status("Curseg assigned to previous found segment.");

	return 1;
}
Beispiel #22
0
void move_object_to_mouse_click_delta(fix delta_distance)
{
	short			xcrd,ycrd;
	vms_vector	vec_through_screen;

	if (Cur_object_index == -1) {
		editor_status("Cur_object_index == -1, cannot move that peculiar object...aborting!");
		return;
	}

	xcrd = GameViewBox->b1_drag_x1;
	ycrd = GameViewBox->b1_drag_y1;

	med_point_2_vec(&_canv_editor_game, &vec_through_screen, xcrd, ycrd);

	//mprintf((0, "Mouse click at %i %i, vector = %7.3f %7.3f %7.3f\n", xcrd, ycrd, f2fl(vec_through_screen.x), f2fl(vec_through_screen.y), f2fl(vec_through_screen.z)));

	move_object_to_vector(&vec_through_screen, delta_distance);

}
Beispiel #23
0
int bind_matcen_to_trigger() {

	int wall_num, trigger_num, link_num;
	int i;

	if (!Markedsegp) {
		editor_status("No marked segment.");
		return 0;
	}

	wall_num = Markedsegp->sides[Markedside].wall_num;
	if (wall_num == -1) {
		editor_status("No wall at Markedside.");
		return 0;
	}

	trigger_num = Walls[wall_num].trigger;	

	if (trigger_num == -1) {
		editor_status("No trigger at Markedside.");
		return 0;
	}

	if (!(Cursegp->special & SEGMENT_IS_ROBOTMAKER)) {
		editor_status("No Matcen at Cursegp.");
		return 0;
	}

	link_num = Triggers[trigger_num].num_links;
	for (i=0;i<link_num;i++)
		if (Cursegp-Segments == Triggers[trigger_num].seg[i]) {
			editor_status("Matcen already bound to Markedside.");
			return 0;
		}

	// Error checking completed, actual binding begins
	Triggers[trigger_num].seg[link_num] = Cursegp - Segments;
	Triggers[trigger_num].num_links++;

	mprintf((0, "seg %d linked to link_num %d\n",
				Triggers[trigger_num].seg[link_num], link_num)); 

	editor_status("Matcen linked to trigger");

	return 1;
}
Beispiel #24
0
int remove_trigger_num(int trigger_num)
{
	if (trigger_num != -1)
	{
		int t, w;
	
		Num_triggers--;
		for (t = trigger_num; t < Num_triggers; t++)
			Triggers[t] = Triggers[t + 1];
	
		for (w = 0; w < Num_walls; w++)
		{
			if (Walls[w].trigger == trigger_num)
				Walls[w].trigger = -1;	// a trigger can be shared by multiple walls
			else if (Walls[w].trigger > trigger_num) 
				Walls[w].trigger--;
		}

		return 1;
	}

	editor_status("No trigger to remove");
	return 0;
}
Beispiel #25
0
void move_object_to_position(int objnum, vms_vector *newpos)
{
	object	*objp = &Objects[objnum];

	segmasks	result = get_seg_masks(newpos, objp->segnum, objp->size);

	if (result.facemask == 0) {
		//mprintf((0, "Object #%i moved from (%7.3f %7.3f %7.3f) to (%7.3f %7.3f %7.3f)\n", objnum, f2fl(objp->pos.x), f2fl(objp->pos.y), f2fl(objp->pos.z), f2fl(newpos->x), f2fl(newpos->y), f2fl(newpos->z)));
		objp->pos = *newpos;
	} else {
		if (verify_object_seg(&Objects[objnum], newpos)) {
			int		fate, count;
			int		viewer_segnum;
			object	temp_viewer_obj;
			fvi_query fq;
			fvi_info	hit_info;
			vms_vector	last_outside_pos;
			vms_vector	last_inside_pos;

			temp_viewer_obj = *Viewer;
			viewer_segnum = find_object_seg(&temp_viewer_obj);
			temp_viewer_obj.segnum = viewer_segnum;

			//	If the viewer is outside the mine, get him in the mine!
			if (viewer_segnum == -1) {
				//	While outside mine, move towards object
				count = 0;
				while (viewer_segnum == -1) {
					vms_vector	temp_vec;

					//mprintf((0, "[towards %7.3f %7.3f %7.3f]\n", f2fl(temp_viewer_obj.pos.x), f2fl(temp_viewer_obj.pos.y), f2fl(temp_viewer_obj.pos.z)));
					last_outside_pos = temp_viewer_obj.pos;

					vm_vec_avg(&temp_vec, &temp_viewer_obj.pos, newpos);
					temp_viewer_obj.pos = temp_vec;
					viewer_segnum = find_object_seg(&temp_viewer_obj);
					temp_viewer_obj.segnum = viewer_segnum;

					if (count > 5) {
						editor_status("Unable to move object, can't get viewer in mine.  Aborting");
						return;
					}
				}

				count = 0;
				//	While inside mine, move away from object.
				while (viewer_segnum != -1) {

					vms_vector	temp_vec;

					//mprintf((0, "[away %7.3f %7.3f %7.3f]\n", f2fl(temp_viewer_obj.pos.x), f2fl(temp_viewer_obj.pos.y), f2fl(temp_viewer_obj.pos.z)));
					last_inside_pos = temp_viewer_obj.pos;

					vm_vec_avg(&temp_vec, &temp_viewer_obj.pos, &last_outside_pos);
					temp_viewer_obj.pos = temp_vec;
					update_object_seg(&temp_viewer_obj);
					viewer_segnum = find_object_seg(&temp_viewer_obj);
					temp_viewer_obj.segnum = viewer_segnum;

					if (count > 5) {
						editor_status("Unable to move object, can't get viewer back out of mine.  Aborting");
						return;
					}
				}
			}

			fq.p0						= &temp_viewer_obj.pos;
			fq.startseg				= temp_viewer_obj.segnum;
			fq.p1						= newpos;
			fq.rad					= temp_viewer_obj.size;
			fq.thisobjnum			= -1;
			fq.ignore_obj_list	= NULL;
			fq.flags					= 0;

			fate = find_vector_intersection(&fq,&hit_info);
			if (fate == HIT_WALL) {
				int	new_segnum;

				//mprintf((0, "Hit wall seg:side = %i:%i, point = (%7.3f %7.3f %7.3f)\n", hit_info.hit_seg, hit_info.hit_side, f2fl(hit_info.hit_pnt.x), f2fl(hit_info.hit_pnt.y), f2fl(hit_info.hit_pnt.z)));
				objp->pos = hit_info.hit_pnt;
				new_segnum = find_object_seg(objp);
				Assert(new_segnum != -1);
				obj_relink(objp-Objects, new_segnum);
				//mprintf((0, "Object moved from segment %i to %i\n", old_segnum, objp->segnum));
			} else {
				editor_status("Attempted to move object out of mine.  Object not moved.");
				//mprintf((0,"Attempted to move object out of mine.  Object not moved."));
			}
		}
	}

	Update_flags |= UF_WORLD_CHANGED;
}
Beispiel #26
0
// -----------------------------------------------------------------------------
// Save game
int save_level_sub(char * filename, int compiled_version)
{
	PHYSFS_file * SaveFile;
	char temp_filename[PATH_MAX];
	int minedata_offset=0,gamedata_offset=0,hostagetext_offset=0;

//	if ( !compiled_version )
	{
		write_game_text_file(filename);

		if (Errors_in_mine) {
			if (is_real_level(filename)) {
				char  ErrorMessage[200];
	
				sprintf( ErrorMessage, "Warning: %i errors in this mine!\n", Errors_in_mine );
				gr_palette_load(gr_palette);
	 
				if (nm_messagebox( NULL, 2, "Cancel Save", "Save", ErrorMessage )!=1)	{
					return 1;
				}
			}
		}
//		change_filename_extension(temp_filename,filename,".LVL");
	}
//	else
	{
		change_filename_extension(temp_filename, filename, ".RDL");
	}

	SaveFile = PHYSFSX_openWriteBuffered(temp_filename);
	if (!SaveFile)
	{
		char ErrorMessage[256];

		char fname[20];
		_splitpath( temp_filename, NULL, NULL, fname, NULL );

		sprintf( ErrorMessage, \
			"ERROR: Cannot write to '%s'.\nYou probably need to check out a locked\nversion of the file. You should save\nthis under a different filename, and then\ncheck out a locked copy by typing\n\'co -l %s.lvl'\nat the DOS prompt.\n" 
			, temp_filename, fname );
		gr_palette_load(gr_palette);
		nm_messagebox( NULL, 1, "Ok", ErrorMessage );
		return 1;
	}

	if (Current_level_name[0] == 0)
		strcpy(Current_level_name,"Untitled");

	clear_transient_objects(1);		//1 means clear proximity bombs

	compress_objects();		//after this, Highest_object_index == num objects

	//make sure player is in a segment
	if (update_object_seg(&Objects[Players[0].objnum]) == 0) {
		if (ConsoleObject->segnum > Highest_segment_index)
			ConsoleObject->segnum = 0;
		compute_segment_center(&ConsoleObject->pos,&(Segments[ConsoleObject->segnum]));
	}
 
	fix_object_segs();

	//Write the header

	PHYSFS_writeSLE32(SaveFile, MAKE_SIG('P','L','V','L'));
	PHYSFS_writeSLE32(SaveFile, Gamesave_current_version);

	//save placeholders
	PHYSFS_writeSLE32(SaveFile, minedata_offset);
	PHYSFS_writeSLE32(SaveFile, gamedata_offset);
	PHYSFS_writeSLE32(SaveFile, hostagetext_offset);

	//Now write the damn data

	minedata_offset = PHYSFS_tell(SaveFile);
#if 0	// only save compiled mine data
	if ( !compiled_version )	
		save_mine_data(SaveFile);
	else
#endif
		save_mine_data_compiled(SaveFile);
	gamedata_offset = PHYSFS_tell(SaveFile);
	save_game_data(SaveFile);
	hostagetext_offset = PHYSFS_tell(SaveFile);

	#ifdef HOSTAGE_FACES
	save_hostage_data(SaveFile);
	#endif

	PHYSFS_seek(SaveFile, sizeof(int) + sizeof(Gamesave_current_version));
	PHYSFS_writeSLE32(SaveFile, minedata_offset);
	PHYSFS_writeSLE32(SaveFile, gamedata_offset);
	PHYSFS_writeSLE32(SaveFile, hostagetext_offset);

	//==================== CLOSE THE FILE =============================
	PHYSFS_close(SaveFile);

//	if ( !compiled_version )
	{
		if (EditorWindow)
			editor_status("Saved mine %s, \"%s\"",filename,Current_level_name);
	}

	return 0;

}
Beispiel #27
0
static void move_object_to_position(const vobjptridx_t objp, const vms_vector &newpos)
{
	if (get_seg_masks(newpos, vcsegptr(objp->segnum), objp->size).facemask == 0)
	{
		objp->pos = newpos;
	} else {
		if (verify_object_seg(objp, newpos)) {
			int		fate;
			object	temp_viewer_obj;
			fvi_query fq;
			fvi_info	hit_info;

			temp_viewer_obj = *Viewer;
			auto viewer_segnum = find_object_seg(vobjptr(Viewer));
			temp_viewer_obj.segnum = viewer_segnum;

			//	If the viewer is outside the mine, get him in the mine!
			if (viewer_segnum == segment_none) {
				editor_status("Unable to move object, viewer not in mine.  Aborting");
				return;
#if 0
				vms_vector	last_outside_pos;
				//	While outside mine, move towards object
				count = 0;
				while (viewer_segnum == segment_none) {
					vms_vector	temp_vec;

					last_outside_pos = temp_viewer_obj.pos;

					vm_vec_avg(&temp_vec, &temp_viewer_obj.pos, newpos);
					temp_viewer_obj.pos = temp_vec;
					viewer_segnum = find_object_seg(&temp_viewer_obj);
					temp_viewer_obj.segnum = viewer_segnum;

					if (count > 5) {
						editor_status("Unable to move object, can't get viewer in mine.  Aborting");
						return;
					}
				}

				count = 0;
				//	While inside mine, move away from object.
				while (viewer_segnum != segment_none) {

					vms_vector	temp_vec;

					vm_vec_avg(&temp_vec, &temp_viewer_obj.pos, &last_outside_pos);
					temp_viewer_obj.pos = temp_vec;
					update_object_seg(&temp_viewer_obj);
					viewer_segnum = find_object_seg(&temp_viewer_obj);
					temp_viewer_obj.segnum = viewer_segnum;

					if (count > 5) {
						editor_status("Unable to move object, can't get viewer back out of mine.  Aborting");
						return;
					}
				}
#endif
			}

			fq.p0						= &temp_viewer_obj.pos;
			fq.startseg				= temp_viewer_obj.segnum;
			fq.p1						= &newpos;
			fq.rad					= temp_viewer_obj.size;
			fq.thisobjnum			= object_none;
			fq.ignore_obj_list.first = nullptr;
			fq.flags					= 0;

			fate = find_vector_intersection(fq, hit_info);
			if (fate == HIT_WALL) {

				objp->pos = hit_info.hit_pnt;
				const auto &&segp = find_object_seg(objp);
				if (segp != segment_none)
					obj_relink(objp, segp);
			} else {
				editor_status("Attempted to move object out of mine.  Object not moved.");
			}
		}
	}

	Update_flags |= UF_WORLD_CHANGED;
}
Beispiel #28
0
void do_robot_window()
{
	int	i;
	fix	DeltaTime, Temp;
	int	first_object_index;

	if ( MainWindow == NULL ) return;

	first_object_index = Cur_object_index;
	while (!is_legal_type_for_this_window(Cur_object_index)) {
		LocalObjectSelectNextinMine();
		if (first_object_index == Cur_object_index) {
			break;
		}
	}

	//------------------------------------------------------------
	// Call the ui code..
	//------------------------------------------------------------
	ui_button_any_drawn = 0;
	ui_window_do_gadgets(MainWindow);

	//------------------------------------------------------------
	// If we change objects, we need to reset the ui code for all
	// of the radio buttons that control the ai mode.  Also makes
	// the current AI mode button be flagged as pressed down.
	//------------------------------------------------------------
	if (old_object != Cur_object_index )	{
		for (	i=0; i < NUM_BOXES; i++ )	{
			InitialMode[i]->flag = 0;		// Tells ui that this button isn't checked
			InitialMode[i]->status = 1;	// Tells ui to redraw button
		}
		if ( Cur_object_index > -1 ) {
			int	behavior = Objects[Cur_object_index].ctype.ai_info.behavior;
			if ( !((behavior >= MIN_BEHAVIOR) && (behavior <= MAX_BEHAVIOR))) {
				Objects[Cur_object_index].ctype.ai_info.behavior = AIB_NORMAL;
				behavior = AIB_NORMAL;
			}
			InitialMode[behavior - MIN_BEHAVIOR]->flag = 1;	// Mark this button as checked
		}
	}

	//------------------------------------------------------------
	// If any of the radio buttons that control the mode are set, then
	// update the cooresponding AI state.
	//------------------------------------------------------------
	for (	i=0; i < NUM_BOXES; i++ )	{
		if ( InitialMode[i]->flag == 1 )	
			if (Objects[Cur_object_index].ctype.ai_info.behavior != MIN_BEHAVIOR+i) {
				Objects[Cur_object_index].ctype.ai_info.behavior = MIN_BEHAVIOR+i;		// Set the ai_state to the cooresponding radio button
				call_init_ai_object(&Objects[Cur_object_index], MIN_BEHAVIOR+i);
			}
	}

	//------------------------------------------------------------
	// A simple frame time counter for spinning the objects...
	//------------------------------------------------------------
	Temp = timer_get_fixed_seconds();
	DeltaTime = Temp - Time;
	Time = Temp;

	//------------------------------------------------------------
	// Redraw the object in the little 64x64 box
	//------------------------------------------------------------
	if (Cur_object_index > -1 )	{
		int id;
		gr_set_current_canvas( RobotViewBox->canvas );
		id = get_object_id(&Objects[Cur_object_index]);
		if ( id > -1 )	
			draw_robot_picture(id, &angles, -1 );
		else
			gr_clear_canvas( CGREY );
		angles.h += fixmul(0x1000, DeltaTime );
	} else {
		// no object, so just blank out
		gr_set_current_canvas( RobotViewBox->canvas );
		gr_clear_canvas( CGREY );

//		LocalObjectSelectNextInMine();
	}

	//------------------------------------------------------------
	// Redraw the contained object in the other little box
	//------------------------------------------------------------
	if ((Cur_object_index > -1 ) && (Cur_goody_count > 0))	{
		int id;

		gr_set_current_canvas( ContainsViewBox->canvas );
		id = Cur_goody_id;
		if ( id > -1 )	 {
                        int ol_type=0;
			if (Cur_goody_type == OBJ_ROBOT)
				ol_type = OL_ROBOT;
			else if (Cur_goody_type == OBJ_POWERUP)
				ol_type = OL_POWERUP;
			else
				Int3();	//	Error?  Unknown goody type!

			draw_robot_picture(id, &goody_angles, ol_type );
		} else
			gr_clear_canvas( CGREY );
		goody_angles.h += fixmul(0x1000, DeltaTime );
	} else {
		// no object, so just blank out
		gr_set_current_canvas( ContainsViewBox->canvas );
		gr_clear_canvas( CGREY );

//		LocalObjectSelectNextInMine();
	}

	//------------------------------------------------------------
	// If anything changes in the ui system, redraw all the text that
	// identifies this robot.
	//------------------------------------------------------------

	if (ui_button_any_drawn || (old_object != Cur_object_index) )	{
		int	i;
		char	type_text[STRING_LENGTH+1],id_text[STRING_LENGTH+1];

		if (Cur_object_index != -1) {
			Cur_goody_type = Objects[Cur_object_index].contains_type;
			Cur_goody_id = Objects[Cur_object_index].contains_id;
			if (Objects[Cur_object_index].contains_count < 0)
				Objects[Cur_object_index].contains_count = 0;
			Cur_goody_count = Objects[Cur_object_index].contains_count;
		}

		ui_wprintf_at( MainWindow, GOODY_X, GOODY_Y,    " Type:");
		ui_wprintf_at( MainWindow, GOODY_X, GOODY_Y+24, "   ID:");
		ui_wprintf_at( MainWindow, GOODY_X, GOODY_Y+48, "Count:");

		for (i=0; i<STRING_LENGTH; i++)
			id_text[i] = ' ';
		id_text[i] = 0;

		switch (Cur_goody_type) {
			case OBJ_ROBOT:
				strcpy(type_text, "Robot  ");
				strncpy(id_text, Robot_names[Cur_goody_id], strlen(Robot_names[Cur_goody_id]));
				break;
			case OBJ_POWERUP:
				strcpy(type_text, "Powerup");
				strncpy(id_text, Powerup_names[Cur_goody_id], strlen(Powerup_names[Cur_goody_id]));
				break;
			default:
				editor_status("Illegal contained object type (%i), changing to powerup.", Cur_goody_type);
				Cur_goody_type = OBJ_POWERUP;
				Cur_goody_id = 0;
				strcpy(type_text, "Powerup");
				strncpy(id_text, Powerup_names[Cur_goody_id], strlen(Powerup_names[Cur_goody_id]));
				break;
		}

		ui_wprintf_at( MainWindow, GOODY_X+108, GOODY_Y, type_text);
		ui_wprintf_at( MainWindow, GOODY_X+108, GOODY_Y+24, id_text);
		ui_wprintf_at( MainWindow, GOODY_X+108, GOODY_Y+48, "%i", Cur_goody_count);

		if ( Cur_object_index > -1 )	{
			int	id = Objects[Cur_object_index].id;
			char	id_text[12];
			int	i;

			for (i=0; i<STRING_LENGTH; i++)
				id_text[i] = ' ';
			id_text[i] = 0;

			strncpy(id_text, Robot_names[id], strlen(Robot_names[id]));

			ui_wprintf_at( MainWindow, 12,  6, "Robot: %3d ", Cur_object_index );
			ui_wprintf_at( MainWindow, 12, 22, "   Id: %3d", id);
			ui_wprintf_at( MainWindow, 12, 38, " Name: %8s", id_text);

		}	else {
			ui_wprintf_at( MainWindow, 12,  6, "Robot: none" );
			ui_wprintf_at( MainWindow, 12, 22, " Type: ?  "  );
			ui_wprintf_at( MainWindow, 12, 38, " Name: ________" );
		}
		Update_flags |= UF_WORLD_CHANGED;
	}

	if ( QuitButton->pressed || (last_keypress==KEY_ESC))	{
		robot_close_window();
		return;
	}		

	old_object = Cur_object_index;
}
Beispiel #29
0
// Handler for the main editor dialog
int editor_handler(UI_DIALOG *dlg, d_event *event, void *data)
{
	editor_view *new_cv;
	int keypress = 0;
	int rval = 0;

	if (event->type == EVENT_KEY_COMMAND)
		keypress = event_key_get(event);
	else if (event->type == EVENT_WINDOW_CLOSE)
	{
		close_editor();
		EditorWindow = NULL;
		return 0;
	}
	
	// Update the windows

	if (event->type == EVENT_UI_DIALOG_DRAW)
	{
		gr_set_curfont(editor_font);

		// Draw status box
		gr_set_current_canvas( NULL );
		gr_setcolor( CGREY );
		gr_rect(STATUS_X,STATUS_Y,STATUS_X+STATUS_W-1,STATUS_Y+STATUS_H-1);			//0, 582, 799, 599 );
		
		medlisp_update_screen();
		calc_frame_time();
		texpage_do(event);
		objpage_do(event);
		ui_pad_draw(EditorWindow, PAD_X, PAD_Y);

		print_status_bar(status_line);
		TimedAutosave(mine_filename);	// shows the time, hence here
		set_editor_time_of_day();
		return 1;
	}
	
	if ((selected_gadget == (UI_GADGET *)GameViewBox && !render_3d_in_big_window) ||
		(selected_gadget == (UI_GADGET *)LargeViewBox && render_3d_in_big_window))
		switch (event->type)
		{
			case EVENT_MOUSE_BUTTON_UP:
			case EVENT_MOUSE_BUTTON_DOWN:
				break;
			case EVENT_MOUSE_MOVED:
				if (!keyd_pressed[ KEY_LCTRL ] && !keyd_pressed[ KEY_RCTRL ])
					break;
			case EVENT_JOYSTICK_BUTTON_UP:
			case EVENT_JOYSTICK_BUTTON_DOWN:
			case EVENT_JOYSTICK_MOVED:
			case EVENT_KEY_COMMAND:
			case EVENT_KEY_RELEASE:
			case EVENT_IDLE:
				kconfig_read_controls(event, 1);

				if (slew_frame(0))
				{		//do movement and check keys
					Update_flags |= UF_GAME_VIEW_CHANGED;
					if (Gameview_lockstep)
					{
						Cursegp = &Segments[ConsoleObject->segnum];
						med_create_new_segment_from_cursegp();
						Update_flags |= UF_ED_STATE_CHANGED;
					}

					rval = 1;
				}
				break;
				
			default:
				break;
		}

	//do non-essential stuff in idle event
	if (event->type == EVENT_IDLE)
	{
		check_wall_validity();
		Assert(Num_walls>=0);

		if (Gameview_lockstep) {
			static segment *old_cursegp=NULL;
			static int old_curside=-1;

			if (old_cursegp!=Cursegp || old_curside!=Curside) {
				SetPlayerFromCursegMinusOne();
				old_cursegp = Cursegp;
				old_curside = Curside;
			}
		}

		if ( event_get_idle_seconds() > COMPRESS_INTERVAL ) 
		{
			med_compress_mine();
			event_reset_idle_seconds();
		}

	//	Commented out because it occupies about 25% of time in twirling the mine.
	// Removes some Asserts....
	//		med_check_all_vertices();
		clear_editor_status();		// if enough time elapsed, clear editor status message
	}

	gr_set_current_canvas( GameViewBox->canvas );
	
	// Remove keys used for slew
	switch(keypress)
	{
		case KEY_PAD9:
		case KEY_PAD7:
		case KEY_PADPLUS:
		case KEY_PADMINUS:
		case KEY_PAD8:
		case KEY_PAD2:
		case KEY_LBRACKET:
		case KEY_RBRACKET:
		case KEY_PAD1:
		case KEY_PAD3:
		case KEY_PAD6:
		case KEY_PAD4:
			keypress = 0;
	}
	if ((keypress&0xff)==KEY_LSHIFT) keypress=0;
	if ((keypress&0xff)==KEY_RSHIFT) keypress=0;
	if ((keypress&0xff)==KEY_LCTRL) keypress=0;
	if ((keypress&0xff)==KEY_RCTRL) keypress=0;
//		if ((keypress&0xff)==KEY_LALT) keypress=0;
//		if ((keypress&0xff)==KEY_RALT) keypress=0;

	//=================== DO FUNCTIONS ====================

	if ( KeyFunction[ keypress ] != NULL )
	{
		KeyFunction[keypress]();
		keypress = 0;
		rval = 1;
	}

	switch (keypress)
	{
		case 0:
		case KEY_Z:
		case KEY_G:
		case KEY_LALT:
		case KEY_RALT:
		case KEY_LCTRL:
		case KEY_RCTRL:
		case KEY_LSHIFT:
		case KEY_RSHIFT:
		case KEY_LAPOSTRO:
			break;
		case KEY_SHIFTED + KEY_L:
			ToggleLighting();
			rval = 1;
			break;
		case KEY_F1:
			render_3d_in_big_window = !render_3d_in_big_window;
			Update_flags |= UF_ALL;
			rval = 1;
			break;			
		default:
			if (!rval)
			{
				char kdesc[100];
				GetKeyDescription( kdesc, keypress );
				editor_status_fmt("Error: %s isn't bound to anything.", kdesc  );
			}
	}

	//================================================================

	if (ModeFlag)
	{
		ui_close_dialog(EditorWindow);
		return 0;
	}

//		if (EditorWindow->keyboard_focus_gadget == (UI_GADGET *)GameViewBox) current_view=NULL;
//		if (EditorWindow->keyboard_focus_gadget == (UI_GADGET *)GroupViewBox) current_view=NULL;

	new_cv = current_view;

#if ORTHO_VIEWS
	if (EditorWindow->keyboard_focus_gadget == (UI_GADGET *)LargeViewBox) new_cv=&LargeView;
	if (EditorWindow->keyboard_focus_gadget == (UI_GADGET *)TopViewBox)	new_cv=&TopView;
	if (EditorWindow->keyboard_focus_gadget == (UI_GADGET *)FrontViewBox) new_cv=&FrontView;
	if (EditorWindow->keyboard_focus_gadget == (UI_GADGET *)RightViewBox) new_cv=&RightView;
#endif
	if (new_cv != current_view ) {
		current_view->ev_changed = 1;
		new_cv->ev_changed = 1;
		current_view = new_cv;
	}

	// DO TEXTURE STUFF
	if (texpage_do(event))
		rval = 1;
	
	if (objpage_do(event))
		rval = 1;


	// Process selection of Cursegp using mouse.
	if (GADGET_PRESSED(LargeViewBox) && !render_3d_in_big_window) 
	{
		int	xcrd,ycrd;
		xcrd = LargeViewBox->b1_drag_x1;
		ycrd = LargeViewBox->b1_drag_y1;

		find_segments(xcrd,ycrd,LargeViewBox->canvas,&LargeView,Cursegp,Big_depth);	// Sets globals N_found_segs, Found_segs

		// If shift is down, then add segment to found list
		if (keyd_pressed[ KEY_LSHIFT ] || keyd_pressed[ KEY_RSHIFT ])
			subtract_found_segments_from_selected_list();
		else
			add_found_segments_to_selected_list();

		Found_seg_index = 0;	
	
		if (N_found_segs > 0) {
			sort_seg_list(N_found_segs,Found_segs,&ConsoleObject->pos);
			Cursegp = &Segments[Found_segs[0]];
			med_create_new_segment_from_cursegp();
			if (Lock_view_to_cursegp)
				set_view_target_from_segment(Cursegp);
		}

		Update_flags |= UF_ED_STATE_CHANGED | UF_VIEWPOINT_MOVED;
	}

	if ((event->type == EVENT_UI_USERBOX_DRAGGED) && (ui_event_get_gadget(event) == (UI_GADGET *)GameViewBox))
	{
		int	x, y;
		x = GameViewBox->b1_drag_x2;
		y = GameViewBox->b1_drag_y2;

		gr_set_current_canvas( GameViewBox->canvas );
		gr_setcolor( 15 );
		gr_rect( x-1, y-1, x+1, y+1 );
	}
	
	// Set current segment and side by clicking on a polygon in game window.
	//	If ctrl pressed, also assign current texture map to that side.
	//if (GameViewBox->mouse_onme && (GameViewBox->b1_done_dragging || GameViewBox->b1_clicked)) {
	if ((GADGET_PRESSED(GameViewBox) && !render_3d_in_big_window) ||
		(GADGET_PRESSED(LargeViewBox) && render_3d_in_big_window))
	{
		int	xcrd,ycrd;
		int seg,side,face,poly,tmap;

		if (render_3d_in_big_window) {
			xcrd = LargeViewBox->b1_drag_x1;
			ycrd = LargeViewBox->b1_drag_y1;
		}
		else {
			xcrd = GameViewBox->b1_drag_x1;
			ycrd = GameViewBox->b1_drag_y1;
		}

		//Int3();

		if (find_seg_side_face(xcrd,ycrd,&seg,&side,&face,&poly)) {


			if (seg<0) {							//found an object

				Cur_object_index = -seg-1;
				editor_status_fmt("Object %d selected.",Cur_object_index);

				Update_flags |= UF_ED_STATE_CHANGED;
			}
			else {

				//	See if either shift key is down and, if so, assign texture map
				if (keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT]) {
					Cursegp = &Segments[seg];
					Curside = side;
					AssignTexture();
					med_create_new_segment_from_cursegp();
					editor_status("Texture assigned");
				} else if (keyd_pressed[KEY_G])	{
					tmap = Segments[seg].sides[side].tmap_num;
					texpage_grab_current(tmap);
					editor_status( "Texture grabbed." );
				} else if (keyd_pressed[ KEY_LAPOSTRO] ) {
					move_object_to_mouse_click();
				} else {
					Cursegp = &Segments[seg];
					Curside = side;
					med_create_new_segment_from_cursegp();
					editor_status("Curseg and curside selected");
				}
			}

			Update_flags |= UF_ED_STATE_CHANGED;
		}
		else 
			editor_status("Click on non-texture ingored");

	}

	// Allow specification of LargeView using mouse
	if (event->type == EVENT_MOUSE_MOVED && (keyd_pressed[ KEY_LCTRL ] || keyd_pressed[ KEY_RCTRL ]))
	{
		int dx, dy, dz;

		event_mouse_get_delta(event, &dx, &dy, &dz);
		if ((dx != 0) && (dy != 0))
		{
			vms_matrix	MouseRotMat,tempm;
			
			GetMouseRotation( dx, dy, &MouseRotMat );
			vm_matrix_x_matrix(&tempm,&LargeView.ev_matrix,&MouseRotMat);
			LargeView.ev_matrix = tempm;
			LargeView.ev_changed = 1;
			Large_view_index = -1;			// say not one of the orthogonal views
			rval = 1;
		}
	}

	if (event->type == EVENT_MOUSE_MOVED)
	{
		int dx, dy, dz;

		event_mouse_get_delta(event, &dx, &dy, &dz);
		if (dz != 0)
		{
			current_view->ev_dist += dz*10000;
			current_view->ev_changed = 1;
		}
	}
	
	return rval;
}
Beispiel #30
0
Datei: med.c Projekt: paud/d2x-xl
// ---------------------------------------------------------------------------------------------------
//this function is the editor. called when editor mode selected.  runs until
//game mode or exit selected
void editor(void)
{
	int w,h;
	grsBitmap * savedbitmap;
	editorView *new_cv;
        static int padnum=0;
	vmsMatrix	MouseRotMat,tempm;
	//@@short camera_objnum;			//a camera for viewing

	init_editor();

	InitCurve();

	RestoreEffectBitmapIcons();

	if (!SetScreenMode(SCREEN_EDITOR))	{
		SetScreenMode(SCREEN_GAME);
		gameStates.app.nFunctionMode=FMODE_GAME;			//force back into game
		return;
	}

	GrSetCurrentCanvas( NULL );
	GrSetCurFont(editor_font);

	//Editor renders into full (320x200) game screen 

	SetWarnFunc(med_show_warning);

	gameStates.input.keys.bRepeat = 1;		// Allow repeat in editor

//	_MARK_("start of editor");//Nuked to compile -KRB

	ui_mouse_hide();
	ui_reset_idleSeconds();
	gameData.objs.viewer = gameData.objs.console;
	slew_init(gameData.objs.console);
	UpdateFlags = UF_ALL;
	medlisp_update_screen();

	//set the wire-frame window to be the current view
	currentView = &LargeView;

	if (faded_in==0)
	{
		faded_in = 1;
		//gr_pal_fade_in( grdCurScreen->pal );
	}

	w = GameViewBox->canvas->cvBitmap.bmProps.w;
	h = GameViewBox->canvas->cvBitmap.bmProps.h;

	savedbitmap = GrCreateBitmap(w, h );

	GrBmUBitBlt( w, h, 0, 0, 0, 0, &GameViewBox->canvas->cvBitmap, savedbitmap );

	GrSetCurrentCanvas( GameViewBox->canvas );
	GrSetCurFont(editor_font);
	//GrSetColor( CBLACK );
	//gr_deaccent_canvas();
	//gr_grey_canvas();

	ui_mouse_show();

	GrSetCurFont(editor_font);
	ui_pad_goto(padnum);

	gamestate_restore_check();

	while (gameStates.app.nFunctionMode == FMODE_EDITOR) {

		GrSetCurFont(editor_font);
		info_display_all(EditorWindow);

		ModeFlag = 0;

		// Update the windows

		// Only update if there is no key waiting and we're not in
		// fast play mode.
		if (!KeyPeekKey()) //-- && (MacroStatus != UI_STATUS_FASTPLAY))
			medlisp_update_screen();

		//do editor stuff
		GrSetCurFont(editor_font);
		ui_mega_process();
		last_keypress &= ~KEYDBGGED;		//	mask off delete key bit which has no function in editor.
		ui_window_do_gadgets(EditorWindow);
		doRobot_window();
		doObject_window();
		do_wall_window();
		do_trigger_window();
		do_hostage_window();
		do_centers_window();
		check_wall_validity();
		Assert(gameData.walls.nWalls>=0);

		if (Gameview_lockstep) {
			static tSegment *old_cursegp=NULL;
			static int old_curside=-1;

			if (old_cursegp!=Cursegp || old_curside!=Curside) {
				SetPlayerFromCursegMinusOne();
				old_cursegp = Cursegp;
				old_curside = Curside;
			}
		}

		if ( ui_get_idleSeconds() > COMPRESS_INTERVAL ) 
			{
			med_compress_mine();
			ui_reset_idleSeconds();
			}
  
//	Commented out because it occupies about 25% of time in twirling the mine.
// Removes some Asserts....
//		med_check_all_vertices();
		clear_editor_status();		// if enough time elapsed, clear editor status message
		TimedAutosave(mine_filename);
		set_editorTime_of_day();
		GrSetCurrentCanvas( GameViewBox->canvas );
	
		// Remove keys used for slew
		switch(last_keypress)
		{
		case KEY_PAD9:
		case KEY_PAD7:
		case KEY_PADPLUS:
		case KEY_PADMINUS:
		case KEY_PAD8:
		case KEY_PAD2:
		case KEY_LBRACKET:
		case KEY_RBRACKET:
		case KEY_PAD1:
		case KEY_PAD3:
		case KEY_PAD6:
		case KEY_PAD4:
			last_keypress = 0;
		}
		if ((last_keypress&0xff)==KEY_LSHIFT) last_keypress=0;
		if ((last_keypress&0xff)==KEY_RSHIFT) last_keypress=0;
		if ((last_keypress&0xff)==KEY_LCTRL) last_keypress=0;
		if ((last_keypress&0xff)==KEY_RCTRL) last_keypress=0;
//		if ((last_keypress&0xff)==KEY_LALT) last_keypress=0;
//		if ((last_keypress&0xff)==KEY_RALT) last_keypress=0;

		GrSetCurFont(editor_font);
		menubar_do( last_keypress );

		//=================== DO FUNCTIONS ====================

		if ( KeyFunction[ last_keypress ] != NULL )	{
			KeyFunction[last_keypress]();
			last_keypress = 0;
		}
		switch (last_keypress)
		{
		case 0:
		case KEY_Z:
		case KEY_G:
		case KEY_LALT:
		case KEY_RALT:
		case KEY_LCTRL:
		case KEY_RCTRL:
		case KEY_LSHIFT:
		case KEY_RSHIFT:
		case KEY_LAPOSTRO:
			break;
		case KEY_SHIFTED + KEY_L:
			ToggleLighting();
			break;
		case KEY_F1:
			render_3d_in_big_window = !render_3d_in_big_window;
			UpdateFlags |= UF_ALL;
			break;		
		default:
			{
			char kdesc[100];
			GetKeyDescription( kdesc, last_keypress );
			editor_status("Error: %s isn't bound to anything.", kdesc  );
			}
		}

		//================================================================

		if (ModeFlag==1)
		{
			close_editor_screen();
			gameStates.app.nFunctionMode=FMODE_EXIT;
				GrFreeBitmap( savedbitmap );
			break;
		}

		if (ModeFlag==2) //-- && MacroStatus==UI_STATUS_NORMAL )
		{
			ui_mouse_hide();
			gameStates.app.nFunctionMode = FMODE_GAME;
			GrBmUBitBlt( w, h, 0, 0, 0, 0, savedbitmap, &GameViewBox->canvas->cvBitmap);
			GrFreeBitmap( savedbitmap );
			break;
		}

		if (ModeFlag==3) //-- && MacroStatus==UI_STATUS_NORMAL )
		{
//			med_compress_mine();						//will be called anyways before game.
			close_editor_screen();
			gameStates.app.nFunctionMode=FMODE_GAME;			//force back into game
			SetScreenMode(SCREEN_GAME);		//put up game screen
			GrFreeBitmap( savedbitmap );
			break;
		}

//		if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)GameViewBox) currentView=NULL;
//		if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)GroupViewBox) currentView=NULL;

		new_cv = currentView ;

#if ORTHO_VIEWS
		if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)LargeViewBox) new_cv=&LargeView;
		if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)TopViewBox)	new_cv=&TopView;
		if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)FrontViewBox) new_cv=&FrontView;
		if (CurWindow->keyboard_focus_gadget == (UI_GADGET *)RightViewBox) new_cv=&RightView;
#endif
		if (new_cv != currentView ) {
			currentView->ev_changed = 1;
			new_cv->ev_changed = 1;
			currentView = new_cv;
		}

		CalcFrameTime();
		if (slew_frame(0)) {		//do movement and check keys
			UpdateFlags |= UF_GAME_VIEW_CHANGED;
			if (Gameview_lockstep) {
				Cursegp = &gameData.segs.segments[gameData.objs.console->nSegment];
				med_create_new_segment_from_cursegp();
				UpdateFlags |= UF_ED_STATE_CHANGED;
			}
		}

		// DO TEXTURE STUFF
		texpage_do();
		objpage_do();


		// Process selection of Cursegp using mouse.
		if (LargeViewBox->mouse_onme && LargeViewBox->b1_clicked && !render_3d_in_big_window) 
		{
			int	xcrd,ycrd;
			xcrd = LargeViewBox->b1_drag_x1;
			ycrd = LargeViewBox->b1_drag_y1;

			find_segments(xcrd,ycrd,LargeViewBox->canvas,&LargeView,Cursegp,Big_depth);	// Sets globals N_found_segs, Found_segs

			// If shift is down, then add tSegment to found list
			if (gameStates.input.keys.pressed[ KEY_LSHIFT ] || gameStates.input.keys.pressed[ KEY_RSHIFT ])
				subtract_found_segments_from_selected_list();
			else
				add_found_segments_to_selected_list();

  			Found_seg_index = 0;
	
			if (N_found_segs > 0) {
				sort_seg_list(N_found_segs,Found_segs,&gameData.objs.console->position.vPos);
				Cursegp = &gameData.segs.segments[Found_segs[0]];
				med_create_new_segment_from_cursegp();
				if (LockView_to_cursegp)
					setView_target_from_segment(Cursegp);
			}

			UpdateFlags |= UF_ED_STATE_CHANGED | UF_VIEWPOINT_MOVED;
		}

		if (GameViewBox->mouse_onme && GameViewBox->b1_dragging) {
			int	x, y;
			x = GameViewBox->b1_drag_x2;
			y = GameViewBox->b1_drag_y2;

			ui_mouse_hide();
			GrSetCurrentCanvas( GameViewBox->canvas );
			GrSetColor( 15 );
			GrRect( x-1, y-1, x+1, y+1 );
			ui_mouse_show();

		}
	
		// Set current tSegment and tSide by clicking on a polygon in game window.
		//	If ctrl pressed, also assign current texture map to that tSide.
		//if (GameViewBox->mouse_onme && (GameViewBox->b1_done_dragging || GameViewBox->b1_clicked)) {
		if ((GameViewBox->mouse_onme && GameViewBox->b1_clicked && !render_3d_in_big_window) ||
			(LargeViewBox->mouse_onme && LargeViewBox->b1_clicked && render_3d_in_big_window)) {

			int	xcrd,ycrd;
			int seg,tSide,face,poly,tmap;

			if (render_3d_in_big_window) {
				xcrd = LargeViewBox->b1_drag_x1;
				ycrd = LargeViewBox->b1_drag_y1;
			}
			else {
				xcrd = GameViewBox->b1_drag_x1;
				ycrd = GameViewBox->b1_drag_y1;
			}

			//Int3();

			if (FindSegSideFace(xcrd,ycrd,&seg,&tSide,&face,&poly)) {


				if (seg<0) {							//found an tObject

					CurObject_index = -seg-1;
					editor_status("Object %d selected.",CurObject_index);

					UpdateFlags |= UF_ED_STATE_CHANGED;
				}
				else {

					//	See if either shift key is down and, if so, assign texture map
					if (gameStates.input.keys.pressed[KEY_LSHIFT] || gameStates.input.keys.pressed[KEY_RSHIFT]) {
						Cursegp = &gameData.segs.segments[seg];
						Curside = tSide;
						AssignTexture();
						med_create_new_segment_from_cursegp();
						editor_status("Texture assigned");
					} else if (gameStates.input.keys.pressed[KEY_G])	{
						tmap = gameData.segs.segments[seg].sides[tSide].nBaseTex;
						texpage_grab_current(tmap);
						editor_status( "Texture grabbed." );
					} else if (gameStates.input.keys.pressed[ KEY_LAPOSTRO] ) {
						ui_mouse_hide();
						moveObject_to_mouse_click();
					} else {
						Cursegp = &gameData.segs.segments[seg];
						Curside = tSide;
						med_create_new_segment_from_cursegp();
						editor_status("Curseg and curside selected");
					}
				}

				UpdateFlags |= UF_ED_STATE_CHANGED;
			}
			else 
				editor_status("Click on non-texture ingored");

		}

		// Allow specification of LargeView using mouse
		if (gameStates.input.keys.pressed[ KEY_LCTRL ] || gameStates.input.keys.pressed[ KEY_RCTRL ]) {
			ui_mouse_hide();
			if ( (Mouse.dx!=0) && (Mouse.dy!=0) ) {
				GetMouseRotation( Mouse.dx, Mouse.dy, &MouseRotMat );
				VmMatMul(&tempm,&LargeView.ev_matrix,&MouseRotMat);
				LargeView.ev_matrix = tempm;
				LargeView.ev_changed = 1;
				LargeView_index = -1;			// say not one of the orthogonal views
			}
		} else  {
			ui_mouse_show();
		}

		if ( gameStates.input.keys.pressed[ KEY_Z ] ) {
			ui_mouse_hide();
			if ( Mouse.dy!=0 ) {
				currentView->evDist += Mouse.dy*10000;
				currentView->ev_changed = 1;
			}
		} else {
			ui_mouse_show();
		}

	}

//	_MARK_("end of editor");//Nuked to compile -KRB

	ClearWarnFunc(med_show_warning);

	//kill our camera tObject

	gameData.objs.viewer = gameData.objs.console;					//reset viewer
	//@@ReleaseObject(camera_objnum);

	padnum = ui_pad_get_current();

	close_editor();
	ui_close();


}