コード例 #1
0
void wid_game_map_client_scroll_adjust (uint8_t adjust) 
{
    if (!player) {
        return;
    }

    widp w = player->wid;
    if (!w) {
        return;
    }

    uint32_t gridw;
    uint32_t gridh;

    wid_get_grid_dim(wid_game_map_client_grid_container, &gridw, &gridh);

    double fgridw = (double)gridw;
    double fgridh = (double)gridh;

    double winw = wid_get_width(wid_game_map_client_window);
    double winh = wid_get_height(wid_game_map_client_window);

    gridw -= winw;
    gridh -= winh;

    double playerx = wid_get_cx(w);
    double playery = wid_get_cy(w);

    playerx -= winw / 2.0;
    playery -= winh / 2.0;

    playerx /= fgridw;
    playery /= fgridh;

    if (adjust || (last_playery != playery)) {
        wid_move_to_vert_pct(wid_game_map_client_vert_scroll, playery);
    }

    if (adjust || (last_playerx != playerx)) {
        wid_move_to_horiz_pct(wid_game_map_client_horiz_scroll, playerx);
    }

    /*
     * Lock the level scroll bar so we don't adjust the level size when 
     * explosions or anything else leaks over the edge.
     */
    wid_game_map_client_grid_container->grid->bounds_locked = 1;

    last_playerx = playerx;
    last_playery = playery;
}
コード例 #2
0
/*
 * Replace or place a tile.
 */
widp
wid_game_map_client_replace_tile (widp w, 
                                  double x, double y, 
                                  thingp t,
                                  tpp tp)
{
    tree_rootp thing_tiles;
    const char *tilename;
    tilep tile;
    widp child;

    verify(w);

    /*
     * Grow tl and br to fit the template thing. Use the first tile.
     */
    if (!tp) {
        tp = thing_tp(t);
        if (!tp) {
            ERR("no thing template to replace on client");
            return (0);
        }
    }

    if ((x < 0) || (y < 0) || (x >= MAP_WIDTH) || (y >= MAP_WIDTH)) {
        LOG("client: thing template [%s] cannot be placed at %f %f",
            tp_short_name(tp), x, y);
        return (0);
    }

    thing_tiles = tp_get_tiles(tp);
    if (!thing_tiles) {
        ERR("thing template [%s] has no tiles", tp_short_name(tp));
        return (0);
    }

    thing_tilep thing_tile;

    /*
     * Get a random tile to start with.
     */
    thing_tile = (typeof(thing_tile)) thing_tile_random(thing_tiles);

    /*
     * Find the real tile that corresponds to this name.
     */
    tilename = thing_tile_name(thing_tile);
    tile = tile_find(tilename);

    if (!tile) {
        ERR("tile name %s from thing %s not found on client",
            tilename,
            tp_short_name(tp));
        return (0);
    }

    /*
     * Make a new thing.
     */
    child = wid_new_square_button(wid_game_map_client_grid_container,
                                  "client map tile");

    wid_set_mode(child, WID_MODE_NORMAL);
    wid_set_no_shape(child);

    /*
     * "paint" the thing.
     */
    wid_game_map_client_set_thing_template(child, tp);

    if (!t) {
        t = thing_client_local_new(tp);
    }

    wid_set_thing(child, t);
    wid_set_tile(child, tile);

    double dx = 0;
    double dy = 0;

    /*
     * Does it appear as a different size on screen?
     */
    double scale = tp_get_scale(tp);

    /*
     * So we have baby and bigger slimes. But alas this is visual only and has 
     * no effect on hp on the server yet.
     */
    if (thing_is_variable_size(t)) {
        scale += gaussrand(0.0, 0.05);
    }

    if (scale != 1.0) {
        wid_scaling_blit_to_pct_in(child, scale, scale, 500, 9999999);
    }

    if (thing_is_cloud_effect(t)) {
        /*
         * The epicenter needs to be where it was on the server as we do a 
         * flood fill to see where the rest of the explosion goes.
         */
        if (!t->is_epicenter) {
            dx = gaussrand(0.0, 0.5);
            dy = gaussrand(0.0, 0.5);
        }

        wid_fade_out(child, 1000);
    }

    thing_client_wid_update(t, x + dx, y + dy, false /* smooth */,
                            true /* is new */);

    /*
     * Offset tall things
     */
    if (scale != 1.0) {
        if (thing_is_blit_y_offset(t)) {
            wid_set_blit_y_offset(child, 
                                  wid_get_height(child) * scale * -((scale - 1.0) / 2.0));
        }
    }

    /*
     * If this is a pre-existing thing perhaps being recreated ona new level
     * then it will have a direction already. Update it.
     */
    if (thing_is_animated(t)) {
        thing_animate(t);
    }

    /*
     * This adds it to the grid wid.
     */
#ifdef DEBUG_CLIENT_THING
    wid_update(child);
    char name[20];
    sprintf(name, "%d",t->thing_id);
    wid_set_text(child,name);
#endif

    /*
     * We've been told about the epicenter of an explsion, now emulate the 
     * blast.
     */
    if (t->is_epicenter && thing_is_cloud_effect(t) ) {

        if ((tp->id == THING_EXPLOSION1)        ||
            (tp->id == THING_EXPLOSION2)        ||
            (tp->id == THING_EXPLOSION3)        ||
            (tp->id == THING_EXPLOSION4)        ||
            (tp->id == THING_SMALL_EXPLOSION1)  ||
            (tp->id == THING_SMALL_EXPLOSION2)  ||
            (tp->id == THING_SMALL_EXPLOSION3)  ||
            (tp->id == THING_SMALL_EXPLOSION4)  ||
            (tp->id == THING_MED_EXPLOSION1)    ||
            (tp->id == THING_MED_EXPLOSION2)    ||
            (tp->id == THING_MED_EXPLOSION3)    ||
            (tp->id == THING_MED_EXPLOSION4)    ||
            (tp->id == THING_FIREBURST1)        ||
            (tp->id == THING_FIREBURST2)        ||
            (tp->id == THING_FIREBURST3)        ||
            (tp->id == THING_FIREBURST4)        ||
            (tp->id == THING_BOMB)              ||
            (tp->id == THING_POISON1)           ||
            (tp->id == THING_POISON2)           ||
            (tp->id == THING_CLOUDKILL1)        ||
            (tp->id == THING_CLOUDKILL2)) {

            level_place_explosion(client_level,
                                  0, /* owner */
                                  tp,
                                  t->x, t->y,
                                  t->x, t->y);
        } else {
            ERR("unknown explosion %s", thing_logname(t));
        }
    }

    const char *sound = tp_sound_on_creation(tp);
    if (sound) {
        if (thing_is_cloud_effect(t)) {
            if (t->is_epicenter) {
                sound_play_at(sound, t->x, t->y);
            }
        } else {
            sound_play_at(sound, t->x, t->y);
        }
    }

    return (child);
}
コード例 #3
0
/*
 * Key down etc...
 */
