Beispiel #1
0
static money32 BannerRemove(sint16 x, sint16 y, uint8 baseHeight, uint8 direction, uint8 flags)
{
    sint32 z = baseHeight * 8;
    gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING;
    gCommandPosition.x = x + 16;
    gCommandPosition.y = y + 16;
    gCommandPosition.z = z;

    if (!(flags & GAME_COMMAND_FLAG_GHOST) && game_is_paused() && !gCheatsBuildInPauseMode)
    {
        gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED;
        return MONEY32_UNDEFINED;
    }

    if (!map_can_build_at(x, y, z - 16))
    {
        return MONEY32_UNDEFINED;
    }

    // Slight modification to the code so that it now checks height as well
    // This was causing a bug with banners on two paths stacked.
    rct_tile_element* tileElement = map_get_banner_element_at(x / 32, y / 32, baseHeight, direction);
    if (tileElement == nullptr)
    {
        return MONEY32_UNDEFINED;
    }

    rct_banner *banner = &gBanners[tileElement->properties.banner.index];
    rct_scenery_entry *bannerEntry = get_banner_entry(banner->type);
    money32 refund = 0;
    if (bannerEntry != nullptr)
    {
        refund = -((bannerEntry->banner.price * 3) / 4);
    }

    if (flags & GAME_COMMAND_FLAG_APPLY)
    {
        if (gGameCommandNestLevel == 1 && !(flags & GAME_COMMAND_FLAG_GHOST))
        {
            LocationXYZ16 coord;
            coord.x = x + 16;
            coord.y = y + 16;
            coord.z = tile_element_height(coord.x, coord.y);
            network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord);
        }

        tile_element_remove_banner_entry(tileElement);
        map_invalidate_tile_zoom1(x, y, z, z + 32);
        tile_element_remove(tileElement);
    }

    if (gParkFlags & PARK_FLAGS_NO_MONEY)
    {
        refund = 0;
    }
    return refund;
}
/**
 *
 *  rct2: 0x0068A15E
 */
