diff options
| -rw-r--r-- | src/client/targets.cc | 33 | ||||
| -rw-r--r-- | src/client/targets.h | 3 | ||||
| -rw-r--r-- | src/core/entity.cc | 2 | ||||
| -rw-r--r-- | src/game/base/ship.cc | 46 | 
4 files changed, 59 insertions, 25 deletions
diff --git a/src/client/targets.cc b/src/client/targets.cc index 6809939..8a7f402 100644 --- a/src/client/targets.cc +++ b/src/client/targets.cc @@ -39,6 +39,7 @@ unsigned int current_target_id = 0;  unsigned int current_hover = 0;  const core::Entity *current_target = 0; +math::Vector3f cursor_aim;  bool is_valid_map_target(const core::Entity *entity)  { @@ -295,6 +296,11 @@ void shutdown()  	core::Func::remove("target_center");  } +const math::Vector3f & aim() +{ +	return cursor_aim; +} +  // render targets and sounds (in world coordinates)  void frame()  { @@ -327,14 +333,9 @@ void frame()  		y = (float)(input::mouse_position_y() - render::State::height() / 2) / (float)render::State::height() / render::State::aspect();  	} -	Vector3f cursor = render::Camera::eye() + render::Camera::axis().forward() * (render::FRUSTUMFRONT + 0.001); -	cursor -= render::Camera::axis().left() * x; -	cursor -= render::Camera::axis().up() * y; -	 -	// set aim -	if (core::localcontrol()) { -		core::localcontrol()->set_target_aim(cursor); -	} +	cursor_aim.assign(render::Camera::eye() + render::Camera::axis().forward() * (render::FRUSTUMFRONT + 0.001)); +	cursor_aim -= render::Camera::axis().left() * x; +	cursor_aim -= render::Camera::axis().up() * y;  	//math::Vector3f center = render::Camera::eye() + (render::Camera::axis().forward() * (render::FRUSTUMFRONT + 0.001f));  	for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { @@ -359,7 +360,7 @@ void frame()  			if (math::dotproduct(render::Camera::axis().forward(), v) > 0.75) {  				// calculate the distance from entity location to the line [eye - cursor] -				float d = math::Vector3f::length(math::crossproduct((cursor - render::Camera::eye()) , (render::Camera::eye() - entity->location()))) / math::Vector3f::length(cursor - render::Camera::eye()); +				float d = math::Vector3f::length(math::crossproduct((cursor_aim - render::Camera::eye()) , (render::Camera::eye() - entity->location()))) / math::Vector3f::length(cursor_aim - render::Camera::eye());  				float r = entity->radius() * 0.5f; @@ -372,7 +373,7 @@ void frame()  				// if the cursor-beam hits the entity sphere  				if (d < r) { -					float myz = math::distance(cursor, entity->location()); +					float myz = math::distance(cursor_aim, entity->location());  					if (z < 0 || myz < z) {  						current_hover = entity->id();  						z = myz; @@ -384,13 +385,21 @@ void frame()  		}  	} +	float d = 64.0f;	// default aim distance +	  	if (!current_target) {  		current_target_id = 0;  	} else {  		current_target_id  = current_target->id(); - - +		d = math::distance(render::Camera::eye(), current_target->location()); +	} +	cursor_aim = render::Camera::eye() + (cursor_aim - render::Camera::eye())  / math::distance(render::Camera::eye(), cursor_aim)  * d; +	 +	// set aim +	if (core::localcontrol()) {		 +		core::localcontrol()->set_target_aim(cursor_aim);  	} +  }  } diff --git a/src/client/targets.h b/src/client/targets.h index e66ff97..ed681c3 100644 --- a/src/client/targets.h +++ b/src/client/targets.h @@ -48,6 +48,9 @@ void set_target(unsigned int id);  /// target a specific entity  void set_target(const core::Entity *entity); +/// return current cursor aim location in world space +const math::Vector3f &cursor_aim(); +  }  } diff --git a/src/core/entity.cc b/src/core/entity.cc index 4a603f1..589d132 100644 --- a/src/core/entity.cc +++ b/src/core/entity.cc @@ -1177,6 +1177,7 @@ void EntityControlable::serialize_client_update(std::ostream & os) const  	os << target_vstrafe << " ";  	os << target_afterburner << " ";  	os << target_controlflags << " "; +	os << target_aim << " ";  }  void EntityControlable::receive_client_update(std::istream &is) @@ -1190,6 +1191,7 @@ void EntityControlable::receive_client_update(std::istream &is)  	is >> target_vstrafe;  	is >> target_afterburner;  	is >> target_controlflags; +	is >> target_aim;  }  void EntityControlable::serialize_server_update(std::ostream & os) const diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index ea793af..219cb0c 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -917,22 +917,42 @@ void Ship::frame(const unsigned long elapsed)  				const Weapon *weapon = static_cast<const Weapon *>(slot->item()->info());  				if ((weapon->subtype() == Weapon::Cannon) && (weapon->projectile_interval() > 0) && (slot->last_fired() + weapon->projectile_interval() <=  core::server()->timestamp())) { -					// spawn a new projectile -					core::EntityProjectile *projectile = new core::EntityProjectile(this); +					// aim +					const float projectile_radius = 0.01f; // FIXME this should be defined somewhere +					 +					math::Axis projectile_axis(axis() * slot->axis()); +					math::Vector3f projectile_location(location() + (axis() * slot->location() * modelscale) + projectile_axis.forward() * projectile_radius);					 +					math::Vector3f projectile_direction(target_aim - projectile_location); +					projectile_direction.normalize(); +					float cosa = math::dotproduct(projectile_direction, projectile_axis.forward()); +					 +					// fire a projectile if the angle between the aim direction and the slot's forward direction is small enough +					// TODO configurable aim cone +					if (cosa > 0.5f) { +						// aim +						math::Vector3f normal(math::crossproduct(projectile_direction, projectile_axis.forward())); +						if (normal.length() > MIN_DELTA) { +							float sina = sqrt(1 - cosa * cosa); +							 +							normal.normalize(); +							projectile_axis.rotate(normal, cosa, sina); +						} -					projectile->set_damage(weapon->damage()); -					projectile->set_lifespan(weapon->projectile_lifespan()); -					projectile->set_projectile_modelname(weapon->projectile_modelname()); -					projectile->set_projectile_soundname(weapon->projectile_soundname()); -	 -					projectile->set_axis(axis() * slot->axis()); -					projectile->set_location(location() + (axis() * slot->location() * modelscale) + projectile->axis().forward() * projectile->radius()); -					projectile->set_speed(weapon->projectile_speed()); +						// spawn a new projectile +						core::EntityProjectile *projectile = new core::EntityProjectile(this); -					projectile->reset(); -					 -					slot->set_last_fired(core::server()->timestamp()); +						projectile->set_damage(weapon->damage()); +						projectile->set_lifespan(weapon->projectile_lifespan()); +						projectile->set_projectile_modelname(weapon->projectile_modelname()); +						projectile->set_projectile_soundname(weapon->projectile_soundname()); +		 +						projectile->set_axis(projectile_axis); +						projectile->set_location(projectile_location); +						projectile->set_speed(weapon->projectile_speed()); +						projectile->reset(); +						slot->set_last_fired(core::server()->timestamp()); +					}  				}  			}  		}  | 
