Exemplo n.º 1
0
int main() {
	{
		TimeCheck time;

		auto surface = create_surface(CAIRO_FORMAT_ARGB32, SURFACE_SIZE{ 256, 256 });
		auto cr = create(surface);

		arc(cr, POINT{ 128.0, 128.0 }, 76.8, DEGRESS{ 0 }, DEGRESS{ 360 });
		clip(cr);

		new_path(cr);  /* current path is not  consumed by cairo_clip() */
		rectangle(cr, POINT{ 0, 0 }, SIZE{ 255, 255 });
		fill(cr);
		
		source(cr, RGB{ 0, 1, 0 });
		move_to(cr, POINT{ 0, 0 });
		line_to(cr, POINT{ 256, 256 });
		move_to(cr, POINT{ 256, 0 });
		line_to(cr, POINT{ 0, 256 });
		line_width(cr, 10.0);
		stroke(cr);
		
		write_to_png(surface, "image.png");
	}
	return 0;
}
Exemplo n.º 2
0
void
PathParser::append(const UnivocalPath& append_path)
{
  const std::vector<Edge>& edges = append_path._path->m_edges;

  if (append_path._fill_type == UnivocalPath::FILL_LEFT) {

    std::for_each(edges.begin(), edges.end(), boost::bind(&PathParser::line_to,
                                                          this, _1));
  } else {

    for (std::vector<Edge>::const_reverse_iterator prev = edges.rbegin(),
         it = boost::next(prev), end = edges.rend(); it != end; ++it, ++prev) {
      if ((*prev).straight()) {
        lineTo((*it).ap);
      } else {
        line_to(Edge((*prev).cp, (*it).ap));
      }
    }

    line_to(Edge(edges.front().cp, append_path.endPoint()));
  }
    
  _cur_endpoint = append_path.endPoint();
}
Exemplo n.º 3
0
void mdeath::focused_beam(monster *z)
{

    for (int k = g->m.i_at(z->posx(), z->posy()).size() - 1; k >= 0; k--) {
        if (g->m.i_at(z->posx(), z->posy())[k].type->id == "processor") {
            g->m.i_rem(z->posx(), z->posy(), k);
        }
    }

    if (z->inv.size() > 0) {

        if (g->u_see(z)) {
            add_msg(m_warning, _("As the final light is destroyed, it erupts in a blinding flare!"));
        }

        item &settings = z->inv[0];

        int x = z->posx() + atoi(settings.item_vars["SL_SPOT_X"].c_str());
        int y = z->posy() + atoi(settings.item_vars["SL_SPOT_Y"].c_str());

        std::vector <point> traj = line_to(z->posx(), z->posy(), x, y, 0);
        for( auto &elem : traj ) {
            if( !g->m.trans( elem.x, elem.y ) ) {
                break;
            }
            g->m.add_field( elem.x, elem.y, fd_dazzling, 2 );
        }
    }

    z->inv.clear();

    g->explosion(z->posx(), z->posy(), 8, 0, false);
}
Exemplo n.º 4
0
void mdeath::focused_beam(monster *z)
{

    for (int k = g->m.i_at(z->pos()).size() - 1; k >= 0; k--) {
        if (g->m.i_at(z->pos())[k].type->id == "processor") {
            g->m.i_rem(z->pos(), k);
        }
    }

    if (z->inv.size() > 0) {

        if (g->u.sees(*z)) {
            add_msg(m_warning, _("As the final light is destroyed, it erupts in a blinding flare!"));
        }

        item &settings = z->inv[0];

        int x = z->posx() + settings.get_var( "SL_SPOT_X", 0 );
        int y = z->posy() + settings.get_var( "SL_SPOT_Y", 0 );
        tripoint p( x, y, z->posz() );

        std::vector <tripoint> traj = line_to(z->pos(), p, 0, 0);
        for( auto &elem : traj ) {
            if( !g->m.trans( elem ) ) {
                break;
            }
            g->m.add_field( elem, fd_dazzling, 2, 0 );
        }
    }

    z->inv.clear();

    g->explosion(z->pos3(), 8, 0, false);
}
Exemplo n.º 5
0
/*
 * Function PlotPoly
 * writes a filled or not filled polyline to output file
 * @param aCornerList = buffer of corners coordinates
 * @param aFill = plot option (NO_FILL, FILLED_SHAPE, FILLED_WITH_BG_BODYCOLOR)
 * @param aWidth = Width of the line to plot.
 */
