コード例 #1
0
// evaluate a certain function for all docked objects
void dock_evaluate_all_docked_objects(object *objp, dock_function_info *infop, void (*function)(object *, dock_function_info *))
{
	Assert((objp != NULL) && (infop != NULL) && (function != NULL));

	// not docked?
	if (!object_is_docked(objp))
	{
		// call the function for just the one object
		function(objp, infop);
		return;
	}

	// we only have two objects docked
	if (dock_check_docked_one_on_one(objp))
	{
		// call the function for the first object, and return if instructed
		function(objp, infop);
		if (infop->early_return_condition) return;

		// call the function for the second object, and return if instructed
		function(objp->dock_list->docked_objp, infop);
		if (infop->early_return_condition) return;
	}

	// we have multiple objects docked and we're treating them as a hub
	else if (dock_check_assume_hub())
	{
		// get the hub
		object *hub_objp = dock_get_hub(objp);

		// call the function for the hub, and return if instructed
		function(hub_objp, infop);
		if (infop->early_return_condition) return;

		// iterate through all docked objects
		for (dock_instance *ptr = hub_objp->dock_list; ptr != NULL; ptr = ptr->next)
		{
			// call the function for this object, and return if instructed
			function(ptr->docked_objp, infop);
			if (infop->early_return_condition) return;
		}
	}

	// we have multiple objects docked and we must treat them as a tree
	else
	{
		// create a bit array to mark the objects we check
		ubyte *visited_bitstring = (ubyte *) vm_malloc(calculate_num_bytes(MAX_OBJECTS));

		// clear it
		memset(visited_bitstring, 0, calculate_num_bytes(MAX_OBJECTS));

		// start evaluating the tree
		dock_evaluate_tree(objp, infop, function, visited_bitstring);

		// destroy the bit array
		vm_free(visited_bitstring);
		visited_bitstring = NULL;
	}
}
コード例 #2
0
object *dock_get_first_docked_object(object *objp)
{
	// are we docked?
	if (!object_is_docked(objp))
		return NULL;

	return objp->dock_list->docked_objp;
}
コード例 #3
0
void initial_status::undock(object *objp1, object *objp2)
{
	vec3d v;
	int ship_num, other_ship_num;

	if (objp1 == NULL || objp2 == NULL)
		return;

	vm_vec_sub(&v, &objp2->pos, &objp1->pos);
	vm_vec_normalize(&v);
	ship_num = get_ship_from_obj(OBJ_INDEX(objp1));
	other_ship_num = get_ship_from_obj(OBJ_INDEX(objp2));

	if (ship_class_compare(Ships[ship_num].ship_info_index, Ships[other_ship_num].ship_info_index) <= 0)
		vm_vec_scale_add2(&objp2->pos, &v, objp2->radius * 2.0f);
	else
		vm_vec_scale_add2(&objp1->pos, &v, objp1->radius * -2.0f);

	ai_do_objects_undocked_stuff(objp1, objp2);

	// check to see if one of these ships has an arrival cue of false.  If so, then
	// reset it back to default value of true.  be sure to correctly update before
	// and after setting data.
	// Goober5000 - but don't reset it if it's part of a wing!
	Ship_editor_dialog.update_data(1);

	if ( Ships[ship_num].arrival_cue == Locked_sexp_false && Ships[ship_num].wingnum < 0 ) {
		Ships[ship_num].arrival_cue = Locked_sexp_true;
	} else if ( Ships[other_ship_num].arrival_cue == Locked_sexp_false && Ships[other_ship_num].wingnum < 0 ) {
		Ships[other_ship_num].arrival_cue = Locked_sexp_true;
	}

	// if this ship is no longer docked, ensure its dock leader flag is clear
    if (!object_is_docked(&Objects[Ships[ship_num].objnum]))
        Ships[ship_num].flags.remove(Ship::Ship_Flags::Dock_leader);

	// same for the other ship
    if (!object_is_docked(&Objects[Ships[other_ship_num].objnum]))
        Ships[other_ship_num].flags.remove(Ship::Ship_Flags::Dock_leader);

	Ship_editor_dialog.initialize_data(1);
}
コード例 #4
0
void dock_undock_all(object *objp)
{
	Assert(objp != NULL);

	while (object_is_docked(objp))
	{
		object* dockee = dock_get_first_docked_object(objp);

		dock_undock_objects(objp, dockee);
	}
}
コード例 #5
0
object *dock_get_hub(object *objp)
{
	Assert(dock_check_assume_hub() && object_is_docked(objp));

