Esempio n. 1
0
func Bounce(int xdir, int ydir)
{
	var angle = Angle(0, 0, xdir, ydir);
	
	var surface = GetSurfaceVector(0, 0);
	var surface_angle = Angle(0, 0, surface[0], surface[1]);
	var angle_diff = GetTurnDirection(angle - 180, surface_angle);
	var new_angle = surface_angle + angle_diff;
	
	SetXDir(Sin(new_angle, Speed*10), 100);
	SetYDir(-Cos(new_angle, Speed*10), 100);
}
Esempio n. 2
0
AIAction PlayerAI::Tick(float _timespan, std::vector<Core*>& /*_allies*/, std::vector<Core*>& _enemies, Core* _self)
{
	if(core_id_ == -1)
	{
		core_id_ = _self->GetSectionID();
		if(core_id_ != -1)
		{
			core_ids_.push_back(core_id_);
		}
		else
			Logger::ErrorOut() << "Player ID of -1 encountered\n";
	}

	if(core_ids_.size() == 1)
	{
		Radar::SetPlayerPosition(_self->GetGlobalPosition());
	}

	AIAction action;
	Uint8* keystates = SDL_GetKeyState(0);
	int mx, my;
	int mb = SDL_GetMouseState(&mx, &my);

	Vector3f point_to_face;
	Vector3f peer_factor;
	bool lock_movement = false;
	bool lock_angle = false;
	bool look_backwards = false;

	if(SDL_NumJoysticks())
		SDL_JoystickUpdate();
	point_to_face = _self->GetGlobalPosition();
	
	std::vector<InputConfig>& binds = bindings[player_id_];

	for(std::vector<InputConfig>::iterator it = binds.begin(); it != binds.end(); ++it)
	{
		switch(it->type)
		{
		case BindingType::MouseAxisBinding:
			{
			float axis_value = 0;
			float ltv_axis_value = 0;
			switch(it->binding.mouse_axis)
			{
			case MouseAxis::MouseX:
				axis_value = static_cast<float>(mx);
				ltv_axis_value = ltv_mouse_position_.x;
				break;
			case MouseAxis::MouseY:
				axis_value = static_cast<float>(my);
				ltv_axis_value = ltv_mouse_position_.y;
				break;
			}
			switch(it->action)
			{
			case Action::LookXAxis:
				point_to_face.x = Camera::Instance().ScreenToWorld(Vector3f(axis_value, 0, 0)).x;
				peer_factor.x = (axis_value - (Camera::Instance().GetWindowWidth() / 2.0f)) * 2.0f / Camera::Instance().GetWindowWidth();
				break;
			case Action::LookYAxis:
				point_to_face.y = Camera::Instance().ScreenToWorld(Vector3f(0, axis_value, 0)).y;
				peer_factor.y = -(axis_value - (Camera::Instance().GetWindowHeight() / 2.0f)) * 2.0f / Camera::Instance().GetWindowHeight();
				break;
			case Action::XMovement:
				movement_integrator_.x *= (1.0f - 0.2f * _timespan);
				movement_integrator_.x += axis_value - ltv_axis_value;
				action.dx_ += movement_integrator_.x / (fabs(movement_integrator_.x) > 1.0f ? fabs(movement_integrator_.x) : 1.0f);
				break;
			case Action::YMovement:
				movement_integrator_.y *= (1.0f - 0.2f * _timespan);
				movement_integrator_.y += axis_value - ltv_axis_value;
				action.dx_ += movement_integrator_.y / (fabs(movement_integrator_.y) > 1.0f ? fabs(movement_integrator_.y) : 1.0f);
				break;
			}
			}
			break;
		case BindingType::JoystickAxisBinding:
			{
				float axis_value = 0;
				if(it->binding.joystick_axis.joystick)
				{
					Sint16 js_axis_val = SDL_JoystickGetAxis(it->binding.joystick_axis.joystick, it->binding.joystick_axis.axis_index);
					if(abs(js_axis_val) < MAXSHORT * 0.2f)
						js_axis_val = 0;
					axis_value = (float)js_axis_val / (float)MAXSHORT;
				}

				switch(it->action)
				{
				case Action::LookXAxis:
					point_to_face.x += axis_value;
					peer_factor.x = axis_value;
					break;
				case Action::LookYAxis:
					point_to_face.y -= axis_value;
					peer_factor.y = -axis_value;
					break;
				case Action::XMovement:
					action.dx_ += axis_value;
					break;
				case Action::YMovement:
					action.dy_ -= axis_value;
					break;
				}
				break;
			}
		case BindingType::KeyboardBinding:
		case BindingType::MouseButtonBinding:
		case BindingType::JoystickButtonBinding:

			if((it->type == BindingType::KeyboardBinding && keystates[it->binding.key]) ||
			   (it->type == BindingType::MouseButtonBinding && (mb & SDL_BUTTON(GetSDLCode(it->binding.mouse_button)))) ||
			   (it->type == BindingType::JoystickButtonBinding && it->binding.joystick_button.joystick && SDL_JoystickGetButton(it->binding.joystick_button.joystick, it->binding.joystick_button.button_index)))
			{
				switch(it->action)
				{
				case Action::Fire:
					action.firing_ = true;
					break;
				case Action::Boost:
					action.thrust_ = true;
					break;
				case Action::Target:
					break;
				case Action::MoveLeft:
					action.dx_--;
					break;
				case Action::MoveRight:
					action.dx_++;
					break;
				case Action::MoveUp:
					action.dy_++;
					break;
				case Action::MoveDown:
					action.dy_--;
					break;
				case Action::LockMovement:
					lock_movement = true;
					break;
				case Action::LockAngle:
					lock_angle = true;
					break;
				case Action::LookBackwards:
					look_backwards = true;
					break;
				}
			}
			break;
		}
	}
	if(look_backwards)
	{
		point_to_face *= -1;
	}
	if(lock_angle_)
	{
		point_to_face = lock_vector_ + _self->GetGlobalPosition();//+ _self->GetAngle();
	}

	Vector3f point_to_face_relative = point_to_face - _self->GetGlobalPosition();
	if(point_to_face_relative.lengthSq()!=0)
	{
		TurnData turn_data = GetTurnDirection(_self->GetAngle(), point_to_face_relative);
		float dotprod = turn_data.turn_factor;
		action.dtheta_ = ClampTurnDirection(dotprod, 0.4f);

		if(peer_factor.lengthSq() > 1)
			peer_factor.normalize();
		Vector3f camera_centre = _self->GetGlobalPosition();
		Camera::Instance().SetCentreTarget(camera_centre.x, camera_centre.y, peer_factor.x, peer_factor.y, CameraLevel::Human);
		Camera::Instance().SetFocus(_self->GetPosition().x, _self->GetPosition().y, CameraLevel::Human);
	} else
	{
		Camera::Instance().SetCentreTarget(_self->GetPosition().x, _self->GetPosition().y, 0, 0, CameraLevel::Human);
		Camera::Instance().SetFocus(_self->GetPosition().x, _self->GetPosition().y, CameraLevel::Human);
	}

	ltv_mouse_position_.x = static_cast<float>(mx);
	ltv_mouse_position_.y = static_cast<float>(my);

	if(lock_movement)
	{
		action.dx_ = 0;
		action.dy_ = 0;
	}

	if(lock_angle && !lock_angle_)
	{
		lock_vector_ = Vector3f(sinf(_self->GetAngle() * M_PI / 180.0f),
							    cosf(_self->GetAngle() * M_PI / 180.0f), 0);
	}
	lock_angle_ = lock_angle;

	return action;
}
Esempio n. 3
0
void ThrusterTrail::Tick(float _timespan, Matrix4f _transform, std::vector<Decoration_ptr>& _decoration_spawn)
{
	Decoration::Tick(_timespan, _transform, _decoration_spawn);
	if(source_!=NULL && _timespan > 0)
	{
		//Get updated position and angle for the root segment, Speed is calculated purely by change in position
		Vector3f np = source_->GetTransform() * offset_;
		Vector3f dp = np - ltv_source_position_;

		float angle = source_->GetGlobalAngle() + angular_offset_;
		//if(!angular_corrected_)
			//angle += angular_offset_;
		Vector3f forward = Vector3f(sin(angle * M_PI / 180.0f), cos(angle * M_PI / 180.0f), 0);			

		float speed  = dp.length() / _timespan;
		float target_length = speed * 0.02f * length_scale_;

		if(dp.lengthSq() > 0.0f)
		{
			//Calculate the dot product of section movement with section angle. This is used to turn the plume towards the back of the segment
			dp.normalize();
			float alignment_scale = dp.dotProduct(forward);
			/* k(x+1)^2 + P = y. Fit points (-1,P) and (1, 1) -> k = (1-P)/4 valid for -1 to 1.*/
			alignment_scale = ((alignment_scale+1) * (alignment_scale+1) * (1.0f - antiparallel_factor_) / 4.0f) + antiparallel_factor_;
			target_length *= alignment_scale;

			if(angular_corrected_)
			{
				TurnData td = GetTurnDirection(angle, dp);
				angle += td.turn_factor * 30;
			}
		}

		//Calculate the weighting to give the new calculated length, so that length changes smoothly regardless of framerate.
		float new_weight = 1.0f - expf(-_timespan * 7.0f);
		float rotation_rate = (400 + speed) * 1;

		if(section_length_ < 0)
			section_length_ = 0;
		section_length_ = (1.0f - new_weight) * section_length_ + new_weight * target_length;
		float section_length_sqr = sqrt(section_length_);

		//Calculate worldspace coordinates of plume polygons
		points_[0] = angle;
		cartesian_points_[0] = np;
		for(int i = 1; i < points_.size(); i++)
		{
			TurnData td = GetTurnDirection(points_[i], points_[i-1]);
			cartesian_points_[i] = cartesian_points_[i-1] + Vector3f(-sin(points_[i] * M_PI / 180.0f), -cos(points_[i] * M_PI / 180.0f), 0) * section_length_;
			points_[i] = points_[i] + td.turn_factor * _timespan * rotation_rate;

			Vector3f perp = cartesian_points_[i] - cartesian_points_[i-1];
			perp.z = perp.x;
			perp.x = -perp.y;
			perp.y = perp.z;
			perp.z = 0;
			if(perp.lengthSq() > 0)
				perp.normalize();
			perp *= (1.0f + 3.0f * section_length_sqr * sin(((float)i / (float)points_.size()) * M_PI));
			perp *= width_scale_;

			int base = (i - 2) * 6 + 3;
			if(i==1)
			{
				fill_points_[0] = cartesian_points_[0];
				fill_points_[1] = cartesian_points_[1] + perp;
				fill_points_[2] = cartesian_points_[1] - perp;
			} else if(i < points_.size() - 1)
			{
				fill_points_[base + 0] = fill_points_[base - 1];
				fill_points_[base + 1] = fill_points_[base - 2];
				fill_points_[base + 2] = cartesian_points_[i] + perp;
				fill_points_[base + 3] = fill_points_[base - 1];
				fill_points_[base + 4] = cartesian_points_[i] + perp;
				fill_points_[base + 5] = cartesian_points_[i] - perp;
			} else
			{
				cartesian_points_[i] = cartesian_points_[i-1] + Vector3f(-sin(points_[i] * M_PI / 180.0f), -cos(points_[i] * M_PI / 180.0f), 0) * section_length_ * 2;
				fill_points_[base + 0] = fill_points_[base - 1];
				fill_points_[base + 1] = fill_points_[base - 2];
				fill_points_[base + 2] = cartesian_points_[i];
			}
		}

		lifetime_ = 1.0f; // should live as long as source exists
		ltv_source_position_ = source_->GetGlobalPosition();

		const float minimum_length = 0.4f;
		const float fade_length = 1.0f;
		
		if(section_length_ < minimum_length)
		{
			fill_.GetFillColor().a = 0;
		} else if(section_length_ < fade_length + minimum_length)
		{
			float alpha = 255.0f * ((section_length_ - minimum_length) / fade_length) ;
			fill_.GetFillColor().a = alpha;
		} else
		{
			fill_.GetFillColor().a = 255;
		}
		
	} else
	{
		fill_.GetFillColor().a = 255.0f * lifetime_;
	}
}
Esempio n. 4
0
AIAction SimpleAI::Tick(float _timespan, std::vector<Core_ptr>& /*_allies*/, std::vector<Core_ptr>& _enemies, Core_ptr _self)
{
	AIAction a = AIAction(0, 0, 0, false, false); 

	sum_time_ += _timespan;
	focus_time_ += _timespan;
	strafe_time_ += _timespan;
	if(strafe_time_ > SimpleAIStrafeTime)
	{
		strafe_time_ = 0;
		if(Random::RandomChance(0.4f))
			strafe_clockwise_ = !strafe_clockwise_;
		if(Random::RandomChance(0.8f))
			preferred_minimum_range_ = SimpleAIMinimumRange * 1.5f;
		else
			preferred_minimum_range_ = SimpleAIMinimumRange * 1.0f;
	}

	if(focus_time_ > max_focus_time_ || target_ == NULL)
	{
		focus_time_ = 0;
		//Pick a new target
		if(_enemies.size() > 0)
		{
			if(target_ != NULL)
				target_->RemoveSubscriber(this);
			int index = Random::RandomIndex(static_cast<int>(_enemies.size()));

			target_ = _enemies[index];
			target_->AddSubscriber(this);
		}
	}	

	if(target_ != NULL)
	{
		Vector3f relative_position = (target_->GetPosition() - _self->GetPosition());
		float range = relative_position.length();
		float angle = atan2f(relative_position.x, relative_position.y);
		if(relative_position.lengthSq() > 0)
			relative_position.normalize();
		if(range > preferred_minimum_range_ * 2) //Close on target
		{
			a.dx_ = sinf(angle);
			a.dy_ = cosf(angle);
		}else if(range < preferred_minimum_range_) //Back off target
		{
			a.dx_ = -sinf(angle);
			a.dy_ = -cosf(angle);
		} else //Circle strafe
		{
			//Add sideways movement
			if(strafe_clockwise_)
			{
				a.dx_ = -cosf(angle) * 0.2f;
				a.dy_ = sinf(angle) * 0.2f;
			} else
			{
				a.dx_ = cosf(angle) * 0.2f;
				a.dy_ = -sinf(angle) * 0.2f;
			}
			//Reduce range movement
			float movement_in_range_dimension;
			Vector3f self_velocity = _self->GetVelocity();
			if(self_velocity.lengthSq() > 0)
			{
				self_velocity.normalize();
				movement_in_range_dimension = self_velocity.dotProduct(relative_position);
				a.dx_ -= 0.8f * sinf(angle) * movement_in_range_dimension;
				a.dy_ -= 0.8f * cosf(angle) * movement_in_range_dimension;
			}
		}
		TurnData td = GetTurnDirection(_self->GetAngle(), relative_position);
		td.turn_factor = ClampTurnDirection(td.turn_factor, 0.1f);
		//td.turn_factor *= 0.2f;
		a.dtheta_ = td.turn_factor;
		a.firing_ = true;
		a.target_ = target_;
	}

	return a;
}