-
-
Notifications
You must be signed in to change notification settings - Fork 666
/
SAV_FestivalPlaza.cs
740 lines (660 loc) · 35.1 KB
/
SAV_FestivalPlaza.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using PKHeX.Core;
namespace PKHeX.WinForms
{
public partial class SAV_FestivalPlaza : Form
{
private readonly SaveFile Origin;
private readonly SAV7 SAV;
public SAV_FestivalPlaza(SaveFile sav)
{
InitializeComponent();
SAV = (SAV7)(Origin = sav).Clone();
editing = true;
typeMAX = SAV is SAV7USUM ? 0x7F : 0x7C;
TB_PlazaName.Text = SAV.Festa.FestivalPlazaName;
if (SAV is SAV7USUM)
{
PBs = new[] { ppkx1, ppkx2, ppkx3 };
NUD_Trainers = new[] { NUD_Trainer1, NUD_Trainer2, NUD_Trainer3 };
LoadBattleAgency();
}
else
{
TC_Editor.TabPages.Remove(Tab_BattleAgency);
}
if (Main.Unicode)
{
try { TB_OTName.Font = FontUtil.GetPKXFont(11); }
catch (Exception e) { WinFormsUtil.Alert("Font loading failed...", e.ToString()); }
}
var cc = SAV.Festa.FestaCoins;
var cu = SAV.GetRecord(038);
NUD_FC_Current.Value = Math.Min(cc, NUD_FC_Current.Maximum);
NUD_FC_Used.Value = Math.Min(cu, NUD_FC_Used.Maximum);
L_FC_CollectedV.Text = (cc + cu).ToString();
string[] res;
switch (Main.CurrentLanguage)
{
case "ja":
res = new[] {
"おじさんの きんのたま だからね!","かがくの ちからって すげー","1 2の …… ポカン!","おーす! みらいの チャンピオン!","おお! あんたか!","みんな げんきに なりましたよ!","とっても 幸せそう!","なんでも ないです","いあいぎりで きりますか?","レポートを かきこんでいます",
"…… ぼくも もう いかなきゃ!","ボンジュール!","バイビー!","ばか はずれです……","やけどなおしの よういは いいか!","ウー! ハーッ!","ポケモンは たたかわせるものさ","ヤドランは そっぽを むいた!","マサラは まっしろ はじまりのいろ","10000こうねん はやいんだよ!","おーい! まてー! まつんじゃあ!","こんちわ! ぼく ポケモン……!","っだと こらあ!","ぐ ぐーッ! そんな ばかなーッ!","みゅう!","タチサレ…… タチサレ……",
"カイリュー はかいこうせん","どっちか 遊んでくれないか?","ぬいぐるみ かっておいたわよ","ひとのこと じろじろ みてんなよ","なんのことだか わかんない","みんな ポケモン やってるやん","きょうから 24時間 とっくんだ!","あたいが ホンモノ!","でんげきで いちころ……","スイクンを おいかけて 10ねん","かんどうが よみがえるよ!","われわれ ついに やりましたよー!","ヤドンのシッポを うるなんて……","ショオーッ!!","ギャーアアス!!","だいいっぽを ふみだした!",
"いちばん つよくて すごいんだよね","にくらしいほど エレガント!","そうぞうりょくが たりないよ","キミは ビッグウェーブ!","おまえさんには しびれた わい","なに いってんだろ…… てへへ……","ぬいぐるみ なんか かってないよ","ここで ゆっくり して おいき!","はじけろ! ポケモン トレーナー!","はいが はいに はいった……","…できる!","ぶつかった かいすう 5かい!","たすけて おくれーっ!!","マボロシじま みえんのう……","ひゅああーん!","しゅわーん!",
"あつい きもち つたわってくる!","こいつが! おれの きりふだ!","ひとりじめとか そういうの ダメよ!","ワーオ! ぶんせきどーり!","ぱるぱるぅ!!!","グギュグバァッ!!!","ばっきん 100まんえん な!","オレ つよくなる……","ながれる 時間は とめられない!","ぜったいに お願いだからね","きみたちから はどうを かんじる!","あたしのポケモンに なにすんのさ!","リングは おれの うみ~♪","オレの おおごえの ひとりごとを","そう コードネームは ハンサム!","……わたしが まけるかも だと!?",
"やめたげてよぉ!","ブラボー! スーパー ブラボー!","ボクは チャンピオンを こえる","オレは いまから いかるぜッ!","ライモンで ポケモン つよいもん","キミ むしポケモン つかいなよ","ストップ!","ひとよんで メダルおやじ!","トレーナーさんも がんばれよ!","おもうぞんぶん きそおーぜ!","プラズマズイ!","ワタクシを とめることは できない!","けいさんずみ ですとも!","ババリバリッシュ!","ンバーニンガガッ!","ヒュラララ!",
"お友達に なっちゃお♪","じゃあ みんな またねえ!","このひとたち ムチャクチャです……","トレーナーとは なにか しりたい","スマートに くずれおちるぜ","いのち ばくはつッ!!","いいんじゃない いいんじゃないの!","あれだよ あれ おみごとだよ!","ぜんりょくでいけー! ってことよ!","おまちなさいな!","つまり グッド ポイント なわけ!","ざんねん ですが さようなら","にくすぎて むしろ 好きよ","この しれもの が!","イクシャア!!","イガレッカ!!",
"フェスサークル ランク 100!",
};
break;
default:
const string musical8note = "♪";
const string linedP = "₽"; //currency Ruble
res = new[] { //source:UltraMoon
/* (SM)Pokémon House */"There's nothing funny about Nuggets.","The Power of science is awesome.","1, 2, and... Ta-da!","How's the future Champ today?","Why, you!","There! All happy and healthy!","Your Pokémon seems to be very happy!","No thanks!","Would you like to use Cut?","Saving...",
/* (SM)Kanto Tent */"Well, I better get going!","Bonjour!","Smell ya later!","Sorry! Bad call!","You better have Burn Heal!","Hoo hah!","Pokémon are for battling!","Slowbro took a snooze...","Shades of your journey await!","You're 10,000 light-years from facing Brock!","Hey! Wait! Don't go out!","Hiya! I'm a Pokémon...","What do you want?","WHAT! This can't be!","Mew!","Be gone... Intruders...",
/* (SM)Joht Tent */"Dragonite, Hymer Beam.","Spread the fun around.","I bought an adorable doll with your money.","What are you staring at?","I just don't understand.","Everyone is into Pokémon.","I'm going to train 24 hours a day!","I'm the real deal!","With a jolt of electricity...","For 10 years I chased Suicune.","I am just so deeply moved!","We have finally made it!","...But selling Slowpoke Tails?","Shaoooh!","Gyaaas!","you've taken your first step!",
/* (SM)Hoenn Tent */"I'm just the strongest there is right now.","And confoundedly elegant!","You guys need some imagination.","You made a much bigger splash!","You ended up giving me a thrill!","So what am I talking about...","I'm not buying any Dolls.","Take your time and rest up!","Have a blast, Pokémon Trainers!","I got ashes in my eyelashes!","You're sharp!","Number of collisions: 5 times!","Please! Help me out!","I can't see Mirage Island today...","Hyahhn!","Shwahhn!",
/* (SM)Sinnoh Tent */"Your will is overwhelming me!","This is it! My trump card!","Trying to monopolize Pokémon just isn't...","See? Just as analyzed.","Gagyagyaah!","Gugyugubah!","It's a "+linedP+"10 million fine if you're late!","I'm going to get tougher...","You'll never be able to stem the flow of time!","Please come!","Your team! I sense your strong aura!","What do you think you're doing?!","The ring is my rolling sea. "+musical8note,"I was just thinking out loud.","My code name, it is Looker.","It's not possible that I lose!",
/* (SM)Unova Tent */"Knock it off!","Bravo! Excellent!!","I'll defeat the Champion.","You're about to feel my rage!","Nimbasa's Pokémon can dance a nimble bossa!","Use Bug-type Pokémon!","Stop!","People call me Mr. Medal!","Trainer, do your best, too!","See who's stronger!","Plasbad, for short!","I won't allow anyone to stop me!","I was expecting exactly that kind of move!","Bazzazzazzash!","Preeeeaah!","Haaahraaan!",
/* (SM)Kalos Tent */"We'll become friends. "+musical8note,"I'll see you all later!","These people have a few screws loose...","I want to know what a \"Trainer\" is.","When I lose, I go out in style!","Let's give it all we've got!","Fantastic! Just fantastic!","Outstanding!","Try as hard as possible!","Stop right there!","That really hit me right here...","But this is adieu to you all.","You're just too much, you know?","Fool! You silly, unseeing child!","Xsaaaaaah!","Yvaaaaaar!",
"I reached Festival Plaza Rank 100!",
};
break;
}
CLB_Phrases.Items.Clear();
CLB_Phrases.Items.Add(res.Last(), SAV.Festa.GetFestaPhraseUnlocked(106)); //add Lv100 before TentPhrases
for (int i = 0; i < res.Length - 1; i++)
CLB_Phrases.Items.Add(res[i], SAV.Festa.GetFestaPhraseUnlocked(i));
DateTime dt = SAV.Festa.FestaDate ?? new DateTime(2000, 1, 1);
CAL_FestaStartDate.Value = CAL_FestaStartTime.Value = dt;
string[] res2 = { "Rank 4: missions","Rank 8: facility","Rank 10: fashion","Rank 20: rename","Rank 30: special menu","Rank 40: BGM","Rank 50: theme Glitz","Rank 60: theme Fairy","Rank 70: theme Tone","Rank 100: phrase","Current Rank", };
CLB_Reward.Items.Clear();
CLB_Reward.Items.Add(res2.Last(), (CheckState)RewardState[SAV.Festa.GetFestPrizeReceived(10)]); //add CurrentRank before const-rewards
for (int i = 0; i < res2.Length - 1; i++)
CLB_Reward.Items.Add(res2[i], (CheckState)RewardState[SAV.Festa.GetFestPrizeReceived(i)]);
for (int i = 0; i < 7; i++)
f[i] = new FestaFacility(SAV, i);
string[] res3 = { "Meet", "Part", "Moved", "Disappointed" };
CB_FacilityMessage.Items.Clear();
CB_FacilityMessage.Items.AddRange(res3);
string[] res5 =
{
"Ace Trainer" + gendersymbols[1],
"Ace Trainer" + gendersymbols[0],
"Veteran" + gendersymbols[1],
"Veteran" + gendersymbols[0],
"Office Worker" + gendersymbols[0],
"Office Worker" + gendersymbols[1],
"Punk Guy",
"Punk Girl",
"Breeder" + gendersymbols[0],
"Breeder" + gendersymbols[1],
"Youngster",
"Lass"
};
CB_FacilityNPC.Items.Clear();
CB_FacilityNPC.Items.AddRange(res5);
string[] res6 = { "Lottery", "Haunted", "Goody", "Food", "Bouncy", "Fortune", "Dye", "Exchange" };
string[][] res7 = {
new[]{"BigDream","GoldRush","TreasureHunt"},
new[]{"GhostsDen","TrickRoom","ConfuseRay"},
new[]{"Ball","General","Battle","SoftDrink","Pharmacy"},
new[]{"Rare","Battle", "FriendshipCafé", "FriendshipParlor"},
new[]{"Thump","Clink","Stomp"},
new[]{"Kanto","Johto","Hoenn","Sinnoh","Unova","Kalos","Pokémon"},
new[]{"Red","Yellow","Green","Blue","Orange","NavyBlue","Purple","Pink"},
new[]{"Switcheroo"}
};
CB_FacilityType.Items.Clear();
for (int k = 0; k < RES_FacilityLevelType.Length - (SAV is SAV7USUM ? 0 : 1); k++) //Exchange is USUM only
{
for (int j = 0; j < RES_FacilityLevelType[k].Length; j++)
{
if (RES_FacilityLevelType[k][j] != 4)
{
for (int i = 0; i < RES_FacilityLevelType[k][j]; i++)
CB_FacilityType.Items.Add($"{res6[k]} {res7[k][j]} {i + 1}");
}
else
{
CB_FacilityType.Items.Add($"{res6[k]} {res7[k][j]} 1");
CB_FacilityType.Items.Add($"{res6[k]} {res7[k][j]} 3");
CB_FacilityType.Items.Add($"{res6[k]} {res7[k][j]} 5");
}
}
}
string[] types = { "GTS", "Wonder Trade", "Battle Spot", "Festival Plaza", "mission", "lottery shop", "haunted house" };
string[] lvl = { "+", "++", "+++" };
CB_LuckyResult.Items.Clear();
CB_LuckyResult.Items.Add("none");
foreach (string type in types)
{
foreach (string lv in lvl)
CB_LuckyResult.Items.Add($"{lv} {type}");
}
NUD_Rank.Value = SAV.Festa.FestaRank;
LoadRankLabel(SAV.Festa.FestaRank);
NUD_Messages = new[] { NUD_MyMessageMeet, NUD_MyMessagePart, NUD_MyMessageMoved, NUD_MyMessageDissapointed };
for (int i = 0; i < NUD_Messages.Length; i++)
NUD_Messages[i].Value = SAV.Festa.GetFestaMessage(i);
LB_FacilityIndex.SelectedIndex = 0;
CB_FacilityMessage.SelectedIndex = 0;
editing = false;
entry = 0;
LoadFacility();
}
private bool editing;
private readonly byte[] RewardState = { 0, 2, 1 }; // CheckState.Indeterminate <-> CheckState.Checked
private readonly int typeMAX;
private readonly FestaFacility[] f = new FestaFacility[7];
private readonly string[] RES_Color = { "Red", "Blue", "Gold", "Black", "Purple", "Yellow", "Brown", "Green", "Orange", "NavyBlue", "Pink", "White" };
private readonly byte[][] RES_FacilityColor = //facility appearance
{
new byte[]{0,1,2,3},//Lottery
new byte[]{4,0,5,3},//Haunted
new byte[]{1,0,5,3},//Goody
new byte[]{6,7,0,3},//Food
new byte[]{4,5,8,3},//Bouncy
new byte[]{0,1,2,3},//Fortune
new byte[]{0,7,8,4,5,1,9,10},//Dye
new byte[]{11,1,5,3},//Exchange
};
private readonly byte[][] RES_FacilityLevelType = //3:123 4:135 5:12345
{
new byte[]{5,5,5},
new byte[]{5,5,5},
new byte[]{3,5,3,3,3},
new byte[]{5,4,5,5},
new byte[]{5,5,5},
new byte[]{4,4,4,4,4,4,4},
new byte[]{4,4,4,4,4,4,4,4},
new byte[]{3}
};
private int TypeIndexToType(int typeIndex)
{
if ((uint)typeIndex > typeMAX + 1) return -1;
if (typeIndex < 0x0F) return 0;
if (typeIndex < 0x1E) return 1;
if (typeIndex < 0x2F) return 2;
if (typeIndex < 0x41) return 3;
if (typeIndex < 0x50) return 4;
if (typeIndex < 0x65) return 5;
if (typeIndex < 0x7D) return 6;
return 7;
}
private int GetColorCount(int i) =>
i >= 0 && i < RES_FacilityColor.Length - (SAV is SAV7USUM ? 0 : 1)
? RES_FacilityColor[i].Length - 1
: 3;
private int entry = -1;
private void LoadFacility()
{
editing = true;
var facility = f[entry];
CB_FacilityType.SelectedIndex =
CB_FacilityType.Items.Count > facility.Type
? facility.Type
: -1;
int type = TypeIndexToType(CB_FacilityType.SelectedIndex);
NUD_FacilityColor.Maximum = GetColorCount(type);
NUD_FacilityColor.Value = Math.Min(facility.Color, NUD_FacilityColor.Maximum);
if (type >= 0) LoadColorLabel(type);
CB_LuckyResult.Enabled = CB_LuckyResult.Visible = L_LuckyResult.Visible = type == 5;
NUD_Exchangable.Enabled = NUD_Exchangable.Visible = L_Exchangable.Visible = type == 7;
switch (type)
{
case 5:
int lucky = (facility.UsedLuckyPlace * 3) + facility.UsedLuckyRank - 3;
if ((uint)lucky >= CB_LuckyResult.Items.Count)
lucky = 0;
CB_LuckyResult.SelectedIndex = lucky;
break;
case 7:
NUD_Exchangable.Value = facility.ExchangeLeftCount;
break;
}
CB_FacilityNPC.SelectedIndex =
CB_FacilityNPC.Items.Count > facility.NPC
? facility.NPC
: 0;
CHK_FacilityIntroduced.Checked = facility.IsIntroduced;
TB_OTName.Text = facility.OT_Name;
LoadOTlabel(facility.Gender);
if (CB_FacilityMessage.SelectedIndex >= 0) LoadFMessage(CB_FacilityMessage.SelectedIndex);
TB_UsedFlags.Text = f[entry].UsedFlags.ToString("X8");
TB_UsedStats.Text = f[entry].UsedRandStat.ToString("X8");
var bytes = f[entry].TrainerFesID;
var str = BitConverter.ToString(bytes).Replace("-", string.Empty);
TB_FacilityID.Text = str;
editing = false;
}
private void Save()
{
SAV.Festa.SetFestaPhraseUnlocked(106, CLB_Phrases.GetItemChecked(0));
for (int i = 1; i < CLB_Phrases.Items.Count; i++)
SAV.Festa.SetFestaPhraseUnlocked(i - 1, CLB_Phrases.GetItemChecked(i));
SAV.SetRecord(038, (int)NUD_FC_Used.Value);
SAV.Festa.FestaCoins = (int)NUD_FC_Current.Value;
SAV.Festa.FestaDate = new DateTime(CAL_FestaStartDate.Value.Year, CAL_FestaStartDate.Value.Month, CAL_FestaStartDate.Value.Day, CAL_FestaStartTime.Value.Hour, CAL_FestaStartTime.Value.Minute, CAL_FestaStartTime.Value.Second);
SAV.Festa.SetFestaPrizeReceived(10, RewardState[(int)CLB_Reward.GetItemCheckState(0)]);
for (int i = 1; i < CLB_Reward.Items.Count; i++)
SAV.Festa.SetFestaPrizeReceived(i - 1, RewardState[(int)CLB_Reward.GetItemCheckState(i)]);
SaveFacility();
foreach (FestaFacility facility in f)
facility.CopyTo(SAV);
if (SAV is SAV7USUM)
SaveBattleAgency();
}
private void LoadBattleAgency()
{
p[0] = SAV.GetStoredSlot(0x6C200);
p[1] = SAV.GetPartySlot(0x6C2E8);
p[2] = SAV.GetPartySlot(0x6C420);
LoadPictureBox();
B_ImportParty.Visible = SAV.HasParty;
CHK_Choosed.Checked = SAV.GetFlag(0x6C55E, 1);
CHK_TrainerInvited.Checked = IsTrainerInvited();
ushort valus = BitConverter.ToUInt16(SAV.GetData(0x6C55C, 2), 0);
int grade = valus >> 6 & 0x3F;
NUD_Grade.Value = grade;
int max = (Math.Min(49, grade) / 10 * 3) + 2;
int defeated = valus >> 12;
NUD_Defeated.Value = defeated > max ? max : defeated;
NUD_Defeated.Maximum = max;
NUD_DefeatMon.Value = BitConverter.ToUInt16(SAV.GetData(0x6C558, 2), 0);
for (int i = 0; i < NUD_Trainers.Length; i++)
{
int j = GetSavData16(0x6C56C + (0x14 * i));
var m = (int)NUD_Trainers[i].Maximum;
NUD_Trainers[i].Value = (uint)j > m ? m : j;
}
B_AgentGlass.Enabled = (SAV.GetData(SAV.Fashion + 0xD0, 1)[0] & 1) == 0;
}
private void LoadPictureBox()
{
for (int i = 0; i < 3; i++)
PBs[i].Image = p[i].Sprite(SAV, -1, -1, flagIllegal: true);
}
private readonly NumericUpDown[] NUD_Trainers = new NumericUpDown[3];
private ushort GetSavData16(int Offset) => BitConverter.ToUInt16(SAV.GetData(Offset, 2), 0);
private const ushort InvitedValue = 0x7DFF;
private readonly PKM[] p = new PKM[3];
private readonly PictureBox[] PBs = new PictureBox[3];
private bool IsTrainerInvited() => (GetSavData16(0x6C3EE) & InvitedValue) == InvitedValue && (GetSavData16(0x6C526) & InvitedValue) == InvitedValue;
private void SaveBattleAgency()
{
SAV.SetFlag(0x6C55E, 1, CHK_Choosed.Checked);
if (IsTrainerInvited() ^ CHK_TrainerInvited.Checked)
{
SAV.SetData(BitConverter.GetBytes((ushort)(CHK_TrainerInvited.Checked ? GetSavData16(0x6C3EE) | InvitedValue : 0)), 0x6C3EE);
SAV.SetData(BitConverter.GetBytes((ushort)(CHK_TrainerInvited.Checked ? GetSavData16(0x6C526) | InvitedValue : 0)), 0x6C526);
}
SAV.SetData(p[0].EncryptedBoxData, 0x6C200);
SAV.SetData(p[1].EncryptedPartyData, 0x6C2E8);
SAV.SetData(p[2].EncryptedPartyData, 0x6C420);
SAV.SetData(BitConverter.GetBytes((ushort)(((int)NUD_Defeated.Value & 0xF) << 12 | ((int)NUD_Grade.Value & 0x3F) << 6 | (SAV.Data[0x6C55C] & 0x3F))), 0x6C55C);
SAV.SetData(BitConverter.GetBytes((ushort)NUD_DefeatMon.Value), 0x6C558);
for (int i = 0; i < NUD_Trainers.Length; i++)
SAV.SetData(BitConverter.GetBytes((ushort)NUD_Trainers[i].Value), 0x6C56C + (0x14 * i));
SAV.Festa.FestivalPlazaName = TB_PlazaName.Text;
}
private void NUD_FC_ValueChanged(object sender, EventArgs e)
{
if (editing) return;
L_FC_CollectedV.Text = (NUD_FC_Current.Value + NUD_FC_Used.Value).ToString();
}
private void B_Cancel_Click(object sender, EventArgs e)
{
Close();
}
private void B_Save_Click(object sender, EventArgs e)
{
Save();
Origin.CopyChangesFrom(SAV);
Close();
}
private void B_AllReceiveReward_Click(object sender, EventArgs e)
{
for (int i = 0; i < CLB_Reward.Items.Count; i++)
CLB_Reward.SetItemCheckState(i, CheckState.Checked);
}
private void B_AllReadyReward_Click(object sender, EventArgs e)
{
for (int i = 0; i < CLB_Reward.Items.Count; i++)
CLB_Reward.SetItemCheckState(i, CheckState.Indeterminate);
}
private void B_AllPhrases_Click(object sender, EventArgs e)
{
for (int i = 0; i < CLB_Phrases.Items.Count; i++)
CLB_Phrases.SetItemChecked(i, true);
}
private void TB_OTName_MouseDown(object sender, MouseEventArgs e)
{
TextBox tb = sender as TextBox ?? TB_OTName;
// Special Character Form
if (ModifierKeys != Keys.Control)
return;
var d = new TrashEditor(tb, null, SAV);
d.ShowDialog();
tb.Text = d.FinalString;
}
private readonly string[] gendersymbols = { "♂", "♀" };
private void LoadOTlabel(int b)
{
Label_OTGender.Text = gendersymbols[b & 1];
Label_OTGender.ForeColor = b == 1 ? Color.Red : Color.Blue;
}
private void Label_OTGender_Click(object sender, EventArgs e)
{
if (entry < 0)
return;
var b = f[entry].Gender;
b ^= 1;
f[entry].Gender = b;
LoadOTlabel(b);
}
private void LoadFMessage(int fmIndex) => NUD_FacilityMessage.Value = f[entry].GetMessage(fmIndex);
private void CB_FacilityMessage_SelectedIndexChanged(object sender, EventArgs e)
{
if (editing)
return;
int fmIndex = CB_FacilityMessage.SelectedIndex;
if (fmIndex < 0)
return;
if (entry < 0)
return;
editing = true;
LoadFMessage(fmIndex);
editing = false;
}
private void NUD_FacilityMessage_ValueChanged(object sender, EventArgs e)
{
if (editing)
return;
int fmIndex = CB_FacilityMessage.SelectedIndex;
if (fmIndex < 0)
return;
if (entry < 0)
return;
f[entry].SetMessage(fmIndex, (ushort)NUD_FacilityMessage.Value);
}
private void HexTextBox_TextChanged(object sender, EventArgs e)
{
if (editing)
return;
if (entry < 0)
return;
string t = Util.GetOnlyHex(((TextBox)sender).Text);
if (string.IsNullOrWhiteSpace(t))
t = "0";
int maxlen = sender == TB_FacilityID ? 12 << 1 : 4 << 1;
if (t.Length > maxlen)
{
t = t.Substring(0, maxlen);
editing = true;
((TextBox)sender).Text = t;
editing = false;
System.Media.SystemSounds.Asterisk.Play();
}
if (sender == TB_UsedFlags)
{
f[entry].UsedFlags = Convert.ToUInt32(t, 16);
}
else if (sender == TB_UsedStats)
{
f[entry].UsedRandStat = Convert.ToUInt32(t, 16);
}
else if (sender == TB_FacilityID)
{
if (t.Length != 12 * 2)
t = t.PadLeft(24, '0');
var bytes = t.ToByteArray();
Array.Resize(ref bytes, 12);
f[entry].TrainerFesID = bytes;
}
}
private void LoadColorLabel(int type) => L_FacilityColorV.Text = RES_Color[RES_FacilityColor[type][(int)NUD_FacilityColor.Value]];
private void NUD_FacilityColor_ValueChanged(object sender, EventArgs e)
{
if (editing)
return;
if (entry < 0)
return;
f[entry].Color = (byte)NUD_FacilityColor.Value;
int type = TypeIndexToType(CB_FacilityType.SelectedIndex);
if (type < 0)
return;
editing = true;
LoadColorLabel(type);
editing = false;
}
private void CB_FacilityType_SelectedIndexChanged(object sender, EventArgs e)
{
if (editing)
return;
if (entry < 0)
return;
int typeIndex = CB_FacilityType.SelectedIndex;
if (typeIndex < 0)
return;
var facility = f[entry];
facility.Type = typeIndex;
// reset color
int type = TypeIndexToType(typeIndex);
int colorCount = GetColorCount(type);
editing = true;
if (colorCount < NUD_FacilityColor.Value)
{
NUD_FacilityColor.Value = colorCount;
facility.Color = colorCount;
}
NUD_FacilityColor.Maximum = colorCount;
LoadColorLabel(type);
// reset forms
CB_LuckyResult.Enabled = CB_LuckyResult.Visible = L_LuckyResult.Visible = type == 5;
NUD_Exchangable.Enabled = NUD_Exchangable.Visible = L_Exchangable.Visible = type == 7;
switch (type)
{
case 5:
int lucky = (facility.UsedLuckyPlace * 3) + facility.UsedLuckyRank - 3;
if (lucky < 0 || lucky >= CB_LuckyResult.Items.Count) lucky = 0;
CB_LuckyResult.SelectedIndex = lucky;
break;
case 7:
NUD_Exchangable.Value = facility.ExchangeLeftCount;
break;
}
editing = false;
}
private void SaveFacility()
{
if (entry < 0)
return;
var facility = f[entry];
if (CB_FacilityType.SelectedIndex >= 0)
facility.Type = CB_FacilityType.SelectedIndex;
facility.Color = (byte)NUD_FacilityColor.Value;
facility.OT_Name = TB_OTName.Text;
if (CB_FacilityNPC.SelectedIndex >= 0)
facility.NPC = CB_FacilityNPC.SelectedIndex;
facility.IsIntroduced = CHK_FacilityIntroduced.Checked;
int type = TypeIndexToType(facility.Type);
facility.ExchangeLeftCount = type == 7 ? (byte)NUD_Exchangable.Value : 0;
int lucky = CB_LuckyResult.SelectedIndex - 1;
bool writeLucky = type == 5 && lucky >= 0;
facility.UsedLuckyRank = writeLucky ? (lucky % 3) + 1 : 0;
facility.UsedLuckyPlace = writeLucky ? (lucky / 3) + 1 : 0;
}
private void LoadRankLabel(int rank) => L_RankFC.Text = GetRankText(rank);
private static string GetRankText(int rank)
{
if (rank < 1) return string.Empty;
if (rank == 1) return "0 - 5";
if (rank == 2) return "6 - 15";
if (rank == 3) return "16 - 30";
if (rank <= 10)
{
int i = ((rank - 1) * (rank - 2) * 5) + 1;
return $"{i} - {i + ((rank - 1) * 10) - 1}";
}
if (rank <= 20)
{
int i = (rank * 100) - 649;
return $"{i} - {i + 99}";
}
if (rank <= 70)
{
int j = (rank - 1) / 10;
int i = (rank * ((j * 30) + 60)) - ((j * j * 150) + (j * 180) + 109); // 30 * (rank - 5 * j + 4) * (j + 2) - 349;
return $"{i} - {i + (j * 30) + 59}";
}
if (rank <= 100)
{
int i = (rank * 270) - 8719;
return $"{i} - {i + 269}";
}
if (rank <= 998)
{
int i = (rank * 300) - 11749;
return $"{i} - {i + 299}";
}
if (rank == 999)
return "287951 - ";
return string.Empty;
}
private void NUD_Rank_ValueChanged(object sender, EventArgs e)
{
if (editing) return;
int rank = (int)NUD_Rank.Value;
SAV.Festa.FestaRank = (ushort)rank;
LoadRankLabel(rank);
}
private readonly NumericUpDown[] NUD_Messages;
private void NUD_MyMessage_ValueChanged(object sender, EventArgs e)
{
if (editing)
return;
int mmIndex = Array.IndexOf(NUD_Messages, (NumericUpDown)sender);
if (mmIndex < 0)
return;
SAV.Festa.SetFestaMessage(mmIndex, (ushort)((NumericUpDown)sender).Value);
}
private void CHK_FacilityIntroduced_CheckedChanged(object sender, EventArgs e)
{
if (editing)
return;
if (entry < 0)
return;
f[entry].IsIntroduced = CHK_FacilityIntroduced.Checked;
}
private void TB_OTName_TextChanged(object sender, EventArgs e)
{
if (editing)
return;
if (entry < 0)
return;
f[entry].OT_Name = TB_OTName.Text;
}
private void LB_FacilityIndex_SelectedIndexChanged(object sender, EventArgs e)
{
if (editing)
return;
SaveFacility();
entry = LB_FacilityIndex.SelectedIndex;
if (entry < 0)
return;
LoadFacility();
}
private void LB_FacilityIndex_DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();
e.Graphics.DrawString(((ListBox)sender).Items[e.Index].ToString(), e.Font, new SolidBrush(e.ForeColor), new RectangleF(e.Bounds.X, e.Bounds.Y + (e.Bounds.Height - 12 >> 1), e.Bounds.Width, 12));
e.DrawFocusRectangle();
}
private void B_DelVisitor_Click(object sender, EventArgs e)
{
if (entry < 0) return;
var facility = f[entry];
// there is a unknown value when not introduced...no reproducibility, just mistake?
if (facility.IsIntroduced)
facility.TrainerFesID = new byte[12];
facility.IsIntroduced = false;
facility.OT_Name = string.Empty;
facility.Gender = 0;
for (int i = 0; i < 4; i++)
facility.SetMessage(i, 0);
LoadFacility();
}
private string GetSpeciesNameFromPKM(PKM pkm) => SpeciesName.GetSpeciesName(pkm.Species, SAV.Language);
private void B_ImportParty_Click(object sender, EventArgs e)
{
if (!SAV.HasParty) return;
var party = SAV.PartyData;
string msg = string.Empty;
for (int i = 0; i < 3; i++)
{
if (i < party.Count)
msg += $"{Environment.NewLine}{GetSpeciesNameFromPKM(p[i])} -> {GetSpeciesNameFromPKM(party[i])}";
else
msg += $"{Environment.NewLine}not replaced: {GetSpeciesNameFromPKM(p[i])}";
}
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Replace PKM?", msg))
return;
for (int i = 0, min = Math.Min(3, party.Count); i < min; i++)
p[i] = party[i];
LoadPictureBox();
}
private void MnuSave_Click(object sender, EventArgs e)
{
var pb = WinFormsUtil.GetUnderlyingControl<PictureBox>(sender);
int i = Array.IndexOf(PBs, pb);
if (i < 0)
return;
WinFormsUtil.SavePKMDialog(p[i]);
}
private void NUD_Grade_ValueChanged(object sender, EventArgs e)
{
if (editing) return;
int max = (Math.Min(49, (int)NUD_Grade.Value) / 10 * 3) + 2;
editing = true;
if (NUD_Defeated.Value > max)
NUD_Defeated.Value = max;
NUD_Defeated.Maximum = max;
editing = false;
}
private void NUD_Exchangable_ValueChanged(object sender, EventArgs e)
{
if (editing)
return;
if (entry < 0)
return;
f[entry].ExchangeLeftCount = (byte)NUD_Exchangable.Value;
}
private void CB_LuckyResult_SelectedIndexChanged(object sender, EventArgs e)
{
if (editing)
return;
if (entry < 0)
return;
int lucky = CB_LuckyResult.SelectedIndex;
if (lucky-- < 0)
return;
// both 0 if "none"
f[entry].UsedLuckyRank = lucky < 0 ? 0 : (lucky % 3) + 1;
f[entry].UsedLuckyPlace = lucky < 0 ? 0 : (lucky / 3) + 1;
}
private void B_AgentGlass_Click(object sender, EventArgs e)
{
if (NUD_Grade.Value < 30 && DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Agent Sunglasses is reward of Grade 30.", "Continue?"))
return;
SAV.SetData(new byte[] { 3 }, SAV.Fashion + 0xD0);
B_AgentGlass.Enabled = false;
System.Media.SystemSounds.Asterisk.Play();
}
}
}