1 /*****************************************************************************
2 * Copyright (c) 2014-2020 OpenRCT2 developers
3 *
4 * For a complete list of all authors, please refer to contributors.md
5 * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
6 *
7 * OpenRCT2 is licensed under the GNU General Public License version 3.
8 *****************************************************************************/
9 #include "MoneyEffect.h"
10
11 #include "../OpenRCT2.h"
12 #include "../drawing/Drawing.h"
13 #include "../interface/Viewport.h"
14 #include "../interface/Window.h"
15 #include "../localisation/Localisation.h"
16 #include "../network/network.h"
17 #include "Entity.h"
18 #include "Map.h"
19 #include "Sprite.h"
20
21 static constexpr const CoordsXY _moneyEffectMoveOffset[] = {
22 { 1, -1 },
23 { 1, 1 },
24 { -1, 1 },
25 { -1, -1 },
26 };
27
Is() const28 template<> bool EntityBase::Is<MoneyEffect>() const
29 {
30 return Type == EntityType::MoneyEffect;
31 }
32
33 /**
34 *
35 * rct2: 0x0067351F
36 */
CreateAt(money64 value,const CoordsXYZ & effectPos,bool vertical)37 void MoneyEffect::CreateAt(money64 value, const CoordsXYZ& effectPos, bool vertical)
38 {
39 if (value == MONEY(0, 00))
40 return;
41
42 MoneyEffect* moneyEffect = CreateEntity<MoneyEffect>();
43 if (moneyEffect == nullptr)
44 return;
45
46 moneyEffect->Value = value;
47 moneyEffect->Vertical = (vertical ? 1 : 0);
48 moneyEffect->sprite_width = 64;
49 moneyEffect->sprite_height_negative = 20;
50 moneyEffect->sprite_height_positive = 30;
51 moneyEffect->MoveTo(effectPos);
52 moneyEffect->NumMovements = 0;
53 moneyEffect->MoveDelay = 0;
54
55 int16_t offsetX = 0;
56 if (!gOpenRCT2NoGraphics)
57 {
58 auto [stringId, newValue] = moneyEffect->GetStringId();
59 char buffer[128];
60 format_string(buffer, 128, stringId, &newValue);
61 offsetX = -(gfx_get_string_width(buffer, FontSpriteBase::MEDIUM) / 2);
62 }
63 moneyEffect->OffsetX = offsetX;
64 moneyEffect->Wiggle = 0;
65 }
66
67 /**
68 *
69 * rct2: 0x0069C5D0
70 */
Create(money64 value,const CoordsXYZ & loc)71 void MoneyEffect::Create(money64 value, const CoordsXYZ& loc)
72 {
73 auto offsetLoc = loc;
74 if (loc.IsNull())
75 {
76 // If game actions return no valid location of the action we can not use the screen
77 // coordinates as every client will have different ones.
78 if (network_get_mode() != NETWORK_MODE_NONE)
79 {
80 log_warning("Attempted to create money effect without a valid location in multiplayer");
81 return;
82 }
83
84 rct_window* mainWindow = window_get_main();
85 if (mainWindow == nullptr)
86 return;
87
88 rct_viewport* mainViewport = window_get_viewport(mainWindow);
89 auto mapPositionXY = screen_get_map_xy(
90 { mainViewport->pos.x + (mainViewport->width / 2), mainViewport->pos.y + (mainViewport->height / 2) }, nullptr);
91 if (!mapPositionXY.has_value())
92 return;
93
94 offsetLoc = { mapPositionXY.value(), tile_element_height(*mapPositionXY) };
95 }
96 offsetLoc.z += 10;
97 CreateAt(-value, offsetLoc, false);
98 }
99
100 /**
101 *
102 * rct2: 0x00673232
103 */
Update()104 void MoneyEffect::Update()
105 {
106 Wiggle++;
107 if (Wiggle >= 22)
108 {
109 Wiggle = 0;
110 }
111
112 MoveDelay++;
113 if (MoveDelay < 2)
114 {
115 return;
116 }
117
118 int32_t newX = x;
119 int32_t newY = y;
120 int32_t newZ = z;
121 MoveDelay = 0;
122
123 if (Vertical)
124 {
125 newZ += 1;
126 }
127 newY += _moneyEffectMoveOffset[get_current_rotation()].y;
128 newX += _moneyEffectMoveOffset[get_current_rotation()].x;
129
130 MoveTo({ newX, newY, newZ });
131
132 NumMovements++;
133 if (NumMovements < 55)
134 {
135 return;
136 }
137
138 sprite_remove(this);
139 }
140
GetStringId() const141 std::pair<rct_string_id, money64> MoneyEffect::GetStringId() const
142 {
143 rct_string_id spentStringId = Vertical ? STR_MONEY_EFFECT_SPEND_HIGHP : STR_MONEY_EFFECT_SPEND;
144 rct_string_id receiveStringId = Vertical ? STR_MONEY_EFFECT_RECEIVE_HIGHP : STR_MONEY_EFFECT_RECEIVE;
145 rct_string_id stringId = receiveStringId;
146 money64 outValue = Value;
147 if (Value < 0)
148 {
149 outValue *= -1;
150 stringId = spentStringId;
151 }
152
153 return std::make_pair(stringId, outValue);
154 }
155