OpenRCT2/src/openrct2/windows/new_campaign.c

401 lines
14 KiB
C
Raw Normal View History

#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
2017-02-18 16:45:10 +01:00
#include "../config/Config.h"
2014-10-06 18:36:58 +02:00
#include "../game.h"
#include "../localisation/localisation.h"
#include "../interface/widget.h"
#include "../interface/window.h"
#include "../management/marketing.h"
#include "../ride/ride.h"
2015-08-05 20:17:37 +02:00
#include "../ride/ride_data.h"
2014-10-06 18:36:58 +02:00
#include "dropdown.h"
2014-08-12 01:27:25 +02:00
#define SELECTED_RIDE_UNDEFINED ((uint16)0xFFFF)
2014-08-12 01:27:25 +02:00
enum WINDOW_NEW_CAMPAIGN_WIDGET_IDX {
WIDX_BACKGROUND,
WIDX_TITLE,
WIDX_CLOSE,
WIDX_RIDE_LABEL,
WIDX_RIDE_DROPDOWN,
WIDX_RIDE_DROPDOWN_BUTTON,
WIDX_WEEKS_LABEL,
WIDX_WEEKS_SPINNER,
WIDX_WEEKS_INCREASE_BUTTON,
WIDX_WEEKS_DECREASE_BUTTON,
WIDX_START_BUTTON
2014-08-12 01:27:25 +02:00
};
static rct_widget window_new_campaign_widgets[] = {
{ WWT_FRAME, 0, 0, 349, 0, 106, 0xFFFFFFFF, STR_NONE }, // panel / background
{ WWT_CAPTION, 0, 1, 348, 1, 14, 0, STR_WINDOW_TITLE_TIP }, // title bar
{ WWT_CLOSEBOX, 0, 337, 347, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, // close x button
{ WWT_24, 0, 0, 139, 24, 35, 0, STR_NONE }, // ride label
{ WWT_DROPDOWN, 0, 100, 341, 24, 35, 0, STR_NONE }, // ride dropdown
{ WWT_DROPDOWN_BUTTON, 0, 330, 340, 25, 34, STR_DROPDOWN_GLYPH, STR_NONE }, // ride dropdown button
{ WWT_24, 0, 0, 139, 41, 52, STR_LENGTH_OF_TIME, STR_NONE }, // weeks label
{ WWT_SPINNER, 0, 120, 219, 41, 52, 0, STR_NONE }, // weeks
{ WWT_DROPDOWN_BUTTON, 0, 208, 218, 42, 46, STR_NUMERIC_UP, STR_NONE }, // weeks +
{ WWT_DROPDOWN_BUTTON, 0, 208, 218, 47, 51, STR_NUMERIC_DOWN, STR_NONE }, // weeks -
{ WWT_DROPDOWN_BUTTON, 0, 14, 335, 89, 100, STR_MARKETING_START_THIS_MARKETING_CAMPAIGN, STR_NONE }, // start button
{ WIDGETS_END }
2014-08-12 01:27:25 +02:00
};
2017-05-01 15:41:45 +02:00
static void window_new_campaign_mouseup(rct_window *w, rct_widgetindex widgetIndex);
static void window_new_campaign_mousedown(rct_widgetindex widgetIndex, rct_window*w, rct_widget* widget);
static void window_new_campaign_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex);
static void window_new_campaign_invalidate(rct_window *w);
static void window_new_campaign_paint(rct_window *w, rct_drawpixelinfo *dpi);
2014-08-12 01:27:25 +02:00
static rct_window_event_list window_new_campaign_events = {
NULL,
window_new_campaign_mouseup,
NULL,
window_new_campaign_mousedown,
window_new_campaign_dropdown,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
window_new_campaign_invalidate,
window_new_campaign_paint,
NULL
2014-08-12 01:27:25 +02:00
};
uint8 window_new_campaign_rides[MAX_RIDES];
uint8 window_new_campaign_shop_items[64];
2017-01-04 22:17:08 +01:00
static sint32 ride_value_compare(const void *a, const void *b)
2014-08-12 01:27:25 +02:00
{
rct_ride *rideA, *rideB;
2014-08-12 01:27:25 +02:00
rideA = get_ride(*((uint8*)a));
rideB = get_ride(*((uint8*)b));
return rideB->value - rideA->value;
2014-08-12 01:27:25 +02:00
}
2017-01-04 22:17:08 +01:00
static sint32 ride_name_compare(const void *a, const void *b)
2014-08-12 01:27:25 +02:00
{
char rideAName[256], rideBName[256];
rct_ride *rideA, *rideB;
2014-08-12 01:27:25 +02:00
rideA = get_ride(*((uint8*)a));
rideB = get_ride(*((uint8*)b));
2014-08-12 01:27:25 +02:00
format_string(rideAName, 256, rideA->name, &rideA->name_arguments);
format_string(rideBName, 256, rideB->name, &rideB->name_arguments);
2014-08-12 01:27:25 +02:00
return _strcmpi(rideAName, rideBName);
2014-08-12 01:27:25 +02:00
}
/**
2015-10-20 20:16:30 +02:00
*
* rct2: 0x0069E16F
*/
void window_new_campaign_open(sint16 campaignType)
{
rct_window *w;
rct_ride *ride;
sint32 i, numApplicableRides;
w = window_bring_to_front_by_class(WC_NEW_CAMPAIGN);
if (w != NULL) {
if (w->campaign.campaign_type == campaignType)
return;
window_close(w);
}
w = window_create_auto_pos(350, 107, &window_new_campaign_events, WC_NEW_CAMPAIGN, 0);
w->widgets = window_new_campaign_widgets;
w->enabled_widgets =
(1 << WIDX_CLOSE) |
(1 << WIDX_RIDE_DROPDOWN) |
(1 << WIDX_RIDE_DROPDOWN_BUTTON) |
(1 << WIDX_WEEKS_INCREASE_BUTTON) |
(1 << WIDX_WEEKS_DECREASE_BUTTON) |
(1 << WIDX_START_BUTTON);
w->hold_down_widgets =
(1 << WIDX_WEEKS_INCREASE_BUTTON) |
(1 << WIDX_WEEKS_DECREASE_BUTTON);
window_init_scroll_widgets(w);
window_new_campaign_widgets[WIDX_TITLE].text = MarketingCampaignNames[campaignType][0];
// Campaign type
w->campaign.campaign_type = campaignType;
// Number of weeks
w->campaign.no_weeks = 2;
// Currently selected ride
w->campaign.ride_id = SELECTED_RIDE_UNDEFINED;
// Get all applicable rides
numApplicableRides = 0;
window_new_campaign_rides[0] = 255;
FOR_ALL_RIDES(i, ride) {
if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP | RIDE_TYPE_FLAG_SELLS_FOOD | RIDE_TYPE_FLAG_SELLS_DRINKS | RIDE_TYPE_FLAG_IS_BATHROOM))
window_new_campaign_rides[numApplicableRides++] = i;
}
// Take top 40 most reliable rides
if (numApplicableRides > 40) {
qsort(window_new_campaign_rides, numApplicableRides, sizeof(uint8), ride_value_compare);
numApplicableRides = 40;
}
// Sort rides by name
qsort(window_new_campaign_rides, numApplicableRides, sizeof(uint8), ride_name_compare);
window_new_campaign_rides[numApplicableRides] = 255;
2014-08-12 01:27:25 +02:00
}
/**
2015-10-20 20:16:30 +02:00
*
2014-08-12 01:27:25 +02:00
* rct2: 0x0069E320
*/
static void window_new_campaign_get_shop_items()
{
sint32 i, numItems;
rct_ride *ride;
uint64 items = 0;
FOR_ALL_RIDES(i, ride) {
rct_ride_entry *rideType = get_ride_entry(ride->subtype);
if (rideType == NULL) {
continue;
}
uint8 itemType = rideType->shop_item;
if (itemType != 255)
items |= 1LL << itemType;
}
// Remove certain items?
items &= 0x0011FF78036BA3E0;
//
numItems = 0;
for (i = 0; i < 64; i++)
if (items & (1LL << i))
window_new_campaign_shop_items[numItems++] = i;
window_new_campaign_shop_items[numItems] = 255;
2014-08-12 01:27:25 +02:00
}
/**
2015-10-20 20:16:30 +02:00
*
2014-08-12 01:27:25 +02:00
* rct2: 0x0069E50B
*/
2017-05-01 15:41:45 +02:00
static void window_new_campaign_mouseup(rct_window *w, rct_widgetindex widgetIndex)
2014-08-12 01:27:25 +02:00
{
switch (widgetIndex) {
case WIDX_CLOSE:
window_close(w);
break;
case WIDX_START_BUTTON:
marketing_start_campaign(w->campaign.campaign_type, w->campaign.ride_id, w->campaign.no_weeks);
break;
}
2014-08-12 01:27:25 +02:00
}
/**
2015-10-20 20:16:30 +02:00
*
2014-08-12 01:27:25 +02:00
* rct2: 0x0069E51C
*/
2017-05-01 15:41:45 +02:00
static void window_new_campaign_mousedown(rct_widgetindex widgetIndex, rct_window *w, rct_widget* widget)
2014-08-12 01:27:25 +02:00
{
rct_widget *dropdownWidget;
switch (widgetIndex) {
case WIDX_RIDE_DROPDOWN_BUTTON:
dropdownWidget = widget - 1;
if (w->campaign.campaign_type == ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE) {
window_new_campaign_get_shop_items();
if (window_new_campaign_shop_items[0] != 255) {
sint32 numItems = 0;
for (sint32 i = 0; i < 40; i++) {
if (window_new_campaign_shop_items[i] == 255)
break;
gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
gDropdownItemsArgs[i] = ShopItemStringIds[window_new_campaign_shop_items[i]].plural;
numItems++;
}
window_dropdown_show_text_custom_width(
w->x + dropdownWidget->left,
w->y + dropdownWidget->top,
dropdownWidget->bottom - dropdownWidget->top + 1,
w->colours[1],
0,
DROPDOWN_FLAG_STAY_OPEN,
numItems,
dropdownWidget->right - dropdownWidget->left - 3
);
}
} else {
sint32 numItems = 0;
for (sint32 i = 0; i < 40; i++) {
if (window_new_campaign_rides[i] == 255)
break;
rct_ride *ride = get_ride(window_new_campaign_rides[i]);
gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
gDropdownItemsArgs[i] = ((uint64)ride->name_arguments << 16ULL) | ride->name;
numItems++;
}
window_dropdown_show_text_custom_width(
w->x + dropdownWidget->left,
w->y + dropdownWidget->top,
dropdownWidget->bottom - dropdownWidget->top + 1,
w->colours[1],
0,
DROPDOWN_FLAG_STAY_OPEN,
numItems,
dropdownWidget->right - dropdownWidget->left - 3
);
}
break;
// In RCT2, the maximum was 6 weeks
case WIDX_WEEKS_INCREASE_BUTTON:
w->campaign.no_weeks = min(w->campaign.no_weeks + 1, 12);
window_invalidate(w);
break;
case WIDX_WEEKS_DECREASE_BUTTON:
w->campaign.no_weeks = max(w->campaign.no_weeks - 1, 2);
window_invalidate(w);
break;
}
2014-08-12 01:27:25 +02:00
}
/**
2015-10-20 20:16:30 +02:00
*
2014-08-12 01:27:25 +02:00
* rct2: 0x0069E537
*/
2017-05-01 15:41:45 +02:00
static void window_new_campaign_dropdown(rct_window *w, rct_widgetindex widgetIndex, sint32 dropdownIndex)
2014-08-12 01:27:25 +02:00
{
if (widgetIndex != WIDX_RIDE_DROPDOWN_BUTTON)
return;
2014-08-12 01:27:25 +02:00
if (dropdownIndex == -1)
return;
if (w->campaign.campaign_type == ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE) {
w->campaign.ride_id = window_new_campaign_shop_items[dropdownIndex];
} else {
w->campaign.ride_id = window_new_campaign_rides[dropdownIndex];
}
2014-08-12 01:27:25 +02:00
window_invalidate(w);
2014-08-12 01:27:25 +02:00
}
/**
2015-10-20 20:16:30 +02:00
*
2014-08-12 01:27:25 +02:00
* rct2: 0x0069E397
*/
static void window_new_campaign_invalidate(rct_window *w)
2014-08-12 01:27:25 +02:00
{
window_new_campaign_widgets[WIDX_RIDE_LABEL].type = WWT_EMPTY;
window_new_campaign_widgets[WIDX_RIDE_DROPDOWN].type = WWT_EMPTY;
window_new_campaign_widgets[WIDX_RIDE_DROPDOWN_BUTTON].type = WWT_EMPTY;
window_new_campaign_widgets[WIDX_RIDE_DROPDOWN].text = STR_MARKETING_NOT_SELECTED;
switch (w->campaign.campaign_type) {
case ADVERTISING_CAMPAIGN_RIDE_FREE:
case ADVERTISING_CAMPAIGN_RIDE:
window_new_campaign_widgets[WIDX_RIDE_LABEL].type = WWT_24;
window_new_campaign_widgets[WIDX_RIDE_DROPDOWN].type = WWT_DROPDOWN;
window_new_campaign_widgets[WIDX_RIDE_DROPDOWN_BUTTON].type = WWT_DROPDOWN_BUTTON;
window_new_campaign_widgets[WIDX_RIDE_LABEL].text = STR_MARKETING_RIDE;
if (w->campaign.ride_id != SELECTED_RIDE_UNDEFINED) {
rct_ride *ride = get_ride(w->campaign.ride_id);
window_new_campaign_widgets[WIDX_RIDE_DROPDOWN].text = ride->name;
set_format_arg(0, uint32, ride->name_arguments);
}
break;
case ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE:
window_new_campaign_widgets[WIDX_RIDE_LABEL].type = WWT_24;
window_new_campaign_widgets[WIDX_RIDE_DROPDOWN].type = WWT_DROPDOWN;
window_new_campaign_widgets[WIDX_RIDE_DROPDOWN_BUTTON].type = WWT_DROPDOWN_BUTTON;
window_new_campaign_widgets[WIDX_RIDE_LABEL].text = STR_MARKETING_ITEM;
if (w->campaign.ride_id != SELECTED_RIDE_UNDEFINED) {
window_new_campaign_widgets[WIDX_RIDE_DROPDOWN].text = ShopItemStringIds[w->campaign.ride_id].plural;
}
break;
}
// Set current number of weeks spinner (moved to paint due to required parameter)
window_new_campaign_widgets[WIDX_WEEKS_SPINNER].text = STR_NONE;
// Enable / disable start button based on ride dropdown
w->disabled_widgets &= ~(1 << WIDX_START_BUTTON);
if (window_new_campaign_widgets[WIDX_RIDE_DROPDOWN].type == WWT_DROPDOWN && w->campaign.ride_id == SELECTED_RIDE_UNDEFINED)
w->disabled_widgets |= 1 << WIDX_START_BUTTON;
2014-08-12 01:27:25 +02:00
}
/**
2015-10-20 20:16:30 +02:00
*
2014-08-12 01:27:25 +02:00
* rct2: 0x0069E493
*/
static void window_new_campaign_paint(rct_window *w, rct_drawpixelinfo *dpi)
2014-08-12 01:27:25 +02:00
{
sint32 x, y;
window_draw_widgets(w, dpi);
// Number of weeks
rct_widget *spinnerWidget = &window_new_campaign_widgets[WIDX_WEEKS_SPINNER];
gfx_draw_string_left(
dpi,
w->campaign.no_weeks == 1 ? STR_MARKETING_1_WEEK : STR_X_WEEKS,
&w->campaign.no_weeks,
w->colours[0],
w->x + spinnerWidget->left + 1,
w->y + spinnerWidget->top
);
x = w->x + 14;
y = w->y + 60;
// Price per week
money32 pricePerWeek = AdvertisingCampaignPricePerWeek[w->campaign.campaign_type];
gfx_draw_string_left(dpi, STR_MARKETING_COST_PER_WEEK, &pricePerWeek, COLOUR_BLACK, x, y);
y += 13;
// Total price
money32 totalPrice = AdvertisingCampaignPricePerWeek[w->campaign.campaign_type] * w->campaign.no_weeks;
gfx_draw_string_left(dpi, STR_MARKETING_TOTAL_COST, &totalPrice, COLOUR_BLACK, x, y);
}