@@ -10,122 +10,236 @@ enum WeekendXP
10
10
{
11
11
SETTING_WEEKEND_XP_RATE = 0 ,
12
12
SETTING_WEEKEND_XP_DISABLE = 1 ,
13
+ SETTING_WEEKEND_XP_VERSION = 2 ,
13
14
14
15
LANG_CMD_WEEKEND_XP_SET = 11120 ,
15
16
LANG_CMD_WEEKEND_XP_ERROR = 11121 ,
17
+ LANG_CMD_WEEKEND_XP_CONFIG = 11122 ,
16
18
17
19
WD_FRIDAY = 5 ,
18
20
WD_SATURDAY = 6 ,
19
21
WD_SUNDAY = 0 ,
20
22
};
21
23
22
- class weekendxp_commandscript : public CommandScript
24
+ class DoubleXpWeekend
23
25
{
26
+
24
27
public:
25
- weekendxp_commandscript () : CommandScript(" weekendxp_commandscript" ) { }
28
+
29
+ DoubleXpWeekend () { }
30
+
31
+ // NOTE We need to access the DoubleXpWeekend logic from other
32
+ // places, so keep all the logic accessible via a singleton here,
33
+ // and have the `CommandScript` and the `PlayeScript` access this
34
+ // for the functionality they need.
35
+ static DoubleXpWeekend* instance ()
36
+ {
37
+ static DoubleXpWeekend instance;
38
+ return &instance;
39
+ }
26
40
27
- ChatCommandTable GetCommands ( ) const override
41
+ uint32 OnGiveXP (Player* player, uint32 originalAmount, uint8 xpSource ) const
28
42
{
29
- static ChatCommandTable commandTable =
43
+ if (! IsEventActive ())
30
44
{
31
- { " weekendxp rate " , HandleSetXPBonusCommand, SEC_PLAYER, Console::No },
32
- };
45
+ return originalAmount;
46
+ }
33
47
34
- return commandTable;
48
+ if (ConfigQuestOnly () && xpSource != PlayerXPSource::XPSOURCE_QUEST && xpSource != PlayerXPSource::XPSOURCE_QUEST_DF)
49
+ {
50
+ return originalAmount;
51
+ }
52
+
53
+ if (player->GetLevel () >= ConfigMaxLevel ())
54
+ {
55
+ return originalAmount;
56
+ }
57
+
58
+ float newAmount = (float )originalAmount * GetExperienceRate (player);
59
+ return (uint32) newAmount;
35
60
}
36
61
37
- static bool HandleSetXPBonusCommand (ChatHandler* handler, int8 rate)
62
+ void OnLogin (Player* player, ChatHandler* handler) const
63
+ {
64
+ // TODO I am assuming that this is always called when a character logs in...
65
+ // if that is not the case, thing migh get weird... Adding some asserts or warnings would be nice
66
+ // but I'm not sure how to handle "This shouldn't be happening but it is" kind of scenarios in acore
67
+ MigratePlayerSettings (player, handler);
68
+
69
+ if (ConfigAnnounce ())
70
+ {
71
+ if (IsEventActive () && !ConfigAlwaysEnabled ())
72
+ {
73
+ float rate = GetExperienceRate (player);
74
+ handler->PSendSysMessage (" It's the weekend! Your XP rate has been set to: {}" , rate);
75
+ }
76
+ else if (IsEventActive () && ConfigAlwaysEnabled ())
77
+ {
78
+ float rate = GetExperienceRate (player);
79
+ handler->PSendSysMessage (" Your XP rate has been set to: {}" , rate);
80
+ }
81
+ else
82
+ {
83
+ handler->PSendSysMessage (" This server is running the |cff4CFF00Double XP Weekend |rmodule." );
84
+ }
85
+ }
86
+ }
87
+
88
+ bool HandleSetXPBonusCommand (ChatHandler* handler, float rate) const
38
89
{
39
90
Player* player = handler->GetPlayer ();
40
91
41
- int8 maxRate = sConfigMgr -> GetOption <int8>( " XPWeekend.MaxAllowedRate " , 2 );
92
+ float maxRate = ConfigMaxAllowedRate ( );
42
93
43
- if (rate <= 0 || rate > maxRate)
94
+ if (rate <= 0 . 0f || rate > maxRate)
44
95
{
45
96
handler->PSendSysMessage (LANG_CMD_WEEKEND_XP_ERROR, maxRate);
46
97
handler->SetSentErrorMessage (true );
47
98
return true ;
48
99
}
49
100
50
- player-> UpdatePlayerSetting ( " mod-double-xp-weekend " , SETTING_WEEKEND_XP_RATE , rate);
101
+ PlayerSettingSetRate (player , rate);
51
102
handler->PSendSysMessage (LANG_CMD_WEEKEND_XP_SET, rate);
52
103
104
+ // TODO if the `EnablePlayerSettings` is not set, the setting wont be remembered by the
105
+ // server after the player logs out, meaning the player needs to do this again on next login
106
+
53
107
return true ;
54
108
}
55
- };
56
109
57
- class DoubleXpWeekend : public PlayerScript
58
- {
59
- public:
60
- DoubleXpWeekend () : PlayerScript(" DoubleXpWeekend" ) { }
110
+ bool HandleGetCurrentConfigCommand (ChatHandler* handler) const
111
+ {
112
+ Player* player = handler->GetPlayer ();
61
113
62
- void OnLogin (Player* player) override
114
+ const float actualRate = GetExperienceRate (player);
115
+ const bool isAnnounceEnabled = ConfigAnnounce ();
116
+ const bool isAlwaysEnabled = ConfigAlwaysEnabled ();
117
+ const bool isQuestOnly = ConfigQuestOnly ();
118
+ const uint32 maxLevel = ConfigMaxLevel ();
119
+ const float xpRate = ConfigxpAmount ();
120
+ const bool isIndividulaXpEnabled = ConfigIndividualXPEnabled ();
121
+ const bool isEnabled = ConfigEnabled ();
122
+ const float maxXpRate = ConfigMaxAllowedRate ();
123
+
124
+ handler->PSendSysMessage (LANG_CMD_WEEKEND_XP_CONFIG,
125
+ actualRate,
126
+ isAnnounceEnabled,
127
+ isAlwaysEnabled,
128
+ isQuestOnly,
129
+ maxLevel,
130
+ xpRate,
131
+ isIndividulaXpEnabled,
132
+ isEnabled,
133
+ maxXpRate
134
+ );
135
+
136
+ return true ;
137
+ }
138
+
139
+ private:
140
+
141
+ // NOTE keep options together to prevent having more than 1 potential default value
142
+ bool ConfigAlwaysEnabled () const { return sConfigMgr ->GetOption <bool >(" XPWeekend.AlwaysEnabled" , false ); }
143
+ bool ConfigAnnounce () const { return sConfigMgr ->GetOption <bool >(" XPWeekend.Announce" , false ); }
144
+ bool ConfigQuestOnly () const { return sConfigMgr ->GetOption <bool >(" XPWeekend.QuestOnly" , false ); }
145
+ uint32 ConfigMaxLevel () const { return sConfigMgr ->GetOption <uint32>(" XPWeekend.MaxLevel" , 80 ); }
146
+ float ConfigxpAmount () const { return sConfigMgr ->GetOption <float >(" XPWeekend.xpAmount" , 2 .0f ); }
147
+ bool ConfigIndividualXPEnabled () const { return sConfigMgr ->GetOption <bool >(" XPWeekend.IndividualXPEnabled" , false ); }
148
+ bool ConfigEnabled () const { return sConfigMgr ->GetOption <bool >(" XPWeekend.Enabled" , false ); }
149
+ float ConfigMaxAllowedRate () const { return sConfigMgr ->GetOption <float >(" XPWeekend.MaxAllowedRate" , 2 .0f ); }
150
+
151
+ void PlayerSettingSetRate (Player* player, float rate) const
63
152
{
64
- if (sConfigMgr ->GetOption <bool >(" XPWeekend.Announce" , false ))
65
- {
66
- if (IsEventActive () && !sConfigMgr ->GetOption <bool >(" XPWeekend.AlwaysEnabled" , false ))
67
- {
68
- ChatHandler (player->GetSession ()).PSendSysMessage (" It's the weekend! Your XP rate has been set to: {}" , GetExperienceRate (player));
69
- }
70
- else if (IsEventActive () && sConfigMgr ->GetOption <bool >(" XPWeekend.AlwaysEnabled" , false ))
71
- {
72
- ChatHandler (player->GetSession ()).PSendSysMessage (" Your XP rate has been set to: {}" , GetExperienceRate (player));
73
- }
74
- else
75
- {
76
- ChatHandler (player->GetSession ()).PSendSysMessage (" This server is running the |cff4CFF00Double XP Weekend |rmodule." );
77
- }
78
- }
153
+ // HACK PlayerSetting seems to store uint32 only, so save our `float` as if it was a `uint32`
154
+ uint32 encodedRate;
155
+ float * reinterpretingPointer = (float *)&encodedRate;
156
+ *reinterpretingPointer = rate;
157
+ player->UpdatePlayerSetting (" mod-double-xp-weekend" , SETTING_WEEKEND_XP_RATE, encodedRate);
158
+ }
159
+
160
+ float PlayerSettingGetRate (Player* player) const
161
+ {
162
+ uint32 rateStored = player->GetPlayerSetting (" mod-double-xp-weekend" , SETTING_WEEKEND_XP_RATE).value ;
163
+ // HACK PlayerSetting seems to store uint32 only, so save our `float` as if it was a `uint32`
164
+ float rate = *(float *)&rateStored;
165
+ return rate;
79
166
}
80
167
81
- void OnGiveXP (Player* player, uint32& amount, Unit * /* victim */ , uint8 xpSource) override
168
+ void MigratePlayerSettings (Player* player, ChatHandler * /* handler */ ) const
82
169
{
83
- if (!IsEventActive ())
170
+ static const uint32 VERSION = 1 ;
171
+
172
+ uint32 playersCurrentVersion = player->GetPlayerSetting (" mod-double-xp-weekend" , SETTING_WEEKEND_XP_VERSION).value ;
173
+ bool validMigration = playersCurrentVersion == 0 && VERSION == 1 ;
174
+ if (!validMigration)
84
175
{
176
+ // Currently there is only either version 0 (the default) or 1
177
+ // This check should never fail unless a new version is introduced and the
178
+ // migration here is not updated.
85
179
return ;
86
180
}
87
181
88
- if (sConfigMgr ->GetOption <bool >(" XPWeekend.QuestOnly" , false ) && xpSource != PlayerXPSource::XPSOURCE_QUEST && xpSource != PlayerXPSource::XPSOURCE_QUEST_DF)
182
+ // On version 1 the only thing to migrate is the SETTING_WEEKEND_XP_RATE
183
+ float newRate = ConfigxpAmount ();
184
+ uint32 originalRate = player->GetPlayerSetting (" mod-double-xp-weekend" , SETTING_WEEKEND_XP_RATE).value ;
185
+ if (originalRate <= 0 )
89
186
{
90
- return ;
187
+ // player setting was never set before, just use default
91
188
}
92
-
93
- if (player->GetLevel () >= sConfigMgr ->GetOption <uint32>(" XPWeekend.MaxLevel" , 80 ))
189
+ else if ((float )originalRate > ConfigMaxAllowedRate ())
94
190
{
95
- return ;
191
+ // player setting was set but the value is not valid, just use default
192
+ }
193
+ else
194
+ {
195
+ // player setting was set, use the same rate
196
+ newRate = (float ) originalRate;
96
197
}
97
198
98
- amount *= GetExperienceRate (player);
199
+ // HACK PlayerSetting seems to store uint32 only, so save our `float` as if it was a `uint32`
200
+ uint32 encodedRate;
201
+ float * reinterpretingPointer = (float *)&encodedRate;
202
+ *reinterpretingPointer = newRate;
203
+ player->UpdatePlayerSetting (" mod-double-xp-weekend" , SETTING_WEEKEND_XP_RATE, encodedRate);
204
+ player->UpdatePlayerSetting (" mod-double-xp-weekend" , SETTING_WEEKEND_XP_VERSION, VERSION);
99
205
}
100
-
101
- int8 GetExperienceRate (Player * player) const
206
+
207
+ // TODO why is there a `GetDisable` player setting but no way to actually modify it? Leaving as is for now...
208
+ bool PlayerSettingGetDisable (Player* player) const
102
209
{
103
- int8 rate = sConfigMgr ->GetOption <int8>(" XPWeekend.xpAmount" , 2 );
210
+ return player->GetPlayerSetting (" mod-double-xp-weekend" , SETTING_WEEKEND_XP_DISABLE).value == (uint32)1 ;
211
+ }
104
212
105
- int8 individualRate = player->GetPlayerSetting (" mod-double-xp-weekend" , SETTING_WEEKEND_XP_RATE).value ;
213
+ float GetExperienceRate (Player* player) const
214
+ {
215
+ float rate = ConfigxpAmount ();
106
216
107
- if (player-> GetPlayerSetting ( " mod-double-xp-weekend " , SETTING_WEEKEND_XP_DISABLE). value )
217
+ if (PlayerSettingGetDisable (player) )
108
218
{
109
- return 1 ;
219
+ return 1 . 0f ;
110
220
}
111
221
112
222
// If individualxp setting is enabled... and a rate was set, overwrite it.
113
- if (sConfigMgr -> GetOption < bool >( " XPWeekend.IndividualXPEnabled " , false ) && individualRate )
223
+ if (ConfigIndividualXPEnabled () )
114
224
{
115
- rate = individualRate ;
225
+ rate = PlayerSettingGetRate (player) ;
116
226
}
117
227
118
228
// Prevent returning 0% rate.
119
- return rate ? rate : 1 ;
229
+ return rate > 0 . 0f ? rate : 1 . 0f ;
120
230
}
121
231
122
232
bool IsEventActive () const
123
233
{
124
- if (sConfigMgr ->GetOption <bool >(" XPWeekend.AlwaysEnabled" , false ))
234
+ if (ConfigAlwaysEnabled ())
235
+ {
125
236
return true ;
237
+ }
126
238
127
- if (!sConfigMgr ->GetOption <bool >(" XPWeekend.Enabled" , false ))
239
+ if (!ConfigEnabled ())
240
+ {
128
241
return false ;
242
+ }
129
243
130
244
time_t t = time (nullptr );
131
245
tm * now = localtime (&t);
@@ -134,8 +248,57 @@ class DoubleXpWeekend : public PlayerScript
134
248
}
135
249
};
136
250
251
+ class weekendxp_commandscript : public CommandScript
252
+ {
253
+ public:
254
+ weekendxp_commandscript () : CommandScript(" weekendxp_commandscript" ) { }
255
+
256
+ ChatCommandTable GetCommands () const override
257
+ {
258
+ static ChatCommandTable commandTable =
259
+ {
260
+ { " weekendxp rate" , HandleSetXPBonusCommand, SEC_PLAYER, Console::No },
261
+ { " weekendxp config" , HandleGetCurrentConfigCommand, SEC_PLAYER, Console::No },
262
+ };
263
+
264
+ return commandTable;
265
+ }
266
+
267
+ static bool HandleSetXPBonusCommand (ChatHandler* handler, float rate)
268
+ {
269
+ DoubleXpWeekend* mod = DoubleXpWeekend::instance ();
270
+ return mod->HandleSetXPBonusCommand (handler, rate);
271
+ }
272
+
273
+ static bool HandleGetCurrentConfigCommand (ChatHandler* handler)
274
+ {
275
+ DoubleXpWeekend* mod = DoubleXpWeekend::instance ();
276
+ return mod->HandleGetCurrentConfigCommand (handler);
277
+ }
278
+ };
279
+
280
+ class DoubleXpWeekendPlayerScript : public PlayerScript
281
+ {
282
+ public:
283
+ DoubleXpWeekendPlayerScript () : PlayerScript(" DoubleXpWeekend" ) { }
284
+
285
+ void OnLogin (Player* player) override
286
+ {
287
+ DoubleXpWeekend* mod = DoubleXpWeekend::instance ();
288
+ ChatHandler handler = ChatHandler (player->GetSession ());
289
+ mod->OnLogin (player, &handler);
290
+ }
291
+
292
+ void OnGiveXP (Player* player, uint32& amount, Unit* /* victim*/ , uint8 xpSource) override
293
+ {
294
+ DoubleXpWeekend* mod = DoubleXpWeekend::instance ();
295
+ amount = mod->OnGiveXP (player, amount, xpSource);
296
+ }
297
+
298
+ };
299
+
137
300
void AdddoublexpScripts ()
138
301
{
139
- new DoubleXpWeekend ();
302
+ new DoubleXpWeekendPlayerScript ();
140
303
new weekendxp_commandscript ();
141
304
}
0 commit comments