From fd0204acd320e838bbcac45bd633e543985feb6e Mon Sep 17 00:00:00 2001 From: MegaMech Date: Thu, 26 Jun 2025 17:00:52 -0600 Subject: [PATCH 1/5] Update code_80005FD0.c --- src/code_80005FD0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/code_80005FD0.c b/src/code_80005FD0.c index a66d410fb..a3d822bc8 100644 --- a/src/code_80005FD0.c +++ b/src/code_80005FD0.c @@ -7091,7 +7091,7 @@ void cpu_use_item_strategy(s32 playerId) { if (((gNumPathPointsTraversed[playerId] + (playerId * 0x14) + 0x64) % 0x8 == 0) && (temp_s0->timer >= 0x200)) { cpu_decisions_branch_item(playerId, &temp_s0->branch, - gen_random_item_human((s16) gLapCountByPlayerId[playerId], + hard_cpu_gen_random_item((s16) gLapCountByPlayerId[playerId], gGPCurrentRaceRankByPlayerId[playerId])); } } From 47975c2c8de29b568e586a65b62c78f2c2551b04 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Thu, 26 Jun 2025 17:09:59 -0600 Subject: [PATCH 2/5] Update update_objects.c --- src/update_objects.c | 180 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 173 insertions(+), 7 deletions(-) diff --git a/src/update_objects.c b/src/update_objects.c index 6d5406f8d..39d0b4508 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -2796,7 +2796,7 @@ ItemProbabilities grandPrixHumanProbabilityTable[] = { .superMushroom = 10 }, }; -ItemProbabilities grandPrixAIProbabilityTable[] = { +ItemProbabilities grandPrixCPUProbabilityTable[] = { { .banana = 60, .bananaBunch = 0, .greenShell = 25, @@ -2919,6 +2919,129 @@ ItemProbabilities grandPrixAIProbabilityTable[] = { .superMushroom = 0 }, }; +ItemProbabilities grandPrixHardCPUProbabilityTable[] = { + { .banana = 30, + .bananaBunch = 5, + .greenShell = 30, + .tripleGreenShell = 5, + .redShell = 5, + .tripleRedShell = 0, + .blueSpinyShell = 0, + .thunderbolt = 0, + .fakeItemBox = 10, + .star = 0, + .boo = 5, + .mushroom = 10, + .doubleMushroom = 0, + .tripleMushroom = 0, + .superMushroom = 0 }, + { .banana = 5, + .bananaBunch = 5, + .greenShell = 5, + .tripleGreenShell = 10, + .redShell = 15, + .tripleRedShell = 20, + .blueSpinyShell = 0, + .thunderbolt = 0, + .fakeItemBox = 5, + .star = 5, + .boo = 5, + .mushroom = 5, + .doubleMushroom = 0, + .tripleMushroom = 15, + .superMushroom = 5 }, + { .banana = 3, + .bananaBunch = 2, + .greenShell = 0, + .tripleGreenShell = 10, + .redShell = 20, + .tripleRedShell = 20, + .blueSpinyShell = 0, + .thunderbolt = 0, + .fakeItemBox = 0, + .star = 10, + .boo = 0, + .mushroom = 5, + .doubleMushroom = 0, + .tripleMushroom = 20, + .superMushroom = 10 }, + { .banana = 5, + .bananaBunch = 0, + .greenShell = 5, + .tripleGreenShell = 5, + .redShell = 15, + .tripleRedShell = 10, + .blueSpinyShell = 0, + .thunderbolt = 0, + .fakeItemBox = 5, + .star = 15, + .boo = 5, + .mushroom = 5, + .doubleMushroom = 0, + .tripleMushroom = 20, + .superMushroom = 10 }, + { .banana = 0, + .bananaBunch = 0, + .greenShell = 0, + .tripleGreenShell = 0, + .redShell = 10, + .tripleRedShell = 20, + .blueSpinyShell = 5, + .thunderbolt = 0, + .fakeItemBox = 5, + .star = 15, + .boo = 0, + .mushroom = 5, + .doubleMushroom = 5, + .tripleMushroom = 25, + .superMushroom = 10 }, + { .banana = 0, + .bananaBunch = 0, + .greenShell = 0, + .tripleGreenShell = 0, + .redShell = 5, + .tripleRedShell = 20, + .blueSpinyShell = 10, + .thunderbolt = 0, + .fakeItemBox = 0, + .star = 20, + .boo = 0, + .mushroom = 5, + .doubleMushroom = 5, + .tripleMushroom = 25, + .superMushroom = 10 }, + { .banana = 0, + .bananaBunch = 0, + .greenShell = 5, + .tripleGreenShell = 0, + .redShell = 5, + .tripleRedShell = 20, + .blueSpinyShell = 10, + .thunderbolt = 0, + .fakeItemBox = 0, + .star = 30, + .boo = 0, + .mushroom = 5, + .doubleMushroom = 5, + .tripleMushroom = 10, + .superMushroom = 10 }, + { .banana = 0, + .bananaBunch = 0, + .greenShell = 0, + .tripleGreenShell = 5, + .redShell = 5, + .tripleRedShell = 20, + .blueSpinyShell = 15, + .thunderbolt = 10, + .fakeItemBox = 0, + .star = 30, + .boo = 0, + .mushroom = 0, + .doubleMushroom = 0, + .tripleMushroom = 5, + .superMushroom = 10 }, +}; + ItemProbabilities versus2PlayerProbabilityTable[] = { { .banana = 25, .bananaBunch = 10, @@ -3097,6 +3220,32 @@ void getProbabilityArray(const ItemProbabilities* probStruct, u8* probArray) { probArray[14] = probStruct->superMushroom; } +// Output a warning if a probability table does not add up to 100 +void verify_probability_table(char* str, const ItemProbabilities* probs, int16_t rank) { +#ifndef _DEBUG + return; +#endif + u8 itemProbabilities[ITEM_MAX - 1]; + + getProbabilityArray(probs, itemProbabilities); + size_t count = 0; + for (size_t i = 0; i < ITEM_MAX - 1; i++) { + //printf("prob %d ", itemProbabilities[i]); + count += itemProbabilities[i]; + } + //printf("\n"); + + if (count != 100) { + printf("update_objects.c::verify_probability_table\n %s table for rank %d is imba %d/100\n", str, rank, count); + } +} + +enum RandomItemOption { + HUMAN_TABLE, + CPU_TABLE, + HARD_CPU_TABLE, +}; + /** * New random item system uses chance based on percent * Likely functionally equivallent to the old system but easier to modify @@ -3111,27 +3260,40 @@ u8 gen_random_item(s16 rank, s16 isCpu) { switch (gModeSelection) { case GRAND_PRIX: - if (isCpu == false) { - distributionTable = &grandPrixHumanProbabilityTable[rank]; - } else { - distributionTable = &grandPrixAIProbabilityTable[rank]; + switch(option) { + case HUMAN_TABLE: + distributionTable = &grandPrixHumanProbabilityTable[rank]; + verify_probability_table("Human", distributionTable, rank); + break; + case EASY_CPU_TABLE: + distributionTable = &grandPrixEasyCPUProbabilityTable[rank]; + verify_probability_table("CPU", distributionTable, rank); + break; + case NORMAL_CPU_TABLE: + distributionTable = &grandPrixNormalCPUProbabilityTable[rank]; + verify_probability_table("Hard CPU", distributionTable, rank); + break; } break; case VERSUS: switch (gPlayerCountSelection1) { case TWO_PLAYERS_SELECTED: distributionTable = &versus2PlayerProbabilityTable[rank]; + verify_probability_table("Versus 2P", distributionTable, rank); break; case THREE_PLAYERS_SELECTED: distributionTable = &versus3PlayerProbabilityTable[rank]; + verify_probability_table("Versus 3P", distributionTable, rank); break; case FOUR_PLAYERS_SELECTED: distributionTable = &versus4PlayerProbabilityTable[rank]; + verify_probability_table("Versus 4P", distributionTable, rank); break; } break; case BATTLE: distributionTable = &battleProbabilityCurve[0]; + verify_probability_table("Battle", distributionTable, rank); break; } @@ -3150,11 +3312,15 @@ u8 gen_random_item(s16 rank, s16 isCpu) { } u8 gen_random_item_human(UNUSED s16 arg0, s16 rank) { - return gen_random_item(rank, false); + return gen_random_item(rank, HUMAN_TABLE); } u8 cpu_gen_random_item(UNUSED s32 arg0, s16 rank) { - return gen_random_item(rank, true); + return gen_random_item(rank, CPU_TABLE); +} + +u8 hard_cpu_gen_random_item(UNUSED s32 arg0, s16 rank) { + return gen_random_item(rank, HARD_CPU_TABLE); } s16 func_8007AFB0(s32 objectIndex, s32 arg1) { From c0b4fa7889e94267f198cf061124494d8fd3d5fe Mon Sep 17 00:00:00 2001 From: MegaMech Date: Thu, 26 Jun 2025 17:18:44 -0600 Subject: [PATCH 3/5] Update update_objects.c --- src/update_objects.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/update_objects.c b/src/update_objects.c index 39d0b4508..b3796ed92 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -3265,11 +3265,11 @@ u8 gen_random_item(s16 rank, s16 isCpu) { distributionTable = &grandPrixHumanProbabilityTable[rank]; verify_probability_table("Human", distributionTable, rank); break; - case EASY_CPU_TABLE: + case CPU_TABLE: distributionTable = &grandPrixEasyCPUProbabilityTable[rank]; verify_probability_table("CPU", distributionTable, rank); break; - case NORMAL_CPU_TABLE: + case HARD_CPU_TABLE: distributionTable = &grandPrixNormalCPUProbabilityTable[rank]; verify_probability_table("Hard CPU", distributionTable, rank); break; From 74dfa8c1e2e2102904198446564835f93410257e Mon Sep 17 00:00:00 2001 From: MegaMech Date: Thu, 26 Jun 2025 17:19:50 -0600 Subject: [PATCH 4/5] Update update_objects.h --- src/update_objects.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/update_objects.h b/src/update_objects.h index ed5e190c8..a26d04a99 100644 --- a/src/update_objects.h +++ b/src/update_objects.h @@ -201,6 +201,7 @@ void consume_item(s32); u8 gen_random_item(s16, s16); u8 gen_random_item_human(s16, s16); u8 cpu_gen_random_item(s32, s16); +u8 hard_cpu_gen_random_item(UNUSED s32 arg0, s16 rank); s16 func_8007AFB0(s32, s32); s32 func_8007B040(s32, s32); void func_8007B254(s32, s32); From d962e21355d90577402dae8eeab59c2606800d76 Mon Sep 17 00:00:00 2001 From: MegaMech Date: Thu, 26 Jun 2025 17:36:39 -0600 Subject: [PATCH 5/5] Update update_objects.c --- src/update_objects.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/update_objects.c b/src/update_objects.c index b3796ed92..0b3411f77 100644 --- a/src/update_objects.c +++ b/src/update_objects.c @@ -3312,7 +3312,11 @@ u8 gen_random_item(s16 rank, s16 isCpu) { } u8 gen_random_item_human(UNUSED s16 arg0, s16 rank) { - return gen_random_item(rank, HUMAN_TABLE); + if (CVarGetInteger("gHarderCPU", 0) == true) { + return gen_random_item(rank, HARD_CPU_TABLE); + } else { + return gen_random_item(rank, HUMAN_TABLE); + } } u8 cpu_gen_random_item(UNUSED s32 arg0, s16 rank) {