Example #1
0
/*
 * Given a 'brush' that's pushing things out of the way (possibly already
 * cut down to just the part relevant to our line) and a line that
 * intersects it on some layer, find the 45/90 lines required to go around
 * the brush on the named side.  Create them and remove the original.
 */
static int
MakeBypassingLines(POLYAREA *brush, LayerType *layer, LineType *line, int side, POLYAREA **expandp)
{
	Vector pA, pB, flatA, flatB, qA, qB;
	Vector lA, lB;
	Vector a, b, c, d, junk;
	int hits;

	SET_FLAG(DRCFLAG, line);	/* will cause sublines to inherit */
	lA[0] = line->Point1.X;
	lA[1] = line->Point1.Y;
	lB[0] = line->Point2.X;
	lB[1] = line->Point2.Y;

	/*
	 * Imagine side = north:
	 *
	 *                 /      \
	 *            ----b##FLAT##c----
	 *               Q          P
	 *   lA-ORIG####a            d####ORIG-lB
	 *             /              \
	 *
	 * First find the extended three lines that go around the brush.
	 * Then intersect them with each other and the original to find
	 * points a, b, c, d.  Finally connect the dots and remove the
	 * old straight line.
	 */
	POLYAREA_findXmostLine(brush, side, flatA, flatB, line->Thickness / 2);
	POLYAREA_findXmostLine(brush, rotateSide(side, 1), pA, pB, line->Thickness / 2);
	POLYAREA_findXmostLine(brush, rotateSide(side, -1), qA, qB, line->Thickness / 2);
	hits = vect_inters2(lA, lB, qA, qB, a, junk) + 
	       vect_inters2(qA, qB, flatA, flatB, b, junk) +
	       vect_inters2(pA, pB, flatA, flatB, c, junk) +
	       vect_inters2(lA, lB, pA, pB, d, junk);
	if (hits != 4) {
		return 0;
	}
	/* flip the line endpoints to match up with a/b */
	if (vect_dist2(lA, d) < vect_dist2(lA, a)) {
		Vswp2(lA, lB);
	}
	MakeBypassLine(layer, lA, a, line, NULL);
	MakeBypassLine(layer, a, b, line, expandp);
	MakeBypassLine(layer, b, c, line, expandp);
	MakeBypassLine(layer, c, d, line, expandp);
	MakeBypassLine(layer, d, lB, line, NULL);
	RemoveLine(layer, line);
	return 1;
}
Example #2
0
/**
 * @brief Check to see if a planet is in sensor range of the pilot.
 *
 *    @param p Pilot who is trying to check to see if the planet is in sensor range.
 *    @param target Planet to see if is in sensor range.
 *    @return 1 if they are in range, 0 if they aren't.
 */
int pilot_inRangePlanet( const Pilot *p, int target )
{
   double d;
   Planet *pnt;
   double sense;

   /* pilot must exist */
   if ( p == NULL )
      return 0;

   /* Get the planet. */
   pnt = cur_system->planets[target];

   /* target must not be virtual */
   if ( !pnt->real )
      return 0;

   /* @TODO ew_detect should be squared upon being set. */
   sense = sensor_curRange * pow2(p->ew_detect);

   /* Get distance. */
   d = vect_dist2( &p->solid->pos, &pnt->pos );

   if (d * pnt->hide < sense )
      return 1;

   return 0;
}
Example #3
0
/**
 * @brief Check to see if a jump point is in sensor range of the pilot.
 *
 *    @param p Pilot who is trying to check to see if the jump point is in sensor range.
 *    @param target Jump point to see if is in sensor range.
 *    @return 1 if they are in range, 0 if they aren't.
 */
int pilot_inRangeJump( const Pilot *p, int i )
{
   double d;
   JumpPoint *jp;
   double sense;
   double hide;

   /* pilot must exist */
   if ( p == NULL )
      return 0;

   /* Get the jump point. */
   jp = &cur_system->jumps[i];

   /* We don't want exit-only or unknown hidden jumps. */
   if ((jp_isFlag(jp, JP_EXITONLY)) || ((jp_isFlag(jp, JP_HIDDEN)) && (!jp_isKnown(jp)) ))
      return 0;

   sense = sensor_curRange * p->ew_jumpDetect;
   hide = jp->hide;

   /* Get distance. */
   d = vect_dist2( &p->solid->pos, &jp->pos );

   if (d * hide < sense)
      return 1;

   return 0;
}
Example #4
0
/**
 * @brief Check to see if a jump point is in sensor range of the pilot.
 *
 *    @param p Pilot who is trying to check to see if the jump point is in sensor range.
 *    @param target Jump point to see if is in sensor range.
 *    @return 1 if they are in range, 0 if they aren't.
 */