void GERBER_PLOTTER::PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth )
{
    if( aCornerList.size() <= 1 )
        return;

    set_current_line_width( aWidth );

    if( aFill )
        fputs( "G36*\n", output_file );

    move_to( aCornerList[0] );

    for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
    {
        line_to( aCornerList[ii] );
    }

    if( aFill )
    {
        finish_to( aCornerList[0] );
        fputs( "G37*\n", output_file );
    }
    else
    {
        pen_finish();
    }
}
Exemplo n.º 6
0
void MWcanvas16::curve_to(
    Coord x,
    Coord y,
    Coord x1,
    Coord y1,
    Coord x2,
    Coord y2)
{
    PathRenderInfo* p = &MWcanvas16::path_;
    Coord px = p->curx_;
    Coord py = p->cury_;

    if (straight(matrix(), px, py, x1, y1, x2, y2, x, y))
    {
        line_to(x, y);
    }
    else
    {
        Coord xx = mid(x1, x2);
        Coord yy = mid(y1, y2);
        Coord x11 = mid(px, x1);
        Coord y11 = mid(py, y1);
        Coord x22 = mid(x2, x);
        Coord y22 = mid(y2, y);
        Coord x12 = mid(x11, xx);
        Coord y12 = mid(y11, yy);
        Coord x21 = mid(xx, x22);
        Coord y21 = mid(yy, y22);
        Coord cx = mid(x12, x21);
        Coord cy = mid(y12, y21);

        curve_to(cx, cy, x11, y11, x12, y12);
        curve_to(x, y, x21, y21, x22, y22);
    }
}
Exemplo n.º 7
0
static cairo_status_t
close_path (void *closure)
{
    struct stroker *stroker = closure;
    cairo_status_t status;

    status = line_to (stroker, &stroker->first_point);
    if (unlikely (status))
        return status;

    if (stroker->has_first_face && stroker->has_current_face) {
        /* Join first and final faces of sub path */
        outer_close (stroker, &stroker->current_face, &stroker->first_face);
        inner_close (stroker, &stroker->current_face, &stroker->first_face);
    } else {
        /* Cap the start and end of the sub path as needed */
        add_caps (stroker);
    }

    stroker->has_sub_path = FALSE;
    stroker->has_first_face = FALSE;
    stroker->has_current_face = FALSE;

    return CAIRO_STATUS_SUCCESS;
}
void draw_line( std::function<void( const int, const int )>set, int x1, int y1, int x2, int y2 )
{
    std::vector<point> line = line_to( x1, y1, x2, y2, 0 );
    for( auto &i : line ) {
        set( i.x, i.y );
    }
    set( x1, y1 );
}
Exemplo n.º 9
0
std::vector<point> continue_line(const std::vector<point> &line, const int distance)
{
    const point start = line.back();
    point end = line.back();
    const std::pair<double, double> slope = slope_of(line);
    end.x += distance * slope.first;
    end.y += distance * slope.second;
    return line_to(start.x, start.y, end.x, end.y, 0);
}
Exemplo n.º 10
0
static cairo_status_t
curve_to (void *closure,
          const cairo_point_t *b,
          const cairo_point_t *c,
          const cairo_point_t *d)
{
    struct stroker *stroker = closure;
    cairo_spline_t spline;
    cairo_stroke_face_t face;

    if (stroker->has_limits) {
        if (! _cairo_spline_intersects (&stroker->current_face.point, b, c, d,
                                        &stroker->limit))
            return line_to (closure, d);
    }

    if (! _cairo_spline_init (&spline, spline_to, stroker,
                              &stroker->current_face.point, b, c, d))
        return line_to (closure, d);

    compute_face (&stroker->current_face.point, &spline.initial_slope,
                  stroker, &face);

    if (stroker->has_current_face) {
        int clockwise = join_is_clockwise (&stroker->current_face, &face);
        /* Join with final face from previous segment */
        outer_join (stroker, &stroker->current_face, &face, clockwise);
        inner_join (stroker, &stroker->current_face, &face, clockwise);
    } else {
        if (! stroker->has_first_face) {
            /* Save sub path's first face in case needed for closing join */
            stroker->first_face = face;
            _cairo_tristrip_move_to (stroker->strip, &face.cw);
            stroker->has_first_face = TRUE;
        }
        stroker->has_current_face = TRUE;

        _cairo_tristrip_add_point (stroker->strip, &face.cw);
        _cairo_tristrip_add_point (stroker->strip, &face.ccw);
    }
    stroker->current_face = face;

    return _cairo_spline_decompose (&spline, stroker->tolerance);
}
Exemplo n.º 11
0
/*
 *  Calculate target_list based on origin and target class variables, and shapetype.
 */
