void AndrosynthBubble::calculate() { STACKTRACE; if (!(ship && ship->exists())) { state = 0; return; } double newAngle; AnimatedShot::calculate(); courseFrames += frame_time; if (courseFrames >= 150) { courseFrames -= 150; newAngle = random(PI2); vel = v * unit_vector(newAngle); int i; double r = 99999; newAngle = 99999; // ship->control->ship == 0 (can happen ?!) // ... yeah ... look at control->select_ship. There you can see // that control->ship=0 if the ship does not exist. Perhaps there's // a de-synch between the two calculations (!exists() lags the control->ship) ? if (ship && ship->exists() && ship->control && ship->control->ship) { for (i = 0; i < targets->N; i += 1) { SpaceObject *s = targets->item[i]; if (ship->control->valid_target(s) && (distance(s) < r) && !s->isInvisible()) { r = distance(s); newAngle = trajectory_angle(s); } } } else { for (i = 0; i < targets->N; i += 1) { SpaceObject *s = targets->item[i]; if (s->sameTeam(this) && (distance(s) < r) && !s->isInvisible()) { r = distance(s); newAngle = trajectory_angle(s); } } } if (newAngle < PI * 4) { vel += unit_vector(newAngle) * v / 2; } } return; }
int EarthlingCruiserMk3::activate_special() { STACKTRACE; bool fire = false;; SpaceObject *o; double rng = 1e40; SpaceObject *tgt = NULL; //!!! pos -= unit_vector(angle) * 6; Query q; for (q.begin(this, bit(LAYER_SHIPS) + bit(LAYER_SHOTS) + bit(LAYER_SPECIAL) + bit(LAYER_CBODIES), specialRange); q.current; q.next()) { o = q.currento; if (!o->isInvisible() && !o->sameTeam(this) && (o->collide_flag_anyone&bit(LAYER_LINES)) && (distance(o) < rng)) { tgt = o; rng = distance(o); } } q.end(); //!!! pos += unit_vector(angle) * 6; if (tgt) { game->add(new EarthlingCruiserMk3Beam(this, Vector2(0,-6), specialRange, specialDamage, specialDamageShots, specialFrames, tgt)); play_sound(data->sampleSpecial[0]); fire = true; } return(fire); }
int EarthlingCruiser2::activate_special() { STACKTRACE; int fire = FALSE; SpaceObject *o; Query q; for (q.begin(this, bit(LAYER_SHIPS) + bit(LAYER_SHOTS) + bit(LAYER_SPECIAL) + bit(LAYER_CBODIES), specialRange); q.current; q.next()) { o = q.currento; if (!o->isInvisible() && !o->sameTeam(this) && (o->collide_flag_anyone&bit(LAYER_LINES))) { SpaceLocation *l = new PointLaser(this, pallete_color[specialColor], 1, specialFrames, this, o, Vector2(0.0,0.0)); add(l); if (l->exists()) { fire = TRUE; l->set_depth(LAYER_EXPLOSIONS); } } } q.end(); if (fire) sound.play((SAMPLE *)(melee[MELEE_BOOM + 0].dat)); return(fire); }
int VelronCruiser::fire_def_shot(double lowAngle, double highAngle, double defaultAngle) { STACKTRACE; SpaceObject *o; double distance2, bestDistance2 = 99999999; double angleShift, relativeAngle; double firingAngle = defaultAngle; angleShift = ((double)(random()%2001-1000)/1000.0) * specialLaunchAngleDeflectionRange; Query a; for (a.begin(this, OBJECT_LAYERS, specialRange); a.current; a.next()) { o = a.currento; if ( (!o->isInvisible()) && !o->sameTeam(this) && (o->collide_flag_anyone & bit(LAYER_SHOTS))) { distance2 = distance(o); relativeAngle = get_aim(o, lowAngle, highAngle); if ((distance2 < bestDistance2) && (relativeAngle > -1000)) { bestDistance2 = distance2; firingAngle = relativeAngle; } } } add(new VelronCrDefShot(this, 0.0, 0.0, normalize(angle + firingAngle + angleShift, PI2), specialVelocity, specialDamage, specialRange, specialArmour, data->spriteSpecial, specialRelativity)); return(TRUE); }
void EarthlingCruiserMk3Beam::calculate() { STACKTRACE; if (!(lpos && lpos->exists())) { lpos = 0; state = 0; } if ((frame < frame_count) && (lpos && lpos->exists())) { pos = lpos->normal_pos() + rotate(rel_pos, lpos->get_angle() - PI/2); vel = lpos->get_vel(); SpaceLine::calculate(); frame += frame_time; } else state = 0; if ((!target) && (switch_counter <= 0)) { SpaceObject *o; double rng = 1e40; SpaceObject *tgt = NULL; Query a; for (a.begin(this, bit(LAYER_SHIPS) + bit(LAYER_SHOTS) + bit(LAYER_SPECIAL) + bit(LAYER_CBODIES), base_length); a.current; a.next()) { o = a.currento; if (!o->isInvisible() && !o->sameTeam(this) && (o->collide_flag_anyone&bit(LAYER_LINES)) && (distance(o) < rng)) { tgt = o; rng = distance(o); } } if (tgt) { target = tgt; // switch_counter = 55; got_spark = false; } } if (target && (distance(target) <= base_length)) { length = base_length; if (target->exists() && canCollide(target) && target->canCollide(this)) { angle = trajectory_angle(target); } if (!target->exists()) target = NULL; } else { target = NULL; if (switch_counter <= 0) // die(); length = 0; else switch_counter -= frame_time; } color = tw_makecol(100+tw_random()%105,100+tw_random()%105,255); }
void EarthlingCruiserMk3::calculate() { STACKTRACE; Ship::calculate(); double track_angle = 0; double track_min = PI2; double d_a; SpaceObject *tgt = 0; //!!! pos += unit_vector(angle) * 28; int i; for (i=0; i < targets->N; i++) { tgt = targets->item[i]; if ((tgt != this) && (!tgt->sameShip(this)) && (!tgt->sameTeam(this)) && (!tgt->isInvisible()) && (distance(tgt) <= 1.2*(weaponRange + abs(vel)*game->shot_relativity))) { d_a = trajectory_angle(tgt); double s = unit_vector(d_a + PI/2).dot(tgt->get_vel() - vel * game->shot_relativity) / weaponVelocity; if (fabs(s) > 0.99) track_angle = 0; else { s = atan(s/sqrt(1-s*s)); s = normalize(s + d_a - angle - turn_step, PI2); if (s > PI) s -= PI2; if (fabs(s) <= weaponTrackingAngle) { d_a = s - launch_angle; if (tgt == target) { track_angle = s; break; } if (fabs(d_a) < track_min) { track_angle = s; track_min = fabs(d_a); } } } } } //!!! pos -= unit_vector(angle) * 28; d_a = track_angle - launch_angle; double ta = weaponTrackingRate * frame_time; if (fabs(d_a) < ta) ta = fabs(d_a); if (d_a > 0) launch_angle += ta; else launch_angle -= ta; }
void SpaceStation::calculate() { STACKTRACE; //Healing beam code Query a; SpaceObject *o; for (a.begin(this, bit(LAYER_SHIPS), 200.); a.current; a.next()) { o = a.currento; if (!o->isInvisible()) { game->add(new PointLaser(this, 0x0000ffff, -1, 10, this, o, Vector2(0.0, 10.0))); } } }
void AutoGun::calculate() { STACKTRACE; BigShipPartDevice::calculate(); if (!(ownerpart && !ownerpart->isdisabled())) return; // find the closest target Query a; SpaceObject *oclosest; double R; oclosest = 0; R = 1E99; double da_track; da_track = -a_track; // forces to go back into default position for (a.begin(this, OBJECT_LAYERS, 0.75*shotrange); a.current != 0; a.next()) { SpaceObject *o; o = a.currento; if (!o->isObject()) continue; if (o->sameShip(this) || o->sameTeam(this)) continue; if (o->isPlanet()) continue; if (o->isInvisible()) continue; double L = 0; L = distance(o); if (!oclosest || L < R) { // this is a possible candidate but, is it also within the view angle ? double a, b, da; a = trajectory_angle(o); // check relative to the gun's neutral position b = ownerpart->get_angle() + a_center; da = a - b; while (da < -PI) da += PI2; while (da > PI) da -= PI2; if (da > -a_view && da < a_view) { // okay! it's close, within dist-range, and it's within angle-range oclosest = o; R = L; // required movement is relative to the gun's current position // note that at this moment, you cannot use the value of "angle" // which is overridden by the call to AyronShipPart::calculate; so, // use "b" instead. b += a_track; da_track = a - b; while (da_track < -PI) da_track += PI2; while (da_track > PI) da_track -= PI2; } } } // track the target (or go back to neutral position) // max tracking speed per second (0.1 circles / second). // this tracking angle is relative to the neutral angle of the gun. double da; da = 100 * PI2 * frame_time * 1E-3; if (da_track > da) da_track = da; if (da_track < -da) da_track = -da; a_track += da_track; if (a_track < -a_view) a_track = -a_view; if (a_track > a_view) a_track = a_view; // absolute angle of the gun angle = ownerpart->get_angle() + a_center + a_track; sprite_index = get_index(angle); // fire the weapon ? if (oclosest && ownerpart->ship && ownerpart->ship->batt > shotdrain && !shotbusy) { Shot *s; s = new Shot(this, Vector2(0,0), angle, shotvel, shotdamage, shotrange, shotarmour, this, sprshot, 0); s->set_depth(DEPTH_SHIPS + 0.1); game->add( s ); shotbusy = shotperiod; ownerpart->ship->handle_fuel_sap(this, shotdrain); } if (shotbusy > 0) shotbusy -= frame_time * 1E-3; else shotbusy = 0; }