1#include "teeinfo.h"
2
3#include <base/color.h>
4#include <base/system.h>
5
6class CStandardSkin
7{
8public:
9 char m_aSkinName[MAX_SKIN_LENGTH];
10 char m_aaSkinPartNames[protocol7::NUM_SKINPARTS][protocol7::MAX_SKIN_LENGTH];
11 bool m_aUseCustomColors[protocol7::NUM_SKINPARTS];
12 int m_aSkinPartColors[protocol7::NUM_SKINPARTS];
13};
14
15static constexpr CStandardSkin STANDARD_SKINS[] = {
16 {.m_aSkinName: "default", .m_aaSkinPartNames: {"standard", "", "", "standard", "standard", "standard"}, .m_aUseCustomColors: {true, false, false, true, true, false}, .m_aSkinPartColors: {1798004, 0, 0, 1799582, 1869630, 0}},
17 {.m_aSkinName: "bluekitty", .m_aaSkinPartNames: {"kitty", "whisker", "", "standard", "standard", "negative"}, .m_aUseCustomColors: {true, true, false, true, true, true}, .m_aSkinPartColors: {8681144, -8229413, 0, 7885547, 8868585, 9043712}},
18 {.m_aSkinName: "bluestripe", .m_aaSkinPartNames: {"standard", "stripes", "", "standard", "standard", "standard"}, .m_aUseCustomColors: {true, false, false, true, true, false}, .m_aSkinPartColors: {10187898, 0, 0, 750848, 1944919, 0}},
19 {.m_aSkinName: "brownbear", .m_aaSkinPartNames: {"bear", "bear", "hair", "standard", "standard", "standard"}, .m_aUseCustomColors: {true, true, false, true, true, false}, .m_aSkinPartColors: {1082745, -15634776, 0, 1082745, 1147174, 0}},
20 {.m_aSkinName: "cammo", .m_aaSkinPartNames: {"standard", "cammo2", "", "standard", "standard", "standard"}, .m_aUseCustomColors: {true, true, false, true, true, false}, .m_aSkinPartColors: {5334342, -11771603, 0, 750848, 1944919, 0}},
21 {.m_aSkinName: "cammostripes", .m_aaSkinPartNames: {"standard", "cammostripes", "", "standard", "standard", "standard"}, .m_aUseCustomColors: {true, true, false, true, true, false}, .m_aSkinPartColors: {5334342, -14840320, 0, 750848, 1944919, 0}},
22 {.m_aSkinName: "coala", .m_aaSkinPartNames: {"koala", "twinbelly", "", "standard", "standard", "standard"}, .m_aUseCustomColors: {true, true, false, true, true, false}, .m_aSkinPartColors: {184, -15397662, 0, 184, 9765959, 0}},
23 {.m_aSkinName: "limekitty", .m_aaSkinPartNames: {"kitty", "whisker", "", "standard", "standard", "negative"}, .m_aUseCustomColors: {true, true, false, true, true, true}, .m_aSkinPartColors: {4612803, -12229920, 0, 3827951, 3827951, 8256000}},
24 {.m_aSkinName: "pinky", .m_aaSkinPartNames: {"standard", "whisker", "", "standard", "standard", "standard"}, .m_aUseCustomColors: {true, true, false, true, true, false}, .m_aSkinPartColors: {15911355, -801066, 0, 15043034, 15043034, 0}},
25 {.m_aSkinName: "redbopp", .m_aaSkinPartNames: {"standard", "donny", "unibop", "standard", "standard", "standard"}, .m_aUseCustomColors: {true, true, true, true, true, false}, .m_aSkinPartColors: {16177260, -16590390, 16177260, 16177260, 7624169, 0}},
26 {.m_aSkinName: "redstripe", .m_aaSkinPartNames: {"standard", "stripe", "", "standard", "standard", "standard"}, .m_aUseCustomColors: {true, false, false, true, true, false}, .m_aSkinPartColors: {16307835, 0, 0, 184, 9765959, 0}},
27 {.m_aSkinName: "saddo", .m_aaSkinPartNames: {"standard", "saddo", "", "standard", "standard", "standard"}, .m_aUseCustomColors: {true, true, false, true, true, false}, .m_aSkinPartColors: {7171455, -9685436, 0, 3640746, 5792119, 0}},
28 {.m_aSkinName: "toptri", .m_aaSkinPartNames: {"standard", "toptri", "", "standard", "standard", "standard"}, .m_aUseCustomColors: {true, false, false, true, true, false}, .m_aSkinPartColors: {6119331, 0, 0, 3640746, 5792119, 0}},
29 {.m_aSkinName: "twinbop", .m_aaSkinPartNames: {"standard", "duodonny", "twinbopp", "standard", "standard", "standard"}, .m_aUseCustomColors: {true, true, true, true, true, false}, .m_aSkinPartColors: {15310519, -1600806, 15310519, 15310519, 37600, 0}},
30 {.m_aSkinName: "twintri", .m_aaSkinPartNames: {"standard", "twintri", "", "standard", "standard", "standard"}, .m_aUseCustomColors: {true, true, false, true, true, false}, .m_aSkinPartColors: {3447932, -14098717, 0, 185, 9634888, 0}},
31 {.m_aSkinName: "warpaint", .m_aaSkinPartNames: {"standard", "warpaint", "", "standard", "standard", "standard"}, .m_aUseCustomColors: {true, false, false, true, true, false}, .m_aSkinPartColors: {1944919, 0, 0, 750337, 1944919, 0}},
32 /* custom */
33 {.m_aSkinName: "greensward", .m_aaSkinPartNames: {"greensward", "duodonny", "", "standard", "standard", "standard"}, .m_aUseCustomColors: {true, true, false, false, false, false}, .m_aSkinPartColors: {5635840, -11141356, 65408, 65408, 65408, 65408}},
34};
35
36CTeeInfo::CTeeInfo(const char *pSkinName, int UseCustomColor, int ColorBody, int ColorFeet)
37{
38 str_copy(dst&: m_aSkinName, src: pSkinName);
39 m_UseCustomColor = UseCustomColor;
40 m_ColorBody = ColorBody;
41 m_ColorFeet = ColorFeet;
42}
43
44CTeeInfo::CTeeInfo(const char *apSkinPartNames[protocol7::NUM_SKINPARTS], int aUseCustomColors[protocol7::NUM_SKINPARTS], int aSkinPartColors[protocol7::NUM_SKINPARTS])
45{
46 for(int Part = 0; Part < protocol7::NUM_SKINPARTS; Part++)
47 {
48 str_copy(dst&: m_aaSkinPartNames[Part], src: apSkinPartNames[Part]);
49 m_aUseCustomColors[Part] = aUseCustomColors[Part];
50 m_aSkinPartColors[Part] = aSkinPartColors[Part];
51 }
52}
53
54void CTeeInfo::ToSixup()
55{
56 // reset to default skin
57 for(int Part = 0; Part < protocol7::NUM_SKINPARTS; Part++)
58 {
59 str_copy(dst&: m_aaSkinPartNames[Part], src: STANDARD_SKINS[0].m_aaSkinPartNames[Part]);
60 m_aUseCustomColors[Part] = STANDARD_SKINS[0].m_aUseCustomColors[Part];
61 m_aSkinPartColors[Part] = STANDARD_SKINS[0].m_aSkinPartColors[Part];
62 }
63
64 // check for standard skin
65 for(const auto &StandardSkin : STANDARD_SKINS)
66 {
67 if(str_comp(a: m_aSkinName, b: StandardSkin.m_aSkinName) == 0)
68 {
69 for(int Part = 0; Part < protocol7::NUM_SKINPARTS; Part++)
70 {
71 str_copy(dst&: m_aaSkinPartNames[Part], src: StandardSkin.m_aaSkinPartNames[Part]);
72 m_aUseCustomColors[Part] = StandardSkin.m_aUseCustomColors[Part];
73 m_aSkinPartColors[Part] = StandardSkin.m_aSkinPartColors[Part];
74 }
75 break;
76 }
77 }
78
79 if(m_UseCustomColor)
80 {
81 const int ColorBody = ColorHSLA(m_ColorBody).UnclampLighting(Darkest: ColorHSLA::DARKEST_LGT).Pack(Darkest: ColorHSLA::DARKEST_LGT7);
82 const int ColorFeet = ColorHSLA(m_ColorFeet).UnclampLighting(Darkest: ColorHSLA::DARKEST_LGT).Pack(Darkest: ColorHSLA::DARKEST_LGT7);
83 m_aUseCustomColors[protocol7::SKINPART_BODY] = true;
84 m_aUseCustomColors[protocol7::SKINPART_MARKING] = true;
85 m_aUseCustomColors[protocol7::SKINPART_DECORATION] = true;
86 m_aUseCustomColors[protocol7::SKINPART_HANDS] = true;
87 m_aUseCustomColors[protocol7::SKINPART_FEET] = true;
88 m_aSkinPartColors[protocol7::SKINPART_BODY] = ColorBody;
89 m_aSkinPartColors[protocol7::SKINPART_MARKING] = 0x22FFFFFF;
90 m_aSkinPartColors[protocol7::SKINPART_DECORATION] = ColorBody;
91 m_aSkinPartColors[protocol7::SKINPART_HANDS] = ColorBody;
92 m_aSkinPartColors[protocol7::SKINPART_FEET] = ColorFeet;
93 }
94}
95
96void CTeeInfo::FromSixup()
97{
98 // reset to default skin
99 str_copy(dst&: m_aSkinName, src: "default");
100 m_UseCustomColor = false;
101 m_ColorBody = 0;
102 m_ColorFeet = 0;
103
104 // check for standard skin
105 for(const auto &StandardSkin : STANDARD_SKINS)
106 {
107 bool Match = true;
108 for(int Part = 0; Part < protocol7::NUM_SKINPARTS; Part++)
109 {
110 if(str_comp(a: m_aaSkinPartNames[Part], b: StandardSkin.m_aaSkinPartNames[Part]) != 0 ||
111 m_aUseCustomColors[Part] != StandardSkin.m_aUseCustomColors[Part] ||
112 (m_aUseCustomColors[Part] && m_aSkinPartColors[Part] != StandardSkin.m_aSkinPartColors[Part]))
113 {
114 Match = false;
115 break;
116 }
117 }
118 if(Match)
119 {
120 str_copy(dst&: m_aSkinName, src: StandardSkin.m_aSkinName);
121 return;
122 }
123 }
124
125 // find closest match
126 int BestMatches = -1;
127 const CStandardSkin *pBestSkin = &STANDARD_SKINS[0];
128 for(const auto &StandardSkin : STANDARD_SKINS)
129 {
130 int Matches = 0;
131 for(int Part = 0; Part <= protocol7::SKINPART_DECORATION; Part++) // not all parts are considered for comparison
132 {
133 if(str_comp(a: m_aaSkinPartNames[Part], b: StandardSkin.m_aaSkinPartNames[Part]) == 0)
134 {
135 Matches++;
136 }
137 }
138 if(Matches > BestMatches)
139 {
140 BestMatches = Matches;
141 pBestSkin = &StandardSkin;
142 }
143 }
144
145 str_copy(dst&: m_aSkinName, src: pBestSkin->m_aSkinName);
146 m_UseCustomColor = true;
147 m_ColorBody = ColorHSLA(m_aUseCustomColors[protocol7::SKINPART_BODY] ? m_aSkinPartColors[protocol7::SKINPART_BODY] : 255)
148 .UnclampLighting(Darkest: ColorHSLA::DARKEST_LGT7)
149 .Pack(Darkest: ColorHSLA::DARKEST_LGT);
150 m_ColorFeet = ColorHSLA(m_aUseCustomColors[protocol7::SKINPART_FEET] ? m_aSkinPartColors[protocol7::SKINPART_FEET] : 255)
151 .UnclampLighting(Darkest: ColorHSLA::DARKEST_LGT7)
152 .Pack(Darkest: ColorHSLA::DARKEST_LGT);
153}
154