66#include " game_addrs.hpp"
77#include < imgui.h>
88#include " notifications.hpp"
9+ #include < array>
910
10- StageTable_mb CustomStageTable[ 0x40 ] ;
11+ std::array< StageTable_mb, 0x40 > CustomStageTable ;
1112int CustomStageTableCount = 0 ;
1213
14+ char ShareCode[256 ];
15+
1316class CourseReplacement : public Hook
1417{
1518 inline static SafetyHookMid midhook{};
@@ -21,12 +24,12 @@ class CourseReplacement : public Hook
2124 // If replacement is disabled we'll copy the loaded one into our replacement table, so user has something to modify
2225 if (!Game::CourseReplacementEnabled || !CustomStageTableCount)
2326 {
24- CustomStageTableCount = *SumoScript_StageTableCount;
25- memcpy (CustomStageTable, (void *)ctx.ebx , sizeof (StageTable_mb) * CustomStageTableCount);
27+ CustomStageTableCount = min ( *SumoScript_StageTableCount, CustomStageTable. size ()) ;
28+ memcpy (CustomStageTable. data () , (void *)ctx.ebx , sizeof (StageTable_mb) * CustomStageTableCount);
2629 }
2730 else
2831 {
29- ctx.ebx = (uintptr_t )CustomStageTable;
32+ ctx.ebx = (uintptr_t )CustomStageTable. data () ;
3033 ctx.esi = ctx.ebx ;
3134 *SumoScript_StageTableCount = CustomStageTableCount;
3235 }
@@ -62,6 +65,8 @@ class CourseReplacement : public Hook
6265};
6366CourseReplacement CourseReplacement::instance;
6467
68+ void sharecode_generate ();
69+
6570bool update_stage (StageTable_mb* tableEntry, GameStage newStage, bool isGoalColumn)
6671{
6772 tableEntry->StageUniqueName_0 = newStage;
@@ -102,9 +107,62 @@ bool update_stage(StageTable_mb* tableEntry, GameStage newStage, bool isGoalColu
102107 tableEntry->CsInfoPtr_14 = cs_info_tbl[tableEntry->CsInfoId_1C ];
103108 tableEntry->BrInfoPtr_18 = br_info_tbl[tableEntry->BrInfoId_20 ];
104109
110+ sharecode_generate ();
111+
105112 return true ;
106113}
107114
115+ void sharecode_generate ()
116+ {
117+ std::string code = " " ;
118+ for (int i = 0 ; i < 15 ; i++)
119+ {
120+ auto & stg = CustomStageTable[i];
121+ code += std::format (" {:X}-" , int (stg.StageUniqueName_0 ));
122+ }
123+ if (code.empty ())
124+ return ;
125+
126+ code = code.substr (0 , code.length () - 1 );
127+ strcpy (ShareCode, code.c_str ());
128+ }
129+
130+ void sharecode_apply ()
131+ {
132+ std::string code = ShareCode;
133+
134+ size_t start = 0 ;
135+ size_t end;
136+
137+ int num = 0 ;
138+ do
139+ {
140+ if (num >= CustomStageTable.size ())
141+ break ;
142+
143+ end = code.find (' -' , start);
144+ std::string part = code.substr (start, (end == std::string::npos) ? std::string::npos : end - start);
145+
146+ int stageNum = 0 ;
147+ try
148+ {
149+ stageNum = std::stol (part, nullptr , 16 );
150+ }
151+ catch (...)
152+ {
153+ stageNum = 0 ;
154+ }
155+ if (stageNum < 0 || stageNum >= 0x42 )
156+ stageNum = 0 ;
157+
158+ update_stage (&CustomStageTable[num], GameStage (stageNum), num > 9 );
159+
160+ num++;
161+
162+ start = end + 1 ;
163+ } while (end != std::string::npos);
164+ }
165+
108166void Overlay_CourseEditor ()
109167{
110168 /*
@@ -136,7 +194,8 @@ void Overlay_CourseEditor()
136194 if (disable_checkbox)
137195 ImGui::BeginDisabled ();
138196
139- ImGui::Checkbox (" Enable Course Override (use in C2C OutRun mode)" , &Game::CourseReplacementEnabled);
197+ if (ImGui::Checkbox (" Enable Course Override (use in C2C OutRun mode)" , &Game::CourseReplacementEnabled))
198+ sharecode_generate ();
140199
141200 if (disable_checkbox)
142201 ImGui::EndDisabled ();
@@ -164,7 +223,7 @@ void Overlay_CourseEditor()
164223 bool has_updated = false ;
165224
166225 int num = 0 ;
167- StageTable_mb* curStage = CustomStageTable;
226+ StageTable_mb* curStage = CustomStageTable. data () ;
168227 for (int col = 0 ; col < 5 ; ++col)
169228 {
170229 float columnHeight = (comboHeight + verticalSpacing) * (col + 1 ) - verticalSpacing;
@@ -222,6 +281,14 @@ void Overlay_CourseEditor()
222281 ImGui::SameLine (0 , 20 .0f );
223282 }
224283
284+ ImGui::Text (" Share Code: " );
285+ ImGui::SameLine ();
286+ ImGui::SetNextItemWidth (400 .f );
287+ ImGui::InputText (" ##ShareCode" , ShareCode, 256 );
288+ ImGui::SameLine ();
289+ if (ImGui::Button (" Apply Code" ))
290+ sharecode_apply ();
291+
225292 if (editor_disabled)
226293 {
227294 ImGui::EndDisabled ();
0 commit comments