Esempio n. 1
0
///
//Updates a GObject using a Template state
//
//Parameters:
//	obj: A pointer to the GObject being updated
//	state: A pointer to the state updating the GObject
void State_ParkourController_Update(GObject* obj, State* state)
{
    //Get a reference to the state members
    struct State_ParkourController_Members* members = (struct State_ParkourController_Members*)state->members;


    //If it needs to be updated, update the shoot timer
    if(members->shootTimer < members->shootCooldown)
    {
        float dt = TimeManager_GetDeltaSec();
        members->shootTimer += dt;
    }
    //If the left mouse button is down, shoot
    if(InputManager_IsMouseButtonPressed(0))
    {
        State_ParkourController_Shoot(obj, state);
    }

    //Get a reference to the camera
    Camera* cam = RenderingManager_GetRenderingBuffer()->camera;

    //Determine if the object is colliding with anything
    if(obj->collider->currentCollisions->size > 0)
    {
        //Determine if the object is on the ground
        if(State_ParkourController_IsOnGround(obj))
        {
            //Allow the object to accelerate
            State_ParkourController_Accelerate(obj, state);
            if(InputManager_IsKeyDown(' '))
            {
                State_ParkourController_Jump(obj, state);
            }
        }

        //If the spacebar is being pressed even if the object is not on the floor
        if(InputManager_IsKeyDown(' '))
        {
            //Attempt to wallrun!
            State_ParkourController_Wallrun(obj, state);
        }
        else if(members->verticalRunning || members->horizontalRunning)
        {
            //Wall jump!
            State_ParkourController_WallJump(obj, state);

            //If vertically wallrunning, start spinning right round baby right round!
            if(members->verticalRunning) members->spinningTimer = 0.0f;

            //The object was wallrunning but now (s)he stopped before the wall ended
            members->verticalRunning = members->horizontalRunning = 0;
        }
    }
    else if(members->verticalRunning || members->horizontalRunning)
    {
        if(members->verticalRunning)
        {
            State_ParkourController_WallVault(obj, state);
        }

        //The character was wallrunning but now there is no wall
        members->verticalRunning = members->horizontalRunning = 0;
    }

    //If the parkour controller currently spinning off a wall, let it continue, else let the player rotate the controller
    if(members->spinningTimer < members->spinningTime)
    {
        float dt = TimeManager_GetDeltaSec();
        members->spinningTimer += dt;
        Camera_ChangeYaw(cam, spinningRate * dt);
    }
    else
    {
        //Allow the user to rotate the parkour controller
        State_ParkourController_Rotate(state);
    }

    //Set the position of the camera to match the object
    Camera_SetPosition(cam, obj->frameOfReference->position);
}
///
//Updates the object attached to a runner controller
//This object will always accelerate forward while on a surface unless the velocity is already at the max velocity.
//
//Parameters:
//	obj: A pointer to the gameobject to update as a runner
//	state: A pointer to the runner controller state
void State_RunnerController_Update(GObject* obj, State* state)
{
	struct State_RunnerController_Members* members = (struct State_RunnerController_Members*)state->members;

	//If the object is colliding with something, allow it to possibly wall run
	if(obj->collider->currentCollisions->size > 0)
	{
		//If the user is pressing RMB
		if(InputManager_IsMouseButtonPressed(2))
		{
			State_RunnerController_Wallrun(obj, state);
		}
		else if(members->verticalRunning || members->horizontalRunning)
		{
			//Wall jump
			if(members->verticalRunning)
			{
				members->spinningTimer = 0.0f;
			}

			State_RunnerController_WallJump(obj, state);

			members->verticalRunning = members->horizontalRunning = 0;

		}
		else
		{
			if(State_RunnerController_IsOnGround(obj, state))
			{
				State_RunnerController_Accelerate(obj, state);
			}
		}


		//If the user is pressing LMB
		if(InputManager_IsMouseButtonPressed(0))
		{
			State_RunnerController_Jump(obj, state);
		}

	}
	else if(members->verticalRunning || members->horizontalRunning)
	{

		//Wall vault
		if(members->verticalRunning)
		{
			State_RunnerController_WallVault(obj, state);
		}

		members->verticalRunning = members->horizontalRunning = 0;

	}


	Camera* cam = RenderingManager_GetRenderingBuffer()->camera;

	if(members->spinningTimer < members->spinningTime)
	{
		float dt = TimeManager_GetDeltaSec();
		members->spinningTimer += dt;
		Camera_ChangeYaw(cam, spinningRate * dt);
	}
	else
	{
		//Rotate runner
		State_RunnerController_Rotate(obj, state);
	}
	//Grab the camera

	// Set position of Camera to the body
	Camera_SetPosition(cam, obj->body->frame->position);
}
// Create an object in front of the character and fire
// Parameters:
//	GO: The object getting passed in, in this case the character
//	State: Needed to grab members
void State_CharacterController_ShootBullet(GObject* GO, State* state)
{
	//Get members
	struct State_CharacterController_Members* members = (struct State_CharacterController_Members*)state->members;

	// Camera local
	Camera* cam = RenderingManager_GetRenderingBuffer()->camera;
	// Gets the time per second
	float dt = TimeManager_GetDeltaSec();
	members->timer += dt;

	if(InputManager_GetInputBuffer().mouseLock)
	{
		// Create a net movement vector
		Vector direction;
		Vector_INIT_ON_STACK(direction, 3);
		if (InputManager_IsMouseButtonPressed(0) && members->timer >= members->coolDown)
		{
			//Get "forward" Vector
			Matrix_SliceRow(&direction, cam->rotationMatrix, 2, 0, 3);
			Vector_Scale(&direction,-1.0f);

			// Create the bullet object
			GObject* bullet = GObject_Allocate();
			GObject_Initialize(bullet);

			//bullet->mesh = AssetManager_LookupMesh("Sphere");
			bullet->mesh = AssetManager_LookupMesh("Arrow");
			bullet->texture = AssetManager_LookupTexture("Arrow");


			bullet->body = RigidBody_Allocate();
			RigidBody_Initialize(bullet->body, bullet->frameOfReference, 0.45f);
			bullet->body->coefficientOfRestitution = 0.2f;

			bullet->collider = Collider_Allocate();
			ConvexHullCollider_Initialize(bullet->collider);
			ConvexHullCollider_MakeRectangularCollider(bullet->collider->data->convexHullData, 0.1f, 2.0f, 0.1f);
			//AABBCollider_Initialize(bullet->collider, 2.0f, 2.0f, 2.0f, &Vector_ZERO);

			//Lay arrow flat
			GObject_Rotate(bullet, &Vector_E1, -3.14159f / 2.0f);

			//Construct a rotation matrix to orient bullet
			Matrix rot;
			Matrix_INIT_ON_STACK(rot, 3, 3);
			//Grab 4,4 minor to get 3x3 rotation matrix of camera
			Matrix_GetMinor(&rot, cam->rotationMatrix, 3, 3);
			//Transpose it to get correct direction
			Matrix_Transpose(&rot);
			//Rotate the bullet
			Matrix_TransformMatrix(&rot, bullet->frameOfReference->rotation);
			Matrix_TransformMatrix(&rot, bullet->body->frame->rotation);


			Vector vector;
			Vector_INIT_ON_STACK(vector,3);
			vector.components[0] = 0.9f;
			vector.components[1] = 1.0f;
			vector.components[2] = 0.9f;
			GObject_Scale(bullet, &vector);

			Vector translation;
			Vector_INIT_ON_STACK(translation, 3);
			Vector_GetScalarProduct(&translation, &direction, 2.82843);
			GObject_Translate(bullet, GO->frameOfReference->position);
			GObject_Translate(bullet, &translation);

			Vector_Scale(&direction, 25.0f);

			//Vector_Increment(bullet->body->velocity,&direction);
			RigidBody_ApplyImpulse(bullet->body,&direction,&Vector_ZERO);

			//Add remove state
			State* state = State_Allocate();
			State_Remove_Initialize(state, 5.0f);
			GObject_AddState(bullet, state);

			ObjectManager_AddObject(bullet);

			members->timer = 0;
		}
	}
}