src/Projectile.cc
author Tero Marttila <terom@fixme.fi>
Tue, 20 Jan 2009 23:30:18 +0200
changeset 408 e6cfc44266af
parent 338 fe2b3c6fff54
child 412 721c60072091
permissions -rw-r--r--
reorganize Terrain/PhysicsWorld/GameState/Engine to use NetworkClientConnect, and hence handle the connection process asynchronously, and finally properly implement receiving the terrain data from the server
#include "Projectile.hh"
#include "Graphics.hh"
#include "Timer.hh"

   
Projectile::Projectile (Player *player, Vector position, Vector velocity, Weapon *weapon, bool visible) :
    PhysicsObject(player->state.world, weapon->getMass(), position, velocity, PROJECTILE, weapon->getBounce()),
    player(player), 
    visible(visible), 
    weapon(weapon)
{
    // set birth tick
    birth_tick = world.getTicks();

    // XXX: projectiles should be particles?
    std::vector<Vector> shape(4);

    shape[0] = Vector(0                   ,  -weapon->getRadius()  );
    shape[1] = Vector(weapon->getRadius() ,  0                    );
    shape[2] = Vector(0                   ,  weapon->getRadius()  );
    shape[3] = Vector(-weapon->getRadius(),  0                    );

    setShape(shape);
    
    // add to state
    player->state.addProjectile(this);
}

Projectile::~Projectile (void) {
    player->state.projectiles.remove(this);
}
 
void Projectile::onDestroy (Vector position, bool removeGround) {
    if (removeGround)
        world.terrain.removeGround(position, weapon->getExplosionRadius());

    destroy();
}

Health Projectile::getDamage () {
    return weapon->getDamage();
}

void Projectile::addKillToOwner () {
    player->addKill();
} 

const Player* Projectile::getOwner () {
    return player;
}
   
void Projectile::onHitPlayer (Player *player) {
    player->takeDamage(this);
}

void Projectile::onCollision (Vector collisionPoint, PhysicsObject *other) {
    // did we hit a player?
    if (other != NULL && other->getType() == PLAYER) {
        Player* player = dynamic_cast<Player*>(other);

        // XXX: check that player really is !NULL
        onHitPlayer(player);
    }

    if (collision_elasticity == 0)
        onDestroy(collisionPoint, true);
}
   
void Projectile::tick (TimeMS dt) {
    // expire projectiles
    if (world.getTicks() > birth_tick + weapon->getExpire())
        onDestroy(position, true);

    // super
    PhysicsObject::tick(dt);
}

void Projectile::draw(Graphics *g, PixelCoordinate camera) const {
    CL_GraphicContext *gc = g->get_gc();

    if (visible) {
        PixelCoordinate pos = getCoordinate() - camera;
        // XXX: scale
        PixelDimension radius = (unsigned int) weapon->getRadius();

        CL_Quad projectile(
                pos.x,              pos.y - radius,
                pos.x + radius,     pos.y,
                pos.x,              pos.y + radius,
                pos.x - radius,     pos.y
        );
        
        gc->fill_quad(projectile, CL_Color::green);
    }
}