@@ -145,41 +145,30 @@ CourseReplacement CourseReplacement::instance;
145145
146146void sharecode_generate ();
147147
148- bool update_stage (StageTable_mb* tableEntry, GameStage newStage, bool isGoalColumn )
148+ bool update_stage (StageTable_mb* tableEntry, GameStage newStage, int stageTableId )
149149{
150150 tableEntry->StageUniqueName_0 = newStage;
151- tableEntry->CsInfoId_1C = tableEntry->BrInfoId_20 = newStage;
151+ tableEntry->CsInfoId_1C = newStage;
152+
153+ tableEntry->BrInfoId_20 = 0 ; // 0 allows highway to always spawn
152154
153155 TAG_model_info** cs_info_tbl = Module::exe_ptr<TAG_model_info*>(0x2A54E0 );
154156 TAG_model_info** br_info_tbl = Module::exe_ptr<TAG_model_info*>(0x2A55E8 );
155157
156- if (newStage == STAGE_PALM_BEACH_T || newStage == STAGE_PALM_BEACH_BT)
157- tableEntry->BrInfoId_20 = STAGE_PALM_BEACH;
158- else if (newStage == STAGE_BEACH_T || newStage == STAGE_BEACH_BT)
159- tableEntry->BrInfoId_20 = STAGE_BEACH;
160- else if (newStage == STAGE_PALM_BEACH_BR)
161- tableEntry->BrInfoId_20 = STAGE_PALM_BEACH_R;
162- else if (newStage == STAGE_BEACH_BR)
163- tableEntry->BrInfoId_20 = STAGE_BEACH_R;
164-
165- if (isGoalColumn)
158+ if (stageTableId > 9 ) // goal stage
166159 {
167- // If stage is set to one of the existing goal-stages, use the goal bunki for it
168- // (otherwise will default to normal bunki, sadly goal bunki can't be shared between maps)
169-
170- if (tableEntry->BrInfoId_20 == STAGE_TULIP_GARDEN)
171- tableEntry->BrInfoId_20 = STAGE_EASTER_ISLAND_R + 1 ; // ENDA
172- else if (tableEntry->BrInfoId_20 == STAGE_METROPOLIS)
173- tableEntry->BrInfoId_20 = STAGE_EASTER_ISLAND_R + 2 ; // ENDB
174- else if (tableEntry->BrInfoId_20 == STAGE_ANCIENT_RUINS)
175- tableEntry->BrInfoId_20 = STAGE_EASTER_ISLAND_R + 3 ; // ENDC
176- else if (tableEntry->BrInfoId_20 == STAGE_CAPE_WAY)
177- tableEntry->BrInfoId_20 = STAGE_EASTER_ISLAND_R + 4 ; // ENDD
178- else if (tableEntry->BrInfoId_20 == STAGE_IMPERIAL_AVENUE)
179- tableEntry->BrInfoId_20 = STAGE_EASTER_ISLAND_R + 5 ; // ENDE
180-
181- else if (tableEntry->BrInfoId_20 == STAGE_PALM_BEACH)
182- tableEntry->BrInfoId_20 = STAGE_EASTER_ISLAND_R + 5 ; // ANDA (todo: what are ANDB - ANDJ for?)
160+ // TODO: allow swapping to 2SP goal-bunkis somehow?
161+ // TODO2: is there a generic goal-bunki we can use? I guess c2c missions probably use one for the non-goal stages?
162+ if (stageTableId == 10 )
163+ tableEntry->BrInfoId_20 = STAGE_TULIP_GARDEN; // goal A
164+ else if (stageTableId == 11 )
165+ tableEntry->BrInfoId_20 = STAGE_METROPOLIS; // goal B
166+ else if (stageTableId == 12 )
167+ tableEntry->BrInfoId_20 = STAGE_ANCIENT_RUINS; // goal C
168+ else if (stageTableId == 13 )
169+ tableEntry->BrInfoId_20 = STAGE_CAPE_WAY; // goal D
170+ else if (stageTableId == 14 )
171+ tableEntry->BrInfoId_20 = STAGE_IMPERIAL_AVENUE; // goal E
183172 }
184173
185174 tableEntry->CsInfoPtr_14 = cs_info_tbl[tableEntry->CsInfoId_1C ];
@@ -233,7 +222,7 @@ void sharecode_apply()
233222 if (stageNum < 0 || stageNum >= 0x42 )
234223 stageNum = 0 ;
235224
236- update_stage (&CustomStageTable[num], GameStage (stageNum), num > 9 );
225+ update_stage (&CustomStageTable[num], GameStage (stageNum), num);
237226
238227 num++;
239228
@@ -334,7 +323,7 @@ void Overlay_CourseEditor()
334323
335324 std::string name = std::format (" {}.{}" , (col + 1 ), (row + 1 ));
336325 if (ImGui::Combo (name.c_str (), &selected, stageNames, 0x42 ))
337- has_updated |= update_stage (curStage, GameStage (selected), col == 4 );
326+ has_updated |= update_stage (curStage, GameStage (selected), num );
338327
339328 curStage++;
340329
@@ -361,11 +350,75 @@ void Overlay_CourseEditor()
361350
362351 ImGui::Text (" Share Code: " );
363352 ImGui::SameLine ();
364- ImGui::SetNextItemWidth (400 .f );
353+ ImGui::SetNextItemWidth (500 .f );
365354 ImGui::InputText (" ##ShareCode" , ShareCode, 256 );
366355 ImGui::SameLine ();
367356 if (ImGui::Button (" Apply Code" ))
368357 sharecode_apply ();
358+ ImGui::SameLine ();
359+ if (ImGui::Button (" Copy Code" ))
360+ {
361+ HGLOBAL hMem = GlobalAlloc (GMEM_MOVEABLE, strlen (ShareCode) + 1 );
362+ if (hMem)
363+ {
364+ memcpy (GlobalLock (hMem), ShareCode, strlen (ShareCode) + 1 );
365+ GlobalUnlock (hMem);
366+ OpenClipboard (0 );
367+ EmptyClipboard ();
368+ SetClipboardData (CF_TEXT, hMem);
369+ CloseClipboard ();
370+ }
371+ }
372+ ImGui::SameLine ();
373+ if (ImGui::Button (" Paste Code" ))
374+ {
375+ if (OpenClipboard (0 ))
376+ {
377+ HANDLE hClipboardData = GetClipboardData (CF_UNICODETEXT);
378+ if (hClipboardData == nullptr )
379+ hClipboardData = GetClipboardData (CF_TEXT);
380+
381+ if (hClipboardData != nullptr )
382+ {
383+ void * clipboardData = GlobalLock (hClipboardData);
384+ if (clipboardData)
385+ {
386+ if (hClipboardData == GetClipboardData (CF_UNICODETEXT))
387+ {
388+ wchar_t * wideText = static_cast <wchar_t *>(clipboardData);
389+
390+ // Convert unicode to char
391+ int bufferSize = WideCharToMultiByte (CP_UTF8, 0 , wideText, -1 , nullptr , 0 , nullptr , nullptr );
392+ if (bufferSize > 0 && bufferSize < sizeof (ShareCode))
393+ WideCharToMultiByte (CP_UTF8, 0 , wideText, -1 , ShareCode, bufferSize, nullptr , nullptr );
394+ else
395+ {
396+ // Handle the case where the buffer is too small, truncate if necessary
397+ WideCharToMultiByte (CP_UTF8, 0 , wideText, -1 , ShareCode, sizeof (ShareCode) - 1 , nullptr , nullptr );
398+ ShareCode[sizeof (ShareCode) - 1 ] = ' \0 ' ; // Null-terminate
399+ }
400+ }
401+ else if (hClipboardData == GetClipboardData (CF_TEXT))
402+ {
403+ char * asciiText = static_cast <char *>(clipboardData);
404+
405+ if (strlen (asciiText) < sizeof (ShareCode))
406+ strcpy (ShareCode, asciiText);
407+ else
408+ {
409+ // If the clipboard text is too large, truncate
410+ strncpy (ShareCode, asciiText, sizeof (ShareCode) - 1 );
411+ ShareCode[sizeof (ShareCode) - 1 ] = ' \0 ' ; // Null-terminate
412+ }
413+ }
414+ sharecode_apply ();
415+
416+ GlobalUnlock (hClipboardData);
417+ }
418+ }
419+ CloseClipboard ();
420+ }
421+ }
369422
370423 if (ImGui::TreeNode (" Randomizer" ))
371424 {
@@ -421,7 +474,7 @@ void Overlay_CourseEditor()
421474 }
422475 }
423476
424- update_stage (&CustomStageTable[i], random_stage, i > 9 );
477+ update_stage (&CustomStageTable[i], random_stage, i);
425478 seen.push_back (random_stage);
426479 }
427480 }
0 commit comments