point editmap::recalc_target(shapetype shape)
{
    point ret = target;
    target_list.clear();
    switch(shape) {
        case editmap_circle: {
            int radius = rl_dist(origin.x, origin.y, target.x, target.y);
            for ( int x = origin.x - radius; x <= origin.x + radius; x++ ) {
                for ( int y = origin.y - radius; y <= origin.y + radius; y++ ) {
                    if(rl_dist(x, y, origin.x, origin.y) <= radius) {
                        if ( inbounds(x, y) ) {
                            target_list.push_back(point(x, y));
                        }
                    }
                }
            }
        }
        break;
        case editmap_rect_filled:
        case editmap_rect:
            int sx;
            int sy;
            int ex;
            int ey;
            if ( target.x < origin.x ) {
                sx = target.x;
                ex = origin.x;
            } else {
                sx = origin.x;
                ex = target.x;
            }
            if ( target.y < origin.y ) {
                sy = target.y;
                ey = origin.y;
            } else {
                sy = origin.y;
                ey = target.y;
            }
            for ( int x = sx; x <= ex; x++ ) {
                for ( int y = sy; y <= ey; y++ ) {
                    if ( shape == editmap_rect_filled || x == sx || x == ex || y == sy || y == ey ) {
                        if ( inbounds(x, y) ) {
                            target_list.push_back(point(x, y));
                        }
                    }
                }
            }
            break;
        case editmap_line:
            int t = 0;
            target_list = line_to(origin.x, origin.y, target.x, target.y, t);
            break;
    }

    return ret;
}
Exemplo n.º 12
0
void add_function(graphics::plot& p, double x0, double x1, Function f, agg::rgba8 color, unsigned flags, int n = 512) {
    agg::rgba8 none(0,0,0,0);
    auto line = new graphics::path();
    line->move_to(x0, f(x0));
    for (int i = 1; i <= n; i++) {
        const double x = x0 + i * (x1 - x0) / n;
        line->line_to(x, f(x));
    }
    p.add(line, color, 1.5, none, flags);
}
Exemplo n.º 13
0
int main() {
	{
		TimeCheck time;
		auto surface = create_surface(CAIRO_FORMAT_ARGB32, SURFACE_SIZE{ 256, 256 });
		auto cr = create(surface);
		
		line_width(cr, 30.0);
		line_cap(cr, CAIRO_LINE_CAP_BUTT); /* default */
		move_to(cr, POINT{ 64.0, 50.0 }); line_to(cr, POINT{ 64.0, 200.0 });
		stroke(cr);

		line_cap(cr, CAIRO_LINE_CAP_ROUND);
		move_to(cr, POINT{ 128.0, 50.0 }); line_to(cr, POINT{ 128.0, 200.0 });
		stroke(cr);

		line_cap(cr, CAIRO_LINE_CAP_SQUARE);
		move_to(cr, POINT{ 192.0, 50.0 }); line_to(cr, POINT{ 192.0, 200.0 });
		stroke(cr);

		/* draw helping lines */
		source(cr, RGB{ 1, 0.2, 0.2 });
		line_width(cr, 2.56);
		move_to(cr, POINT{ 64.0, 50.0 }); line_to(cr, POINT{ 64.0, 200.0 });
		move_to(cr, POINT{ 128.0, 50.0 });  line_to(cr, POINT{ 128.0, 200.0 });
		move_to(cr, POINT{ 192.0, 50.0 }); line_to(cr, POINT{ 192.0, 200.0 });
		stroke(cr);

		write_to_png(surface, "image.png");
	}
	return 0;
}
Exemplo n.º 14
0
void Game::launch_projectile(Item it, Ranged_attack attack,
                             Point origin, Point target)
{
  int range = rl_dist(origin, target);
  int angle_missed_by = attack.roll_variance();
// Use 1800 since attack.variance is measured in 10ths of a degree
  double distance_missed_by = range * tan(angle_missed_by * PI / 1800);
  int tiles_off = int(distance_missed_by);
  if (tiles_off >= 1) {
    target.x += rng(0 - tiles_off, tiles_off);
    target.y += rng(0 - tiles_off, tiles_off);
  }
// fine_distance is used later to see if we hit the target or "barely missed"
  int fine_distance = 100 * (distance_missed_by - tiles_off);
  debugmsg("angle %d, missed %f, tiles %d, fine %d", angle_missed_by, distance_missed_by, tiles_off, fine_distance);

  std::vector<Point> path = map->line_of_sight(origin, target);
  if (path.empty()) { // Lost line of sight at some point
    path = line_to(origin, target);
  }

  for (int i = 0; i < path.size(); i++) {
    if (map->move_cost(path[i].x, path[i].y) == 0) {
// It's a solid tile, so let's try to smash through it!
      map->smash(path[i].x, path[i].y, attack.roll_damage(), false);
      if (map->move_cost(path[i].x, path[i].y) == 0) {
        return; // We didn't make it!
      }
    } else {
      Entity* entity_hit = entities.entity_at(path[i].x, path[i].y);
      if (entity_hit) {
        bool hit;
// TODO: Incorporate the size of the monster
        if (i == path.size() - 1) {
          hit = rng(0, 100) >= fine_distance;
        } else {
          hit = one_in(3);
        }
        if (hit) {
          add_msg("You shoot %s!", entity_hit->get_name_to_player().c_str());
          Damage_set dam = attack.roll_damage();
          entity_hit->take_damage(DAMAGE_PIERCE, dam.get_damage(DAMAGE_PIERCE),
                                  "you");
          return;
        } else if (i == path.size() - 1) {
          add_msg("You barely miss %s.",
                  entity_hit->get_name_to_player().c_str());
        }
      }
    }
  }
}
Exemplo n.º 15
0
void construct::done_tree(game *g, point p)
{
    mvprintz(0, 0, c_red, _("Press a direction for the tree to fall in:"));
    int x = 0, y = 0;
    do get_direction(x, y, input());
    while (x == -2 || y == -2);
    x = p.x + x * 3 + rng(-1, 1);
    y = p.y + y * 3 + rng(-1, 1);
    std::vector<point> tree = line_to(p.x, p.y, x, y, rng(1, 8));
    for (int i = 0; i < tree.size(); i++) {
        g->m.destroy(g, tree[i].x, tree[i].y, true);
        g->m.ter_set(tree[i].x, tree[i].y, t_trunk);
    }
}
Exemplo n.º 16
0
void construct::done_tree( const tripoint &p )
{
    tripoint dirp;
    while( !choose_direction( _( "Press a direction for the tree to fall in:" ), dirp ) ) {
        // try again
    }

    tripoint to = p + point( 3 * dirp.x + rng( -1, 1 ), 3 * dirp.y + rng( -1, 1 ) );
    std::vector<tripoint> tree = line_to( p, to, rng( 1, 8 ) );
    for( auto &elem : tree ) {
        g->m.destroy( elem );
        g->m.ter_set( elem, t_trunk );
    }
}
Exemplo n.º 17
0
std::vector<tripoint> continue_line(const std::vector<tripoint> &line, const int distance)
{ // May want to optimize this, but it's called fairly infrequently as part of specific attack
  // routines, erring on the side of readability.
    tripoint start;
    tripoint end;
    start = end = line.back();
    // slope <<x,y>,z>
    std::pair<std::pair<double, double>, double> slope;
    slope = slope_of(line);
    end.x += int(distance * slope.first.first);
    end.y += int(distance * slope.first.second);
    end.z += int(distance * slope.second);
    return line_to(start, end, 0, 0);
}
Exemplo n.º 18
0
static cairo_status_t
close_path (void *closure)
{
    struct stroker *stroker = closure;
    cairo_status_t status;

    status = line_to (stroker, &stroker->first_point);
    if (unlikely (status))
	return status;

    if (stroker->has_first_face && stroker->has_current_face) {
	/* Join first and final faces of sub path */
	outer_close (stroker, &stroker->current_face, &stroker->first_face);
	inner_close (stroker, &stroker->current_face, &stroker->first_face);
#if 0
	*_cairo_contour_first_point (&stroker->ccw.contour) =
	    *_cairo_contour_last_point (&stroker->ccw.contour);

	*_cairo_contour_first_point (&stroker->cw.contour) =
	    *_cairo_contour_last_point (&stroker->cw.contour);
#endif

	_cairo_polygon_add_contour (stroker->polygon, &stroker->cw.contour);
	_cairo_polygon_add_contour (stroker->polygon, &stroker->ccw.contour);

#if DEBUG
	{
	    FILE *file = fopen ("contours.txt", "a");
	    _cairo_debug_print_contour (file, &stroker->path);
	    _cairo_debug_print_contour (file, &stroker->cw.contour);
	    _cairo_debug_print_contour (file, &stroker->ccw.contour);
	    fclose (file);

	    _cairo_contour_reset (&stroker->path);
	}
#endif
	_cairo_contour_reset (&stroker->cw.contour);
	_cairo_contour_reset (&stroker->ccw.contour);
    } else {
	/* Cap the start and end of the sub path as needed */
	add_caps (stroker);
    }

    stroker->has_initial_sub_path = FALSE;
    stroker->has_first_face = FALSE;
    stroker->has_current_face = FALSE;

    return CAIRO_STATUS_SUCCESS;
}
Exemplo n.º 19
0
std::vector<point> continue_line(std::vector<point> line, int distance)
{
 point start = line.back(), end = line.back();
 double slope = slope_of(line);
 int sX = (line.front().x < line.back().x ? 1 : -1),
     sY = (line.front().y < line.back().y ? 1 : -1);
 if (abs(slope) == 1) {
  end.x += distance * sX;
  end.y += distance * sY;
 } else if (abs(slope) < 1) {
  end.x += distance * sX;
  end.y += int(distance * abs(slope) * sY);
 } else {
  end.y += distance * sY;
  if (slope != SLOPE_VERTICAL)
   end.x += int(distance / abs(slope)) * sX;
 }
 return line_to(start.x, start.y, end.x, end.y, 0);
}
Exemplo n.º 20
0
int monster::group_bash_skill( point target )
{
    if( !has_flag(MF_GROUP_BASH) ) {
        return bash_skill();
    }
    int bashskill = 0;

    // pileup = more bashskill, but only help bashing mob directly infront of target
    const int max_helper_depth = 5;
    const std::vector<point> bzone = get_bashing_zone( target, pos(), max_helper_depth );

    for( point candidate : bzone ) {
        // Drawing this line backwards excludes the target and includes the candidate.
        std::vector<point> path_to_target = line_to( target.x, target.y,
                                                     candidate.x, candidate.y, 0);
        bool connected = true;
        int mondex = -1;
        for( point in_path : path_to_target ) {
            // If any point in the line from zombie to target is not a cooperating zombie,
            // it can't contribute.
            mondex = g->mon_at( in_path );
            if( mondex == -1 ) {
                connected = false;
                break;
            }
            monster &helpermon = g->zombie( mondex );
            if( !helpermon.has_flag(MF_GROUP_BASH) ) {
                connected = false;
                break;
            }
        }
        if( !connected ) {
            continue;
        }
        // If we made it here, the last monster checked was the candidate.
        monster &helpermon = g->zombie( mondex );
        // Contribution falls off rapidly with distance from target.
        bashskill += helpermon.bash_skill() / rl_dist( candidate, target );
    }

    return bashskill;
}
Exemplo n.º 21
0
void scatter_chunks( const std::string &chunk_name, int chunk_amt, monster &z, int distance,
                     int pile_size = 1 )
{
    // can't have less than one item in a pile or it would cause an infinite loop
    pile_size = std::max( pile_size, 1 );
    // can't have more items in a pile than total items
    pile_size = std::min( chunk_amt, pile_size );
    distance = abs( distance );
    const item chunk( chunk_name, calendar::turn, pile_size );
    for( int i = 0; i < chunk_amt; i += pile_size ) {
        bool drop_chunks = true;
        tripoint tarp( z.pos() + point( rng( -distance, distance ), rng( -distance, distance ) ) );
        const auto traj = line_to( z.pos(), tarp );

        for( size_t j = 0; j < traj.size(); j++ ) {
            tarp = traj[j];
            if( one_in( 2 ) && z.bloodType() != fd_null ) {
                g->m.add_splatter( z.bloodType(), tarp );
            } else {
                g->m.add_splatter( z.gibType(), tarp, rng( 1, j + 1 ) );
            }
            if( g->m.impassable( tarp ) ) {
                g->m.bash( tarp, distance );
                if( g->m.impassable( tarp ) ) {
                    // Target is obstacle, not destroyed by bashing,
                    // stop trajectory in front of it, if this is the first
                    // point (e.g. wall adjacent to monster), don't drop anything on it
                    if( j > 0 ) {
                        tarp = traj[j - 1];
                    } else {
                        drop_chunks = false;
                    }
                    break;
                }
            }
        }
        if( drop_chunks ) {
            g->m.add_item_or_charges( tarp, chunk );
        }
    }
}
Exemplo n.º 22
0
int monster::group_bash_skill( const tripoint &target )
{
    if( !has_flag( MF_GROUP_BASH ) ) {
        return bash_skill();
    }
    int bashskill = 0;

    // pileup = more bash skill, but only help bashing mob directly in front of target
    const int max_helper_depth = 5;
    const std::vector<tripoint> bzone = get_bashing_zone( target, pos(), max_helper_depth );

    for( const tripoint &candidate : bzone ) {
        // Drawing this line backwards excludes the target and includes the candidate.
        std::vector<tripoint> path_to_target = line_to( target, candidate, 0, 0 );
        bool connected = true;
        monster *mon = nullptr;
        for( const tripoint &in_path : path_to_target ) {
            // If any point in the line from zombie to target is not a cooperating zombie,
            // it can't contribute.
            mon = g->critter_at<monster>( in_path );
            if( !mon ) {
                connected = false;
                break;
            }
            monster &helpermon = *mon;
            if( !helpermon.has_flag( MF_GROUP_BASH ) || helpermon.is_hallucination() ) {
                connected = false;
                break;
            }
        }
        if( !connected || !mon ) {
            continue;
        }
        // If we made it here, the last monster checked was the candidate.
        monster &helpermon = *mon;
        // Contribution falls off rapidly with distance from target.
        bashskill += helpermon.bash_skill() / rl_dist( candidate, target );
    }

    return bashskill;
}
Exemplo n.º 23
0
// Returns a vector of the adjacent square in the direction of the target,
// and the two squares flanking it.
std::vector<point> squares_in_direction( const int x1, const int y1, const int x2, const int y2 )
{
    int junk = 0;
    point center_square = line_to( x1, y1, x2, y2, junk )[0];
    std::vector<point> adjacent_squares;
    adjacent_squares.push_back( center_square );
    if( x1 == center_square.x ) {
        // Horizontally adjacent.
        adjacent_squares.push_back( point( x1 + 1, center_square.y ) );
        adjacent_squares.push_back( point( x1 - 1, center_square.y ) );
    } else if( y1 == center_square.y ) {
        // Vertically adjacent.
        adjacent_squares.push_back( point( center_square.x, y1 + 1 ) );
        adjacent_squares.push_back( point( center_square.x, y1 - 1 ) );
    } else {
        // Diagonally adjacent.
        adjacent_squares.push_back( point( x1, center_square.y ) );
        adjacent_squares.push_back( point( center_square.x, y1 ) );
    }
    return adjacent_squares;
}
Exemplo n.º 24
0
/**
 * Function circle
 * writes a non filled circle to output file
 * Plot one circle as segments (6 to 16 depending on its radius
 * @param aCentre = center coordinates
 * @param aDiameter = diameter of the circle
 * @param aFill = plot option (NO_FILL, FILLED_SHAPE, FILLED_WITH_BG_BODYCOLOR)
 * not used here: circles are always not filled the gerber. Filled circles are flashed
 * @param aWidth = line width
 */