int pilot_inRangeJump( const Pilot *p, int i )
{
    double d;
    JumpPoint *jp;
    double sense;
    double hide;

    /* pilot must exist */
    if ( p == NULL )
        return 0;

    /* Get the jump point. */
    jp = &cur_system->jumps[i];

    /* We don't want exit-only jumps. */
    if (jp_isFlag(jp, JP_EXITONLY))
        return 0;

    /* Handle hidden jumps separately, as they use a special range parameter. */
    if (jp_isFlag(jp, JP_HIDDEN))
        sense = pow(p->stats.misc_hidden_jump_detect, 2);
    else
        sense = sensor_curRange * p->ew_jump_detect;

    hide = jp->hide;

    /* Get distance. */
    d = vect_dist2( &p->solid->pos, &jp->pos );

    if (d * hide < sense)
        return 1;

    return 0;
}
Example #5
0
/**
 * @brief Check to see if a planet is in sensor range of the pilot.
 *
 *    @param p Pilot who is trying to check to see if the planet is in sensor range.
 *    @param target Planet to see if is in sensor range.
 *    @return 1 if they are in range, 0 if they aren't.
 */
int pilot_inRangePlanet( const Pilot *p, int target )
{
   (void)p;
   (void)target;

   /* Always consider planets in range. */
   return 1;

#if 0
   double d;
   Planet *pnt;

   if (cur_system->interference == 0.)
      return 1;

   /* Get the planet. */
   pnt = cur_system->planets[target];

   /* Get distance. */
   d = vect_dist2( &p->solid->pos, &pnt->pos );

   if (d < sensor_curRange)
      return 1;

   return 0;
#endif
}
Example #6
0
/**
 * @brief Check to see if a pilot is in sensor range of another.
 *
 *    @param p Pilot who is trying to check to see if other is in sensor range.
 *    @param target Target of p to check to see if is in sensor range.
 *    @return 1 if they are in range, 0 if they aren't and -1 if they are detected fuzzily.
 */
int pilot_inRangePilot( const Pilot *p, const Pilot *target )
{
   double d, sense;

   /* Special case player or omni-visible. */
   if ((pilot_isPlayer(p) && pilot_isFlag(target, PILOT_VISPLAYER)) ||
         pilot_isFlag(target, PILOT_VISIBLE))
      return 1;

   /* Get distance. */
   d = vect_dist2( &p->solid->pos, &target->solid->pos );

   sense = sensor_curRange * p->ew_detect;
   if (d * target->ew_evasion < sense)
      return 1;
   else if  (d * target->ew_hide < sense)
      return -1;

   return 0;
}
Example #7
0
/**
 * @brief Handles the autonav braking.
 *
 *    @return 1 on completion.
 */
static int player_autonavBrake (void)
{
   int ret;
   JumpPoint *jp;
   Vector2d pos;

   if ((player.autonav == AUTONAV_JUMP_BRAKE) && (player.p->nav_hyperspace != -1)) {
      jp  = &cur_system->jumps[ player.p->nav_hyperspace ];

      pilot_brakeDist( player.p, &pos );
      if (vect_dist2( &pos, &jp->pos ) > pow2(jp->radius))
         ret = pilot_interceptPos( player.p, jp->pos.x, jp->pos.y );
      else
         ret = pilot_brake( player.p );
   }
   else
      ret = pilot_brake(player.p);

   player_acc = player.p->solid->thrust / player.p->thrust;

   return ret;
}
Example #8
0
/**
 * @brief Gets the squared distance from the Vec2 (saves a sqrt())
 *
 * @usage my_vec:dist2() -- Gets squared length of the vector (distance squared from origin).
 * @usage my_vec:dist2( your_vec ) -- Gets squared distance from both vectors (your_vec - my_vec)^2.
 *
 *    @luaparam v Vector to act as origin.
 *    @luaparam v2 Vector to get squared distance from, uses origin (0,0) if not set.
 *    @luareturn The distance calculated.
 * @luafunc dist2( v, v2 )
 */
