|
From: Rob <geo...@us...> - 2006-02-20 23:05:19
|
Update of /cvsroot/timewarp/source/ppiships In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27452/source/ppiships Added Files: shpsefna.cpp shptauh2.cpp Log Message: --- NEW FILE: shptauh2.cpp --- /* $Id: shptauh2.cpp,v 1.1 2006/02/20 23:05:12 geomannl Exp $ */ #include "../ship.h" REGISTER_FILE class TauHunterPPIPortal; class TauHunterPPI : public Ship { public: IDENTITY(TauHunterPPI); double weaponRange, weaponVelocity, weaponRelativity, weaponSpread; double weaponLength, weaponDamage; int weaponNumber; bool weaponAlternating; //double specialRange, specialVelocity; //double specialDamage, specialArmour; double extraVelocity, extraExitVelocityFactor; int extraFrameTime; //double residual_drain; int weapon_side, weapon_angle; //int ship_recharge_amount; //int exit_countdown; //Vector2 ee, vv; double s_a; //int batt_delay, weapon_delay, special_delay, extra_delay; //double default_recharge_rate; bool prevent_more_special; int jumptime, max_jumptime; bool SlidingEntry; Vector2 jumpvector; public: //double extraCriticalRange; //double extraCriticalAngle; //bool holding_spec; bool in_jump; bool just_exited; TauHunterPPI (Vector2 opos, double shipAngle, ShipData *shipData, unsigned int code); virtual int activate_weapon(); virtual void calculate_fire_special(); virtual void calculate(); virtual int handle_damage(SpaceLocation* source, double normal, double direct); virtual int handle_fuel_sap(SpaceLocation* source, double normal); virtual double handle_speed_loss(SpaceLocation* source, double normal); virtual int canCollide(SpaceLocation *other); virtual int translate(Vector2 rel_pos); virtual int accelerate(SpaceLocation *source, double angle, double vel, double max_speed); virtual void animate(Frame *space); virtual double isProtected() const; virtual double isInvisible() const; virtual void calculate_hotspots(); virtual void calculate_turn_left(); virtual void calculate_turn_right(); virtual RGB battPanelColor(); }; class TauHunterPPILaser : public SpaceLine { public: IDENTITY(TauHunterPPILaser); double range, d, v; public: TauHunterPPILaser (double ox, double oy, double oangle, double ov, double orange, double olength, SpaceLocation *creator, double relativity, double odamage); virtual void calculate(); virtual void inflict_damage(SpaceObject *other); }; TauHunterPPI::TauHunterPPI (Vector2 opos, double shipAngle, ShipData *shipData, unsigned int code) : Ship(opos, shipAngle, shipData, code) { //weapon_delay = scale_frames(get_config_float("Weapon", "RechargeDelay", 0)); //special_delay = scale_frames(get_config_float("Special", "RechargeDelay", 0)); //extra_delay = scale_frames(get_config_float("Extra", "RechargeDelay", 0)); weaponRange = scale_range(get_config_float("Weapon", "Range", 0)); weaponVelocity = scale_velocity(get_config_float("Weapon", "Velocity", 0)); weaponLength = get_config_int("Weapon", "Length", 0); weaponSpread = get_config_float("Weapon", "Spread", 0)*PI/180; weaponAlternating = (get_config_int("Weapon", "Alternating", 0) != 0); weaponNumber = get_config_int("Weapon", "Number", 1); weaponDamage = get_config_float("Weapon", "Damage", 0); weaponRelativity = get_config_float("Weapon", "Relativity", 0.0); //specialRange = scale_range(get_config_float("Special", "Range", 0)); //specialVelocity = scale_velocity(get_config_float("Special", "Velocity", 0)); //specialDamage = get_config_int("Special", "Damage", 0); //specialArmour = get_config_int("Special", "Armour", 0); extraVelocity = scale_velocity(get_config_float("Extra", "Velocity", 0)); // extraDrain = get_config_float("Extra", "Drain", 0) / 1000.0; extraExitVelocityFactor = get_config_float("Extra", "ExitVelocityFactor", 1.0); // extraCriticalAngle = get_config_float("Extra", "CriticalAngle", 60)*PI/180; // extraCriticalRange = get_config_float("Extra", "CriticalRange", 0); extraFrameTime = get_config_int("Extra", "FrameTime", 50); weapon_side = tw_random(3); weapon_angle = tw_random(6); in_jump = false; //ship_recharge_amount = recharge_amount; //exit_countdown = 0; // holding_spec = false; just_exited = false; prevent_more_special = true; jumptime = 0; max_jumptime = get_config_int("Extra", "JumpTime", 1000); SlidingEntry = get_config_int("Extra", "SlidingEntry", 0); jumpvector = 0; } int TauHunterPPI::activate_weapon() { STACKTRACE #define R1 27.5 #define R2 5.0 if (in_jump) return false; double wx, wy = 10; double a, b, c; int i, k; for ( k=0; k<3; k++ ) { for ( i=0; i<weaponNumber; i++ ) { wx = R1 * cos((angle + weapon_side*PI2/3)) + -R2 * sin((weapon_angle + i) * PI/3); a = (1 - (random(2.0))/100.0); b = (1 - 0.1*(random(2.0))/100.0); c = (1 - 0.1*(random(2.0))/100.0); SpaceLocation* s = new TauHunterPPILaser(wx, wy, angle + weaponSpread * a, weaponVelocity * c, weaponRange * (1 - 0.2*fabs(a)) * b, weaponLength, this, weaponRelativity, weaponDamage); add(s); if ( sin((angle + weapon_side*PI2/3)) < 0) s->set_depth(get_depth() + 1); else s->set_depth(get_depth() - 1); } weapon_side += 1; if ( weapon_side == 3 ) { weapon_side = 0; weapon_angle += weaponNumber; if ( weapon_angle >= 6 ) weapon_angle -= 6; } if (weaponAlternating) break; } return true; } void TauHunterPPI::calculate_fire_special() { STACKTRACE; special_low = false; if (!fire_special) { prevent_more_special = false; return; } // check timer if(special_recharge > 0) return; if (prevent_more_special) return; if (in_jump) return; if ( batt < special_drain ) { special_low = true; return; } prevent_more_special = true; batt -= special_drain; special_recharge += special_rate; // reset timer //special_recharge += special_rate; // SpaceLocation *s = new TauHunterPPIShot(0, 16, angle, specialVelocity, specialDamage, specialRange, specialArmour, this, // data->spriteWeapon, data->spriteWeaponExplosion, data->spriteSpecial, extraFrameTime); // add(s); add(new Animation(this, pos, data->spriteSpecial, 0, data->spriteSpecial->frames(), extraFrameTime, DEPTH_SPECIAL)); play_sound2(data->sampleSpecial[0]); jumptime = max_jumptime; if (SlidingEntry && vel != 0) jumpvector = unit_vector(vel); else jumpvector = unit_vector(angle); in_jump = true; } void TauHunterPPI::calculate() { STACKTRACE just_exited = false; Ship::calculate(); if ( in_jump ) { jumptime -= frame_time; // exiting the jump if (!fire_special || jumptime < 0) { jumptime = 0; in_jump = false; just_exited = true; prevent_more_special = false; //recharge_amount = 0; targets->add(this); //pos = ee; // reset the battery recharge to immediate recharge. recharge_step = 0; // reset the special-timer to a full period of waiting. special_recharge = special_rate; //pos = normalize(pos + vv * frame_time, map_size); // movement on exit of jumpspace... vel = speed_max * extraExitVelocityFactor * jumpvector;//unit_vector(angle); } else { // prevent recharge timing. recharge_step = 1000; // movement while in jump-space. Vector2 vv = extraVelocity * jumpvector; pos = normalize(pos + vv * frame_time, map_size); vel = 0; } } else if (prevent_more_special) { // prevent recharge timing if you're maintaining a shot. recharge_step = 1000; } } int TauHunterPPI::handle_damage(SpaceLocation *source, double normal, double direct) { STACKTRACE if ( in_jump ) return 0; if ( just_exited && source->isPlanet() ) normal = crew+1; return Ship::handle_damage(source, normal, direct); } int TauHunterPPI::handle_fuel_sap(SpaceLocation *source, double normal) { STACKTRACE if ( in_jump ) return 0; return Ship::handle_fuel_sap(source, normal); } double TauHunterPPI::handle_speed_loss(SpaceLocation *source, double normal) { STACKTRACE if ( in_jump ) return 0; return Ship::handle_speed_loss(source, normal); } int TauHunterPPI::canCollide(SpaceLocation *other) { STACKTRACE if ( in_jump ) return false; else return Ship::canCollide(other); } int TauHunterPPI::translate(Vector2 rel_pos) { STACKTRACE if ( !in_jump ) return Ship::translate(rel_pos); return false; } int TauHunterPPI::accelerate(SpaceLocation *source, double oangle, double vel, double omax_speed) { STACKTRACE if ( !in_jump ) return Ship::accelerate(source, oangle, vel, omax_speed); return false; } void TauHunterPPI::animate(Frame* space) { STACKTRACE if ( !in_jump ) Ship::animate(space); } double TauHunterPPI::isProtected() const { STACKTRACE if ( in_jump ) return 1.0; else return Ship::isProtected(); } double TauHunterPPI::isInvisible() const { STACKTRACE if ( in_jump ) return 1.0; else return Ship::isInvisible(); } void TauHunterPPI::calculate_hotspots() { STACKTRACE if ( !in_jump ) Ship::calculate_hotspots(); } void TauHunterPPI::calculate_turn_left() { STACKTRACE //if ( exit_countdown <= 0 ) if ( !in_jump ) Ship::calculate_turn_left(); } void TauHunterPPI::calculate_turn_right() { STACKTRACE //if ( exit_countdown <= 0 ) if ( !in_jump ) Ship::calculate_turn_right(); } RGB TauHunterPPI::battPanelColor() { RGB c = {50,50,170}; if ( in_jump ) return c; return Ship::battPanelColor(); } TauHunterPPILaser::TauHunterPPILaser (double ox, double oy, double oangle, double ov, double orange, double olength, SpaceLocation *creator, double relativity, double odamage) : SpaceLine(creator, creator->normal_pos(), oangle, olength, makecol(255,255,255)), range(orange), d(0), v(ov) { pos = normalize(pos + rotate(Vector2(-ox, oy), -PI/2+creator->get_angle())); damage_factor = odamage; vel = unit_vector(angle) + creator->get_vel() * relativity; } void TauHunterPPILaser::calculate() { STACKTRACE double r = (d) / range; double r2 = r*r; double r3 = r2*r; int g = (int)floor(225*(1 - 2*r2 + r3)); if (g < 0) g = 0; int b = (int)floor(255*(1 - 6*r2+5*r3)); if (b < 0) b = 0; color = makecol(int(235/(0.7*r+1)), g, b); SpaceLine::calculate(); d += v * frame_time; if (d > range) state = 0; } void TauHunterPPILaser::inflict_damage(SpaceObject *other) { STACKTRACE if (d >= range) return; damage_factor *= pow((1-d/range), 0.2); SpaceLine::inflict_damage(other); state = 0; } REGISTER_SHIP(TauHunterPPI) --- NEW FILE: shpsefna.cpp --- /* $Id: shpsefna.cpp,v 1.1 2006/02/20 23:05:12 geomannl Exp $ */ #include "../ship.h" #include "../frame.h" REGISTER_FILE /* A ship with a harpoon, and a short-range laser. */ class Hook; class SefyNautilus : public Ship { public: int weaponColor; double weaponRange; int weaponFrames; int weaponDamage; double TurnRateFactor, HookDamage; public: Hook *hook; double unrolltime; double specialRange, specialDelay, specialOscFreq, specialRelVelocity, specialSegLength, specialArmour, specialSprConst, specialLifeTime; SefyNautilus(Vector2 opos, double angle, ShipData *data, unsigned int code); virtual void calculate(); virtual int activate_weapon(); virtual int activate_special(); virtual int handle_damage(SpaceLocation *src, double normal, double direct=0); }; static const int maxnodes = 50; class Hook : public SpaceObject { public: double armour; struct ropenode { Vector2 pos, vel, acc; int col; double dL; } ropenode[maxnodes]; int Nnodes, hooklocked; double L, Lmax, ropestart, roll_time, exist_time, life_time, oscperiod, ejvel, ropeseglen, hookfixdist, hookfixangle, hookfixorientation, hooksize, springconst; SpaceLocation *hooktarget; double turnrate_factor; Hook(SefyNautilus *creator, Vector2 orelpos, double TurnRateFactor, double HookDamage, SpaceSprite *osprite); virtual void calculate(); virtual void inflict_damage(SpaceObject *other); virtual int handle_damage(SpaceLocation *src, double normal, double direct=0); virtual void animate ( Frame *space ); void animate_ropeseg( Frame *space, Vector2 pos1, Vector2 pos2, int ropecol ); void unroll(); }; SefyNautilus::SefyNautilus(Vector2 opos, double angle, ShipData *data, unsigned int code) : Ship(opos, angle, data, code) { weaponColor = get_config_int("Weapon", "Color", 0); weaponFrames = get_config_int("Weapon", "Frames", 0); weaponRange = scale_range(get_config_float("Weapon", "Range", 0)); weaponDamage = get_config_int("Weapon", "Damage", 0); // time for retracting 1 piece of rope, in seconds specialLifeTime = get_config_float("Special", "LifeTime", 60.0); // time for retracting 1 piece of rope, in seconds specialDelay = get_config_float("Special", "Delay", 0.5); // osc freq. of the rope when it's released specialOscFreq = get_config_float("Special", "OscFreq", 5.0); // extra velocity of the rope when release specialRelVelocity = scale_velocity(get_config_float("Special", "Velocity", 0)); // default segment length of a piece of rope (in pixels) specialSegLength = get_config_float("Special", "SegLength", 2.0); // armour of the hook specialArmour = get_config_float("Special", "Armour", 5.0); // spring constant: higher value, faster oscillations specialSprConst = get_config_float("Special", "SprConst", 250.0); TurnRateFactor = get_config_float("Special", "TurnRateFactor", 250.0); HookDamage = get_config_float("Special", "Damage", 250.0); hook = 0; unrolltime = 0; } int SefyNautilus::activate_weapon() { STACKTRACE if ( this->nextkeys & keyflag::special ) return FALSE; const int N = 2; Vector2 Laserpositions[N] = { Vector2(-10, 50), Vector2(10, 50) }; double angles[N] = { -0.1, 0.1 }; for ( int i = 0; i < N; ++i ) { game->add(new Laser(this, get_angle()+angles[i], pallete_color[weaponColor], weaponRange, weaponDamage, weaponFrames, this, Laserpositions[i], true )); // synching=true } return TRUE; } int SefyNautilus::activate_special() { STACKTRACE unrolltime += frame_time * 1E-3; if ( hook && hook->exists() ) { if ( !(hook->hooktarget && hook->hooktarget->exists()) ) { // the hook hasn't attached yet - cancel this shot. hook->state = 0; return FALSE; } if (unrolltime > specialDelay) { hook->unroll(); //hook->hooklocked = 1; // stop unrolling any further //--hook->Nnodes; unrolltime -= specialDelay; } return FALSE; } hook = new Hook(this, 100*unit_vector(angle), TurnRateFactor, HookDamage, data->spriteSpecial); game->add( hook ); return TRUE; } void SefyNautilus::calculate() { STACKTRACE Ship::calculate(); // release the hook: if ( (this->nextkeys & keyflag::special) && (this->nextkeys & keyflag::fire ) ) if ( hook && hook->exists() ) hook->state = 0; // detect when the hook disappears - reset the pointer to 0 in that case if ( !(hook && hook->exists()) ) hook = 0; } int SefyNautilus::handle_damage(SpaceLocation *src, double normal, double direct) { STACKTRACE Ship::handle_damage(src, normal, direct); return iround(normal + direct); } Hook::Hook(SefyNautilus *creator, Vector2 orelpos, double TurnRateFactor, double HookDamage, SpaceSprite *osprite) : SpaceObject(creator, creator->pos+orelpos, creator->angle, osprite) { // double specialRange, specialDelay // ; damage_factor = HookDamage; turnrate_factor = TurnRateFactor; sprite_index = get_index(angle); ejvel = creator->specialRelVelocity; // velocity of the ejected hook (0.5). vel = ship->vel + ejvel * unit_vector(ship->angle); // this is in ms armour = creator->specialArmour; Nnodes = 0; roll_time = 0; exist_time = 0; life_time = creator->specialLifeTime; oscperiod = creator->specialOscFreq; ropestart = 50.0; ropeseglen = creator->specialSegLength; // minimum pixels length of a rope segment, approx. hooktarget = 0; hooklocked = 0; springconst = creator->specialSprConst; hooksize = 9; // from center to the eye for the rope. layer = LAYER_SHOTS; set_depth(DEPTH_SHOTS); collide_flag_anyone = ALL_LAYERS; collide_flag_sameteam = ALL_LAYERS; collide_flag_sameship = ALL_LAYERS; isblockingweapons = false; } void Hook::calculate() { STACKTRACE exist_time += frame_time * 1E-3; if ( exist_time > life_time ) state = 0; // if it's completely unrolled ... if ( hooklocked && Nnodes <= 0 ) state = 0; // or if the host ship has gone if ( !(ship && ship->exists()) ) { ship = 0; state = 0; } if ( hooktarget && hooktarget->exists() ) { vel = hooktarget->vel; angle = hooktarget->angle + hookfixangle; sprite_index = get_index(angle); pos = hooktarget->pos + hookfixdist * unit_vector(hooktarget->angle + hookfixorientation); } else if (hooklocked) { state = 0; hooktarget = 0; } if ( state == 0 ) return; SpaceObject::calculate(); if ( !hooklocked) roll_time += frame_time * 1E-3; else // otherwise it keeps pumping energy into the line roll_time = 0.0; Vector2 hookendpos; hookendpos = pos - hooksize * unit_vector(angle); Vector2 ejpos; if (ship && ship->exists() ) { ejpos = ship->pos + ropestart * unit_vector(ship->angle) + 15 * sin(oscperiod*roll_time) * unit_vector(ship->angle + 0.5*PI); } else ejpos = 0; if (ship && ship->exists() && !hooklocked ) { // extend the elastic rope slowly double dL; if ( Nnodes > 0 ) dL = magnitude(min_delta(ropenode[Nnodes-1].pos, ejpos, map_size)); else dL = magnitude(min_delta(hookendpos, ejpos, map_size)); if ( dL > ropeseglen && Nnodes < maxnodes ) { ropenode[Nnodes].pos = ejpos; ropenode[Nnodes].vel = (ship->vel + ejvel * unit_vector(ship->angle)) * 1E+3; // *1E+3 because from now we do calculations in seconds instead of ms. ropenode[Nnodes].col = pallete_color[11 + (Nnodes/4) % 3]; // changes color every 4 pieces ? dL = ropeseglen; ropenode[Nnodes].dL = dL; // relaxed length of the segment between nodes i and i-1. ++ Nnodes; if ( Nnodes == maxnodes ) state = 0; // no target found ... poor thing ;) } } // calculate the nodes on the elastic rope (except the end-points, which are fixed: double k = springconst; // 250.0 int i; Vector2 D; double R; // ropenode[0].acc = ..; // ropenode[Nnodes-1].acc = ..; int Ninterpol, iinterpol; // this may be needed if values of the spring constant are high Ninterpol = 10; double dt = frame_time * 1E-3 / Ninterpol; for ( iinterpol = 0; iinterpol < Ninterpol; ++iinterpol ) { // reset forces for ( i = 0; i < Nnodes; ++i ) ropenode[i].acc = 0; // forces between rope nodes for ( i = 0; i < Nnodes; ++i ) { if ( i > 0 ) { D = min_delta(ropenode[i-1].pos - ropenode[i].pos, map_size); R = D.length(); L = ropenode[i].dL; if ( R != 0 ) ropenode[i].acc += k * (R - L) * D / R; } if ( i < Nnodes-1 ) { D = min_delta(ropenode[i+1].pos - ropenode[i].pos, map_size); R = D.length(); L = ropenode[i+1].dL; if ( R != 0 ) ropenode[i].acc += k * (R - L) * D / R; } } // attached to the hook Vector2 hookacc; hookacc = 0; if ( Nnodes > 0 ) { i = 0; D = min_delta(hookendpos - ropenode[i].pos, map_size); R = D.length(); L = ropenode[i].dL; hookacc = k * (R - L) * D / R; if ( R != 0 ) ropenode[i].acc += hookacc; } // attached to the ship, if it still exists... if ( ship && ship->exists() && Nnodes > 0 ) { i = Nnodes-1; D = min_delta(ejpos - ropenode[i].pos, map_size); R = D.length(); L = ropeseglen; // should be i+1, but that doesn't exist if ( R != 0 ) ropenode[i].acc += k * (R - L) * D / R;; } // slow down a little, for stability for ( i = 0; i < Nnodes; ++i ) ropenode[i].acc -= 10.0 * ropenode[i].vel * dt; // apply accelerations (also to the end points) for ( i = 0; i < Nnodes; ++i ) { ropenode[i].vel += ropenode[i].acc * dt; ropenode[i].pos += ropenode[i].vel * dt; } // apply acceleration to the target: if ( hooktarget && hooktarget->exists() ) { hooktarget->vel -= 0.1 * 1E-3 * hookacc * dt; // and also some deceleration ... double a = 1 - 0.1*dt; if ( a < 0 ) a = 0; if ( a > 1 ) a = 1; hooktarget->vel *= a; // influence the angle of the enemy ship: a = atan(hookendpos - hooktarget->pos); double b, da, rotacc; b = atan(hookacc); da = b - a; rotacc = magnitude(hookacc) * sin(da); hooktarget->angle -= 0.25 * 1E-3 * rotacc * dt; // angle must never exceed half PI with the end of the rope... b = atan(ropenode[0].pos - hookendpos); da = b - a; while ( da > PI ) da -= PI2; while ( da < -PI ) da += PI2; if ( da < -0.5*PI || da > 0.5*PI ) { double dacorr = fabs(da) - 0.5*PI; if ( dacorr > 5*PI2*dt ) dacorr = 5*PI2*dt; if ( da < 0.0 ) hooktarget->angle -= dacorr; else hooktarget->angle += dacorr; } // to stabilize, make sure neither vessels' speed ever exceeds the maximum: double V1, V2; if ( ship && ship->exists() ) { V1 = magnitude(ship->vel); V2 = 2 * ship->speed_max; if ( V1 > V2 ) ship->vel *= V2 / V1; } if ( hooktarget->isShip() ) { V1 = magnitude(hooktarget->vel); V2 = 2 * ((Ship*) hooktarget)->speed_max; if ( V1 > V2 ) hooktarget->vel *= V2 / V1; } } } } void Hook::inflict_damage(SpaceObject *other) { SpaceObject::inflict_damage(other); damage_factor = 0; } int Hook::handle_damage(SpaceLocation *src, double normal, double direct) { STACKTRACE if ( src == hooktarget ) return 0; if ( src->isShip() ) { if ( hooktarget ) // if it's already attached to another ship return 0; if ( src == ship ) return 0; // if it is the ship itself (doh) hooktarget = src; hookfixdist = magnitude(min_delta(pos, src->pos, map_size)); // it makes a different, where you hit the enemy. In the side is better than head-on. // where it is attacked. hookfixorientation = atan(min_delta(pos, src->pos, map_size)) - src->angle + 0.2*PI*(random(2.0)-1.0); hookfixangle = angle - src->angle; collide_flag_anyone = 0; collide_flag_sameteam = 0; collide_flag_sameship = 0; // this is done by inflict-damage... but that applies it all the time, so let's handle that here, instead. //damage(src, damage_factor, 0.0); //damage_factor = 0; // then, reset the damage to zero... hooklocked = 1; // stop unrolling any further src->ship->turn_rate *= turnrate_factor; return 0; } else { SpaceObject::handle_damage(src, normal, direct); armour -= normal + direct; if ( armour <= 0 ) state = 0; return iround(normal + direct); } } void Hook::animate_ropeseg( Frame *space, Vector2 pos1, Vector2 pos2, int ropecol ) { STACKTRACE int ix1, iy1, ix2, iy2; Vector2 co; co = corner(pos1); ix1 = int(co.x); iy1 = int(co.y); co = corner(pos2); ix2 = int(co.x); iy2 = int(co.y); int dx, dy; dx = iround(min_delta(ix2, ix1, map_size.x)); dy = iround(min_delta(iy2, iy1, map_size.y)); ix2 = ix1 + dx; iy2 = iy1 + dy; // simulate visibility of a glittering line in the sun ... double a, colscale; a = atan2((double)dy,(double)dx); colscale = fabs(sin(a)); // flat lying = less visible. int col, r, g, b; col = ropecol; r = iround(getr(col) * colscale); g = iround(getg(col) * colscale); b = iround(getb(col) * colscale); col = makecol(r, g, b); // draw the line line(space->surface, ix1, iy1, ix2, iy2, col); space->add_line(ix1, iy1, ix2, iy2); } void Hook::animate ( Frame *space ) { STACKTRACE SpaceObject::animate(space); // also, animate the rope, these are points in space int i; for ( i = 0; i < Nnodes-1; ++i ) { animate_ropeseg(space, ropenode[i].pos, ropenode[i+1].pos, ropenode[i+1].col); } // extra part, leading to the end of the hook: Vector2 hookendpos; hookendpos = pos - hooksize * unit_vector(angle); i = 0; animate_ropeseg(space, hookendpos, ropenode[i].pos, ropenode[i].col); } void Hook::unroll() { hooklocked = 1; if ( Nnodes > 1 ) --Nnodes; // if ( Nnodes == 0 ) // return; /* Vector2 pos1old = ropenode[0].pos; Vector2 pos2old = ropenode[Nnodes].pos; Vector2 pos1new = pos1old; Vector2 pos2new = ropenode[Nnodes-1].pos; // spread the disappeared distance a little: int i; for ( i = Nnodes-1; i >= 0; --i ) { ropenode[i] = ropenode[i-1]; } */ } REGISTER_SHIP ( SefyNautilus ) |