void GERBER_PLOTTER::circle( wxPoint aCentre, int aDiameter, FILL_T aFill, int aWidth )
{
    wxASSERT( output_file );
    wxPoint   start, end;
    double    radius = aDiameter / 2;
    const int delta  = 3600 / 32; /* increment (in 0.1 degrees) to draw circles */

    start.x = aCentre.x + wxRound( radius );
    start.y = aCentre.y;
    set_current_line_width( aWidth );
    move_to( start );

    for( int ii = delta; ii < 3600; ii += delta )
    {
        end.x = aCentre.x + (int) ( radius * cos( DEG2RAD( (double)ii / 10.0 ) ) );
        end.y = aCentre.y + (int) ( radius * sin( DEG2RAD( (double)ii / 10.0 ) ) );
        line_to( end );
    }

    finish_to( start );
}
Exemplo n.º 25
0
    void add_path(VertexSource& vs, unsigned path_id=0)
    {
        double x;
        double y;

        unsigned flag;
        vs.rewind(path_id);
        while(!agg::is_stop(flag = vs.vertex(&x, &y)))
        {
            if(agg::is_vertex(flag))
            {
                if(agg::is_move_to(flag)) 
                {
                    move_to(int(x), int(y));
                }
                else 
                {
                    line_to(int(x), int(y));
                }
            }
        }
    }