	// if our dock list contains only one object, it must be the hub
	if (objp->dock_list->next == NULL)
	{
		return dock_get_first_docked_object(objp);
	}
	// otherwise we are the hub
	else
	{
		return objp;
	}
}
コード例 #6
0
void dock_move_docked_objects(object *objp)
{
	Assert(objp != NULL);

	if ((objp->type != OBJ_SHIP) && (objp->type != OBJ_START))
		return;

	if (!object_is_docked(objp))
		return;

	// has this object (by extension, this group of docked objects) been handled already?
	if (objp->flags[Object::Object_Flags::Docked_already_handled])
		return;

	Assert((objp->instance >= 0) && (objp->instance < MAX_SHIPS));

	dock_function_info dfi;
	object *fastest_objp;

	// in FRED, objp is the object everyone moves with
	if (Fred_running)
	{
		fastest_objp = objp;
	}
	else
	{
		// find the object with the highest max speed
		dock_evaluate_all_docked_objects(objp, &dfi, dock_find_max_speed_helper);
		fastest_objp = dfi.maintained_variables.objp_value;

		// if we have no max speed, just use the first one
		if (fastest_objp == NULL)
			fastest_objp = objp;
	}
	
	// start a tree with that object as the parent... do NOT use the überfunction for this,
	// because we must use a tree for the parent ancestry to work correctly

	// we don't need a bit array because OF_DOCKED_ALREADY_HANDLED takes care of it
	// and must persist for the entire game frame

	// start evaluating the tree, starting with the fastest object having no parent
	dock_move_docked_children_tree(fastest_objp, NULL);
}
コード例 #7
0
// evaluate a certain function for all docked objects
void dock_evaluate_all_docked_objects(p_object *objp, p_dock_function_info *infop, void (*function)(p_object *, p_dock_function_info *))
{
	Assert((objp != NULL) && (infop != NULL) && (function != NULL));

	// not docked?
	if (!object_is_docked(objp))
	{
		// call the function for just the one object
		function(objp, infop);
		return;
	}

	// we only have two objects docked
	if (dock_check_docked_one_on_one(objp))
	{
		// call the function for the first object, and return if instructed
		function(objp, infop);
		if (infop->early_return_condition) return;

		// call the function for the second object, and return if instructed
		function(objp->dock_list->docked_objp, infop);
		if (infop->early_return_condition) return;
	}

	// NOTE - never treat a group of parse objects as a hub... it cuts down on bugs, and it's
	// not needed because it's not time-critical

	// we have multiple objects docked and we must treat them as a tree
	else
	{
		// create a bit array to mark the objects we check
		ubyte *visited_bitstring = (ubyte *) vm_malloc(calculate_num_bytes(Parse_objects.size()));

		// clear it
		memset(visited_bitstring, 0, calculate_num_bytes(Parse_objects.size()));

		// start evaluating the tree
		dock_evaluate_tree(objp, infop, function, visited_bitstring);

		// destroy the bit array
		vm_free(visited_bitstring);
		visited_bitstring = NULL;
	}
}
コード例 #8
0
bool dock_check_docked_one_on_one(object *objp)
{
	// we must be docked
	if (!object_is_docked(objp))
		return false;
	
	// our dock list must contain only one object
	if (objp->dock_list->next != NULL)
		return false;

	// the other guy's dock list must contain only one object
	if (dock_get_first_docked_object(objp)->dock_list->next != NULL)
		return false;

	// debug check to make sure that we're docked to each other
	Assert(objp == dock_get_first_docked_object(objp)->dock_list->docked_objp);
	
	// success
	return true;
}
コード例 #9
0
void dock_dock_docked_objects(p_object *objp)
{
	if (!object_is_docked(objp))
		return;

	// has this object (by extension, this group of docked objects) been handled already?
	if (objp->flags[Mission::Parse_Object_Flags::Already_handled])
		return;

	Assert(objp->flags[Mission::Parse_Object_Flags::SF_Dock_leader]);

	p_dock_function_info dfi;
	
	// start a tree with that object as the parent... do NOT use the überfunction for this,
	// because we must use a tree for the parent ancestry to work correctly

	// we don't need a bit array because P2_ALREADY_HANDLED takes care of it

	// start evaluating the tree, starting with the dock leader
	dock_dock_docked_children_tree(objp, NULL);
}
コード例 #10
0
void emp_process_ship(ship *shipp)
{
	object *objp;
	ai_info *aip;	

	Assert(shipp != NULL);
	if(shipp == NULL){
		return;
	}
	Assert(shipp->objnum >= 0);
	if(shipp->objnum < 0){
		return;
	}
	objp = &Objects[shipp->objnum];

	// if the emp intensity is < 0, there is no effect
	if(shipp->emp_intensity < 0.0f){
		shipp->emp_intensity = -1.0f;

		return;
	}

	// reduce the emp effect
	shipp->emp_intensity -= shipp->emp_decr * flFrametime;

	// multiplayer clients should bail here
	if(MULTIPLAYER_CLIENT){
		return;
	}

	// if this is a player ship, don't do anything wacky
	if(objp->flags & OF_PLAYER_SHIP){
		return;
	}

	// lose lock time, etc, etc.
	Assert(shipp->ai_index >= 0);
	aip = &Ai_info[shipp->ai_index];	
	aip->aspect_locked_time = 0.0f;				// hasn't gotten aspect lock at all
	aip->current_target_is_locked = 0;			// isn't locked on his current target
	aip->ai_flags &= ~AIF_SEEK_LOCK;
	aip->nearest_locked_object = -1;				// nothing near me, so I won't launch countermeasures

	// if he's not a fighter or bomber, bail now
	if(!(Ship_info[shipp->ship_info_index].flags & (SIF_FIGHTER | SIF_BOMBER))){
		return;
	}

	// if he's docked, or ordered to not move, bail now
	if (object_is_docked(objp) || (aip->mode == AIM_STILL) || (aip->mode == AIM_PLAY_DEAD)){
		return;
	}
	
	// pick targets randomly and wackily so that the ship flies crazily :)	
	if(((int)f2fl(Missiontime) + (int)(EMP_INTENSITY_MAX * shipp->emp_intensity)) % mod_val == 0){
		int ship_lookup = ship_get_random_team_ship(iff_get_attackee_mask(shipp->team));

		// if we got a valid ship object to target
		if((ship_lookup >= 0) && (Ships[ship_lookup].objnum >= 0) && !(Objects[Ships[ship_lookup].objnum].flags & OF_PROTECTED)){
			// attack the object
			ai_attack_object(objp, &Objects[Ships[ship_lookup].objnum], NULL);
		}
	}
}