Пример #1
0
std::string map_data_common_t::extended_description() const
{
    std::stringstream ss;
    ss << "<header>" << string_format( _( "That is a %s." ), name().c_str() ) << "</header>" << '\n';
    ss << description << std::endl;
    bool has_any_harvest = std::any_of( harvest_by_season.begin(), harvest_by_season.end(),
    []( const harvest_id & hv ) {
        return !hv.obj().empty();
    } );

    if( has_any_harvest ) {
        ss << "--" << std::endl;
        int player_skill = g->u.get_skill_level( skill_survival );
        ss << _( "You could harvest the following things from it:" ) << std::endl;
        // Group them by identical ids to avoid repeating same blocks of data
        // First, invert the mapping: season->id to id->seasons
        std::multimap<harvest_id, season_type> identical_harvest;
        for( size_t season = SPRING; season <= WINTER; season++ ) {
            const auto &hv = harvest_by_season[ season ];
            if( hv.obj().empty() ) {
                continue;
            }

            identical_harvest.insert( std::make_pair( hv, static_cast<season_type>( season ) ) );
        }
        // Now print them in order of seasons
        // @todo: Highlight current season
        for( size_t season = SPRING; season <= WINTER; season++ ) {
            const auto range = identical_harvest.equal_range( harvest_by_season[ season ] );
            if( range.first == range.second ) {
                continue;
            }

            // List the seasons first
            ss << enumerate_as_string( range.first, range.second,
            []( const std::pair<harvest_id, season_type> &pr ) {
                if( pr.second == season_of_year( calendar::turn ) ) {
                    return "<good>" + calendar::name_season( pr.second ) + "</good>";
                }

                return "<dark>" + calendar::name_season( pr.second ) + "</dark>";
            } );
            ss << ":" << std::endl;
            // List the drops
            // They actually describe what player can get from it now, so it isn't spoily
            // @todo: Allow spoily listing of everything
            ss << range.first->first.obj().describe( player_skill ) << std::endl;
            // Remove the range from the multimap so that it isn't listed twice
            identical_harvest.erase( range.first, range.second );
        }

        ss << std::endl;
    }

    return replace_colors( ss.str() );
}
Пример #2
0
/**
  Reduces the number of 4-color palettes in the image described
  by \a buf, \a width and \a height.
  Updates unique_pals to reflect the new palette usage.
  Updates \a pal_indexes to reflect the new palette usage.
  Updates \a buf to reflect the new palette usage.
*/
static void reduce_palettes(unsigned char *buf, int width, int height,
                            const unsigned char *pal_data, const int *pal_sizes,
                            int *unique_pals, int *unique_pals_count, int *pal_indexes)
{
    int i, j;
    int upc = *unique_pals_count;
    if (upc <= 4)
        return; /* nothing to do */

    int cw = width / 16;
    int ch = height / 16;
    /* count palette frequencies */
    int *pal_freqs = (int*)calloc(upc, sizeof(int));
    for (i = 0; i < cw * ch; ++i)
        ++pal_freqs[pal_indexes[i]];

    while (upc > 4) {
        int pi1 = -1;
        int pi2 = -1;
        int diff = INT_MAX;
#if 0
        printf("reducing from %d palettes\n", upc);
        printf("before:\n");
        for (int v = 0; v < upc; ++v) {
            printf(" %d: %d\t", v, pal_freqs[v]);
            for (int f = 0; f < pal_sizes[unique_pals[v]]; ++f)
                printf(" %.2X", pal_data[unique_pals[v]*4 + f]);
            printf("\n");
        }
        for (int w = 0; w < cw*ch; ++w)
            printf("%d ", pal_indexes[w]);
        printf("\n");
#endif
        /* find the two palettes that are most similar */
        for (i = 0; i < upc; ++i) {
            const unsigned char *p1 = &pal_data[unique_pals[i] * 4];
            int s1 = pal_sizes[unique_pals[i]];
            for (j = i + 1; j < upc; ++j) {
                const unsigned char *p2 = &pal_data[unique_pals[j] * 4];
                int s2 = pal_sizes[unique_pals[j]];
                int d = nes_palettes_diff(p1, s1, p2, s2);
                if (d <= diff) {
                    if ((pi1 == -1)
                            || (pal_freqs[i] < pal_freqs[pi1])
                            || (pal_freqs[j] < pal_freqs[pi2])
                            || (pal_freqs[j] < pal_freqs[pi1])
                            || (pal_freqs[i] < pal_freqs[pi2])) {
                        diff = d;
                        pi1 = i;
                        pi2 = j;
                    }
                }
            }
        }

        if (pal_freqs[pi1] > pal_freqs[pi2]) {
            int tmp = pi1;
            pi1 = pi2;
            pi2 = tmp;
        }
        /* replace pi1 by pi2 */
//	printf("replacing %d by %d\n", pi1, pi2);
        const unsigned char *dest_pal = &pal_data[unique_pals[pi2]*4];
        int dest_pal_sz = pal_sizes[unique_pals[pi2]];
        for (i = 0; i < ch; ++i) {
            for (j = 0; j < cw; ++j) {
                int k = i*cw + j;
                if (pal_indexes[k] == pi1) {
                    pal_indexes[k] = pi2;
                    if (pi2 > pi1)
                        --pal_indexes[k]; /* because pi1 will be removed from the array */
                    ++pal_freqs[pi2];
                    --pal_freqs[pi1];
                    /* replace colors so that only colors in target palette are used */
                    replace_colors(&buf[(i*width*16)+(j*16)], 16, 16, width,
                                   dest_pal, dest_pal_sz);
                } else if (pal_indexes[k] > pi1) {
                    --pal_indexes[k];
                }
            }
        }
        assert(pal_freqs[pi1] == 0);
        /* kill the unique_pals entry */
        memmove(&unique_pals[pi1], &unique_pals[pi1+1], (upc-(pi1+1))*sizeof(int));
        memmove(&pal_freqs[pi1], &pal_freqs[pi1+1], (upc-(pi1+1))*sizeof(int));
        --upc;
    }
    *unique_pals_count = upc;
#if 0
    printf("after:\n");
    for (int v = 0; v < upc; ++v) {
        printf(" %d: %d\t", v, pal_freqs[v]);
        for (int f = 0; f < pal_sizes[unique_pals[v]]; ++f)
            printf(" %.2X", pal_data[unique_pals[v]*4 + f]);
        printf("\n");
    }
    for (int w = 0; w < cw*ch; ++w)
        printf("%d ", pal_indexes[w]);
    printf("\n");
#endif
    free(pal_freqs);
}