#include "Player.hh"
#include "Rope.hh"
#include "Engine.hh"
#include "Graphics.hh"
#include <math.h>
Rope::Rope(Player &player) :
PhysicsObject(player.state.world, ROPE_MASS, Vector(0,0), Vector(0,0), false), player(player), state(ROPE_FOLDED)
{
// XXX: better shape
std::vector<Vector> shape(4);
shape[0] = Vector(-1, -1);
shape[1] = Vector(-1, 1);
shape[2] = Vector(1, 1);
shape[3] = Vector(1, -1);
setShape(shape);
}
void Rope::throwRope (void) {
state = ROPE_FLYING;
// XXX: this should probably be more dynamic?
length = ROPE_LENGTH;
// copy position + velocity from player
position = player.getPosition();
velocity = player.getVelocity() + player.getDirection() * ROPE_VELOCITY;
// we are FLYING
inAir = true;
// enable the physics object
enable();
// inform network
player.handleRopeState(state);
}
void Rope::onCollision() {
// attached to something!
state = ROPE_FIXED;
// stop movement
disable();
// set player's pivot
player.setPivot(this);
// inform network
player.handleRopeState(state);
}
void Rope::release (void) {
// disable if we're flying
if (state == ROPE_FLYING)
disable();
// TODO make it fly first and fold only after it's close to the player
state = ROPE_FOLDED;
// player doesn't have a pivot anymore
player.setPivot(NULL);
// inform network
player.handleRopeState(state);
}
void Rope::changeLength (float delta) {
// change length
length += delta;
// minimum length
if (length < 0)
length = 0;
// inform network
player.handleRopeLength(length);
}
RopeState Rope::getState (void) {
return state;
}
float Rope::getLength (void) {
return length;
}
void Rope::updateState (RopeState new_state, Vector position, Vector velocity, float new_length) {
// update physics enabled/disabled state
if (new_state == ROPE_FOLDED || new_state == ROPE_FIXED)
disable();
else // new_state == ROPE_FLYING
enable();
// update player.pivot
if (new_state == ROPE_FIXED)
player.setPivot(this);
else if (this->state == ROPE_FIXED)
player.setPivot(NULL);
// update position stuff
updatePhysics(position, velocity, true, false, 0);
// update vars
this->state = new_state;
this->length = new_length;
}
void Rope::updateLength (float length) {
// update length
this->length = length;
}
float Rope::getPivotForce (PhysicsObject *bob) {
if ((position - player.getPosition()).length() >= length)
return ROPE_FORCE;
else
return 0;
}
void Rope::draw (Graphics *g) const {
if (state == ROPE_FOLDED)
return;
g->get_gc()->draw_line(
player.getPosition().x, player.getPosition().y,
position.x, position.y,
CL_Color::black
);
}