Exemplo n.º 26
0
void cairo_paths_c::arc(double x1, double y1, double rx, double ry, double x_axis_rotation, bool large_arc_flag, bool sweep_flag, double x2, double y2)
{
    double sinf, cosf;
    double x1_, y1_;
    double cx_, cy_, cx, cy;
    double gamma;
    double theta1, delta_theta;
    double k1, k2, k3, k4, k5;

    int i, n_segs;

    if (x1 == x2 && y1 == y2)
        return;

    /* X-axis */
    ts::sincos((float)(x_axis_rotation * M_PI / 180.0), sinf, cosf);

    rx = fabs (rx);
    ry = fabs (ry);

    /* Check the radius against floading point underflow.
       See http://bugs.debian.org/508443 */
    if ((rx < DBL_EPSILON) || (ry < DBL_EPSILON))
    {
        line_to (x2, y2);
        return;
    }

    k1 = (x1 - x2) / 2;
    k2 = (y1 - y2) / 2;

    x1_ = cosf * k1 + sinf * k2;
    y1_ = -sinf * k1 + cosf * k2;

    gamma = (x1_ * x1_) / (rx * rx) + (y1_ * y1_) / (ry * ry);
    if (gamma > 1) {
        rx *= sqrt (gamma);
        ry *= sqrt (gamma);
    }

    /* Compute the center */

    k1 = rx * rx * y1_ * y1_ + ry * ry * x1_ * x1_;
    if (k1 == 0)
        return;

    k1 = sqrt (fabs ((rx * rx * ry * ry) / k1 - 1));
    if (sweep_flag == large_arc_flag)
        k1 = -k1;

    cx_ = k1 * rx * y1_ / ry;
    cy_ = -k1 * ry * x1_ / rx;
    
    cx = cosf * cx_ - sinf * cy_ + (x1 + x2) / 2;
    cy = sinf * cx_ + cosf * cy_ + (y1 + y2) / 2;

    /* Compute start angle */

    k1 = (x1_ - cx_) / rx;
    k2 = (y1_ - cy_) / ry;
    k3 = (-x1_ - cx_) / rx;
    k4 = (-y1_ - cy_) / ry;

    k5 = sqrt (fabs (k1 * k1 + k2 * k2));
    if (k5 == 0)
        return;

    k5 = k1 / k5;
    k5 = ts::CLAMP (k5, -1, 1);
    theta1 = acos (k5);
    if (k2 < 0)
        theta1 = -theta1;

    /* Compute delta_theta */

    k5 = sqrt (fabs ((k1 * k1 + k2 * k2) * (k3 * k3 + k4 * k4)));
    if (k5 == 0)
        return;

    k5 = (k1 * k3 + k2 * k4) / k5;
    k5 = ts::CLAMP (k5, -1, 1);
    delta_theta = acos (k5);
    if (k1 * k4 - k3 * k2 < 0)
        delta_theta = -delta_theta;

    if (sweep_flag && delta_theta < 0)
        delta_theta += M_PI * 2;
    else if (!sweep_flag && delta_theta > 0)
        delta_theta -= M_PI * 2;
   
    /* Now draw the arc */

    n_segs = ts::lround( ceil (fabs (delta_theta / (M_PI * 0.5 + 0.001))));

    for (i = 0; i < n_segs; i++)
        arc_segment (   cx, cy,
                        (float)(theta1 + i * delta_theta / n_segs),
                        (float)(theta1 + (i + 1) * delta_theta / n_segs),
                        rx, ry, x_axis_rotation);
}
Exemplo n.º 27
0
// Why put this in a Big Switch?  Why not let bionics have pointers to
// functions, much like monsters and items?
//
// Well, because like diseases, which are also in a Big Switch, bionics don't
// share functions....
void player::activate_bionic(int b, game *g)
{
 bionic bio = my_bionics[b];
 int power_cost = bionics[bio.id].power_cost;
 if (weapon.type->id == itm_bio_claws && bio.id == bio_claws)
  power_cost = 0;
 if (power_level < power_cost) {
  if (my_bionics[b].powered) {
   g->add_msg("Your %s powers down.", bionics[bio.id].name.c_str());
   my_bionics[b].powered = false;
  } else
   g->add_msg("You cannot power your %s", bionics[bio.id].name.c_str());
  return;
 }

 if (my_bionics[b].powered && my_bionics[b].charge > 0) {
// Already-on units just lose a bit of charge
  my_bionics[b].charge--;
 } else {
// Not-on units, or those with zero charge, have to pay the power cost
  if (bionics[bio.id].charge_time > 0) {
   my_bionics[b].powered = true;
   my_bionics[b].charge = bionics[bio.id].charge_time;
  }
  power_level -= power_cost;
 }

 std::string junk;
 std::vector<point> traj;
 std::vector<std::string> good;
 std::vector<std::string> bad;
 WINDOW* w;
 int dirx, diry, t, index;
 unsigned int l;
 item tmp_item;

 switch (bio.id) {
 case bio_painkiller:
  pkill += 6;
  pain -= 2;
  if (pkill > pain)
   pkill = pain;
  break;

 case bio_nanobots:
  healall(4);
  break;

 case bio_resonator:
  g->sound(posx, posy, 30, "VRRRRMP!");
  for (int i = posx - 1; i <= posx + 1; i++) {
   for (int j = posy - 1; j <= posy + 1; j++) {
    g->m.bash(i, j, 40, junk);
    g->m.bash(i, j, 40, junk);	// Multibash effect, so that doors &c will fall
    g->m.bash(i, j, 40, junk);
    if (g->m.is_destructable(i, j) && rng(1, 10) >= 4)
     g->m.ter(i, j) = t_rubble;
   }
  }
  break;

 case bio_time_freeze:
  moves += 100 * power_level;
  power_level = 0;
  g->add_msg("Your speed suddenly increases!");
  if (one_in(3)) {
   g->add_msg("Your muscles tear with the strain.");
   hurt(g, bp_arms, 0, rng(5, 10));
   hurt(g, bp_arms, 1, rng(5, 10));
   hurt(g, bp_legs, 0, rng(7, 12));
   hurt(g, bp_legs, 1, rng(7, 12));
   hurt(g, bp_torso, 0, rng(5, 15));
  }
  if (one_in(5))
   add_disease(DI_TELEGLOW, rng(50, 400), g);
  break;

 case bio_teleport:
  g->teleport();
  add_disease(DI_TELEGLOW, 300, g);
  break;

// TODO: More stuff here (and bio_blood_filter)
 case bio_blood_anal:
  w = newwin(20, 40, 3, 10);
  wborder(w, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX,
             LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX );
  if (has_disease(DI_FUNGUS))
   bad.push_back("Fungal Parasite");
  if (has_disease(DI_DERMATIK))
   bad.push_back("Insect Parasite");
  if (has_disease(DI_POISON))
   bad.push_back("Poison");
  if (radiation > 0)
   bad.push_back("Irradiated");
  if (has_disease(DI_PKILL1))
   good.push_back("Minor Painkiller");
  if (has_disease(DI_PKILL2))
   good.push_back("Moderate Painkiller");
  if (has_disease(DI_PKILL3))
   good.push_back("Heavy Painkiller");
  if (has_disease(DI_PKILL_L))
   good.push_back("Slow-Release Painkiller");
  if (has_disease(DI_DRUNK))
   good.push_back("Alcohol");
  if (has_disease(DI_CIG))
   good.push_back("Nicotine");
  if (has_disease(DI_HIGH))
   good.push_back("Intoxicant: Other");
  if (has_disease(DI_TOOK_PROZAC))
   good.push_back("Prozac");
  if (has_disease(DI_TOOK_FLUMED))
   good.push_back("Antihistamines");
  if (has_disease(DI_ADRENALINE))
   good.push_back("Adrenaline Spike");
  if (good.size() == 0 && bad.size() == 0)
   mvwprintz(w, 1, 1, c_white, "No effects.");
  else {
   for (unsigned int line = 1; line < 39 && line <= good.size() + bad.size(); line++) {
    if (line <= bad.size())
     mvwprintz(w, line, 1, c_red, bad[line - 1].c_str());
    else
     mvwprintz(w, line, 1, c_green, good[line - 1 - bad.size()].c_str());
   }
  }
  wrefresh(w);
  refresh();
  getch();
  delwin(w);
  break;

 case bio_blood_filter:
  rem_disease(DI_FUNGUS);
  rem_disease(DI_POISON);
  rem_disease(DI_PKILL1);
  rem_disease(DI_PKILL2);
  rem_disease(DI_PKILL3);
  rem_disease(DI_PKILL_L);
  rem_disease(DI_DRUNK);
  rem_disease(DI_CIG);
  rem_disease(DI_HIGH);
  rem_disease(DI_TOOK_PROZAC);
  rem_disease(DI_TOOK_FLUMED);
  rem_disease(DI_ADRENALINE);
  break;

 case bio_evap:
  if (query_yn("Drink directly? Otherwise you will need a container.")) {
   tmp_item = item(g->itypes[itm_water], 0);
   thirst -= 50;
   if (has_trait(PF_GOURMAND) && thirst < -60) {
     g->add_msg("You can't finish it all!");
     thirst = -60;
   } else if (!has_trait(PF_GOURMAND) && thirst < -20) {
     g->add_msg("You can't finish it all!");
     thirst = -20;
   }
  } else {
   t = g->inv("Choose a container:");
   if (i_at(t).type == 0) {
    g->add_msg("You don't have that item!");
    power_level += bionics[bio_evap].power_cost;
   } else if (!i_at(t).is_container()) {
    g->add_msg("That %s isn't a container!", i_at(t).tname().c_str());
    power_level += bionics[bio_evap].power_cost;
   } else {
    it_container *cont = dynamic_cast<it_container*>(i_at(t).type);
    if (i_at(t).volume_contained() + 1 > cont->contains) {
     g->add_msg("There's no space left in your %s.", i_at(t).tname().c_str());
     power_level += bionics[bio_evap].power_cost;
    } else if (!(cont->flags & con_wtight)) {
     g->add_msg("Your %s isn't watertight!", i_at(t).tname().c_str());
     power_level += bionics[bio_evap].power_cost;
    } else {
     g->add_msg("You pour water into your %s.", i_at(t).tname().c_str());
     i_at(t).put_in(item(g->itypes[itm_water], 0));
    }
   }
  }
  break;

 case bio_lighter:
  g->draw();
  mvprintw(0, 0, "Torch in which direction?");
  get_direction(g, dirx, diry, input());
  if (dirx == -2) {
   g->add_msg("Invalid direction.");
   power_level += bionics[bio_lighter].power_cost;
   return;
  }
  dirx += posx;
  diry += posy;
  if (!g->m.add_field(g, dirx, diry, fd_fire, 1))	// Unsuccessful.
   g->add_msg("You can't light a fire there.");
  break;

 case bio_claws:
  if (weapon.type->id == itm_bio_claws) {
   g->add_msg("You withdraw your claws.");
   weapon = ret_null;
  } else if (weapon.type->id != 0) {
   g->add_msg("Your claws extend, forcing you to drop your %s.",
              weapon.tname().c_str());
   g->m.add_item(posx, posy, weapon);
   weapon = item(g->itypes[itm_bio_claws], 0);
   weapon.invlet = '#';
  } else {
   g->add_msg("Your claws extend!");
   weapon = item(g->itypes[itm_bio_claws], 0);
   weapon.invlet = '#';
  }
  break;

 case bio_blaster:
  tmp_item = weapon;
  weapon = item(g->itypes[itm_bio_blaster], 0);
  weapon.curammo = dynamic_cast<it_ammo*>(g->itypes[itm_bio_fusion]);
  weapon.charges = 1;
  g->refresh_all();
  g->plfire(false);
  weapon = tmp_item;
  break;

 case bio_laser:
  tmp_item = weapon;
  weapon = item(g->itypes[itm_v29], 0);
  weapon.curammo = dynamic_cast<it_ammo*>(g->itypes[itm_laser_pack]);
  weapon.charges = 1;
  g->refresh_all();
  g->plfire(false);
  weapon = tmp_item;
  break;

 case bio_emp:
  g->draw();
  mvprintw(0, 0, "Fire EMP in which direction?");
  get_direction(g, dirx, diry, input());
  if (dirx == -2) {
   g->add_msg("Invalid direction.");
   power_level += bionics[bio_emp].power_cost;
   return;
  }
  dirx += posx;
  diry += posy;
  g->emp_blast(dirx, diry);
  break;

 case bio_hydraulics:
  g->add_msg("Your muscles hiss as hydraulic strength fills them!");
  break;

 case bio_water_extractor:
  for (unsigned int i = 0; i < g->m.i_at(posx, posy).size(); i++) {
   item tmp = g->m.i_at(posx, posy)[i];
   if (tmp.type->id == itm_corpse && query_yn("Extract water from the %s",
                                              tmp.tname().c_str())) {
    i = g->m.i_at(posx, posy).size() + 1;	// Loop is finished
    t = g->inv("Choose a container:");
    if (i_at(t).type == 0) {
     g->add_msg("You don't have that item!");
     power_level += bionics[bio_water_extractor].power_cost;
    } else if (!i_at(t).is_container()) {
     g->add_msg("That %s isn't a container!", i_at(t).tname().c_str());
     power_level += bionics[bio_water_extractor].power_cost;
    } else {
     it_container *cont = dynamic_cast<it_container*>(i_at(t).type);
     if (i_at(t).volume_contained() + 1 > cont->contains) {
      g->add_msg("There's no space left in your %s.", i_at(t).tname().c_str());
      power_level += bionics[bio_water_extractor].power_cost;
     } else {
      g->add_msg("You pour water into your %s.", i_at(t).tname().c_str());
      i_at(t).put_in(item(g->itypes[itm_water], 0));
     }
    }
   }
   if (i == g->m.i_at(posx, posy).size() - 1)	// We never chose a corpse
    power_level += bionics[bio_water_extractor].power_cost;
  }
  break;

 case bio_magnet:
  for (int i = posx - 10; i <= posx + 10; i++) {
   for (int j = posy - 10; j <= posy + 10; j++) {
    if (g->m.i_at(i, j).size() > 0) {
     if (g->m.sees(i, j, posx, posy, -1, t))
      traj = line_to(i, j, posx, posy, t);
     else
      traj = line_to(i, j, posx, posy, 0);
    }
    traj.insert(traj.begin(), point(i, j));
    for (unsigned int k = 0; k < g->m.i_at(i, j).size(); k++) {
     if (g->m.i_at(i, j)[k].made_of(IRON) || g->m.i_at(i, j)[k].made_of(STEEL)){
      tmp_item = g->m.i_at(i, j)[k];
      g->m.i_rem(i, j, k);
      for (l = 0; l < traj.size(); l++) {
       index = g->mon_at(traj[l].x, traj[l].y);
       if (index != -1) {
        if (g->z[index].hurt(tmp_item.weight() * 2))
         g->kill_mon(index, true);
        g->m.add_item(traj[l].x, traj[l].y, tmp_item);
        l = traj.size() + 1;
       } else if (l > 0 && g->m.move_cost(traj[l].x, traj[l].y) == 0) {
        g->m.bash(traj[l].x, traj[l].y, tmp_item.weight() * 2, junk);
        g->sound(traj[l].x, traj[l].y, 12, junk);
        if (g->m.move_cost(traj[l].x, traj[l].y) == 0) {
         g->m.add_item(traj[l - 1].x, traj[l - 1].y, tmp_item);
         l = traj.size() + 1;
        }
       }
      }
      if (l == traj.size())
       g->m.add_item(posx, posy, tmp_item);
     }
    }
   }
  }
  break;

 case bio_lockpick:
  g->draw();
  mvprintw(0, 0, "Unlock in which direction?");
  get_direction(g, dirx, diry, input());
  if (dirx == -2) {
   g->add_msg("Invalid direction.");
   power_level += bionics[bio_lockpick].power_cost;
   return;
  }
  dirx += posx;
  diry += posy;
  if (g->m.ter(dirx, diry) == t_door_locked) {
   moves -= 40;
   g->add_msg("You unlock the door.");
   g->m.ter(dirx, diry) = t_door_c;
  } else
   g->add_msg("You can't unlock that %s.", g->m.tername(dirx, diry).c_str());
  break;

  // Unused enums added for completeness.
 default:
  break;
 }
}
Exemplo n.º 28
0
// Resets plans (list of squares to visit) and builds it as a straight line
// to the destination (x,y). t is used to choose which eligable line to use.
// Currently, this assumes we can see (x,y), so shouldn't be used in any other
// circumstance (or else the monster will "phase" through solid terrain!)
void monster::set_dest(int x, int y, int &t)
{
    plans.clear();
// TODO: This causes a segfault, once in a blue moon!  Whyyyyy.
    plans = line_to(_posx, _posy, x, y, t);
}
Exemplo n.º 29
0
static cairo_status_t
_cairo_stroker_curve_to (void *closure,
			 const cairo_point_t *b,
			 const cairo_point_t *c,
			 const cairo_point_t *d)
{
    cairo_stroker_t *stroker = closure;
    cairo_spline_t spline;
    cairo_line_join_t line_join_save;
    cairo_stroke_face_t face;
    double slope_dx, slope_dy;
    cairo_path_fixed_line_to_func_t *line_to;
    cairo_status_t status = CAIRO_STATUS_SUCCESS;

    line_to = stroker->dash.dashed ?
	_cairo_stroker_line_to_dashed :
	_cairo_stroker_line_to;

    if (! _cairo_spline_init (&spline,
			      (cairo_spline_add_point_func_t)line_to, stroker,
			      &stroker->current_point, b, c, d))
    {
	return line_to (closure, d);
    }

    /* If the line width is so small that the pen is reduced to a
       single point, then we have nothing to do. */
    if (stroker->pen.num_vertices <= 1)
	return CAIRO_STATUS_SUCCESS;

    /* Compute the initial face */
    if (! stroker->dash.dashed || stroker->dash.dash_on) {
	slope_dx = _cairo_fixed_to_double (spline.initial_slope.dx);
	slope_dy = _cairo_fixed_to_double (spline.initial_slope.dy);
	if (_compute_normalized_device_slope (&slope_dx, &slope_dy,
					      stroker->ctm_inverse, NULL))
	{
	    _compute_face (&stroker->current_point,
			   &spline.initial_slope,
			   slope_dx, slope_dy,
			   stroker, &face);
	}
	if (stroker->has_current_face) {
	    status = _cairo_stroker_join (stroker,
					  &stroker->current_face, &face);
	    if (unlikely (status))
		return status;
	} else if (! stroker->has_first_face) {
	    stroker->first_face = face;
	    stroker->has_first_face = TRUE;
	}

	stroker->current_face = face;
	stroker->has_current_face = TRUE;
    }

    /* Temporarily modify the stroker to use round joins to guarantee
     * smooth stroked curves. */
    line_join_save = stroker->style.line_join;
    stroker->style.line_join = CAIRO_LINE_JOIN_ROUND;

    status = _cairo_spline_decompose (&spline, stroker->tolerance);
    if (unlikely (status))
	return status;

    /* And join the final face */
    if (! stroker->dash.dashed || stroker->dash.dash_on) {
	slope_dx = _cairo_fixed_to_double (spline.final_slope.dx);
	slope_dy = _cairo_fixed_to_double (spline.final_slope.dy);
	if (_compute_normalized_device_slope (&slope_dx, &slope_dy,
					      stroker->ctm_inverse, NULL))
	{
	    _compute_face (&stroker->current_point,
			   &spline.final_slope,
			   slope_dx, slope_dy,
			   stroker, &face);
	}

	status = _cairo_stroker_join (stroker, &stroker->current_face, &face);
	if (unlikely (status))
	    return status;

	stroker->current_face = face;
    }

    stroker->style.line_join = line_join_save;

    return CAIRO_STATUS_SUCCESS;
}
Exemplo n.º 30
0
void monster::explode()
{
    if( is_hallucination() ) {
        //Can't gib hallucinations
        return;
    }
    if( type->has_flag( MF_NOGIB ) || type->has_flag( MF_VERMIN ) ) {
        return;
    }
    // Send body parts and blood all over!
    const itype_id meat = type->get_meat_itype();
    const field_id type_blood = bloodType();
    const field_id type_gib = gibType();
    if( meat != "null" || type_blood != fd_null || type_gib != fd_null ) {
        // Only create chunks if we know what kind to make.
        int num_chunks = 0;
        switch( type->size ) {
            case MS_TINY:
                num_chunks = 1;
                break;
            case MS_SMALL:
                num_chunks = 2;
                break;
            case MS_MEDIUM:
                num_chunks = 4;
                break;
            case MS_LARGE:
                num_chunks = 8;
                break;
            case MS_HUGE:
                num_chunks = 16;
                break;
        }

        for( int i = 0; i < num_chunks; i++ ) {
            int tarx = _posx + rng( -3, 3 ), tary = _posy + rng( -3, 3 );
            std::vector<point> traj = line_to( _posx, _posy, tarx, tary, 0 );

            for( size_t j = 0; j < traj.size(); j++ ) {
                tarx = traj[j].x;
                tary = traj[j].y;
                if( one_in( 2 ) && type_blood != fd_null ) {
                    g->m.add_field( tarx, tary, type_blood, 1 );
                } else if( type_gib != fd_null ) {
                    g->m.add_field( tarx, tary, type_gib, rng( 1, j + 1 ) );
                }
                if( g->m.move_cost( tarx, tary ) == 0 ) {
                    if( !g->m.bash( tarx, tary, 3 ).second ) {
                        // Target is obstacle, not destroyed by bashing,
                        // stop trajectory in front of it, if this is the first
                        // point (e.g. wall adjacent to monster) , make it invalid.
                        if( j > 0 ) {
                            tarx = traj[j - 1].x;
                            tary = traj[j - 1].y;
                        } else {
                            tarx = -1;
                        }
                        break;
                    }
                }
            }
            if( meat != "null" && tarx != -1 ) {
                g->m.spawn_item( tarx, tary, meat, 1, 0, calendar::turn );
            }
        }
    }
}