static int vectorL_distance2( lua_State *L )
{
    LuaVector *v1, *v2;
    double dist2;

    /* Get self. */
    v1 = luaL_checkvector(L,1);

    /* Get rest of parameters. */
    v2 = NULL;
    if (lua_gettop(L) > 1) {
        v2 = luaL_checkvector(L,2);
    }

    /* Get distance. */
    if (v2 == NULL)
        dist2 = vect_odist2(&v1->vec);
    else
        dist2 = vect_dist2(&v1->vec, &v2->vec);

    /* Return the distance. */
    lua_pushnumber(L, dist2);
    return 1;
}
Example #9
0
/**
 * @brief Fires a weapon set.
 *
 *    @param p Pilot firing weaponsets.
 *    @param ws Weapon set to fire.
 *    @param level Level of the firing weapon set.
 */
static int pilot_weapSetFire( Pilot *p, PilotWeaponSet *ws, int level )
{
   int i, j, ret, s;
   Pilot *pt;
   double dist2;
   Outfit *o;

   /* Case no outfits. */
   if (ws->slots == NULL)
      return 0;

   /* If inrange is set we only fire at targets in range. */
   dist2 = INFINITY; /* With no target we just set distance to infinity. */

   if (ws->inrange) {
      if (p->target != p->id) {
         pt = pilot_get( p->target );
         if (pt != NULL)
            dist2 = vect_dist2( &p->solid->pos, &pt->solid->pos );
      }
   }

   /* Fire. */
   ret    = 0;
   for (i=0; i<array_size(ws->slots); i++) {
      o = ws->slots[i].slot->outfit;

      /* Ignore NULL outfits. */
      if (o == NULL)
         continue;

      /* Only "active" outfits. */
      if ((level != -1) && (ws->slots[i].level != level))
         continue;

      /* Only run once for each weapon type in the group. */
      s = 0;
      for (j=0; j<i; j++) {
         /* Only active outfits. */
         if ((level != -1) && (ws->slots[j].level != level))
            continue;
         /* Found a match. */
         if (ws->slots[j].slot->outfit == o) {
            s = 1;
            break;
         }
      }
      if (s!=0)
         continue;

      /* Only "locked on" outfits. */
      if (outfit_isSeeker(o) &&
            (ws->slots[i].slot->u.ammo.lockon_timer > 0.))
         continue;

      /* Only "inrange" outfits. */
      if (!outfit_isFighterBay(o) &&
            (ws->inrange && (dist2 > ws->slots[i].range2)))
         continue;

      /* Shoot the weapon of the weaponset. */
      ret += pilot_shootWeaponSetOutfit( p, ws, o, level );
   }

   return ret;
}
Example #10
0
/**
 * @brief Handles a click event.
 */
