Impl RandomItemTable class (#598)

* Impl RandomItem class

* Refactor func

* Impl RandomItemTable

* Revert probability inaccuracy

* Remove unnecessary comment

* Fix compile, probably

* As per review 1

---------

Co-authored-by: MegaMech <7255464+MegaMech@users.noreply.github.com>
This commit is contained in:
MegaMech
2025-12-18 11:24:38 -07:00
committed by GitHub
parent 99b5630055
commit f0c2cea0ee
52 changed files with 1018 additions and 1003 deletions
+10
View File
@@ -1,6 +1,16 @@
#ifndef DEFINES_H
#define DEFINES_H
#ifdef __cplusplus
#define EXTERN_C extern "C"
#define EXTERN_C_START extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C extern
#define EXTERN_C_START
#define EXTERN_C_END
#endif
/**
* @brief Options for Controller Pak state
*/
+3 -3
View File
@@ -42,6 +42,7 @@
#include "port/Game.h"
#include "engine/tracks/Track.h"
#include "engine/RaceManager.h"
s32 unk_code_80005FD0_pad[24];
Collision D_80162E70;
@@ -7177,14 +7178,13 @@ void cpu_use_item_strategy(s32 playerId) {
(CVarGetInteger("gHarderCPU", 0) == true)) {
cpu_decisions_branch_item(playerId, &cpuStrategy->branch,
hard_cpu_gen_random_item((s16) gLapCountByPlayerId[playerId],
gGPCurrentRaceRankByPlayerId[playerId]));
RaceManager_GetRandomCPUItem(gGPCurrentRaceRankByPlayerId[playerId]));
// Stock CPU Items
} else if ((((playerId * 20) + 100) < gNumPathPointsTraversed[playerId]) && (cpuStrategy->timer >= 0x259) &&
(cpuStrategy->numItemUse < 3) && (gLapCountByPlayerId[playerId] < 3)) {
cpu_decisions_branch_item(
playerId, &cpuStrategy->branch,
cpu_gen_random_item((s16) gLapCountByPlayerId[playerId], gGPCurrentRaceRankByPlayerId[playerId]));
RaceManager_GetRandomCPUItem(gGPCurrentRaceRankByPlayerId[playerId]));
} else {
func_8001ABE0(playerId, cpuStrategy);
}
+67
View File
@@ -5,6 +5,7 @@
#include "port/Game.h"
#include "engine/editor/Editor.h"
#include "engine/editor/SceneManager.h"
#include "engine/RandomItemTable.h"
extern "C" {
#include "render_courses.h"
@@ -68,6 +69,8 @@ void RaceManager::PreInit() {
} else {
gPlaceItemBoxes = true;
}
RaceManager::SetItemTables();
}
void RaceManager::BeginPlay() {
@@ -114,3 +117,67 @@ void RaceManager::PostInit() {
OTrophy::Spawn(FVector(0,0,0), OTrophy::TrophyType::GOLD, OTrophy::Behaviour::GO_FISH);
}
}
void RaceManager::SetItemTables() {
std::string humanTableName = "";
std::string cpuTableName = "";
switch(gModeSelection) {
case GRAND_PRIX:
if (CVarGetInteger("gHarderCPU", false) == true) {
humanTableName = "mk:hard_cpu_grand_prix";
cpuTableName = "mk:hard_cpu_grand_prix";
} else { // normal gameplay
humanTableName = "mk:human_grand_prix";
cpuTableName = "mk:cpu_grand_prix";
}
case VERSUS:
switch (gPlayerCountSelection1) {
case TWO_PLAYERS_SELECTED:
humanTableName = "mk:versus_2p";
cpuTableName = "none selected";
break;
case THREE_PLAYERS_SELECTED:
humanTableName = "mk:versus_3p";
cpuTableName = "none selected";
break;
case FOUR_PLAYERS_SELECTED:
humanTableName = "mk:versus_4p";
cpuTableName = "none selected";
break;
}
break;
case BATTLE:
humanTableName = "mk:battle";
cpuTableName = "none selected";
break;
}
mHumanItemTable = gItemTableRegistry.Get(humanTableName);
mCPUItemTable = gItemTableRegistry.Get(cpuTableName);
printf("[RaceManager] Selected human item probability table %s\n", humanTableName.c_str());
printf("[RaceManager] Selected cpu item probability table %s\n", cpuTableName.c_str());
}
extern "C" int16_t RaceManager_GetRandomHumanItem(uint32_t rank) {
auto& raceManager = GetWorld()->GetRaceManager();
auto* table = raceManager.GetHumanItemTable();
if (nullptr == table) {
printf("[RaceManager_GetRandomHumanItem] Item table nullptr, giving player a none item\n");
return ITEM_NONE;
}
return table->Roll(rank);
}
extern "C" int16_t RaceManager_GetRandomCPUItem(uint32_t rank) {
auto& raceManager = GetWorld()->GetRaceManager();
auto* table = raceManager.GetCPUItemTable();
if (nullptr == table) {
printf("[RaceManager_GetRandomCPUItem] Item table nullptr, giving player a none item\n");
return ITEM_NONE;
}
return table->Roll(rank);
}
+17 -2
View File
@@ -1,6 +1,10 @@
#pragma once
#ifndef RACE_MANAGER_H
#define RACE_MANAGER_H
#include "defines.h"
#ifdef __cplusplus
#include "engine/RandomItemTable.h"
extern "C" {
#endif
#include <libultraship/libultra/gbi.h>
@@ -37,8 +41,19 @@ public:
virtual void PreInit();
virtual void BeginPlay();
virtual void PostInit();
virtual void SetItemTables();
RandomItemTable* GetHumanItemTable() { return mHumanItemTable; }
RandomItemTable* GetCPUItemTable() { return mCPUItemTable; }
protected:
World& WorldContext;
RandomItemTable* mHumanItemTable;
RandomItemTable* mCPUItemTable;
std::unordered_map<std::string, RandomItemTable> mItemTables;
};
#endif
#endif // __cplusplus
EXTERN_C int16_t RaceManager_GetRandomHumanItem(uint32_t rank);
EXTERN_C int16_t RaceManager_GetRandomCPUItem(uint32_t rank);
#endif // RACE_MANAGER_H
+104
View File
@@ -0,0 +1,104 @@
#include "RandomItemTable.h"
#include "port/Game.h"
extern "C" {
#include "math_util.h"
}
RandomItemTable::RandomItemTable() {
mDistanceEnabled = false;
}
bool RandomItemTable::Add(const std::string& resourceName, uint32_t rank, uint32_t weight, float distance) {
const ItemInfo* info = gItemRegistry.GetInfo(resourceName);
if (!info) {
printf("[ItemTables] Failed to add %s to table,\n item name passed into resourceName does not exist!\n", resourceName.c_str());
return false;
}
if (rank >= mTable.size()) {
if (rank >= NUM_PLAYERS) {
printf("[ItemTables] Failed to add item table, rank value too high!\n");
return false;
}
mTable.resize(rank + 1);
}
// Check if already exists
for (const ItemEntry& entry : mTable[rank]) {
if (entry.Id == info->Id) {
printf("[ItemTables] %s already exists for this rank, skipping...\n", resourceName.c_str());
return false;
}
}
mTable[rank].push_back(ItemEntry{info->Id, weight, distance});
return true;
}
uint8_t RandomItemTable::Roll(uint32_t rank) const {
if (rank >= mTable.size()) {
printf("[ItemTables] [Roll] Invalid rank input %d. Giving player a none item\n", rank);
return ITEM_NONE;
}
// Items that could be selected for this rank
const std::vector<ItemEntry>& itemList = mTable.at(rank);
if (itemList.empty()) {
printf("[ItemTables] [Roll] itemList empty. Giving player a none item\n");
return ITEM_NONE;
}
// Calculate total weight
uint32_t totalWeight = 0;
for (const ItemEntry& entry : itemList) {
if (this->IsBlacklisted(entry.Id)) {
continue;
}
totalWeight += entry.Weight;
}
// Avoid division by zero
if (totalWeight == 0) {
printf("[ItemTables] [Roll] No items to give out for this rank. Giving player a none item\n");
return ITEM_NONE;
}
// Pick a random number from zero to (totalWeight - 1)
uint32_t rand = random_int(totalWeight - 1);
// Cumulative sum over weights
uint32_t accumulated = 0;
for (const ItemEntry& entry : itemList) {
if (this->IsBlacklisted(entry.Id)) {
continue;
}
accumulated += entry.Weight;
if (rand < accumulated) {
return static_cast<uint8_t>(entry.Id);
}
}
// Fallback (should not happen)
printf("[ItemTables] [Roll] Reached unreachable code\n");
[[unlikely]] return ITEM_NONE;
}
void RandomItemTable::Blacklist(const std::string& resourceName) {
const ItemInfo* info = gItemRegistry.GetInfo(resourceName);
if (!info) {
return;
}
mBlacklist.insert(info->Id);
}
bool RandomItemTable::IsBlacklisted(uint32_t itemId) const {
//return mBlacklist.contains(itemId);
return mBlacklist.find(itemId) != mBlacklist.end();
}
void RandomItemTable::ClearBlacklist() {
mBlacklist.clear();
}
+33
View File
@@ -0,0 +1,33 @@
#pragma once
#include <libultraship/libultraship.h>
#include <utility>
/**
* Uses weighted random picking
*
* This allows stock game to work identically
* while allowing mods to add items which equalizes
* the stock items without requiring addition chance editing
*/
class RandomItemTable {
public:
RandomItemTable();
bool Add(const std::string& resourceName, uint32_t rank, uint32_t weight, float distance);
uint8_t Roll(uint32_t rank) const;
void Blacklist(const std::string& resourceName);
bool IsBlacklisted(uint32_t id) const;
void ClearBlacklist();
protected:
bool mDistanceEnabled;
struct ItemEntry {
uint32_t Id;
uint32_t Weight;
float Distance;
};
// Rank index item_id, chance
std::vector<std::vector<ItemEntry>> mTable;
std::unordered_set<uint32_t> mBlacklist;
};
+1 -1
View File
@@ -1,7 +1,7 @@
#pragma once
#include <libultraship.h>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/Actor.h"
#include "CoreMath.h"
+1 -1
View File
@@ -1,7 +1,7 @@
#pragma once
#include <libultraship.h>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/Actor.h"
#include "CoreMath.h"
#include "engine/SpawnParams.h"
+1 -1
View File
@@ -2,7 +2,7 @@
#include <libultraship.h>
#include "CoreMath.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/Actor.h"
extern "C" {
+1 -1
View File
@@ -4,7 +4,7 @@
#include "engine/Actor.h"
#include "CoreMath.h"
#include "engine/World.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
extern "C" {
#include "common_structs.h"
+1 -1
View File
@@ -3,7 +3,7 @@
#include <libultraship.h>
#include <libultra/gbi.h>
#include "CoreMath.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/Actor.h"
class AShip : public AActor {
+1 -1
View File
@@ -3,7 +3,7 @@
#include <libultraship.h>
#include <libultra/gbi.h>
#include "CoreMath.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/Actor.h"
#include "engine/World.h"
+1 -1
View File
@@ -3,7 +3,7 @@
#include <libultraship.h>
#include <libultra/gbi.h>
#include "CoreMath.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/Actor.h"
#include "engine/World.h"
+1 -1
View File
@@ -1,7 +1,7 @@
#pragma once
#include <libultraship.h>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/Actor.h"
#include "src/textures.h"
#include "engine/CoreMath.h"
+1 -1
View File
@@ -1,7 +1,7 @@
#pragma once
#include <libultraship.h>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/Actor.h"
#include "CoreMath.h"
+1 -7
View File
@@ -4,6 +4,7 @@
#include <libultraship/libultraship.h>
#include <libultra/gbi.h>
#include "defines.h"
#ifdef __cplusplus
#include "GameObject.h"
@@ -57,13 +58,6 @@ private:
} // namespace TrackEditor
#endif // __cplusplus
#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C
#endif
EXTERN_C void Editor_Launch(const char* resourceName);
EXTERN_C void Editor_SetLevelDimensions(s16 minX, s16 maxX, s16 minZ, s16 maxZ, s16 minY, s16 maxY);
EXTERN_C bool Editor_IsEnabled();
+4 -3
View File
@@ -104,7 +104,7 @@ namespace TrackEditor {
/** Do not use GetWorld()->CurrentCourse during loading! The current track is not guaranteed! **/
void LoadTrackDataFromJson(Track* track, const std::string& trackPath) {
SPDLOG_INFO("[SceneManager] [LoadTrackDataFromJson] Loading track scenefile...");
SPDLOG_INFO("[SceneManager] [LoadTrackDataFromJson] Loading Track SceneFile...");
if (trackPath.empty()) {
SPDLOG_INFO(" Unable to load track. trackPath empty.");
@@ -147,7 +147,7 @@ namespace TrackEditor {
LoadActors(track, data);
LoadStaticMeshActors(track, data);
LoadTour(track, data);
SPDLOG_INFO("[SceneManager] [LoadTrackDataFromJson] Scene File Loaded!");
SPDLOG_INFO("[SceneManager] [LoadTrackDataFromJson] SceneFile Loaded!\n");
}
void LoadTrackInfo(TrackInfo& info, std::shared_ptr<Ship::Archive> archive, std::string sceneFile) {
@@ -155,6 +155,7 @@ namespace TrackEditor {
SPDLOG_INFO("[SceneManager] [LoadTrackDataFromJson] Failed to load scenefile, track or rootarchive were null");
return;
}
SPDLOG_INFO("[SceneManager] [LoadTrackInfo] Loading TrackInfo...");
/*
* Manually loading a custom asset file (scene.json) with no extractor class means that
@@ -179,7 +180,7 @@ namespace TrackEditor {
LoadTrackInfoData(info, data);
SPDLOG_INFO("[SceneManager] [LoadTrackInfo] Loaded track info!");
SPDLOG_INFO("[SceneManager] [LoadTrackInfo] Loaded TrackInfo!\n");
}
void Load_AddStaticMeshActor(const nlohmann::json& actorJson) {
+1 -1
View File
@@ -4,7 +4,7 @@
#include <vector>
#include "Object.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "World.h"
#include "CoreMath.h"
+1 -1
View File
@@ -1,7 +1,7 @@
#pragma once
#include <libultraship.h>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/objects/Object.h"
#include "World.h"
+1 -1
View File
@@ -4,7 +4,7 @@
#include <vector>
#include "Object.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "World.h"
#include "CoreMath.h"
+1 -1
View File
@@ -3,7 +3,7 @@
#include <libultraship.h>
#include <vector>
#include "Object.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/CoreMath.h"
#include "World.h"
+1 -1
View File
@@ -2,7 +2,7 @@
#include <libultraship.h>
#include <vector>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/objects/Object.h"
#include "CoreMath.h"
#include "World.h"
+1 -1
View File
@@ -4,7 +4,7 @@
#include <vector>
#include "Object.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "World.h"
extern "C" {
+1 -1
View File
@@ -2,7 +2,7 @@
#include <libultraship.h>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/World.h"
#include "engine/objects/Object.h"
+1 -1
View File
@@ -4,7 +4,7 @@
#include <vector>
#include "Object.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/World.h"
extern "C" {
+1 -1
View File
@@ -3,7 +3,7 @@
#include <libultraship.h>
#include "Object.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "World.h"
class OHotAirBalloon : public OObject {
+1 -1
View File
@@ -1,7 +1,7 @@
#pragma once
#include <libultraship.h>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/World.h"
#include "engine/objects/Object.h"
+1 -1
View File
@@ -2,7 +2,7 @@
#include <libultraship.h>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "World.h"
+1 -1
View File
@@ -3,7 +3,7 @@
#include <libultraship.h>
#include "Object.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/World.h"
//! @todo unk_0D5 needs to be a struct variable probably. What does it do? Behaviour?
+1 -1
View File
@@ -3,7 +3,7 @@
#include <libultraship.h>
#include "Object.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "World.h"
extern "C" {
+1 -1
View File
@@ -1,7 +1,7 @@
#pragma once
#include <libultraship.h>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/World.h"
#include "engine/SpawnParams.h"
#include "engine/CoreMath.h"
+1 -1
View File
@@ -3,7 +3,7 @@
#include <libultraship.h>
#include "Object.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "World.h"
class OTrashBin : public OObject {
+1 -1
View File
@@ -2,7 +2,7 @@
#include <libultraship.h>
#include "Object.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "World.h"
#include "engine/particles/StarEmitter.h"
+44
View File
@@ -0,0 +1,44 @@
#pragma once
#include <string>
#include <unordered_map>
#include <memory>
#include <cstdint>
template<typename TObject>
class DataRegistry {
public:
// Add object by copy or move; overwrites if exists
void Add(const std::string& resourceName, TObject&& object) {
mMap[resourceName] = std::make_unique<TObject>(std::forward<TObject>(object));
}
void Add(const std::string& resourceName, const TObject& object) {
mMap[resourceName] = std::make_unique<TObject>(object);
}
// Get pointer to object (nullptr if not found)
TObject* Get(const std::string& resourceName) {
auto it = mMap.find(resourceName);
return it != mMap.end() ? it->second.get() : nullptr;
}
const TObject* Get(const std::string& resourceName) const {
auto it = mMap.find(resourceName);
return it != mMap.end() ? it->second.get() : nullptr;
}
bool Remove(const std::string& resourceName) {
return mMap.erase(resourceName) > 0;
}
size_t Size() const {
return mMap.size();
}
void Clear() {
mMap.clear();
}
private:
std::unordered_map<std::string, std::unique_ptr<TObject>> mMap;
};
@@ -1,11 +1,6 @@
#include "SpawnParams.h"
#include "engine/registry/RegisterContent.h"
#include "engine/CoreMath.h"
#include "Registry.h"
#include "engine/World.h"
#include "RegisterContent.h"
#include "AllTracks.h"
#include "AllActors.h"
#include "engine/AllActors.h"
extern "C" {
#include "common_structs.h"
@@ -15,20 +10,11 @@ extern "C" {
}
/**
* @file RegisterContent
* This file is responsible for registering the games stock content
*/
/**
* DO NOT RE-ORDER ANYTHING IN THESE FILES
*
* DO NOT RE-ORDER ANYTHING IN THIS FILE.
* IT WILL MIX UP THE IDS
*
* Add new content to the end of the function
* It will result in differing Ids
*/
void RegisterActors(Registry<ActorInfo, const SpawnParams&>& r) {
ActorInfo info;
@@ -290,216 +276,3 @@ void RegisterActors(Registry<ActorInfo, const SpawnParams&>& r) {
info = { .ResourceName = "mk:bowser_statue", .Name = "Bowser Statue" };
r.Add(info, AddActorToWorld<ABowserStatue>);
}
void RegisterTracks(Registry<TrackInfo>& r) {
TrackInfo info;
info = {
.ResourceName = "mk:mario_raceway",
.Name = "mario raceway",
.DebugName = "m circuit",
.Length = "567m",
.MinimapTexture = minimap_mario_raceway,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<MarioRaceway>()); });
info = {
.ResourceName = "mk:choco_mountain",
.Name = "choco mountain",
.DebugName = "mountain",
.Length = "687m",
.MinimapTexture = minimap_choco_mountain,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<ChocoMountain>()); });
info = {
.ResourceName = "mk:bowsers_castle",
.Name = "bowser's castle",
.DebugName = "castle",
.Length = "777m",
.MinimapTexture = minimap_bowsers_castle,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<BowsersCastle>()); });
info = {
.ResourceName = "mk:banshee_boardwalk",
.Name = "banshee boardwalk",
.DebugName = "ghost",
.Length = "747m",
.MinimapTexture = minimap_banshee_boardwalk,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<BansheeBoardwalk>()); });
info = {
.ResourceName = "mk:yoshi_valley",
.Name = "yoshi valley",
.DebugName = "maze",
.Length = "772m",
.MinimapTexture = minimap_yoshi_valley,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<YoshiValley>()); });
info = {
.ResourceName = "mk:frappe_snowland",
.Name = "frappe snowland",
.DebugName = "snow",
.Length = "734m",
.MinimapTexture = minimap_frappe_snowland,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<FrappeSnowland>()); });
info = {
.ResourceName = "mk:koopa_beach",
.Name = "koopa troopa beach",
.DebugName = "beach",
.Length = "691m",
.MinimapTexture = minimap_koopa_troopa_beach,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<KoopaTroopaBeach>()); });
info = {
.ResourceName = "mk:royal_raceway",
.Name = "royal raceway",
.DebugName = "p circuit",
.Length = "1025m",
.MinimapTexture = minimap_royal_raceway,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<RoyalRaceway>()); });
info = {
.ResourceName = "mk:luigi_raceway",
.Name = "luigi raceway",
.DebugName = "l circuit",
.Length = "717m",
.MinimapTexture = minimap_luigi_raceway,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<LuigiRaceway>()); });
info = {
.ResourceName = "mk:moo_moo_farm",
.Name = "moo moo farm",
.DebugName = "farm",
.Length = "527m",
.MinimapTexture = minimap_moo_moo_farm,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<MooMooFarm>()); });
info = {
.ResourceName = "mk:toads_turnpike",
.Name = "toad's turnpike",
.DebugName = "highway",
.Length = "1036m",
.MinimapTexture = minimap_toads_turnpike,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<ToadsTurnpike>()); });
info = {
.ResourceName = "mk:kalimari_desert",
.Name = "kalimari desert",
.DebugName = "desert",
.Length = "753m",
.MinimapTexture = minimap_kalimari_desert,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<KalimariDesert>()); });
info = {
.ResourceName = "mk:sherbet_land",
.Name = "sherbet land",
.DebugName = "sherbet",
.Length = "756m",
.MinimapTexture = minimap_sherbet_land,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<SherbetLand>()); });
info = {
.ResourceName = "mk:rainbow_road",
.Name = "rainbow road",
.DebugName = "rainbow",
.Length = "2000m",
.MinimapTexture = minimap_rainbow_road,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<RainbowRoad>()); });
info = {
.ResourceName = "mk:wario_stadium",
.Name = "wario stadium",
.DebugName = "stadium",
.Length = "1591m",
.MinimapTexture = minimap_wario_stadium,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<WarioStadium>()); });
info = {
.ResourceName = "mk:block_fort",
.Name = "block fort",
.DebugName = "block",
.Length = "",
.MinimapTexture = minimap_block_fort,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<BlockFort>()); });
info = {
.ResourceName = "mk:skyscraper",
.Name = "skyscraper",
.DebugName = "skyscraper",
.Length = "",
.MinimapTexture = minimap_skyscraper,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<Skyscraper>()); });
info = {
.ResourceName = "mk:double_deck",
.Name = "double deck",
.DebugName = "deck",
.Length = "",
.MinimapTexture = minimap_double_deck,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<DoubleDeck>()); });
info = {
.ResourceName = "mk:dk_jungle",
.Name = "d.k.'s jungle parkway",
.DebugName = "jungle",
.Length = "893m",
.MinimapTexture = minimap_dks_jungle_parkway,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<DKJungle>()); });
info = {
.ResourceName = "mk:big_donut",
.Name = "big donut",
.DebugName = "doughnut",
.Length = "",
.MinimapTexture = minimap_big_donut,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<BigDonut>()); });
info = {
.ResourceName = "hm:test_track",
.Name = "test track",
.DebugName = "test track",
.Length = "100m",
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<TestTrack>()); });
}
@@ -1,10 +1,11 @@
#pragma once
#include "Object.h"
#include "Registry.h"
#include "SpawnParams.h"
#include "port/Game.h"
#include <memory>
#include "DataRegistry.h"
#include "src/port/Game.h"
#include "engine/objects/Object.h"
#include "engine/Actor.h"
#include "engine/SpawnParams.h"
template<class T> static OObject* AddObjectToWorld(const SpawnParams& params) {
return GetWorld()->AddObject(std::make_unique<T>(params));
@@ -14,5 +15,7 @@ template<class T> static AActor* AddActorToWorld(const SpawnParams& params) {
return GetWorld()->AddActor(std::make_unique<T>(params));
}
void RegisterActors(Registry<ActorInfo, const SpawnParams&>& r);
void RegisterTracks(Registry<TrackInfo>& r);
void RegisterActors(Registry<ActorInfo, const SpawnParams&>& r);
void RegisterItems(Registry<ItemInfo>& r);
void RegisterItemTables(DataRegistry<RandomItemTable>& r);
+379
View File
@@ -0,0 +1,379 @@
#include "RegisterContent.h"
#include <utility>
#include "engine/RandomItemTable.h"
/**
* DO NOT RE-ORDER ANYTHING IN THESE FILES
*
* It will result in differing Ids
*/
enum RANK {
RANK_ONE,
RANK_TWO,
RANK_THREE,
RANK_FOUR,
RANK_FIVE,
RANK_SIX,
RANK_SEVEN,
RANK_EIGHT
};
void RegisterHumanItemTable(DataRegistry<RandomItemTable>& r);
void RegisterCPUItemTable(DataRegistry<RandomItemTable>& r);
void RegisterHardCPUItemTable(DataRegistry<RandomItemTable>& r);
void RegisterVersus2PItemTable(DataRegistry<RandomItemTable>& r);
void RegisterVersus3PItemTable(DataRegistry<RandomItemTable>& r);
void RegisterVersus4PItemTable(DataRegistry<RandomItemTable>& r);
void RegisterBattleItemTable(DataRegistry<RandomItemTable>& r);
void RegisterItemTables(DataRegistry<RandomItemTable>& r) {
RegisterHumanItemTable(r);
RegisterCPUItemTable(r);
RegisterHardCPUItemTable(r);
RegisterVersus2PItemTable(r);
RegisterVersus3PItemTable(r);
RegisterVersus4PItemTable(r);
RegisterBattleItemTable(r);
}
void RegisterHumanItemTable(DataRegistry<RandomItemTable>& r) {
RandomItemTable table;
table.Add("mk:banana", RANK_ONE, 30, 0.0f);
table.Add("mk:banana_bunch", RANK_ONE, 5, 0.0f);
table.Add("mk:green_shell", RANK_ONE, 30, 0.0f);
table.Add("mk:triple_green_shell", RANK_ONE, 5, 0.0f);
table.Add("mk:red_shell", RANK_ONE, 5, 0.0f);
table.Add("mk:fake_item_box", RANK_ONE, 10, 0.0f);
table.Add("mk:boo", RANK_ONE, 5, 0.0f);
table.Add("mk:mushroom", RANK_ONE, 10, 0.0f);
table.Add("mk:banana_bunch", RANK_TWO, 5, 0.0f);
table.Add("mk:green_shell", RANK_TWO, 5, 0.0f);
table.Add("mk:triple_green_shell", RANK_TWO, 10, 0.0f);
table.Add("mk:red_shell", RANK_TWO, 15, 0.0f);
table.Add("mk:triple_red_shell", RANK_TWO, 20, 0.0f);
table.Add("mk:thunderbolt", RANK_TWO, 5, 0.0f);
table.Add("mk:fake_item_box", RANK_TWO, 5, 0.0f);
table.Add("mk:star", RANK_TWO, 5, 0.0f);
table.Add("mk:boo", RANK_TWO, 5, 0.0f);
table.Add("mk:mushroom", RANK_TWO, 5, 0.0f);
table.Add("mk:triple_mushroom",RANK_TWO, 15, 0.0f);
table.Add("mk:super_mushroom", RANK_TWO, 5, 0.0f);
table.Add("mk:triple_green_shell", RANK_THREE, 10, 0.0f);
table.Add("mk:red_shell", RANK_THREE, 20, 0.0f);
table.Add("mk:triple_red_shell", RANK_THREE, 20, 0.0f);
table.Add("mk:thunderbolt", RANK_THREE, 5, 0.0f);
table.Add("mk:star", RANK_THREE, 10, 0.0f);
table.Add("mk:mushroom", RANK_THREE, 5, 0.0f);
table.Add("mk:triple_mushroom",RANK_THREE, 20, 0.0f);
table.Add("mk:super_mushroom", RANK_THREE, 10, 0.0f);
table.Add("mk:red_shell", RANK_FOUR, 15, 0.0f);
table.Add("mk:triple_red_shell", RANK_FOUR, 20, 0.0f);
table.Add("mk:blue_spiny_shell", RANK_FOUR, 5, 0.0f);
table.Add("mk:thunderbolt", RANK_FOUR, 10, 0.0f);
table.Add("mk:star", RANK_FOUR, 15, 0.0f);
table.Add("mk:mushroom", RANK_FOUR, 5, 0.0f);
table.Add("mk:triple_mushroom",RANK_FOUR, 20, 0.0f);
table.Add("mk:super_mushroom", RANK_FOUR, 10, 0.0f);
table.Add("mk:red_shell", RANK_FIVE, 10, 0.0f);
table.Add("mk:triple_red_shell", RANK_FIVE, 20, 0.0f);
table.Add("mk:blue_spiny_shell", RANK_FIVE, 5, 0.0f);
table.Add("mk:thunderbolt", RANK_FIVE, 10, 0.0f);
table.Add("mk:star", RANK_FIVE, 15, 0.0f);
table.Add("mk:mushroom", RANK_FIVE, 5, 0.0f);
table.Add("mk:triple_mushroom",RANK_FIVE, 25, 0.0f);
table.Add("mk:super_mushroom", RANK_FIVE, 10, 0.0f);
table.Add("mk:triple_red_shell", RANK_SIX, 20, 0.0f);
table.Add("mk:blue_spiny_shell", RANK_SIX, 10, 0.0f);
table.Add("mk:thunderbolt", RANK_SIX, 15, 0.0f);
table.Add("mk:star", RANK_SIX, 20, 0.0f);
table.Add("mk:triple_mushroom",RANK_SIX, 25, 0.0f);
table.Add("mk:super_mushroom", RANK_SIX, 10, 0.0f);
table.Add("mk:triple_red_shell", RANK_SEVEN, 20, 0.0f);
table.Add("mk:blue_spiny_shell", RANK_SEVEN, 10, 0.0f);
table.Add("mk:thunderbolt", RANK_SEVEN, 20, 0.0f);
table.Add("mk:star", RANK_SEVEN, 30, 0.0f);
table.Add("mk:triple_mushroom",RANK_SEVEN, 10, 0.0f);
table.Add("mk:super_mushroom", RANK_SEVEN, 10, 0.0f);
table.Add("mk:triple_red_shell", RANK_EIGHT, 20, 0.0f);
table.Add("mk:blue_spiny_shell", RANK_EIGHT, 15, 0.0f);
table.Add("mk:thunderbolt", RANK_EIGHT, 20, 0.0f);
table.Add("mk:star", RANK_EIGHT, 30, 0.0f);
table.Add("mk:triple_mushroom",RANK_EIGHT, 5, 0.0f);
table.Add("mk:super_mushroom", RANK_EIGHT, 10, 0.0f);
r.Add("mk:human_grand_prix", std::move(table));
}
void RegisterCPUItemTable(DataRegistry<RandomItemTable>& r) {
RandomItemTable table;
table.Add("mk:banana", RANK_ONE, 60, 0.0f);
table.Add("mk:green_shell", RANK_ONE, 25, 0.0f);
table.Add("mk:fake_item_box", RANK_ONE, 10, 0.0f);
table.Add("mk:boo", RANK_ONE, 5, 0.0f);
table.Add("mk:banana", RANK_TWO, 50, 0.0f);
table.Add("mk:green_shell", RANK_TWO, 25, 0.0f);
table.Add("mk:triple_green_shell", RANK_TWO, 5, 0.0f);
table.Add("mk:fake_item_box", RANK_TWO, 10, 0.0f);
table.Add("mk:boo", RANK_TWO, 5, 0.0f);
table.Add("mk:mushroom", RANK_TWO, 5, 0.0f);
table.Add("mk:banana", RANK_THREE, 40, 0.0f);
table.Add("mk:green_shell", RANK_THREE, 25, 0.0f);
table.Add("mk:triple_green_shell", RANK_THREE, 10, 0.0f);
table.Add("mk:fake_item_box", RANK_THREE, 10, 0.0f);
table.Add("mk:boo", RANK_THREE, 5, 0.0f);
table.Add("mk:mushroom", RANK_THREE, 10, 0.0f);
table.Add("mk:banana", RANK_FOUR, 35, 0.0f);
table.Add("mk:green_shell", RANK_FOUR, 25, 0.0f);
table.Add("mk:triple_green_shell", RANK_FOUR, 15, 0.0f);
table.Add("mk:fake_item_box", RANK_FOUR, 10, 0.0f);
table.Add("mk:boo", RANK_FOUR, 5, 0.0f);
table.Add("mk:mushroom", RANK_FOUR, 10, 0.0f);
table.Add("mk:banana", RANK_FIVE, 30, 0.0f);
table.Add("mk:green_shell", RANK_FIVE, 20, 0.0f);
table.Add("mk:triple_green_shell", RANK_FIVE, 20, 0.0f);
table.Add("mk:fake_item_box", RANK_FIVE, 5, 0.0f);
table.Add("mk:star", RANK_FIVE, 5, 0.0f);
table.Add("mk:mushroom", RANK_FIVE, 20, 0.0f);
table.Add("mk:banana", RANK_SIX, 30, 0.0f);
table.Add("mk:green_shell", RANK_SIX, 20, 0.0f);
table.Add("mk:triple_green_shell", RANK_SIX, 20, 0.0f);
table.Add("mk:fake_item_box", RANK_SIX, 5, 0.0f);
table.Add("mk:star", RANK_SIX, 5, 0.0f);
table.Add("mk:mushroom", RANK_SIX, 20, 0.0f);
table.Add("mk:banana", RANK_SEVEN, 30, 0.0f);
table.Add("mk:green_shell", RANK_SEVEN, 20, 0.0f);
table.Add("mk:triple_green_shell", RANK_SEVEN, 20, 0.0f);
table.Add("mk:star", RANK_SEVEN, 10, 0.0f);
table.Add("mk:mushroom", RANK_SEVEN, 20, 0.0f);
table.Add("mk:banana", RANK_EIGHT, 25, 0.0f);
table.Add("mk:green_shell", RANK_EIGHT, 20, 0.0f);
table.Add("mk:triple_green_shell", RANK_EIGHT, 20, 0.0f);
table.Add("mk:thunderbolt", RANK_EIGHT, 1, 0.0f);
table.Add("mk:star", RANK_EIGHT, 10, 0.0f);
table.Add("mk:mushroom", RANK_EIGHT, 24, 0.0f);
r.Add("mk:cpu_grand_prix", std::move(table));
}
void RegisterHardCPUItemTable(DataRegistry<RandomItemTable>& r) {
RandomItemTable table;
table.Add("mk:none", RANK_ONE, 4, 0.0f);
table.Add("mk:banana", RANK_ONE, 30, 0.0f);
table.Add("mk:banana_bunch", RANK_ONE, 5, 0.0f);
table.Add("mk:green_shell", RANK_ONE, 30, 0.0f);
table.Add("mk:triple_green_shell", RANK_ONE, 5, 0.0f);
table.Add("mk:red_shell", RANK_ONE, 5, 0.0f);
table.Add("mk:fake_item_box", RANK_ONE, 10, 0.0f);
table.Add("mk:boo", RANK_ONE, 5, 0.0f);
table.Add("mk:mushroom", RANK_ONE, 10, 0.0f);
table.Add("mk:banana", RANK_TWO, 5, 0.0f);
table.Add("mk:banana_bunch", RANK_TWO, 5, 0.0f);
table.Add("mk:green_shell", RANK_TWO, 5, 0.0f);
table.Add("mk:triple_green_shell", RANK_TWO, 10, 0.0f);
table.Add("mk:red_shell", RANK_TWO, 15, 0.0f);
table.Add("mk:triple_red_shell", RANK_TWO, 20, 0.0f);
table.Add("mk:fake_item_box", RANK_TWO, 5, 0.0f);
table.Add("mk:star", RANK_TWO, 5, 0.0f);
table.Add("mk:boo", RANK_TWO, 5, 0.0f);
table.Add("mk:mushroom", RANK_TWO, 5, 0.0f);
table.Add("mk:triple_mushroom",RANK_TWO, 15, 0.0f);
table.Add("mk:super_mushroom", RANK_TWO, 5, 0.0f);
table.Add("mk:banana", RANK_THREE, 5, 0.0f);
table.Add("mk:banana_bunch", RANK_THREE, 3, 0.0f);
table.Add("mk:triple_green_shell", RANK_THREE, 10, 0.0f);
table.Add("mk:red_shell", RANK_THREE, 20, 0.0f);
table.Add("mk:triple_red_shell", RANK_THREE, 19, 0.0f);
table.Add("mk:star", RANK_THREE, 10, 0.0f);
table.Add("mk:mushroom", RANK_THREE, 5, 0.0f);
table.Add("mk:triple_mushroom",RANK_THREE, 19, 0.0f);
table.Add("mk:super_mushroom", RANK_THREE, 9, 0.0f);
table.Add("mk:banana", RANK_FOUR, 5, 0.0f);
table.Add("mk:green_shell", RANK_FOUR, 5, 0.0f);
table.Add("mk:triple_green_shell", RANK_FOUR, 5, 0.0f);
table.Add("mk:red_shell", RANK_FOUR, 15, 0.0f);
table.Add("mk:triple_red_shell", RANK_FOUR, 10, 0.0f);
table.Add("mk:fake_item_box", RANK_FOUR, 5, 0.0f);
table.Add("mk:star", RANK_FOUR, 15, 0.0f);
table.Add("mk:boo", RANK_FOUR, 5, 0.0f);
table.Add("mk:mushroom", RANK_FOUR, 5, 0.0f);
table.Add("mk:triple_mushroom",RANK_FOUR, 20, 0.0f);
table.Add("mk:super_mushroom", RANK_FOUR, 10, 0.0f);
table.Add("mk:red_shell", RANK_FIVE, 10, 0.0f);
table.Add("mk:triple_red_shell", RANK_FIVE, 20, 0.0f);
table.Add("mk:blue_spiny_shell", RANK_FIVE, 5, 0.0f);
table.Add("mk:fake_item_box", RANK_FIVE, 5, 0.0f);
table.Add("mk:star", RANK_FIVE, 15, 0.0f);
table.Add("mk:mushroom", RANK_FIVE, 10, 0.0f);
table.Add("mk:triple_mushroom",RANK_FIVE, 25, 0.0f);
table.Add("mk:super_mushroom", RANK_FIVE, 10, 0.0f);
table.Add("mk:red_shell", RANK_SIX, 5, 0.0f);
table.Add("mk:triple_red_shell", RANK_SIX, 25, 0.0f);
table.Add("mk:blue_spiny_shell", RANK_SIX, 10, 0.0f);
table.Add("mk:star", RANK_SIX, 20, 0.0f);
table.Add("mk:mushroom", RANK_SIX, 5, 0.0f);
table.Add("mk:triple_mushroom",RANK_SIX, 25, 0.0f);
table.Add("mk:super_mushroom", RANK_SIX, 10, 0.0f);
table.Add("mk:green_shell", RANK_SEVEN, 5, 0.0f);
table.Add("mk:red_shell", RANK_SEVEN, 5, 0.0f);
table.Add("mk:triple_red_shell", RANK_SEVEN, 25, 0.0f);
table.Add("mk:blue_spiny_shell", RANK_SEVEN, 10, 0.0f);
table.Add("mk:star", RANK_SEVEN, 30, 0.0f);
table.Add("mk:mushroom", RANK_SEVEN, 5, 0.0f);
table.Add("mk:triple_mushroom",RANK_SEVEN, 10, 0.0f);
table.Add("mk:super_mushroom", RANK_SEVEN, 10, 0.0f);
table.Add("mk:triple_green_shell", RANK_EIGHT, 5, 0.0f);
table.Add("mk:red_shell", RANK_EIGHT, 5, 0.0f);
table.Add("mk:triple_red_shell", RANK_EIGHT, 20, 0.0f);
table.Add("mk:blue_spiny_shell", RANK_EIGHT, 15, 0.0f);
table.Add("mk:thunderbolt", RANK_EIGHT, 10, 0.0f);
table.Add("mk:star", RANK_EIGHT, 30, 0.0f);
table.Add("mk:triple_mushroom",RANK_EIGHT, 5, 0.0f);
table.Add("mk:super_mushroom", RANK_EIGHT, 10, 0.0f);
r.Add("mk:hard_cpu_grand_prix", std::move(table));
}
void RegisterVersus2PItemTable(DataRegistry<RandomItemTable>& r) {
RandomItemTable table;
table.Add("mk:banana", RANK_ONE, 25, 0.0f);
table.Add("mk:banana_bunch", RANK_ONE, 10, 0.0f);
table.Add("mk:green_shell", RANK_ONE, 30, 0.0f);
table.Add("mk:triple_green_shell", RANK_ONE, 5, 0.0f);
table.Add("mk:red_shell", RANK_ONE, 5, 0.0f);
table.Add("mk:fake_item_box", RANK_ONE, 10, 0.0f);
table.Add("mk:boo", RANK_ONE, 5, 0.0f);
table.Add("mk:mushroom", RANK_ONE, 10, 0.0f);
table.Add("mk:banana_bunch", RANK_TWO, 5, 0.0f);
table.Add("mk:triple_green_shell", RANK_TWO, 5, 0.0f);
table.Add("mk:red_shell", RANK_TWO, 5, 0.0f);
table.Add("mk:triple_red_shell", RANK_TWO, 15, 0.0f);
table.Add("mk:blue_spiny_shell", RANK_TWO, 5, 0.0f);
table.Add("mk:thunderbolt", RANK_TWO, 15, 0.0f);
table.Add("mk:star", RANK_TWO, 15, 0.0f);
table.Add("mk:triple_mushroom",RANK_TWO, 15, 0.0f);
table.Add("mk:super_mushroom", RANK_TWO, 20, 0.0f);
r.Add("mk:versus_2p", std::move(table));
}
void RegisterVersus3PItemTable(DataRegistry<RandomItemTable>& r) {
RandomItemTable table;
table.Add("mk:banana", RANK_ONE, 35, 0.0f);
table.Add("mk:banana_bunch", RANK_ONE, 5, 0.0f);
table.Add("mk:green_shell", RANK_ONE, 30, 0.0f);
table.Add("mk:red_shell", RANK_ONE, 5, 0.0f);
table.Add("mk:fake_item_box", RANK_ONE, 10, 0.0f);
table.Add("mk:boo", RANK_ONE, 5, 0.0f);
table.Add("mk:mushroom", RANK_ONE, 10, 0.0f);
table.Add("mk:banana", RANK_TWO, 5, 0.0f);
table.Add("mk:banana_bunch", RANK_TWO, 5, 0.0f);
table.Add("mk:triple_green_shell", RANK_TWO, 10, 0.0f);
table.Add("mk:red_shell", RANK_TWO, 15, 0.0f);
table.Add("mk:triple_red_shell", RANK_TWO, 15, 0.0f);
table.Add("mk:thunderbolt", RANK_TWO, 5, 0.0f);
table.Add("mk:fake_item_box", RANK_TWO, 5, 0.0f);
table.Add("mk:star", RANK_TWO, 5, 0.0f);
table.Add("mk:boo", RANK_TWO, 5, 0.0f);
table.Add("mk:mushroom", RANK_TWO, 5, 0.0f);
table.Add("mk:triple_mushroom",RANK_TWO, 20, 0.0f);
table.Add("mk:super_mushroom", RANK_TWO, 5, 0.0f);
table.Add("mk:red_shell", RANK_THREE, 10, 0.0f);
table.Add("mk:triple_red_shell", RANK_THREE, 20, 0.0f);
table.Add("mk:blue_spiny_shell", RANK_THREE, 10, 0.0f);
table.Add("mk:thunderbolt", RANK_THREE, 15, 0.0f);
table.Add("mk:star", RANK_THREE, 15, 0.0f);
table.Add("mk:triple_mushroom",RANK_THREE, 20, 0.0f);
table.Add("mk:super_mushroom", RANK_THREE, 10, 0.0f);
r.Add("mk:versus_3p", std::move(table));
}
void RegisterVersus4PItemTable(DataRegistry<RandomItemTable>& r) {
RandomItemTable table;
table.Add("mk:banana", RANK_ONE, 35, 0.0f);
table.Add("mk:banana_bunch", RANK_ONE, 5, 0.0f);
table.Add("mk:green_shell", RANK_ONE, 30, 0.0f);
table.Add("mk:red_shell", RANK_ONE, 5, 0.0f);
table.Add("mk:fake_item_box", RANK_ONE, 10, 0.0f);
table.Add("mk:boo", RANK_ONE, 5, 0.0f);
table.Add("mk:mushroom", RANK_ONE, 10, 0.0f);
table.Add("mk:banana", RANK_TWO, 5, 0.0f);
table.Add("mk:banana_bunch", RANK_TWO, 5, 0.0f);
table.Add("mk:green_shell", RANK_TWO, 5, 0.0f);
table.Add("mk:triple_green_shell", RANK_TWO, 10, 0.0f);
table.Add("mk:red_shell", RANK_TWO, 15, 0.0f);
table.Add("mk:triple_red_shell", RANK_TWO, 15, 0.0f);
table.Add("mk:fake_item_box", RANK_TWO, 5, 0.0f);
table.Add("mk:star", RANK_TWO, 5, 0.0f);
table.Add("mk:boo", RANK_TWO, 5, 0.0f);
table.Add("mk:mushroom", RANK_TWO, 5, 0.0f);
table.Add("mk:triple_mushroom",RANK_TWO, 25, 0.0f);
table.Add("mk:banana_bunch", RANK_THREE, 5, 0.0f);
table.Add("mk:triple_green_shell", RANK_THREE, 5, 0.0f);
table.Add("mk:red_shell", RANK_THREE, 10, 0.0f);
table.Add("mk:triple_red_shell", RANK_THREE, 15, 0.0f);
table.Add("mk:blue_spiny_shell", RANK_THREE, 5, 0.0f);
table.Add("mk:thunderbolt", RANK_THREE, 10, 0.0f);
table.Add("mk:fake_item_box", RANK_THREE, 5, 0.0f);
table.Add("mk:star", RANK_THREE, 10, 0.0f);
table.Add("mk:mushroom", RANK_THREE, 5, 0.0f);
table.Add("mk:triple_mushroom",RANK_THREE, 25, 0.0f);
table.Add("mk:super_mushroom", RANK_THREE, 5, 0.0f);
table.Add("mk:triple_red_shell", RANK_FOUR, 20, 0.0f);
table.Add("mk:blue_spiny_shell", RANK_FOUR, 10, 0.0f);
table.Add("mk:thunderbolt", RANK_FOUR, 15, 0.0f);
table.Add("mk:star", RANK_FOUR, 20, 0.0f);
table.Add("mk:triple_mushroom",RANK_FOUR, 25, 0.0f);
table.Add("mk:super_mushroom", RANK_FOUR, 10, 0.0f);
r.Add("mk:versus_4p", std::move(table));
}
void RegisterBattleItemTable(DataRegistry<RandomItemTable>& r) {
RandomItemTable table;
table.Add("mk:banana", RANK_ONE, 10, 0.0f);
table.Add("mk:banana_bunch", RANK_ONE, 5, 0.0f);
table.Add("mk:green_shell", RANK_ONE, 5, 0.0f);
table.Add("mk:triple_green_shell", RANK_ONE, 20, 0.0f);
table.Add("mk:red_shell", RANK_ONE, 20, 0.0f);
table.Add("mk:fake_item_box", RANK_ONE, 15, 0.0f);
table.Add("mk:star", RANK_ONE, 20, 0.0f);
table.Add("mk:boo", RANK_ONE, 5, 0.0f);
r.Add("mk:battle", std::move(table));
}
+55
View File
@@ -0,0 +1,55 @@
#include "RegisterContent.h"
#include "Registry.h"
//! @todo turn items into a class
void RegisterItems(Registry<ItemInfo>& r) {
ItemInfo info;
info = { .ResourceName = "mk:none", .Name = "No Item" };
r.Add(info, {});
info = { .ResourceName = "mk:banana", .Name = "Banana" };
r.Add(info, {});
info = { .ResourceName = "mk:banana_bunch", .Name = "Banana Bunch" };
r.Add(info, {});
info = { .ResourceName = "mk:green_shell", .Name = "Green Shell" };
r.Add(info, {});
info = { .ResourceName = "mk:triple_green_shell", .Name = "Triple Green Shell" };
r.Add(info, {});
info = { .ResourceName = "mk:red_shell", .Name = "Red Shell" };
r.Add(info, {});
info = { .ResourceName = "mk:triple_red_shell", .Name = "Triple Red Shell" };
r.Add(info, {});
info = { .ResourceName = "mk:blue_spiny_shell", .Name = "Blue Spiny Shell" };
r.Add(info, {});
info = { .ResourceName = "mk:thunderbolt", .Name = "Thunderbolt" };
r.Add(info, {});
info = { .ResourceName = "mk:fake_item_box", .Name = "Fake Item Box" };
r.Add(info, {});
info = { .ResourceName = "mk:star", .Name = "Star" };
r.Add(info, {});
info = { .ResourceName = "mk:boo", .Name = "Boo" };
r.Add(info, {});
info = { .ResourceName = "mk:mushroom", .Name = "Mushroom" };
r.Add(info, {});
info = { .ResourceName = "mk:double_mushroom", .Name = "Double Mushroom" };
r.Add(info, {});
info = { .ResourceName = "mk:triple_mushroom", .Name = "Triple Mushroom" };
r.Add(info, {});
info = { .ResourceName = "mk:super_mushroom", .Name = "Super Mushroom" };
r.Add(info, {});
}
+224
View File
@@ -0,0 +1,224 @@
#include "engine/registry/RegisterContent.h"
#include <memory>
#include "port/Game.h"
#include "engine/AllTracks.h"
/**
* DO NOT RE-ORDER ANYTHING IN THESE FILES
*
* It will result in differing Ids
*/
void RegisterTracks(Registry<TrackInfo>& r) {
TrackInfo info;
info = {
.ResourceName = "mk:mario_raceway",
.Name = "mario raceway",
.DebugName = "m circuit",
.Length = "567m",
.MinimapTexture = minimap_mario_raceway,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<MarioRaceway>()); });
info = {
.ResourceName = "mk:choco_mountain",
.Name = "choco mountain",
.DebugName = "mountain",
.Length = "687m",
.MinimapTexture = minimap_choco_mountain,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<ChocoMountain>()); });
info = {
.ResourceName = "mk:bowsers_castle",
.Name = "bowser's castle",
.DebugName = "castle",
.Length = "777m",
.MinimapTexture = minimap_bowsers_castle,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<BowsersCastle>()); });
info = {
.ResourceName = "mk:banshee_boardwalk",
.Name = "banshee boardwalk",
.DebugName = "ghost",
.Length = "747m",
.MinimapTexture = minimap_banshee_boardwalk,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<BansheeBoardwalk>()); });
info = {
.ResourceName = "mk:yoshi_valley",
.Name = "yoshi valley",
.DebugName = "maze",
.Length = "772m",
.MinimapTexture = minimap_yoshi_valley,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<YoshiValley>()); });
info = {
.ResourceName = "mk:frappe_snowland",
.Name = "frappe snowland",
.DebugName = "snow",
.Length = "734m",
.MinimapTexture = minimap_frappe_snowland,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<FrappeSnowland>()); });
info = {
.ResourceName = "mk:koopa_beach",
.Name = "koopa troopa beach",
.DebugName = "beach",
.Length = "691m",
.MinimapTexture = minimap_koopa_troopa_beach,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<KoopaTroopaBeach>()); });
info = {
.ResourceName = "mk:royal_raceway",
.Name = "royal raceway",
.DebugName = "p circuit",
.Length = "1025m",
.MinimapTexture = minimap_royal_raceway,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<RoyalRaceway>()); });
info = {
.ResourceName = "mk:luigi_raceway",
.Name = "luigi raceway",
.DebugName = "l circuit",
.Length = "717m",
.MinimapTexture = minimap_luigi_raceway,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<LuigiRaceway>()); });
info = {
.ResourceName = "mk:moo_moo_farm",
.Name = "moo moo farm",
.DebugName = "farm",
.Length = "527m",
.MinimapTexture = minimap_moo_moo_farm,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<MooMooFarm>()); });
info = {
.ResourceName = "mk:toads_turnpike",
.Name = "toad's turnpike",
.DebugName = "highway",
.Length = "1036m",
.MinimapTexture = minimap_toads_turnpike,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<ToadsTurnpike>()); });
info = {
.ResourceName = "mk:kalimari_desert",
.Name = "kalimari desert",
.DebugName = "desert",
.Length = "753m",
.MinimapTexture = minimap_kalimari_desert,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<KalimariDesert>()); });
info = {
.ResourceName = "mk:sherbet_land",
.Name = "sherbet land",
.DebugName = "sherbet",
.Length = "756m",
.MinimapTexture = minimap_sherbet_land,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<SherbetLand>()); });
info = {
.ResourceName = "mk:rainbow_road",
.Name = "rainbow road",
.DebugName = "rainbow",
.Length = "2000m",
.MinimapTexture = minimap_rainbow_road,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<RainbowRoad>()); });
info = {
.ResourceName = "mk:wario_stadium",
.Name = "wario stadium",
.DebugName = "stadium",
.Length = "1591m",
.MinimapTexture = minimap_wario_stadium,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<WarioStadium>()); });
info = {
.ResourceName = "mk:block_fort",
.Name = "block fort",
.DebugName = "block",
.Length = "",
.MinimapTexture = minimap_block_fort,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<BlockFort>()); });
info = {
.ResourceName = "mk:skyscraper",
.Name = "skyscraper",
.DebugName = "skyscraper",
.Length = "",
.MinimapTexture = minimap_skyscraper,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<Skyscraper>()); });
info = {
.ResourceName = "mk:double_deck",
.Name = "double deck",
.DebugName = "deck",
.Length = "",
.MinimapTexture = minimap_double_deck,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<DoubleDeck>()); });
info = {
.ResourceName = "mk:dk_jungle",
.Name = "d.k.'s jungle parkway",
.DebugName = "jungle",
.Length = "893m",
.MinimapTexture = minimap_dks_jungle_parkway,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<DKJungle>()); });
info = {
.ResourceName = "mk:big_donut",
.Name = "big donut",
.DebugName = "doughnut",
.Length = "",
.MinimapTexture = minimap_big_donut,
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<BigDonut>()); });
info = {
.ResourceName = "hm:test_track",
.Name = "test track",
.DebugName = "test track",
.Length = "100m",
};
r.Add(info, []() { GetWorld()->SetCurrentTrack(std::make_unique<TestTrack>()); });
}
@@ -7,7 +7,7 @@
#include <set>
struct TrackInfo {
int32_t Id;
uint32_t Id;
std::string Path; // Path to the custom track
std::string ResourceName;
std::string Name;
@@ -18,12 +18,18 @@ struct TrackInfo {
};
struct ActorInfo {
int32_t Id;
uint32_t Id;
std::string ResourceName;
std::string Name;
std::set<std::string> Tags; // Category for filtering
};
struct ItemInfo {
uint32_t Id;
std::string ResourceName;
std::string Name;
};
/**
* TInfo must have a ResourceName member of type std::string
* This should be a unique string such as hm:cloud or hm:harbour
@@ -88,6 +94,10 @@ public:
return mMap.find(resourceName) != mMap.end();
}
size_t Size() {
return mMap.size();
}
std::vector<const TInfo*> GetAllInfo() const {
std::vector<const TInfo*> list;
list.reserve(mMap.size());
+1 -1
View File
@@ -8,7 +8,7 @@
#include "ChocoMountain.h"
#include "port/Game.h"
#include "engine/editor/SceneManager.h"
#include "Registry.h"
#include "engine/registry/Registry.h"
#include "libultraship/bridge/resourcebridge.h"
#include "align_asset_macro.h"
+1 -1
View File
@@ -3,7 +3,7 @@
#include <libultraship.h>
#include "Actor.h"
#include <vector>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/SpawnParams.h"
#include "engine/CoreMath.h"
#include "engine/World.h"
+1 -1
View File
@@ -3,7 +3,7 @@
#include <libultraship.h>
#include "Actor.h"
#include <vector>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/SpawnParams.h"
extern "C" {
+1 -1
View File
@@ -3,7 +3,7 @@
#include <libultraship.h>
#include "Actor.h"
#include <vector>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/SpawnParams.h"
extern "C" {
+1 -1
View File
@@ -3,7 +3,7 @@
#include <libultraship.h>
#include "Actor.h"
#include <vector>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/SpawnParams.h"
extern "C" {
+1 -1
View File
@@ -2,7 +2,7 @@
#include <libultraship.h>
#include <vector>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/SpawnParams.h"
#include "engine/CoreMath.h"
#include "engine/World.h"
+1 -1
View File
@@ -3,7 +3,7 @@
#include <libultraship.h>
#include "Actor.h"
#include <vector>
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/SpawnParams.h"
extern "C" {
+11 -1
View File
@@ -23,7 +23,7 @@
#include "engine/editor/Editor.h"
#include "engine/editor/SceneManager.h"
#include "RegisterContent.h"
#include "engine/registry/RegisterContent.h"
#include "engine/cameras/GameCamera.h"
#include "engine/cameras/FreeCamera.h"
@@ -31,6 +31,7 @@
#include "engine/cameras/LookBehindCamera.h"
#include "engine/TrackBrowser.h"
#include "engine/RandomItemTable.h"
#ifdef _WIN32
#include <locale.h>
@@ -73,8 +74,13 @@ TrackEditor::Editor gEditor;
s32 gTrophyIndex = NULL;
/** Spawner Registries **/
Registry<TrackInfo> gTrackRegistry;
Registry<ActorInfo, const SpawnParams&> gActorRegistry;
Registry<ItemInfo> gItemRegistry;
/** Data Registries **/
DataRegistry<RandomItemTable> gItemTableRegistry;
std::unique_ptr<TrackBrowser> gTrackBrowser;
@@ -138,7 +144,11 @@ void CustomEngineInit() {
SetMarioRaceway();
printf("[Game] Registering Game Content...\n");
RegisterActors(gActorRegistry);
RegisterItems(gItemRegistry);
RegisterItemTables(gItemTableRegistry);
printf("[Game] Game Content Registered!\n");
}
void CustomEngineDestroy() {
+4 -1
View File
@@ -7,7 +7,8 @@
#ifdef __cplusplus
#include "engine/editor/Editor.h"
#include "engine/Registry.h"
#include "engine/registry/Registry.h"
#include "engine/registry/DataRegistry.h"
class Track;
struct Properties;
class World;
@@ -30,6 +31,8 @@ extern HarbourMastersIntro gMenuIntro;
extern bool bCleanWorld;
extern Registry<TrackInfo> gTrackRegistry;
extern Registry<ActorInfo, const SpawnParams&> gActorRegistry;
extern Registry<ItemInfo> gItemRegistry;
extern DataRegistry<RandomItemTable> gItemTableRegistry;
World* GetWorld(void); // Retrieve the world instance
#endif
// NOLINTBEGIN(readability-identifier-naming)
+1 -1
View File
@@ -16,7 +16,7 @@
#include "engine/cameras/TourCamera.h"
#include "engine/TrackBrowser.h"
#include "engine/editor/SceneManager.h"
#include "engine/Registry.h"
#include "engine/registry/Registry.h"
extern "C" {
#include "code_800029B0.h"
+5 -711
View File
@@ -44,6 +44,8 @@
#include <assets/textures/tracks/sherbet_land/sherbet_land_data.h>
#include <assets/textures/tracks/rainbow_road/rainbow_road_data.h>
#include "engine/RaceManager.h"
float OTRGetAspectRatio(void);
//! @todo unused?
@@ -2609,719 +2611,11 @@ void consume_item(s32 playerId) {
}
}
typedef struct {
u8 none; // ITEM_NONE
u8 banana; // ITEM_BANANA
u8 bananaBunch; // ITEM_BANANA_BUNCH
u8 greenShell; // ITEM_GREEN_SHELL
u8 tripleGreenShell; // ITEM_TRIPLE_GREEN_SHELL
u8 redShell; // ITEM_RED_SHELL
u8 tripleRedShell; // ITEM_TRIPLE_RED_SHELL
u8 blueSpinyShell; // ITEM_BLUE_SPINY_SHELL
u8 thunderbolt; // ITEM_THUNDERBOLT
u8 fakeItemBox; // ITEM_FAKE_ITEM_BOX
u8 star; // ITEM_STAR
u8 boo; // ITEM_BOO
u8 mushroom; // ITEM_MUSHROOM
u8 doubleMushroom; // ITEM_DOUBLE_MUSHROOM
u8 tripleMushroom; // ITEM_TRIPLE_MUSHROOM
u8 superMushroom; // ITEM_SUPER_MUSHROOM
} ItemProbabilities;
// Each row corresponds to a rank, each column to an item
ItemProbabilities grandPrixHumanProbabilityTable[] = {
{ .none = 0,
.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 },
{ .none = 0,
.banana = 0,
.bananaBunch = 5,
.greenShell = 5,
.tripleGreenShell = 10,
.redShell = 15,
.tripleRedShell = 20,
.blueSpinyShell = 0,
.thunderbolt = 5,
.fakeItemBox = 5,
.star = 5,
.boo = 5,
.mushroom = 5,
.doubleMushroom = 0,
.tripleMushroom = 15,
.superMushroom = 5 },
{ .none = 0,
.banana = 0,
.bananaBunch = 0,
.greenShell = 0,
.tripleGreenShell = 10,
.redShell = 20,
.tripleRedShell = 20,
.blueSpinyShell = 0,
.thunderbolt = 5,
.fakeItemBox = 0,
.star = 10,
.boo = 0,
.mushroom = 5,
.doubleMushroom = 0,
.tripleMushroom = 20,
.superMushroom = 10 },
{ .none = 0,
.banana = 0,
.bananaBunch = 0,
.greenShell = 0,
.tripleGreenShell = 0,
.redShell = 15,
.tripleRedShell = 20,
.blueSpinyShell = 5,
.thunderbolt = 10,
.fakeItemBox = 0,
.star = 15,
.boo = 0,
.mushroom = 5,
.doubleMushroom = 0,
.tripleMushroom = 20,
.superMushroom = 10 },
{ .none = 0,
.banana = 0,
.bananaBunch = 0,
.greenShell = 0,
.tripleGreenShell = 0,
.redShell = 10,
.tripleRedShell = 20,
.blueSpinyShell = 5,
.thunderbolt = 10,
.fakeItemBox = 0,
.star = 15,
.boo = 0,
.mushroom = 5,
.doubleMushroom = 0,
.tripleMushroom = 25,
.superMushroom = 10 },
{ .none = 0,
.banana = 0,
.bananaBunch = 0,
.greenShell = 0,
.tripleGreenShell = 0,
.redShell = 0,
.tripleRedShell = 20,
.blueSpinyShell = 10,
.thunderbolt = 15,
.fakeItemBox = 0,
.star = 20,
.boo = 0,
.mushroom = 0,
.doubleMushroom = 0,
.tripleMushroom = 25,
.superMushroom = 10 },
{ .none = 0,
.banana = 0,
.bananaBunch = 0,
.greenShell = 0,
.tripleGreenShell = 0,
.redShell = 0,
.tripleRedShell = 20,
.blueSpinyShell = 10,
.thunderbolt = 20,
.fakeItemBox = 0,
.star = 30,
.boo = 0,
.mushroom = 0,
.doubleMushroom = 0,
.tripleMushroom = 10,
.superMushroom = 10 },
{ .none = 0,
.banana = 0,
.bananaBunch = 0,
.greenShell = 0,
.tripleGreenShell = 0,
.redShell = 0,
.tripleRedShell = 20,
.blueSpinyShell = 15,
.thunderbolt = 20,
.fakeItemBox = 0,
.star = 30,
.boo = 0,
.mushroom = 0,
.doubleMushroom = 0,
.tripleMushroom = 5,
.superMushroom = 10 },
};
ItemProbabilities grandPrixCPUProbabilityTable[] = {
{ .none = 0,
.banana = 60,
.bananaBunch = 0,
.greenShell = 25,
.tripleGreenShell = 0,
.redShell = 0,
.tripleRedShell = 0,
.blueSpinyShell = 0,
.thunderbolt = 0,
.fakeItemBox = 10,
.star = 0,
.boo = 5,
.mushroom = 0,
.doubleMushroom = 0,
.tripleMushroom = 0,
.superMushroom = 0 },
{ .none = 0,
.banana = 50,
.bananaBunch = 0,
.greenShell = 25,
.tripleGreenShell = 5,
.redShell = 0,
.tripleRedShell = 0,
.blueSpinyShell = 0,
.thunderbolt = 0,
.fakeItemBox = 10,
.star = 0,
.boo = 5,
.mushroom = 5,
.doubleMushroom = 0,
.tripleMushroom = 0,
.superMushroom = 0 },
{ .none = 0,
.banana = 40,
.bananaBunch = 0,
.greenShell = 25,
.tripleGreenShell = 10,
.redShell = 0,
.tripleRedShell = 0,
.blueSpinyShell = 0,
.thunderbolt = 0,
.fakeItemBox = 10,
.star = 0,
.boo = 5,
.mushroom = 10,
.doubleMushroom = 0,
.tripleMushroom = 0,
.superMushroom = 0 },
{ .none = 0,
.banana = 35,
.bananaBunch = 0,
.greenShell = 25,
.tripleGreenShell = 15,
.redShell = 0,
.tripleRedShell = 0,
.blueSpinyShell = 0,
.thunderbolt = 0,
.fakeItemBox = 10,
.star = 0,
.boo = 5,
.mushroom = 10,
.doubleMushroom = 0,
.tripleMushroom = 0,
.superMushroom = 0 },
{ .none = 0,
.banana = 30,
.bananaBunch = 0,
.greenShell = 20,
.tripleGreenShell = 20,
.redShell = 0,
.tripleRedShell = 0,
.blueSpinyShell = 0,
.thunderbolt = 0,
.fakeItemBox = 5,
.star = 5,
.boo = 0,
.mushroom = 20,
.doubleMushroom = 0,
.tripleMushroom = 0,
.superMushroom = 0 },
{ .none = 0,
.banana = 30,
.bananaBunch = 0,
.greenShell = 20,
.tripleGreenShell = 20,
.redShell = 0,
.tripleRedShell = 0,
.blueSpinyShell = 0,
.thunderbolt = 0,
.fakeItemBox = 5,
.star = 5,
.boo = 0,
.mushroom = 20,
.doubleMushroom = 0,
.tripleMushroom = 0,
.superMushroom = 0 },
{ .none = 0,
.banana = 30,
.bananaBunch = 0,
.greenShell = 20,
.tripleGreenShell = 20,
.redShell = 0,
.tripleRedShell = 0,
.blueSpinyShell = 0,
.thunderbolt = 0,
.fakeItemBox = 0,
.star = 10,
.boo = 0,
.mushroom = 20,
.doubleMushroom = 0,
.tripleMushroom = 0,
.superMushroom = 0 },
{ .none = 0,
.banana = 25,
.bananaBunch = 0,
.greenShell = 20,
.tripleGreenShell = 20,
.redShell = 0,
.tripleRedShell = 0,
.blueSpinyShell = 0,
.thunderbolt = 1,
.fakeItemBox = 0,
.star = 10,
.boo = 0,
.mushroom = 24,
.doubleMushroom = 0,
.tripleMushroom = 0,
.superMushroom = 0 },
};
ItemProbabilities grandPrixHardCPUProbabilityTable[] = {
{ .none = 5,
.banana = 25,
.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 },
{ .none = 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 },
{ .none = 0,
.banana = 5,
.bananaBunch = 3,
.greenShell = 0,
.tripleGreenShell = 10,
.redShell = 20,
.tripleRedShell = 19,
.blueSpinyShell = 0,
.thunderbolt = 0,
.fakeItemBox = 0,
.star = 10,
.boo = 0,
.mushroom = 5,
.doubleMushroom = 0,
.tripleMushroom = 19,
.superMushroom = 9 },
{ .none = 0,
.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 },
{ .none = 0,
.banana = 0,
.bananaBunch = 0,
.greenShell = 0,
.tripleGreenShell = 0,
.redShell = 10,
.tripleRedShell = 20,
.blueSpinyShell = 5,
.thunderbolt = 0,
.fakeItemBox = 5,
.star = 15,
.boo = 0,
.mushroom = 10,
.doubleMushroom = 0,
.tripleMushroom = 25,
.superMushroom = 10 },
{ .none = 0,
.banana = 0,
.bananaBunch = 0,
.greenShell = 0,
.tripleGreenShell = 0,
.redShell = 5,
.tripleRedShell = 25,
.blueSpinyShell = 10,
.thunderbolt = 0,
.fakeItemBox = 0,
.star = 20,
.boo = 0,
.mushroom = 5,
.doubleMushroom = 0,
.tripleMushroom = 25,
.superMushroom = 10 },
{ .none = 0,
.banana = 0,
.bananaBunch = 0,
.greenShell = 5,
.tripleGreenShell = 0,
.redShell = 5,
.tripleRedShell = 25,
.blueSpinyShell = 10,
.thunderbolt = 0,
.fakeItemBox = 0,
.star = 30,
.boo = 0,
.mushroom = 5,
.doubleMushroom = 0,
.tripleMushroom = 10,
.superMushroom = 10 },
{ .none = 0,
.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[] = {
{ .none = 0,
.banana = 25,
.bananaBunch = 10,
.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 },
{ .none = 0,
.banana = 0,
.bananaBunch = 5,
.greenShell = 0,
.tripleGreenShell = 5,
.redShell = 5,
.tripleRedShell = 15,
.blueSpinyShell = 5,
.thunderbolt = 15,
.fakeItemBox = 0,
.star = 15,
.boo = 0,
.mushroom = 0,
.doubleMushroom = 0,
.tripleMushroom = 15,
.superMushroom = 20 },
};
ItemProbabilities versus3PlayerProbabilityTable[] = {
{ .none = 0,
.banana = 35,
.bananaBunch = 5,
.greenShell = 30,
.tripleGreenShell = 0,
.redShell = 5,
.tripleRedShell = 0,
.blueSpinyShell = 0,
.thunderbolt = 0,
.fakeItemBox = 10,
.star = 0,
.boo = 5,
.mushroom = 10,
.doubleMushroom = 0,
.tripleMushroom = 0,
.superMushroom = 0 },
{ .none = 0,
.banana = 5,
.bananaBunch = 5,
.greenShell = 0,
.tripleGreenShell = 10,
.redShell = 15,
.tripleRedShell = 15,
.blueSpinyShell = 0,
.thunderbolt = 5,
.fakeItemBox = 5,
.star = 5,
.boo = 5,
.mushroom = 5,
.doubleMushroom = 0,
.tripleMushroom = 20,
.superMushroom = 5 },
{ .none = 0,
.banana = 0,
.bananaBunch = 0,
.greenShell = 0,
.tripleGreenShell = 0,
.redShell = 10,
.tripleRedShell = 20,
.blueSpinyShell = 10,
.thunderbolt = 15,
.fakeItemBox = 0,
.star = 15,
.boo = 0,
.mushroom = 0,
.doubleMushroom = 0,
.tripleMushroom = 20,
.superMushroom = 10 },
};
ItemProbabilities versus4PlayerProbabilityTable[] = {
{ .none = 0,
.banana = 35,
.bananaBunch = 5,
.greenShell = 30,
.tripleGreenShell = 0,
.redShell = 5,
.tripleRedShell = 0,
.blueSpinyShell = 0,
.thunderbolt = 0,
.fakeItemBox = 10,
.star = 0,
.boo = 5,
.mushroom = 10,
.doubleMushroom = 0,
.tripleMushroom = 0,
.superMushroom = 0 },
{ .none = 0,
.banana = 5,
.bananaBunch = 5,
.greenShell = 5,
.tripleGreenShell = 10,
.redShell = 15,
.tripleRedShell = 15,
.blueSpinyShell = 0,
.thunderbolt = 0,
.fakeItemBox = 5,
.star = 5,
.boo = 5,
.mushroom = 5,
.doubleMushroom = 0,
.tripleMushroom = 25,
.superMushroom = 0 },
{ .none = 0,
.banana = 0,
.bananaBunch = 5,
.greenShell = 0,
.tripleGreenShell = 5,
.redShell = 10,
.tripleRedShell = 15,
.blueSpinyShell = 5,
.thunderbolt = 10,
.fakeItemBox = 5,
.star = 10,
.boo = 0,
.mushroom = 5,
.doubleMushroom = 0,
.tripleMushroom = 25,
.superMushroom = 5 },
{ .none = 0,
.banana = 0,
.bananaBunch = 0,
.greenShell = 0,
.tripleGreenShell = 0,
.redShell = 0,
.tripleRedShell = 20,
.blueSpinyShell = 10,
.thunderbolt = 15,
.fakeItemBox = 0,
.star = 20,
.boo = 0,
.mushroom = 0,
.doubleMushroom = 0,
.tripleMushroom = 25,
.superMushroom = 10 },
};
ItemProbabilities battleProbabilityCurve[] = { { .none = 0,
.banana = 10,
.bananaBunch = 5,
.greenShell = 5,
.tripleGreenShell = 20,
.redShell = 20,
.tripleRedShell = 0,
.blueSpinyShell = 0,
.thunderbolt = 0,
.fakeItemBox = 15,
.star = 20,
.boo = 5,
.mushroom = 0,
.doubleMushroom = 0,
.tripleMushroom = 0,
.superMushroom = 0 } };
void getProbabilityArray(const ItemProbabilities* probStruct, u8* probArray) {
probArray[ITEM_NONE] = probStruct->none;
probArray[ITEM_BANANA] = probStruct->banana;
probArray[ITEM_BANANA_BUNCH] = probStruct->bananaBunch;
probArray[ITEM_GREEN_SHELL] = probStruct->greenShell;
probArray[ITEM_TRIPLE_GREEN_SHELL] = probStruct->tripleGreenShell;
probArray[ITEM_RED_SHELL] = probStruct->redShell;
probArray[ITEM_TRIPLE_RED_SHELL] = probStruct->tripleRedShell;
probArray[ITEM_BLUE_SPINY_SHELL] = probStruct->blueSpinyShell;
probArray[ITEM_THUNDERBOLT] = probStruct->thunderbolt;
probArray[ITEM_FAKE_ITEM_BOX] = probStruct->fakeItemBox;
probArray[ITEM_STAR] = probStruct->star;
probArray[ITEM_BOO] = probStruct->boo;
probArray[ITEM_MUSHROOM] = probStruct->mushroom;
probArray[ITEM_DOUBLE_MUSHROOM] = probStruct->doubleMushroom;
probArray[ITEM_TRIPLE_MUSHROOM] = probStruct->tripleMushroom;
probArray[ITEM_SUPER_MUSHROOM] = 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];
getProbabilityArray(probs, itemProbabilities);
size_t count = 0;
for (size_t i = 0; i < ITEM_MAX; 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
*/
u8 gen_random_item(s16 rank, s16 option) {
#define PERCENTAGE_BASE 100
u16 rand = random_int(PERCENTAGE_BASE);
#undef PERCENTAGE_BASE
ItemProbabilities* distributionTable;
u8 randomItem = 0;
u8 cumulativeProbability = 0;
switch (gModeSelection) {
case GRAND_PRIX:
switch (option) {
case HUMAN_TABLE:
distributionTable = &grandPrixHumanProbabilityTable[rank];
verify_probability_table("Human", distributionTable, rank);
break;
case CPU_TABLE:
distributionTable = &grandPrixCPUProbabilityTable[rank];
verify_probability_table("CPU", distributionTable, rank);
break;
case HARD_CPU_TABLE:
distributionTable = &grandPrixHardCPUProbabilityTable[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;
}
u8 itemProbabilities[ITEM_MAX];
getProbabilityArray(distributionTable, itemProbabilities);
for (size_t i = 0; i < ITEM_MAX; i++) {
cumulativeProbability += itemProbabilities[i];
if (rand < cumulativeProbability) {
randomItem = i;
break;
}
}
return randomItem;
}
u8 gen_random_item_human(UNUSED s16 arg0, s16 rank) {
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) {
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 playerId) {
UNUSED s32 pad[3];
s16 randomItem;
randomItem = gen_random_item_human(gLapCountByPlayerId[playerId], gGPCurrentRaceRankByPlayerId[playerId]);
randomItem = RaceManager_GetRandomHumanItem(gGPCurrentRaceRankByPlayerId[playerId]);
if (randomItem == ITEM_NONE) {
play_sound2(SOUND_MENU_FILE_NOT_FOUND);
@@ -3355,11 +2649,11 @@ s32 func_8007B040(s32 objectIndex, s32 playerId) {
if (gModeSelection == GRAND_PRIX) {
// Boo item
if (random_int(0x0064U) < 0x51) {
item = gen_random_item_human(gLapCountByPlayerId[playerId], gGPCurrentRaceRankByPlayerId[playerId]);
item = RaceManager_GetRandomHumanItem(gGPCurrentRaceRankByPlayerId[playerId]);
// ITEM_NONE is not a valid item for ghost, randomize again
size_t attempts = 0;
while (item == ITEM_NONE && attempts < 200) {
item = gen_random_item_human(gLapCountByPlayerId[playerId], gGPCurrentRaceRankByPlayerId[playerId]);
item = RaceManager_GetRandomHumanItem(gGPCurrentRaceRankByPlayerId[playerId]);
attempts++;
}
if (attempts >= 200) {
-4
View File
@@ -198,10 +198,6 @@ void update_object_lakitu(s32);
void func_8007AA44(s32);
void func_8007ABFC(s32, s32);
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);