示例#1
0
short new_projectile(
	world_point3d *origin,
	short polygon_index,
	world_point3d *_vector,
	angle delta_theta, /* ±¶theta is added (in a circle) to the angle before firing */
	short type,
	short owner_index,
	short owner_type,
	short intended_target_index, /* can be NONE */
	_fixed damage_scale)
{
	struct projectile_definition *definition;
	struct projectile_data *projectile;
	short projectile_index;

	type= adjust_projectile_type(origin, polygon_index, type, owner_index, owner_type, intended_target_index, damage_scale);
	definition= get_projectile_definition(type);

	for (projectile_index= 0, projectile= projectiles; projectile_index<MAXIMUM_PROJECTILES_PER_MAP;
		++projectile_index, ++projectile)
	{
		if (SLOT_IS_FREE(projectile))
		{
			angle facing, elevation;
			short object_index;
			struct object_data *object;

			facing= arctangent(_vector->x, _vector->y);
			elevation= arctangent(isqrt(_vector->x*_vector->x+_vector->y*_vector->y), _vector->z);
			if (delta_theta)
			{
				if (!(definition->flags&_no_horizontal_error)) facing= normalize_angle(facing+global_random()%(2*delta_theta)-delta_theta);
				if (!(definition->flags&_no_vertical_error)) elevation= (definition->flags&_positive_vertical_error) ? normalize_angle(elevation+global_random()%delta_theta) :
					normalize_angle(elevation+global_random()%(2*delta_theta)-delta_theta);
			}
			
			object_index= new_map_object3d(origin, polygon_index, definition->collection==NONE ? NONE : BUILD_DESCRIPTOR(definition->collection, definition->shape), facing);
			if (object_index!=NONE)
			{
				object= get_object_data(object_index);
				
				projectile->type= (definition->flags&_alien_projectile) ?
					(alien_projectile_override==NONE ? type : alien_projectile_override) :
					(human_projectile_override==NONE ? type : human_projectile_override);
				projectile->object_index= object_index;
				projectile->owner_index= owner_index;
				projectile->target_index= intended_target_index;
				projectile->owner_type= owner_type;
				projectile->flags= 0;
				projectile->gravity= 0;
				projectile->ticks_since_last_contrail= projectile->contrail_count= 0;
				projectile->elevation= elevation;
				projectile->distance_travelled= 0;
				projectile->damage_scale= damage_scale;
				MARK_SLOT_AS_USED(projectile);

				SET_OBJECT_OWNER(object, _object_is_projectile);
				object->sound_pitch= definition->sound_pitch;
				L_Call_Projectile_Created(projectile_index);
			}
			else
			{
				projectile_index= NONE;
			}
			
			break;
		}
	}
	if (projectile_index==MAXIMUM_PROJECTILES_PER_MAP) projectile_index= NONE;
	
	return projectile_index;
}
示例#2
0
short new_item(struct object_location *location,short type)
{
	short object_index;
	item_definition *definition= get_item_definition(type);
	// LP change: added idiot-proofing
	if (!definition) 
		return false;
	
	bool add_item = true;

	assert(sizeof(item_definitions)/sizeof(struct item_definition)==NUMBER_OF_DEFINED_ITEMS);

	/* Do NOT add items that are network-only in a single player game, and vice-versa */
	if (dynamic_world->player_count>1)
	{
		if (definition->invalid_environments & _environment_network) 
			add_item = false;
		if (get_item_kind(type)==_ball && !current_game_has_balls()) 
			add_item = false;
	} 
	else
	{
		if (definition->invalid_environments & _environment_single_player) add_item= false;
	}

	if (add_item)
	{
		/* add the object to the map */
		object_index= new_map_object(location, definition->base_shape);
		if (object_index!=NONE)
		{
			object_data *object= get_object_data(object_index);
			
			// LP addition: using the facing direction as a flag in the "unanimated" case:
			// will be initially zero, but will become nonzero when initialized,
			// so that the shape randomization will be done only once.
			
			SET_OBJECT_OWNER(object, _object_is_item);
			object->permutation= type;
			
			if ((location->flags&_map_object_is_network_only) && dynamic_world->player_count<=1)
			{

				SET_OBJECT_INVISIBILITY(object, true);
				object->permutation= NONE;
			}
			else if ((get_item_kind(type) == _ball) && !static_world->ball_in_play)
			{
				static_world->ball_in_play = true;
				SoundManager::instance()->PlayLocalSound(_snd_got_ball);
			}
			
			/* let PLACEMENT.C keep track of how many there are */
			object_was_just_added(_object_is_item, type);
			// and let Lua know too
			L_Call_Item_Created(object_index);
 		}
	}
	else
		object_index = NONE;
	
	return object_index;
}