void sub_68A15E(sint32 screenX, sint32 screenY, sint16 *x, sint16 *y, sint32 *direction, rct_tile_element **tileElement)
{
    sint16 my_x, my_y;
    sint32 interactionType;
    rct_tile_element *myTileElement;
    rct_viewport *viewport;
    get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_TERRAIN & VIEWPORT_INTERACTION_MASK_WATER, &my_x, &my_y, &interactionType, &myTileElement, &viewport);

    if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE) {
        *x = LOCATION_NULL;
        return;
    }

    sint16 originalZ = 0;
    if (interactionType == VIEWPORT_INTERACTION_ITEM_WATER) {
        originalZ = surface_get_water_height(myTileElement) << 4;
    }

    LocationXY16 start_vp_pos = screen_coord_to_viewport_coord(viewport, screenX, screenY);
    LocationXY16 map_pos = { (sint16)(my_x + 16), (sint16)(my_y + 16) };

    for (sint32 i = 0; i < 5; i++) {
        sint16 z = originalZ;
        if (interactionType != VIEWPORT_INTERACTION_ITEM_WATER) {
            z = tile_element_height(map_pos.x, map_pos.y);
        }
        map_pos = viewport_coord_to_map_coord(start_vp_pos.x, start_vp_pos.y, z);
        map_pos.x = Math::Clamp<sint16>(map_pos.x, my_x, my_x + 31);
        map_pos.y = Math::Clamp<sint16>(map_pos.y, my_y, my_y + 31);
    }

    // Determine to which edge the cursor is closest
    sint32 myDirection;
    sint32 mod_x = map_pos.x & 0x1F;
    sint32 mod_y = map_pos.y & 0x1F;
    if (mod_x < mod_y) {
        if (mod_x + mod_y < 32) {
            myDirection = 0;
        } else {
            myDirection = 1;
        }
    } else {
        if (mod_x + mod_y < 32) {
            myDirection = 3;
        } else {
            myDirection = 2;
        }
    }

    *x = map_pos.x & ~0x1F;
    *y = map_pos.y & ~0x1F;
    if (direction != nullptr) *direction = myDirection;
    if (tileElement != nullptr) *tileElement = myTileElement;
}
Beispiel #3
0
static std::vector<paint_session> extract_paint_session(const std::string parkFileName)
{
    core_init();
    gOpenRCT2Headless = true;
    auto context = OpenRCT2::CreateContext();
    std::vector<paint_session> sessions;
    log_info("Starting...");
    if (context->Initialise())
    {
        drawing_engine_init();
        if (!context->LoadParkFromFile(parkFileName))
        {
            log_error("Failed to load park!");
            return {};
        }

        gIntroState = INTRO_STATE_NONE;
        gScreenFlags = SCREEN_FLAGS_PLAYING;

        int32_t mapSize = gMapSize;
        int32_t resolutionWidth = (mapSize * 32 * 2);
        int32_t resolutionHeight = (mapSize * 32 * 1);

        resolutionWidth += 8;
        resolutionHeight += 128;

        rct_viewport viewport;
        viewport.x = 0;
        viewport.y = 0;
        viewport.width = resolutionWidth;
        viewport.height = resolutionHeight;
        viewport.view_width = viewport.width;
        viewport.view_height = viewport.height;
        viewport.var_11 = 0;
        viewport.flags = 0;

        int32_t customX = (gMapSize / 2) * 32 + 16;
        int32_t customY = (gMapSize / 2) * 32 + 16;

        int32_t x = 0, y = 0;
        int32_t z = tile_element_height(customX, customY) & 0xFFFF;
        x = customY - customX;
        y = ((customX + customY) / 2) - z;

        viewport.view_x = x - ((viewport.view_width) / 2);
        viewport.view_y = y - ((viewport.view_height) / 2);
        viewport.zoom = 0;
        gCurrentRotation = 0;

        // Ensure sprites appear regardless of rotation
        reset_all_sprite_quadrant_placements();

        rct_drawpixelinfo dpi;
        dpi.x = 0;
        dpi.y = 0;
        dpi.width = resolutionWidth;
        dpi.height = resolutionHeight;
        dpi.pitch = 0;
        dpi.bits = (uint8_t*)malloc(dpi.width * dpi.height);

        log_info("Obtaining sprite data...");
        viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height, &sessions);

        free(dpi.bits);
        drawing_engine_dispose();
    }
    log_info("Got %u paint sessions.", std::size(sessions));
    return sessions;
}
Beispiel #4
0
static money32 BannerPlace(sint16 x, sint16 y, uint8 pathBaseHeight, uint8 direction, uint8 colour, uint8 type, uint8 *bannerIndex, uint8 flags)
{
    gCommandPosition.x = x + 16;
    gCommandPosition.y = y + 16;
    gCommandPosition.z = pathBaseHeight * 16;
    gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING;
    if (game_is_paused() && !gCheatsBuildInPauseMode)
    {
        gGameCommandErrorText = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED;
        return MONEY32_UNDEFINED;
    }

    if (!map_check_free_elements_and_reorganise(1))
    {
        return MONEY32_UNDEFINED;
    }

    if (!map_is_location_valid(x, y))
    {
        return MONEY32_UNDEFINED;
    }

    rct_tile_element* tileElement = map_get_first_element_at(x / 32, y / 32);

    bool pathFound = false;
    do
    {
        if (tile_element_get_type(tileElement) != TILE_ELEMENT_TYPE_PATH)
            continue;

        if (tileElement->base_height != pathBaseHeight * 2 && tileElement->base_height != (pathBaseHeight - 1) * 2)
            continue;

        if (!(tileElement->properties.path.edges & (1 << direction)))
            continue;

        pathFound = true;
        break;
    } while (!tile_element_is_last_for_tile(tileElement++));

    if (!pathFound)
    {
        gGameCommandErrorText = STR_CAN_ONLY_BE_BUILT_ACROSS_PATHS;
        return MONEY32_UNDEFINED;
    }

    if (!map_can_build_at(x, y, pathBaseHeight * 16))
    {
        return MONEY32_UNDEFINED;
    }

    uint8 baseHeight = (pathBaseHeight + 1) * 2;
    tileElement = map_get_banner_element_at(x / 32, y / 32, baseHeight, direction);
    if (tileElement != nullptr)
    {
        gGameCommandErrorText = STR_BANNER_SIGN_IN_THE_WAY;
        return MONEY32_UNDEFINED;
    }

    *bannerIndex = create_new_banner(flags);
    if (*bannerIndex == BANNER_NULL)
    {
        return MONEY32_UNDEFINED;
    }

    if (flags & GAME_COMMAND_FLAG_APPLY)
    {
        if (gGameCommandNestLevel == 1 && !(flags & GAME_COMMAND_FLAG_GHOST))
        {
            LocationXYZ16 coord;
            coord.x = x + 16;
            coord.y = y + 16;
            coord.z = tile_element_height(coord.x, coord.y);
            network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord);
        }

        rct_tile_element* newTileElement = tile_element_insert(x / 32, y / 32, baseHeight, 0);
        assert(newTileElement != nullptr);
        gBanners[*bannerIndex].type = type;
        gBanners[*bannerIndex].colour = colour;
        gBanners[*bannerIndex].x = x / 32;
        gBanners[*bannerIndex].y = y / 32;
        newTileElement->type = TILE_ELEMENT_TYPE_BANNER;
        newTileElement->clearance_height = newTileElement->base_height + 2;
        newTileElement->properties.banner.position = direction;
        newTileElement->properties.banner.flags = 0xFF;
        newTileElement->properties.banner.unused = 0;
        newTileElement->properties.banner.index = *bannerIndex;
        if (flags & GAME_COMMAND_FLAG_GHOST)
        {
            newTileElement->flags |= TILE_ELEMENT_FLAG_GHOST;
        }
        map_invalidate_tile_full(x, y);
        map_animation_create(MAP_ANIMATION_TYPE_BANNER, x, y, newTileElement->base_height);
    }

    rct_scenery_entry *bannerEntry = get_banner_entry(type);
    if (bannerEntry == nullptr)
    {
        return MONEY32_UNDEFINED;
    }

    if (gParkFlags & PARK_FLAGS_NO_MONEY)
    {
        return 0;
    }
    return bannerEntry->banner.price;
}