diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj
index c67891ee19..87cb5837f5 100644
--- a/projects/openrct2.vcxproj
+++ b/projects/openrct2.vcxproj
@@ -26,6 +26,7 @@
+
@@ -67,6 +68,7 @@
+
diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters
index 8000ad144c..4da48f42e3 100644
--- a/projects/openrct2.vcxproj.filters
+++ b/projects/openrct2.vcxproj.filters
@@ -135,6 +135,9 @@
Header Files
+
+ Header Files
+
@@ -323,6 +326,9 @@
Source Files
+
+ Source Files
+
diff --git a/src/game.c b/src/game.c
index d1529dacab..0a9e82f4ab 100644
--- a/src/game.c
+++ b/src/game.c
@@ -1022,7 +1022,7 @@ void handle_shortcut_command(int shortcutIndex)
case SHORTCUT_SHOW_FINANCIAL_INFORMATION:
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0C))
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x800))
- RCT2_CALLPROC_EBPSAFE(0x0069DDF1);
+ window_finances_open();
break;
case SHORTCUT_SHOW_RESEARCH_INFORMATION:
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & 0x0E)) {
diff --git a/src/marketing.c b/src/marketing.c
new file mode 100644
index 0000000000..15b7192035
--- /dev/null
+++ b/src/marketing.c
@@ -0,0 +1,126 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of 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.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#include "addresses.h"
+#include "marketing.h"
+#include "news_item.h"
+#include "rct2.h"
+#include "ride.h"
+#include "string_ids.h"
+#include "window.h"
+
+const int advertisingCampaignGuestGenerationProbabilities[] = { 400, 300, 200, 200, 250, 200 };
+
+int marketing_get_campaign_guest_generation_probability(int campaign)
+{
+ int probability = advertisingCampaignGuestGenerationProbabilities[campaign];
+ rct_ride *ride;
+
+ // Lower probability of guest generation if price was already low
+ switch (campaign) {
+ case ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE:
+ if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) < 4)
+ probability /= 8;
+ break;
+ case ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE:
+ if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) < 6)
+ probability /= 8;
+ break;
+ case ADVERTISING_CAMPAIGN_RIDE_FREE:
+ ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[RCT2_ADDRESS(0x01358116, uint8)[campaign]]);
+ if (ride->price < 3)
+ probability /= 8;
+ break;
+ }
+
+ return probability;
+}
+
+/*
+ * Update status of marketing campaigns and send produce a news item when they have finished.
+ * rct2: 0x0069E0C1
+ **/
+void marketing_update()
+{
+ for (int campaign = 0; campaign < ADVERTISING_CAMPAIGN_COUNT; campaign++) {
+ uint8 campaign_weeks_left = RCT2_ADDRESS(0x01358102, uint8)[campaign];
+ if (campaign_weeks_left == 0)
+ continue;
+
+ window_invalidate_by_id(WC_FINANCES, 0);
+
+ // High bit marks the campaign as inactive, on first check the campaign is set actice
+ // this makes campaigns run a full x weeks even when started in the middle of a week
+ RCT2_ADDRESS(0x01358102, uint8)[campaign] &= ~(1 << 7);
+ if (campaign_weeks_left & (1 << 7))
+ continue;
+
+ RCT2_ADDRESS(0x01358102, uint8)[campaign]--;
+ if (campaign_weeks_left - 1 != 0)
+ continue;
+
+ int campaign_item = RCT2_ADDRESS(0x01358116, uint8)[campaign];
+
+ // This sets the string parameters for the marketing types that have an argument.
+ if (campaign == ADVERTISING_CAMPAIGN_RIDE_FREE || campaign == ADVERTISING_CAMPAIGN_RIDE) {
+ RCT2_GLOBAL(0x013CE952, uint16) = RCT2_GLOBAL(0x01362942 + 304 * campaign_item, uint16);
+ RCT2_GLOBAL(0x013CE954, uint32) = RCT2_GLOBAL(0x01362944 + 152 * campaign_item, uint32);
+ } else if (campaign == ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE) {
+ campaign_item += 2016;
+ if (campaign_item >= 2048)
+ campaign_item += 96;
+ RCT2_GLOBAL(0x013CE952, uint16) = campaign_item;
+ }
+
+ news_item_add_to_queue(NEWS_ITEM_MONEY, STR_MARKETING_FINISHED_BASE + campaign, 0);
+ }
+}
+
+void marketing_set_guest_campaign(rct_peep *peep, int campaign)
+{
+ switch (campaign) {
+ case ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE:
+ peep->item_standard_flags |= PEEP_ITEM_VOUCHER;
+ peep->var_F0 = 0;
+ break;
+ case ADVERTISING_CAMPAIGN_RIDE_FREE:
+ peep->item_standard_flags |= PEEP_ITEM_VOUCHER;
+ peep->var_F0 = 1;
+ peep->var_F1 = RCT2_ADDRESS(0x01358116, uint8)[campaign];
+ peep->var_C5 = RCT2_ADDRESS(0x01358116, uint8)[campaign];
+ peep->var_C6 = 240;
+ break;
+ case ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE:
+ peep->item_standard_flags |= PEEP_ITEM_VOUCHER;
+ peep->var_F0 = 2;
+ break;
+ case ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE:
+ peep->item_standard_flags |= PEEP_ITEM_VOUCHER;
+ peep->var_F0 = 3;
+ peep->var_F1 = RCT2_ADDRESS(0x01358116, uint8)[campaign];
+ break;
+ case ADVERTISING_CAMPAIGN_PARK:
+ break;
+ case ADVERTISING_CAMPAIGN_RIDE:
+ peep->var_C5 = RCT2_ADDRESS(0x01358116, uint8)[campaign];
+ peep->var_C6 = 240;
+ break;
+ }
+}
\ No newline at end of file
diff --git a/src/marketing.h b/src/marketing.h
new file mode 100644
index 0000000000..43e99796c9
--- /dev/null
+++ b/src/marketing.h
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of 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.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#ifndef _MARKETING_H_
+#define _MARKETING_H_
+
+#include "peep.h"
+
+enum {
+ ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE,
+ ADVERTISING_CAMPAIGN_RIDE_FREE,
+ ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE,
+ ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE,
+ ADVERTISING_CAMPAIGN_PARK,
+ ADVERTISING_CAMPAIGN_RIDE,
+ ADVERTISING_CAMPAIGN_COUNT
+};
+
+int marketing_get_campaign_guest_generation_probability(int campaign);
+void marketing_update();
+void marketing_set_guest_campaign(rct_peep *peep, int campaign);
+
+#endif
\ No newline at end of file
diff --git a/src/news_item.c b/src/news_item.c
index c286097201..5e32c37f5b 100644
--- a/src/news_item.c
+++ b/src/news_item.c
@@ -299,8 +299,7 @@ void news_item_open_subject(int type, int subject) {
RCT2_CALLPROC_X(0x006989E9, 0, 0, 0, (int)peep, 0, 0, 0);
break;
case NEWS_ITEM_MONEY:
- // Open finances window
- RCT2_CALLPROC_EBPSAFE(0x0069DDF1);
+ window_finances_open();
break;
case NEWS_ITEM_RESEARCH:
diff --git a/src/park.c b/src/park.c
index 8d65ef999b..191880ff0c 100644
--- a/src/park.c
+++ b/src/park.c
@@ -22,6 +22,7 @@
#include "addresses.h"
#include "finance.h"
#include "map.h"
+#include "marketing.h"
#include "park.h"
#include "peep.h"
#include "ride.h"
@@ -30,8 +31,6 @@
#include "string_ids.h"
#include "window.h"
-const int advertisingCampaignGuestGenerationProbabilities[] = { 400, 300, 200, 200, 250, 200 };
-
int park_is_open()
{
return (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_OPEN) != 0;
@@ -370,17 +369,6 @@ static void get_random_peep_spawn(rct2_peep_spawn *spawn)
*spawn = peepSpawns[1];
}
-static int park_should_generate_new_guest()
-{
- if ((scenario_rand() & 0xFFFF) < RCT2_GLOBAL(0x013580EC, uint16)) {
- int difficultGeneration = (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) != 0;
- if (!difficultGeneration || RCT2_GLOBAL(0x0135883C, uint16) + 150 < RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16))
- return 1;
- }
-
- return 0;
-}
-
static rct_peep *park_generate_new_guest()
{
rct_peep *peep;
@@ -412,76 +400,26 @@ static rct_peep *park_generate_new_guest()
static rct_peep *park_generate_new_guest_due_to_campaign(int campaign)
{
rct_peep *peep = park_generate_new_guest();
- if (peep != NULL) {
- switch (campaign) {
- case ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE:
- peep->item_standard_flags |= PEEP_ITEM_VOUCHER;
- peep->var_F0 = 0;
- break;
- case ADVERTISING_CAMPAIGN_RIDE_FREE:
- peep->item_standard_flags |= PEEP_ITEM_VOUCHER;
- peep->var_F0 = 1;
- peep->var_F1 = RCT2_ADDRESS(0x01358116, uint8)[campaign];
- peep->var_C5 = RCT2_ADDRESS(0x01358116, uint8)[campaign];
- peep->var_C6 = 240;
- break;
- case ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE:
- peep->item_standard_flags |= PEEP_ITEM_VOUCHER;
- peep->var_F0 = 2;
- break;
- case ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE:
- peep->item_standard_flags |= PEEP_ITEM_VOUCHER;
- peep->var_F0 = 3;
- peep->var_F1 = RCT2_ADDRESS(0x01358116, uint8)[campaign];
- break;
- case ADVERTISING_CAMPAIGN_PARK:
- break;
- case ADVERTISING_CAMPAIGN_RIDE:
- peep->var_C5 = RCT2_ADDRESS(0x01358116, uint8)[campaign];
- peep->var_C6 = 240;
- break;
- }
- }
+ if (peep != NULL)
+ marketing_set_guest_campaign(peep, campaign);
return peep;
}
-static int park_get_campaign_guest_generation_probability(int campaign)
-{
- int probability = advertisingCampaignGuestGenerationProbabilities[campaign];
- rct_ride *ride;
-
- // Lower probability of guest generation if price was already low
- switch (campaign) {
- case ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE:
- if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) < 4)
- probability /= 8;
- break;
- case ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE:
- if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) < 6)
- probability /= 8;
- break;
- case ADVERTISING_CAMPAIGN_RIDE_FREE:
- ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[RCT2_ADDRESS(0x01358116, uint8)[campaign]]);
- if (ride->price < 3)
- probability /= 8;
- break;
- }
-
- return probability;
-}
-
static void park_generate_new_guests()
{
- // Check and generate a new guest
- if (park_should_generate_new_guest())
- park_generate_new_guest();
+ // Generate a new guest for some probability
+ if ((scenario_rand() & 0xFFFF) < RCT2_GLOBAL(0x013580EC, uint16)) {
+ int difficultGeneration = (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) != 0;
+ if (!difficultGeneration || RCT2_GLOBAL(0x0135883C, uint16) + 150 < RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16))
+ park_generate_new_guest();
+ }
// Extra guests generated by advertising campaigns
int campaign;
for (campaign = 0; campaign < ADVERTISING_CAMPAIGN_COUNT; campaign++) {
if (RCT2_ADDRESS(0x01358102, uint8)[campaign] != 0) {
// Random chance of guest generation
- if ((scenario_rand() & 0xFFFF) < park_get_campaign_guest_generation_probability(campaign))
+ if ((scenario_rand() & 0xFFFF) < marketing_get_campaign_guest_generation_probability(campaign))
park_generate_new_guest_due_to_campaign(campaign);
}
}
diff --git a/src/park.h b/src/park.h
index 3d4d778caa..9d3dcc4697 100644
--- a/src/park.h
+++ b/src/park.h
@@ -51,16 +51,6 @@ enum {
PARK_AWARD_BEST_GENTLE_RIDES,
};
-enum {
- ADVERTISING_CAMPAIGN_PARK_ENTRY_FREE,
- ADVERTISING_CAMPAIGN_RIDE_FREE,
- ADVERTISING_CAMPAIGN_PARK_ENTRY_HALF_PRICE,
- ADVERTISING_CAMPAIGN_FOOD_OR_DRINK_FREE,
- ADVERTISING_CAMPAIGN_PARK,
- ADVERTISING_CAMPAIGN_RIDE,
- ADVERTISING_CAMPAIGN_COUNT
-};
-
enum {
PARK_FLAGS_PARK_OPEN = (1 << 0),
PARK_FLAGS_FORBID_LANDSCAPE_CHANGES = (1 << 2),
diff --git a/src/scenario.c b/src/scenario.c
index a18407e6f8..9fdd0c0003 100644
--- a/src/scenario.c
+++ b/src/scenario.c
@@ -25,6 +25,7 @@
#include "finance.h"
#include "game.h"
#include "map.h"
+#include "marketing.h"
#include "news_item.h"
#include "object.h"
#include "park.h"
@@ -561,49 +562,6 @@ void scenario_entrance_fee_too_high_check()
}
}
-
-/*
- * Update status of marketing campaigns and send a message when they are done.
- * rct2: 0x0069E0C1
- **/
-void scenario_marketing_update()
-{
- for (int i = 0; i < 6; ++i) {
- uint8 campaign_weeks_left = RCT2_ADDRESS(0x01358102, uint8)[i];
- int campaign_item = 0;
-
- if (!campaign_weeks_left)
- continue;
- window_invalidate_by_id(WC_FINANCES, 0);
-
- // high bit marks the campaign as inactive, on first check the campaign is set actice
- // this makes campaigns run a full x weeks even when started in the middle of a week
- RCT2_ADDRESS(0x01358102, uint8)[i] &= ~(1 << 7);
- if (campaign_weeks_left & (1 << 7))
- continue;
-
- RCT2_ADDRESS(0x01358102, uint8)[i]--;
- if (campaign_weeks_left - 1 != 0)
- continue;
-
- campaign_item = RCT2_ADDRESS(0x01358116, uint8)[i];
-
- // this sets the string parameters for the marketing types that have an argument.
- if (i == 1 || i == 5) { // free RIDES oh yea
- RCT2_GLOBAL(0x013CE952, uint16) = RCT2_GLOBAL(0x01362942 + 304 * campaign_item, uint16);;
- RCT2_GLOBAL(0x013CE954, uint32) = RCT2_GLOBAL(0x01362944 + 152 * campaign_item, uint32);
- } else if (i == 3) { // free food/merch
- campaign_item += 2016;
- if (campaign_item >= 2048)
- campaign_item += 96;
- RCT2_GLOBAL(0x013CE952, uint16) = campaign_item;
- }
-
- news_item_add_to_queue(NEWS_ITEM_MONEY, STR_MARKETING_FINISHED_BASE + i, 0);
- }
-}
-
-
/*
* Scenario and finance related update iteration.
* rct2: 0x006C44B1
@@ -639,7 +597,7 @@ void scenario_update()
finance_pay_wages();
finance_pay_research();
finance_pay_interest();
- scenario_marketing_update();
+ marketing_update();
peep_problem_warnings_update();
RCT2_CALLPROC_EBPSAFE(0x006B7A5E); // check ride reachability
ride_update_favourited_stat();
diff --git a/src/window.h b/src/window.h
index 25e3478852..6e43bd495c 100644
--- a/src/window.h
+++ b/src/window.h
@@ -359,6 +359,7 @@ void window_park_entrance_open();
void window_park_guests_open();
void window_park_objective_open();
void window_park_rating_open();
+void window_finances_open();
void window_ride_list_open();
void window_banner_open();
void window_cheats_open();
diff --git a/src/window_finances.c b/src/window_finances.c
index a2244518dd..0cf98b5d81 100644
--- a/src/window_finances.c
+++ b/src/window_finances.c
@@ -18,9 +18,7 @@
* along with this program. If not, see .
*****************************************************************************/
-#include
#include "addresses.h"
-#include "game.h"
#include "window.h"
enum {
@@ -30,4 +28,13 @@ enum {
WINDOW_FINANCES_TAB_PROFIT_GRAPH,
WINDOW_FINANCES_TAB_MARKETING,
WINDOW_FINANCES_TAB_RESEARCH
-} WINDOW_FINANCIAL_TAB;
\ No newline at end of file
+} WINDOW_FINANCIAL_TAB;
+
+/**
+ *
+ * rct2: 0x0069DDF1
+ */
+void window_finances_open()
+{
+ RCT2_CALLPROC_EBPSAFE(0x0069DDF1);
+}
\ No newline at end of file
diff --git a/src/window_game_bottom_toolbar.c b/src/window_game_bottom_toolbar.c
index 3966c3904f..efe61f769a 100644
--- a/src/window_game_bottom_toolbar.c
+++ b/src/window_game_bottom_toolbar.c
@@ -172,7 +172,7 @@ static void window_game_bottom_toolbar_mouseup()
case WIDX_LEFT_OUTSET:
case WIDX_MONEY:
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x800))
- RCT2_CALLPROC_EBPSAFE(0x0069DDF1);
+ window_finances_open();
break;
case WIDX_GUESTS:
window_park_guests_open();