From 0da054634553b16745e56d9242c25280edf93823 Mon Sep 17 00:00:00 2001 From: ZealanL Date: Tue, 4 Jun 2024 15:51:17 -0700 Subject: [PATCH] (Experimental) Add custom boost pads support --- src/Sim/Arena/Arena.cpp | 54 +++++++++++++------ src/Sim/Arena/ArenaConfig/ArenaConfig.cpp | 24 +++++++++ src/Sim/Arena/ArenaConfig/ArenaConfig.h | 7 +++ src/Sim/BoostPad/BoostPad.cpp | 53 ++++++++++-------- src/Sim/BoostPad/BoostPad.h | 15 ++++-- .../BoostPad/BoostPadGrid/BoostPadGrid.cpp | 6 +-- 6 files changed, 115 insertions(+), 44 deletions(-) diff --git a/src/Sim/Arena/Arena.cpp b/src/Sim/Arena/Arena.cpp index adf5ce91..ca3a8db6 100644 --- a/src/Sim/Arena/Arena.cpp +++ b/src/Sim/Arena/Arena.cpp @@ -517,26 +517,38 @@ Arena::Arena(GameMode gameMode, const ArenaConfig& config, float tickRate) : _mu if (loadArenaStuff) { // Initialize boost pads using namespace RLConst::BoostPads; - bool isHoops = gameMode == GameMode::HOOPS; + if (_config.useCustomBoostPads) { + for (auto& padConfig : _config.customBoostPads) { + BoostPad* pad = BoostPad::_AllocBoostPad(); + pad->_Setup(padConfig); - int amountSmall = isHoops ? LOCS_AMOUNT_SMALL_HOOPS : LOCS_AMOUNT_SMALL_SOCCAR; - _boostPads.reserve(LOCS_AMOUNT_BIG + amountSmall); + _boostPads.push_back(pad); + } + } else { + bool isHoops = gameMode == GameMode::HOOPS; - for (int i = 0; i < (LOCS_AMOUNT_BIG + amountSmall); i++) { - bool isBig = i < LOCS_AMOUNT_BIG; + int amountSmall = isHoops ? LOCS_AMOUNT_SMALL_HOOPS : LOCS_AMOUNT_SMALL_SOCCAR; + _boostPads.reserve(LOCS_AMOUNT_BIG + amountSmall); - btVector3 pos; - if (isHoops) { - pos = isBig ? LOCS_BIG_HOOPS[i] : LOCS_SMALL_HOOPS[i - LOCS_AMOUNT_BIG]; - } else { - pos = isBig ? LOCS_BIG_SOCCAR[i] : LOCS_SMALL_SOCCAR[i - LOCS_AMOUNT_BIG]; - } + for (int i = 0; i < (LOCS_AMOUNT_BIG + amountSmall); i++) { + + BoostPadConfig padConfig; + + padConfig.isBig = i < LOCS_AMOUNT_BIG; + + btVector3 pos; + if (isHoops) { + padConfig.pos = padConfig.isBig ? LOCS_BIG_HOOPS[i] : LOCS_SMALL_HOOPS[i - LOCS_AMOUNT_BIG]; + } else { + padConfig.pos = padConfig.isBig ? LOCS_BIG_SOCCAR[i] : LOCS_SMALL_SOCCAR[i - LOCS_AMOUNT_BIG]; + } - BoostPad* pad = BoostPad::_AllocBoostPad(); - pad->_Setup(isBig, pos); + BoostPad* pad = BoostPad::_AllocBoostPad(); + pad->_Setup(padConfig); - _boostPads.push_back(pad); - _boostPadGrid.Add(pad); + _boostPads.push_back(pad); + _boostPadGrid.Add(pad); + } } } @@ -764,8 +776,16 @@ void Arena::Step(int ticksToSimulate) { for (Car* car : _cars) { car->_PostTickUpdate(gameMode, tickTime, _mutatorConfig); car->_FinishPhysicsTick(_mutatorConfig); - if (hasArenaStuff) - _boostPadGrid.CheckCollision(car); + if (hasArenaStuff) { + if (_config.useCustomBoostPads) { + // TODO: This is quite slow, we should use a sorting method of some sort + for (auto& boostPad : _boostPads) { + boostPad->_CheckCollide(car); + } + } else { + _boostPadGrid.CheckCollision(car); + } + } } if (hasArenaStuff && !ballOnly) diff --git a/src/Sim/Arena/ArenaConfig/ArenaConfig.cpp b/src/Sim/Arena/ArenaConfig/ArenaConfig.cpp index 688e48d7..0456fdc4 100644 --- a/src/Sim/Arena/ArenaConfig/ArenaConfig.cpp +++ b/src/Sim/Arena/ArenaConfig/ArenaConfig.cpp @@ -4,10 +4,34 @@ RS_NS_START void ArenaConfig::Serialize(DataStreamOut& out) const { out.WriteMultiple(ARENA_CONFIG_SERIALIZATION_FIELDS); + + out.Write(useCustomBoostPads); + if (useCustomBoostPads) { + out.Write(customBoostPads.size()); + for (auto& boostPad : customBoostPads) + boostPad.Serialize(out); + } } void ArenaConfig::Deserialize(DataStreamIn& in) { in.ReadMultiple(ARENA_CONFIG_SERIALIZATION_FIELDS); + + useCustomBoostPads = in.Read(); + if (useCustomBoostPads) { + uint32_t numPads = in.Read(); + + // NOTE: Not reserving/resizing customBoostPads from numPads just in case its a horrible corrupted value + + for (uint32_t i = 0; i < numPads; i++) { + BoostPadConfig config; + config.Deserialize(in); + + if (in.IsOverflown()) + RS_ERR_CLOSE("Overflow after reading custom boost (" << (i + 1) << " / " << numPads << ")"); + + customBoostPads.push_back(config); + } + } } RS_NS_END \ No newline at end of file diff --git a/src/Sim/Arena/ArenaConfig/ArenaConfig.h b/src/Sim/Arena/ArenaConfig/ArenaConfig.h index 240e2371..cafdce9d 100644 --- a/src/Sim/Arena/ArenaConfig/ArenaConfig.h +++ b/src/Sim/Arena/ArenaConfig/ArenaConfig.h @@ -3,6 +3,8 @@ #include "../../../DataStream/DataStreamOut.h" #include "../../../DataStream/DataStreamIn.h" +#include "../../BoostPad/BoostPad.h" + RS_NS_START // Mode of speed/memory optimization for the arena @@ -38,6 +40,11 @@ struct ArenaConfig { // Maximum number of objects int maxObjects = 512; + // Use a custom list of boost pads (customBoostPads) instead of the normal one + // NOTE: This will disable the boost pad grid and will thus worsen performance + bool useCustomBoostPads = false; + std::vector customBoostPads = {}; // Custom boost pads to use, if useCustomBoostPads + void Serialize(DataStreamOut& out) const; void Deserialize(DataStreamIn& in); }; diff --git a/src/Sim/BoostPad/BoostPad.cpp b/src/Sim/BoostPad/BoostPad.cpp index eeaa8ccd..d95ff4fd 100644 --- a/src/Sim/BoostPad/BoostPad.cpp +++ b/src/Sim/BoostPad/BoostPad.cpp @@ -6,20 +6,43 @@ RS_NS_START +void BoostPadConfig::Serialize(DataStreamOut& out) const { + out.WriteMultiple( + BOOSTPADCONFIG_SERIALIZATION_FIELDS + ); +} + +void BoostPadConfig::Deserialize(DataStreamIn& in) { + in.ReadMultiple( + BOOSTPADCONFIG_SERIALIZATION_FIELDS + ); +} + +void BoostPadState::Serialize(DataStreamOut& out) const { + out.WriteMultiple( + BOOSTPAD_SERIALIZATION_FIELDS + ); +} + +void BoostPadState::Deserialize(DataStreamIn& in) { + in.ReadMultiple( + BOOSTPAD_SERIALIZATION_FIELDS + ); +} + BoostPad* BoostPad::_AllocBoostPad() { return new BoostPad(); } -void BoostPad::_Setup(bool isBig, Vec pos) { - this->isBig = isBig; - this->pos = pos; +void BoostPad::_Setup(const BoostPadConfig& config) { + this->config = config; - this->_posBT = pos * UU_TO_BT; + this->_posBT = config.pos * UU_TO_BT; { using namespace RLConst::BoostPads; - float boxRad = (isBig ? BOX_RAD_BIG : BOX_RAD_SMALL) * UU_TO_BT; + float boxRad = (config.isBig ? BOX_RAD_BIG : BOX_RAD_SMALL) * UU_TO_BT; this->_boxMinBT = this->_posBT - Vec(boxRad, boxRad, 0); this->_boxMaxBT = this->_posBT + Vec(boxRad, boxRad, BOX_HEIGHT * UU_TO_BT); } @@ -53,7 +76,7 @@ void BoostPad::_CheckCollide(Car* car) { } else { // Check with cylinder-origin collision - float rad = (isBig ? CYL_RAD_BIG : CYL_RAD_SMALL) * UU_TO_BT; + float rad = (config.isBig ? CYL_RAD_BIG : CYL_RAD_SMALL) * UU_TO_BT; if (carPosBT.DistSq2D(this->_posBT) < (rad * rad)) colliding = abs(carPosBT.z - this->_posBT.z) < (CYL_HEIGHT * UU_TO_BT); } @@ -70,27 +93,15 @@ void BoostPad::_PostTickUpdate(float tickTime, const MutatorConfig& mutatorConfi lockedCarID = _internalState.curLockedCar->id; if (_internalState.isActive) { - float boostToAdd = isBig ? BOOST_AMOUNT_BIG : BOOST_AMOUNT_SMALL; + float boostToAdd = config.isBig ? BOOST_AMOUNT_BIG : BOOST_AMOUNT_SMALL; _internalState.curLockedCar->_internalState.boost = RS_MIN(_internalState.curLockedCar->_internalState.boost + boostToAdd, 100); _internalState.isActive = false; - _internalState.cooldown = isBig ? mutatorConfig.boostPadCooldown_Big : mutatorConfig.boostPadCooldown_Small; + _internalState.cooldown = config.isBig ? mutatorConfig.boostPadCooldown_Big : mutatorConfig.boostPadCooldown_Small; } } _internalState.prevLockedCarID = lockedCarID; } -void BoostPadState::Serialize(DataStreamOut& out) const { - out.WriteMultiple( - BOOSTPAD_SERIALIZATION_FIELDS - ); -} - -void BoostPadState::Deserialize(DataStreamIn& in) { - in.ReadMultiple( - BOOSTPAD_SERIALIZATION_FIELDS - ); -} - -RS_NS_END \ No newline at end of file +RS_NS_END diff --git a/src/Sim/BoostPad/BoostPad.h b/src/Sim/BoostPad/BoostPad.h index b583fe90..a843e2fe 100644 --- a/src/Sim/BoostPad/BoostPad.h +++ b/src/Sim/BoostPad/BoostPad.h @@ -10,6 +10,16 @@ RS_NS_START +struct BoostPadConfig { + Vec pos; + bool isBig = false; + + void Serialize(DataStreamOut& out) const; + void Deserialize(DataStreamIn& in); +}; +#define BOOSTPADCONFIG_SERIALIZATION_FIELDS \ +pos, isBig + struct BoostPadState { bool isActive = true; float cooldown = 0; @@ -25,8 +35,7 @@ isActive, cooldown, prevLockedCarID class BoostPad { public: - bool isBig; - Vec pos; + BoostPadConfig config; Vec _posBT; Vec _boxMinBT, _boxMaxBT; @@ -38,7 +47,7 @@ class BoostPad { // For construction by Arena static BoostPad* _AllocBoostPad(); - void _Setup(bool isBig, Vec pos); + void _Setup(const BoostPadConfig& config); void _CheckCollide(Car* car); diff --git a/src/Sim/BoostPad/BoostPadGrid/BoostPadGrid.cpp b/src/Sim/BoostPad/BoostPadGrid/BoostPadGrid.cpp index c27a4a15..2b13bad3 100644 --- a/src/Sim/BoostPad/BoostPadGrid/BoostPadGrid.cpp +++ b/src/Sim/BoostPad/BoostPadGrid/BoostPadGrid.cpp @@ -25,14 +25,14 @@ void BoostPadGrid::CheckCollision(Car* car) { } void BoostPadGrid::Add(BoostPad* pad) { - int indexX = pad->pos.x / CELL_SIZE_X + (CELLS_X / 2); - int indexY = pad->pos.y / CELL_SIZE_Y + (CELLS_Y / 2); + int indexX = pad->config.pos.x / CELL_SIZE_X + (CELLS_X / 2); + int indexY = pad->config.pos.y / CELL_SIZE_Y + (CELLS_Y / 2); BoostPad*& ptrInArray = pads[indexX][indexY]; if (ptrInArray != NULL) { RS_ERR_CLOSE( "BoostPadGrid::Add(): Failed to add a boost pad where there already was one " << - "(old: " << ptrInArray->pos << ", new: " << pad->pos << ") -> " << + "(old: " << ptrInArray->config.pos << ", new: " << pad->config.pos << ") -> " << "[" << indexX << ", " << indexY << "]" ); } else {