コード例 #1
0
ファイル: physics.hpp プロジェクト: bsummer4/cuffs
 /// Find the point closest to p0 between p0 and p1 that is solid,
 /// and set result to it.  Return false if there was not such point.
 bool find_hit(game::Map &map, Point p0, Point p1, Point &result) {
   if (p0 == p1) return false;
   /// @TODO HACK!!! Check to see if p0 and p1 are Really far away
   /// and if they are say no collision.  This lets us do wrapping easier.
   //cerr << "find_hit" << p0.x << "x" << p0.y << " "
   //<< p1.x << "x" << p1.y << endl;
   if (hypot(p0.x - p1.x, p0.y - p1.y) > map.width/2) return false;
   int x0 = p0.x, x1 = p1.x, y0 = p0.y, y1 = p1.y;
   vector <Point> hits;
   bool steep = abs(y1 - y0) > abs(x1 - x0);
   { int temp;
     if (steep) {
       temp = x0;
       x0 = y0;
       y0 = temp;
       temp = x1;
       x1 = y1;
       y1 = temp; }
     if (x0 > x1) {
       temp = x0;
       x0 = x1;
       x1 = temp;
       temp = y0;
       y0 = y1;
       y1 = temp; }}
   int deltax = x1 - x0;
   int deltay = abs(y1 - y0);
   double error = 0;
   double deltaerr = ((double)deltay)/((double)deltax);
   int ystep;
   int y = y0;
   ystep = (y0 < y1) ? 1 : -1;
   for (int x = x0; x <= x1; x++) {
     Point current = steep ? Point(y, x) : Point(x, y);
     //cerr << "  checking: " << current.x << "x" << current.y << endl;
     if (on_map(map,current) && map.is_solid(current.x, current.y))
       hits.push_back(current);
     error += deltaerr;
     if (error >= 0.5) {
       y += ystep;
       error = error - 1.0; }}
   // Calculate the closest hit and return it.  Return false if there
   // was no hit
   if (!hits.size()) return false;
   double lowest_distance = INFINITY;
   FOREACH (vector <Point>, hit, hits) {
     double distance = hypotf(p0.x - hit->x, p0.y - hit->y);
     //cerr << "  hit w/distance=" << distance << " @"
     //<< hit->x << "x" << hit->y << endl;
     // Check for wrapping
     if (distance > map.width/2)
         distance = map.width - distance;
     if (distance < lowest_distance) {
       result = *hit;
       lowest_distance = distance; }}
コード例 #2
0
ファイル: player.c プロジェクト: happyponyland/smallrl
void summon_demons(player_info_t * player, level_t * level)
{
    int how_many;
    int y;
    int x;

    how_many = 2 + rand() % 4;

    while (how_many--)
    {
        y = player->mob->position.y - 2 + rand() % 5;
        x = player->mob->position.x - 2 + rand() % 5;

        if (on_map(level, y, x) &&
            get_mob(level, y, x) == -1 &&
            !(level->map[y * level->width + x].flags & tile_unpassable))
        {
            try_make_mob(level, mob_demon, y, x);
        }
    }

    return;
}
コード例 #3
0
ファイル: ui.c プロジェクト: happyponyland/smallrl
void draw_map(input_type_t input_type, level_t * level)
{
    int y;
    int x;
    int i;

    int offset_y = 1;
    int offset_x = 1;

    int draw_y = offset_y;

    draw_map_border(input_type, level);

    for (y = level->view.ul_position.y; y < level->view.ul_position.y + level->view.height; y += 1)
    {
        move(++draw_y, offset_x);

        for (x = level->view.ul_position.x; x < level->view.ul_position.x + level->view.width; x += 1)
        {
            if(!on_map(level, y, x))
               continue;

            if (level->map[y * level->width + x].is_explored == 0)
            {
                addch(' ');
                continue;
            }

            attrset(A_NORMAL);

            if (level->map[y * level->width + x].item)
            {
                addch('/');
                continue;
            }

            if (level->map[y * level->width + x].is_lit ||
                level->map[y * level->width + x].is_periphery)
            {
                attrset(A_BOLD);
            }

            switch (level->map[y * level->width + x].type)
            {
            case tile_void:
                addch(' ');
                break;

            case tile_floor:
                attron(COLOR_PAIR(color_green));
                addch('.');
                break;

            case tile_doorway:
                attron(COLOR_PAIR(color_green));
                addch(ACS_BLOCK);
                break;

            case tile_corridor:
                addch('#');
                break;

            case tile_wall_r:
            case tile_wall_l:
                attron(COLOR_PAIR(color_yellow));
                addch(ACS_VLINE);
                break;

            case tile_wall_t:
            case tile_wall_b:
                attron(COLOR_PAIR(color_yellow));
                addch(ACS_HLINE);
                break;

            case tile_wall_ll:
                attron(COLOR_PAIR(color_yellow));
                addch(ACS_LLCORNER);
                break;

            case tile_wall_lr:
                attron(COLOR_PAIR(color_yellow));
                addch(ACS_LRCORNER);
                break;

            case tile_wall_ul:
                attron(COLOR_PAIR(color_yellow));
                addch(ACS_ULCORNER);
                break;

            case tile_wall_ur:
                attron(COLOR_PAIR(color_yellow));
                addch(ACS_URCORNER);
                break;

            case tile_wall_plus:
                attron(COLOR_PAIR(color_yellow));
                addch(ACS_PLUS);
                break;

            case tile_wall_ttee:
                attron(COLOR_PAIR(color_yellow));
                addch(ACS_TTEE);
                break;

            case tile_wall_btee:
                attron(COLOR_PAIR(color_yellow));
                addch(ACS_BTEE);
                break;

            case tile_wall_ltee:
                attron(COLOR_PAIR(color_yellow));
                addch(ACS_LTEE);
                break;

            case tile_wall_rtee:
                attron(COLOR_PAIR(color_yellow));
                addch(ACS_RTEE);
                break;

            case tile_stair:
                attron(A_NORMAL);
                addch('>');
                break;

            default:
                attron(COLOR_PAIR(color_red));
                addch('?');
                break;
            }
        }
    }

    attrset(A_NORMAL);

    for (i = 0; i < MAX_MOBS_PER_LEVEL; i++)
    {
        if (level->mobs[i].type && level->map[level->mobs[i].position.y * level->width + level->mobs[i].position.x].is_lit)
        {
            int left = level->view.ul_position.x;
            int top = level->view.ul_position.y;

            int right  = level->view.ul_position.x + level->view.width;
            int bottom  = level->view.ul_position.y + level->view.height;

            int mob_x = level->mobs[i].position.x;
            int mob_y = level->mobs[i].position.y;

            if(mob_x > left && mob_x < right && mob_y > top && mob_y < bottom)
            {
                move(level->mobs[i].position.y - top + offset_y + 1, level->mobs[i].position.x - left + offset_x);
                addch(level->mobs[i].type);
            }
        }
    }

    attrset(A_NORMAL);

    refresh();

    return;
}
コード例 #4
0
ファイル: player.c プロジェクト: happyponyland/smallrl
/*
  Lights up the area near a mob, marks it as explored.
*/
void explore(level_t * level, mob_t * mob)
{
    int p_y;
    int p_x;

    int y;
    int x;

    int top;
    int bottom;
    int left;
    int right;

    top = level->view.ul_position.y;
    bottom = level->view.ul_position.y + level->view.height;

    left = level->view.ul_position.x;
    right = level->view.ul_position.x + level->view.width;

    p_y = mob->position.y;
    p_x = mob->position.x;

    for (y = top; y < bottom; y += 1)
        for (x = left; x < right; x += 1)
            level->map[y * level->width + x].is_lit = 0;

    for (y = p_y - 1; y <= p_y + 1; y++)
    {
        for (x = p_x - 1; x <= p_x + 1; x++)
        {
            if (on_map(level, y, x))
            {
                level->map[y * level->width + x].is_explored = true;
                level->map[y * level->width + x].is_lit = true;
                level->map[y * level->width + x].is_periphery = true;
            }
        }
    }

    /* Floodfill open permalit rooms */

    if (level->map[p_y * level->width + p_x].flags & tile_permalit)
    {
        bool change;

        do
        {
            change = false;

            for (y = top; y < bottom; y += 1)
            {
                if(y < 1)
                    continue;

                if(y > level->height - 1)
                    break;

                for (x = left; x < right; x += 1)
                {
                    if(x < 1)
                        continue;

                    if(x > level->width - 1)
                        break;

                    if (level->map[y * level->width + x].flags & tile_noflood)
                        continue;

                    if (level->map[y * level->width + x].is_lit == 0 &&
                        (level->map[y * level->width + x].flags & tile_permalit ||
                         level->map[(y - 1) * level->width + (x - 1)].flags & tile_permalit ||
                         level->map[(y - 1) * level->width + (x + 1)].flags & tile_permalit ||
                         level->map[(y + 1) * level->width + (x - 1)].flags & tile_permalit ||
                         level->map[(y + 1) * level->width + (x + 1)].flags & tile_permalit ||
                         level->map[(y - 1) * level->width + x].flags & tile_permalit ||
                         level->map[y * level->width + (x - 1)].flags & tile_permalit ||
                         level->map[(y + 1) * level->width + x].flags & tile_permalit ||
                         level->map[y * level->width + (x + 1)].flags & tile_permalit ))
                    {
                        if (level->map[(y - 1) * level->width + x].is_lit ||
                            level->map[y * level->width + (x - 1)].is_lit ||
                            level->map[(y + 1) * level->width + x].is_lit ||
                            level->map[y * level->width + (x + 1)].is_lit)
                        {
                            level->map[y * level->width + x].is_lit = 1;
                            level->map[y * level->width + x].is_explored = 1;

                            change = true;
                        }

                    }
                }
            }
        } while (change);
    }

    bool match;

    for (y = top; y < bottom; y += 1)
    {
        for (x = left; x < right; x += 1)
        {
            match = false;

            if ((level->map[y * level->width + x].flags & tile_noflood) == 0)
                continue;

            if (y >= 1 && level->map[(y - 1) * level->width + x].is_lit)
                match = true;

            if (x >= 1 && level->map[y * level->width + (x - 1)].is_lit)
                match = true;

            if (y < level->height - 1 && level->map[(y + 1) * level->width + x].is_lit)
                match = true;

            if (x < level->width + 1 && level->map[y * level->width + (x + 1)].is_lit)
                match = true;

            if (y >= 1 &&
                x >= 1 &&
                level->map[(y - 1) * level->width + (x - 1)].is_lit)
                match = true;

            if (y >= 1 &&
                x <= level->width &&
                level->map[(y - 1) * level->width + (x + 1)].is_lit)
                match = true;

            if (y <= level->height &&
                x >= 1 &&
                level->map[(y + 1) * level->width + (x - 1)].is_lit)
                match = true;

            if (y <= level->height &&
                x <= level->width &&
                level->map[(y + 1) * level->width + (x + 1)].is_lit)
                match = true;


            if (match)
            {
                level->map[y * level->width + x].is_periphery = true;
                level->map[y * level->width + x].is_explored = true;
            }
        }
    }

    return;
}
コード例 #5
0
const terrain_builder::tile& terrain_builder::tilemap::operator[] (const map_location &loc) const
{
	assert(on_map(loc));

	return tiles_[(loc.x + 2) + (loc.y + 2) * (x_ + 4)];
}