static uint8_t wid_text_input_receive_input (widp w, const SDL_KEYSYM *key)
{
    widp button;

    switch (key->sym) {
        case SDLK_RETURN:
            button = wid_find(wid_get_top_parent(w), "ok");
            if (button) {
                wid_text_input_button_selected(button);
                return (true);
            }

            button = wid_find(wid_get_top_parent(w), "yes");
            if (button) {
                wid_text_input_button_selected(button);
                return (true);
            }

            if (wid_text_input_button_selected(w)) {
                return (true);
            }

            break;

        case SDLK_ESCAPE: {
            button = wid_find(wid_get_top_parent(w), "cancel");
            if (button) {
                wid_text_input_button_selected(button);
                return (true);
            }

            button = wid_find(wid_get_top_parent(w), "no");
            if (button) {
                wid_text_input_button_selected(button);
                return (true);
            }

            button = wid_find(wid_get_top_parent(w), "close");
            if (button) {
                wid_text_input_button_selected(button);
                return (true);
            }

            if (wid_text_input_button_selected(w)) {
                return (true);
            }

            break;
        }

        default:
            break;
    }

    /*
     * Feed to the general input handler
     */
    int32_t ret = wid_receive_input(w, key);

    /*
     * Update the text_input to show only matching files.
     */
    widp container = wid_find(wid_get_top_parent(w),
                              wid_text_input_filelist_container_str);
    if (!container) {
        return (ret);
    }

    tree_root *r = wid_get_children(container);
    if (!r) {
        return (ret);
    }

    tree_node *n = tree_root_first(r);
    while (n) {
        fpoint container_tl;
        fpoint container_br;
        fpoint trough_tl;
        fpoint trough_br;
        double child_height;
        widp child;
        fpoint tl;
        fpoint br;

        child = (typeof(child)) n;

        /*
         * If a partial match, highlight the widget.
         */
        if (strncmp(wid_get_text(child), wid_get_text(w),
                    strlen(wid_get_text(w)))) {

            n = tree_get_next(r, r->node, n);
            continue;
        }

        wid_set_mode(child, WID_MODE_ACTIVE);

        /*
         * Find where the child is with respect to the parent.
         */
        wid_get_tl_br(child, &tl, &br);
        wid_get_tl_br(container, &container_tl, &container_br);

        /*
         * Compare within the overall height of all children.
         */
        wid_get_children_size(container, 0, &child_height);

        /*
         * What percentage of the way down.
         */
        double pct = (double)(tl.y - container_tl.y) / (double)child_height;

        /*
         * Now adjust the scrollbar.
         */
        widp scrollbar = wid_get_scrollbar_vert(container);

        /*
         * But we need the trough height.
         */
        wid_get_tl_br(wid_get_parent(scrollbar), &trough_tl, &trough_br);

        double trough_height =
                wid_get_height(wid_get_parent(scrollbar));

        /*
         * Now apply the same percentage as a wid move.
         */
        wid_move_to_abs_in(scrollbar, trough_tl.x,
                           trough_tl.y + pct * trough_height, 100);

        return (ret);
    }

    return (ret);
}