static void input_clickevent( SDL_Event* event )
{
   unsigned int pid;
   Pilot *p;
   int mx, my, mxr, myr, pntid, jpid;
   int rx, ry, rh, rw, res;
   double x, y, m, r, rp, d, dp, px, py;
   double ang, angp, mouseang;
   Planet *pnt;
   JumpPoint *jp;
   HookParam hparam[2];

   /* Generate hook. */
   hparam[0].type    = HOOK_PARAM_NUMBER;
   hparam[0].u.num   = event->button.button;
   hparam[1].type    = HOOK_PARAM_SENTINEL;
   hooks_runParam( "mouse", hparam );

   /* Handle zoom. */
   if (event->button.button == SDL_BUTTON_WHEELUP) {
      input_clickZoom( 1.1 );
      return;
   }
   else if (event->button.button == SDL_BUTTON_WHEELDOWN) {
      input_clickZoom( 0.9 );
      return;
   }

   /* Middle mouse enables mouse flying. */
   if (event->button.button == SDL_BUTTON_MIDDLE) {
      player_toggleMouseFly();
      return;
   }

   /* Mouse targeting is left only. */
   if (event->button.button != SDL_BUTTON_LEFT)
      return;

   /* Player must not be NULL. */
   if (player_isFlag(PLAYER_DESTROYED) || (player.p == NULL))
      return;

   px = player.p->solid->pos.x;
   py = player.p->solid->pos.y;
   gl_windowToScreenPos( &mx, &my, event->button.x, event->button.y );
   gl_screenToGameCoords( &x, &y, (double)mx, (double)my );
   if ((mx <= 15 || my <= 15 ) || (my >= gl_screen.h - 15 || mx >= gl_screen.w - 15)) { /* Border */
      x = (mx - (gl_screen.w / 2.)) + px;
      y = (my - (gl_screen.h / 2.)) + py;
      mouseang = atan2(py - y, px -  x);
      angp = pilot_getNearestAng( player.p, &pid, mouseang, 1 );
      ang  = system_getClosestAng( cur_system, &pntid, &jpid, x, y, mouseang );

      if  ((ABS(angle_diff(mouseang, angp)) > M_PI / 64) ||
            ABS(angle_diff(mouseang, ang)) < ABS(angle_diff(mouseang, angp)))
         pid = PLAYER_ID; /* Pilot angle is too great, or planet/jump is closer. */
      if  (ABS(angle_diff(mouseang, ang)) > M_PI / 64 )
         jpid = pntid = -1; /* Asset angle difference is too great. */
   }
   else { /* Radar targeting requires raw coordinates. */
      mxr = event->button.x;
      myr  = gl_screen.rh - event->button.y;
      gui_radarGetPos( &rx, &ry );
      gui_radarGetDim( &rw, &rh );
      if ((mxr > rx && mxr <= rx + rw ) && (myr > ry && myr <= ry + rh )) { /* Radar */
         m = 1;
         gui_radarGetRes( &res );
         x = (mxr - (rx + rw / 2.)) * res + px;
         y = (myr - (ry + rh / 2.)) * res + py;
      }
      else /* Visual (on-screen) */
         m = res = 1. / cam_getZoom();
      dp = pilot_getNearestPos( player.p, &pid, x, y, 1 );
      d  = system_getClosest( cur_system, &pntid, &jpid, x, y );
      rp = MAX( 1.5 * PILOT_SIZE_APROX * pilot_get(pid)->ship->gfx_space->sw / 2 * m,  10. * res);

      if (pntid >=0) { /* Planet is closer. */
         pnt = cur_system->planets[ pntid ];
         r  = MAX( 1.5 * pnt->radius, 100. );
      }
      else if (jpid >= 0) {
         jp = &cur_system->jumps[ jpid ];
         r  = MAX( 1.5 * jp->radius, 100. );
      }
      else {
         r  = 0.;
      }
      /* Reject pilot if it's too far or a valid asset is closer. */
      if (dp > pow2(rp) || (d < pow2(r) && dp < pow2(rp) && dp >  d))
         pid = PLAYER_ID;
      if (d > pow2(r)) /* Planet or jump point is too far. */
         jpid = pntid = -1;
   }

   if (pid != PLAYER_ID) {
      /* Apply an action if already selected. */
      if (!pilot_isFlag(player.p, PILOT_DEAD) && (pid == player.p->target)) {
         p = pilot_get(pid);
         if (pilot_isDisabled(p) || pilot_isFlag(p, PILOT_BOARDABLE))
            player_board();
         else
            player_hail();
      }
      else
         player_targetSet( pid );
   }
   else if (pntid >= 0) { /* Planet is closest. */
      if (pntid == player.p->nav_planet) {
         pnt = cur_system->planets[ pntid ];
         player_hyperspacePreempt(0);
         if (planet_hasService(pnt, PLANET_SERVICE_LAND)) {
            if ((pnt->faction >= 0) && (areEnemies( player.p->faction, pnt->faction ) && !pnt->bribed))
               player_hailPlanet();
            else if (vect_dist2(&player.p->solid->pos,&pnt->pos) > pow2(pnt->radius))
               player_autonavStart();
            else
               player_land();
         }
         else
            player_autonavStart();
      }
      else
         player_targetPlanetSet( pntid );
   }
   else if (jpid >= 0) { /* Jump point is closest. */
      if (jpid == player.p->nav_hyperspace) {
         if (space_canHyperspace(player.p))
            player_jump();
         else {
            player_hyperspacePreempt(1);
            player_autonavStart();
         }
      }
      else
         player_targetHyperspaceSet( jpid );
   }
}