diff --git a/module/Core.hpp b/module/Core.hpp index 8af99743..3fb1ea3e 100644 --- a/module/Core.hpp +++ b/module/Core.hpp @@ -993,27 +993,59 @@ template < class F > inline void ForeachActivePickup(F f) { ForeachActiveEntity( template < class F > inline void ForeachActivePlayer(F f) { ForeachActiveEntity(Core::Get().GetPlayers(), std::forward< F >(f)); } template < class F > inline void ForeachActiveVehicle(F f) { ForeachActiveEntity(Core::Get().GetVehicles(), std::forward< F >(f)); } +/* ------------------------------------------------------------------------------------------------ + * Process the identifier of each player slot. +*/ +template < class F > inline void ForeachPlayerSlot(F f) { + for (int32_t i = 0, n = static_cast< int32_t >(_Func->GetMaxPlayers()); i < n; ++i) { + f(i); + } +} +/* ------------------------------------------------------------------------------------------------ + * Process the identifier of each player slot and count processed players. +*/ +template < class F > SQMOD_NODISCARD inline int32_t ForeachPlayerSlotCount(F f) { + int32_t c = 0; + for (int32_t i = 0, n = static_cast< int32_t >(_Func->GetMaxPlayers()); i < n; ++i) { + if (f(i)) ++c; + } + return c; +} +/* ------------------------------------------------------------------------------------------------ + * Process the identifier of each player slot until a certain criteria is met. +*/ +template < class F > SQMOD_NODISCARD inline int32_t ForeachPlayerSlotUntil(F f) { + for (int32_t i = 0, n = static_cast< int32_t >(_Func->GetMaxPlayers()); i < n; ++i) { + if (f(i)) return i; + } + return -1; +} + /* ------------------------------------------------------------------------------------------------ * Process the identifier of each connected player. */ template < class F > inline void ForeachConnectedPlayer(F f) { - for (int32_t i = 0, n = _Func->GetMaxPlayers(); i < n; ++i) f(i); + for (int32_t i = 0, n = static_cast< int32_t >(_Func->GetMaxPlayers()); i < n; ++i) { + if (_Func->IsPlayerConnected(i) != 0) f(i); + } } /* ------------------------------------------------------------------------------------------------ * Process the identifier of each connected player and count processed players. */ template < class F > SQMOD_NODISCARD inline int32_t ForeachConnectedPlayerCount(F f) { int32_t c = 0; - for (int32_t i = 0, n = _Func->GetMaxPlayers(); i < n; ++i) - if (f(i)) ++c; + for (int32_t i = 0, n = static_cast< int32_t >(_Func->GetMaxPlayers()); i < n; ++i) { + if (_Func->IsPlayerConnected(i) != 0 && f(i)) ++c; + } return c; } /* ------------------------------------------------------------------------------------------------ * Process the identifier of each connected player until a certain criteria is met. */ template < class F > SQMOD_NODISCARD inline int32_t ForeachConnectedPlayerUntil(F f) { - for (int32_t i = 0, n = _Func->GetMaxPlayers(); i < n; ++i) - if (f(i)) return i; + for (int32_t i = 0, n = static_cast< int32_t >(_Func->GetMaxPlayers()); i < n; ++i) { + if (_Func->IsPlayerConnected(i) != 0 && f(i)) return i; + } return -1; } diff --git a/module/Misc/Official.cpp b/module/Misc/Official.cpp index 13b352f5..5eaa83e9 100644 --- a/module/Misc/Official.cpp +++ b/module/Misc/Official.cpp @@ -523,7 +523,7 @@ struct LgObject void RotateToEuler(const Vector3 & rotation, int time) const { Get().RotateToEuler(rotation, static_cast< uint32_t >(time)); } void RotateByEuler(const Vector3 & rotOffset, int time) const { Get().RotateByEuler(rotOffset, static_cast< uint32_t >(time)); } void SetAlpha(int alpha, int fadeTime) const { Get().SetAlphaEx(alpha, static_cast< uint32_t >(fadeTime)); } - SQMOD_NODISCARD bool StreamedToPlayer(LgPlayer & player) const; + SQMOD_NODISCARD bool StreamedToPlayer(LgPlayer & player) const; }; /* ------------------------------------------------------------------------------------------------ @@ -943,8 +943,8 @@ struct LgVehicle // ------------------------------------------------------------------------------------------------ inline bool LgCheckpoint::StreamedToPlayer(LgPlayer & player) const { return Get().IsStreamedFor(player.Get()); } -inline bool LgObject::StreamedToPlayer(LgPlayer & player) const { return Get().IsStreamedFor(player.Get()); } -inline bool LgPickup::StreamedToPlayer(LgPlayer & player) const { return Get().IsStreamedFor(player.Get()); } +inline bool LgObject::StreamedToPlayer(LgPlayer & player) const { return Get().IsStreamedFor(player.Get()); } +inline bool LgPickup::StreamedToPlayer(LgPlayer & player) const { return Get().IsStreamedFor(player.Get()); } inline void LgPlayer::SetVehicle(LgVehicle & vehicle) const { Get().Embark(vehicle.Get()); } inline void LgPlayer::SetVehicleSlot(const LgVehicle & vehicle, int slot) const { Get().EmbarkEx(vehicle.Get(), slot, true, false); } @@ -1545,7 +1545,7 @@ SQMOD_NODISCARD SQInteger LgGetObjectCount() { } return count; } -SQMOD_NODISCARD SQInteger LgGetPlayers() { return ForeachConnectedPlayerCount([](int32_t) { return true; }); } +SQMOD_NODISCARD SQInteger LgGetPlayers() { return ForeachPlayerSlotCount([](int32_t idx) -> bool { return _Func->IsPlayerConnected(idx) != 0; }); } // ------------------------------------------------------------------------------------------------ static void LgSetVehiclesForcedRespawnHeight(SQFloat height) { _Func->SetVehiclesForcedRespawnHeight(static_cast< float >(height)); } SQMOD_NODISCARD static SQFloat LgGetVehiclesForcedRespawnHeight() { return _Func->GetVehiclesForcedRespawnHeight(); } @@ -1569,7 +1569,7 @@ SQMOD_NODISCARD static SQInteger LgFindPlayer(HSQUIRRELVM vm) { char name_buf[SQMOD_NAMELENGTH]; const int32_t id = ForeachConnectedPlayerUntil([&](int32_t id) -> bool { _Func->GetPlayerName(id, name_buf, 64); - std::transform(name_buf, name_buf + strlen(name_buf), name_buf, [](unsigned char c){ return std::tolower(c); }); + std::transform(name_buf, name_buf + strlen(name_buf), name_buf, [](unsigned char c) { return std::tolower(c); }); return name.compare(name_buf) == 0; // NOLINT(readability-string-compare) }); if (VALID_ENTITYEX(id, SQMOD_PLAYER_POOL)) Var< LightObj >::push(vm, Core::Get().GetPlayer(id).mLgObj);