GameActionResult::Ptr Execute() const override { rct_banner* banner = &gBanners[_bannerIndex]; utf8 *buffer = gCommonStringFormatBuffer; utf8 *dst = buffer; dst = utf8_write_codepoint(dst, FORMAT_COLOUR_CODE_START + banner->text_colour); String::Set(dst, sizeof(gCommonStringFormatBuffer) - (dst - buffer), _name.c_str(), _name.size()); rct_string_id string_id = user_string_allocate(USER_STRING_DUPLICATION_PERMITTED, buffer); if (string_id == 0) { return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_ERR_CANT_SET_BANNER_TEXT); } rct_string_id prev_string_id = banner->string_idx; banner->string_idx = string_id; user_string_free(prev_string_id); auto intent = Intent(INTENT_ACTION_UPDATE_BANNER); intent.putExtra(INTENT_EXTRA_BANNER_INDEX, _bannerIndex); context_broadcast_intent(&intent); return MakeResult(); }
static money32 BannerSetColour(sint16 x, sint16 y, uint8 baseHeight, uint8 direction, uint8 colour, uint8 flags) { gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LANDSCAPING; sint32 z = (baseHeight * 8); gCommandPosition.x = x + 16; gCommandPosition.y = y + 16; gCommandPosition.z = z; if (!map_can_build_at(x, y, z - 16)) { return MONEY32_UNDEFINED; } if (flags & GAME_COMMAND_FLAG_APPLY) { rct_tile_element* tileElement = map_get_first_element_at(x / 32, y / 32); bool found = false; do { if (tile_element_get_type(tileElement) != TILE_ELEMENT_TYPE_BANNER) continue; if (tileElement->properties.banner.position != direction) continue; found = true; break; } while (!tile_element_is_last_for_tile(tileElement++)); if (!found) { return MONEY32_UNDEFINED; } auto intent = Intent(INTENT_ACTION_UPDATE_BANNER); intent.putExtra(INTENT_EXTRA_BANNER_INDEX, tileElement->properties.banner.index); context_broadcast_intent(&intent); gBanners[tileElement->properties.banner.index].colour = colour; map_invalidate_tile_zoom1(x, y, z, z + 32); } return 0; }
/** * Weather & climate update iteration. * Gradually changes the weather parameters towards their determined next values. */ void climate_update() { // Only do climate logic if playing (not in scenario editor or title screen) if (gScreenFlags & (~SCREEN_FLAGS_PLAYING)) return; if (!gCheatsFreezeClimate) { if (gClimateUpdateTimer) { if (gClimateUpdateTimer == 960) { auto intent = Intent(INTENT_ACTION_UPDATE_CLIMATE); context_broadcast_intent(&intent); } gClimateUpdateTimer--; } else if (!(gCurrentTicks & 0x7F)) { if (gClimateCurrent.Temperature == gClimateNext.Temperature) { if (gClimateCurrent.WeatherGloom == gClimateNext.WeatherGloom) { gClimateCurrent.WeatherEffect = gClimateNext.WeatherEffect; _thunderTimer = 0; _lightningTimer = 0; if (gClimateCurrent.RainLevel == gClimateNext.RainLevel) { gClimateCurrent.Weather = gClimateNext.Weather; climate_determine_future_weather(scenario_rand()); auto intent = Intent(INTENT_ACTION_UPDATE_CLIMATE); context_broadcast_intent(&intent); } else if (gClimateNext.RainLevel <= RAIN_LEVEL_HEAVY) { gClimateCurrent.RainLevel = climate_step_weather_level(gClimateCurrent.RainLevel, gClimateNext.RainLevel); } } else { gClimateCurrent.WeatherGloom = climate_step_weather_level(gClimateCurrent.WeatherGloom, gClimateNext.WeatherGloom); gfx_invalidate_screen(); } } else { gClimateCurrent.Temperature = climate_step_weather_level(gClimateCurrent.Temperature, gClimateNext.Temperature); auto intent = Intent(INTENT_ACTION_UPDATE_CLIMATE); context_broadcast_intent(&intent); } } } if (_thunderTimer != 0) { climate_update_lightning(); climate_update_thunder(); } else if (gClimateCurrent.WeatherEffect == WEATHER_EFFECT_STORM) { // Create new thunder and lightning uint32 randomNumber = util_rand(); if ((randomNumber & 0xFFFF) <= 0x1B4) { randomNumber >>= 16; _thunderTimer = 43 + (randomNumber % 64); _lightningTimer = randomNumber % 32; }
static money32 BannerSetStyle(uint8 bannerIndex, uint8 colour, uint8 textColour, uint8 bannerFlags, uint8 flags) { if (bannerIndex >= MAX_BANNERS) { gGameCommandErrorText = STR_INVALID_SELECTION_OF_OBJECTS; return MONEY32_UNDEFINED; } rct_banner* banner = &gBanners[bannerIndex]; rct_tile_element* tileElement = banner_get_tile_element(bannerIndex); if (tileElement == nullptr) { return MONEY32_UNDEFINED; } if (!(flags & GAME_COMMAND_FLAG_APPLY)) { return 0; } banner->colour = colour; banner->text_colour = textColour; banner->flags = bannerFlags; tileElement->properties.banner.flags = 0xFF; if (banner->flags & BANNER_FLAG_NO_ENTRY) { tileElement->properties.banner.flags &= ~(1 << tileElement->properties.banner.position); } sint32 colourCodepoint = FORMAT_COLOUR_CODE_START + banner->text_colour; utf8 buffer[256]; format_string(buffer, 256, banner->string_idx, nullptr); sint32 firstCodepoint = utf8_get_next(buffer, nullptr); if (firstCodepoint >= FORMAT_COLOUR_CODE_START && firstCodepoint <= FORMAT_COLOUR_CODE_END) { utf8_write_codepoint(buffer, colourCodepoint); } else { utf8_insert_codepoint(buffer, colourCodepoint); } rct_string_id stringId = user_string_allocate(USER_STRING_DUPLICATION_PERMITTED, buffer); if (stringId != 0) { rct_string_id prevStringId = banner->string_idx; banner->string_idx = stringId; user_string_free(prevStringId); auto intent = Intent(INTENT_ACTION_UPDATE_BANNER); intent.putExtra(INTENT_EXTRA_BANNER_INDEX, bannerIndex); context_broadcast_intent(&intent); } else { gGameCommandErrorText = STR_ERR_CANT_SET_BANNER_TEXT; return MONEY32_UNDEFINED; } return 0; }
static money32 BannerSetName(uint8 bannerIndex, uint16 nameChunkIndex, uint32 nameChunk1, uint32 nameChunk2, uint32 nameChunk3, uint8 flags) { static char newName[128]; if (bannerIndex >= MAX_BANNERS) { log_warning("Invalid game command for setting banner name, banner id = %d", bannerIndex); return MONEY32_UNDEFINED; } rct_banner* banner = &gBanners[bannerIndex]; gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS; size_t indexToOffset[3] = { 24, 0, 12 }; if (nameChunkIndex > Util::CountOf(indexToOffset)) { log_warning("Invalid chunk index for setting banner name, banner id = %d, index = %d", bannerIndex, nameChunkIndex); return MONEY32_UNDEFINED; } size_t nameChunkOffset = std::min<size_t>(indexToOffset[nameChunkIndex], Util::CountOf(newName) - 12); std::memcpy(&newName[0 + nameChunkOffset], &nameChunk1, sizeof(uint32)); std::memcpy(&newName[4 + nameChunkOffset], &nameChunk2, sizeof(uint32)); std::memcpy(&newName[8 + nameChunkOffset], &nameChunk3, sizeof(uint32)); if (nameChunkIndex != 0) { return 0; } if (!(flags & GAME_COMMAND_FLAG_APPLY)) { return 0; } utf8 *buffer = gCommonStringFormatBuffer; utf8 *dst = buffer; dst = utf8_write_codepoint(dst, FORMAT_COLOUR_CODE_START + banner->text_colour); String::Set(dst, 256, newName, 32); rct_string_id stringId = user_string_allocate(USER_STRING_DUPLICATION_PERMITTED, buffer); if (stringId != 0) { rct_string_id prevStringId = banner->string_idx; banner->string_idx = stringId; user_string_free(prevStringId); auto intent = Intent(INTENT_ACTION_UPDATE_BANNER); intent.putExtra(INTENT_EXTRA_BANNER_INDEX, bannerIndex); context_broadcast_intent(&intent); } else { gGameCommandErrorText = STR_ERR_CANT_SET_BANNER_TEXT; return MONEY32_UNDEFINED; } return 0; }