diff --git a/source/Base/Algo.cpp b/source/Base/Algo.cpp index 3143e070..c28a3560 100644 --- a/source/Base/Algo.cpp +++ b/source/Base/Algo.cpp @@ -2,7 +2,292 @@ #include "Base/Algo.hpp" // ------------------------------------------------------------------------------------------------ -namespace SqMod { +#include "Entity/Blip.hpp" +#include "Entity/Checkpoint.hpp" +#include "Entity/Keybind.hpp" +#include "Entity/Object.hpp" +#include "Entity/Pickup.hpp" +#include "Entity/Player.hpp" +#include "Entity/Vehicle.hpp" +// ------------------------------------------------------------------------------------------------ +namespace SqMod { +namespace Algo { + +// ================================================================================================ +void Register(HSQUIRRELVM vm) +{ + Table fns(vm); + + fns.Bind(_SC("Blip"), Table(vm) + .Func(_SC("WithID"), &Entity< CBlip >::FindByID) + .Func(_SC("IfTagEquals"), &Entity< CBlip >::FirstWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CBlip >::FirstWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CBlip >::FirstWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CBlip >::FirstWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CBlip >::FirstWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CBlip >::FirstWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CBlip >::FirstWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CBlip >::FirstWhereTagNotContains) + ); + + fns.Bind(_SC("Checkpoint"), Table(vm) + .Func(_SC("WithID"), &Entity< CCheckpoint >::FindByID) + .Func(_SC("IfTagEquals"), &Entity< CCheckpoint >::FirstWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CCheckpoint >::FirstWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CCheckpoint >::FirstWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CCheckpoint >::FirstWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CCheckpoint >::FirstWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CCheckpoint >::FirstWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CCheckpoint >::FirstWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CCheckpoint >::FirstWhereTagNotContains) + ); + + fns.Bind(_SC("Keybind"), Table(vm) + .Func(_SC("WithID"), &Entity< CKeybind >::FindByID) + .Func(_SC("IfTagEquals"), &Entity< CKeybind >::FirstWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CKeybind >::FirstWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CKeybind >::FirstWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CKeybind >::FirstWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CKeybind >::FirstWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CKeybind >::FirstWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CKeybind >::FirstWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CKeybind >::FirstWhereTagNotContains) + ); + + fns.Bind(_SC("Object"), Table(vm) + .Func(_SC("WithID"), &Entity< CObject >::FindByID) + .Func(_SC("IfTagEquals"), &Entity< CObject >::FirstWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CObject >::FirstWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CObject >::FirstWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CObject >::FirstWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CObject >::FirstWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CObject >::FirstWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CObject >::FirstWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CObject >::FirstWhereTagNotContains) + ); + + fns.Bind(_SC("Pickup"), Table(vm) + .Func(_SC("WithID"), &Entity< CPickup >::FindByID) + .Func(_SC("IfTagEquals"), &Entity< CPickup >::FirstWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CPickup >::FirstWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CPickup >::FirstWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CPickup >::FirstWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CPickup >::FirstWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CPickup >::FirstWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CPickup >::FirstWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CPickup >::FirstWhereTagNotContains) + ); + + fns.Bind(_SC("Player"), Table(vm) + .Func(_SC("WithID"), &Entity< CPlayer >::FindByID) + .Func(_SC("IfTagEquals"), &Entity< CPlayer >::FirstWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CPlayer >::FirstWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CPlayer >::FirstWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CPlayer >::FirstWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CPlayer >::FirstWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CPlayer >::FirstWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CPlayer >::FirstWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CPlayer >::FirstWhereTagNotContains) + ); + + fns.Bind(_SC("Vehicle"), Table(vm) + .Func(_SC("WithID"), &Entity< CVehicle >::FindByID) + .Func(_SC("IfTagEquals"), &Entity< CVehicle >::FirstWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CVehicle >::FirstWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CVehicle >::FirstWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CVehicle >::FirstWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CVehicle >::FirstWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CVehicle >::FirstWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CVehicle >::FirstWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CVehicle >::FirstWhereTagNotContains) + ); + + RootTable(vm).Bind(_SC("SqFind"), fns); + + Table cns(vm); + + cns.Bind(_SC("Blip"), Table(vm) + .Func(_SC("IfActive"), &Entity< CBlip >::AllActive) + .Func(_SC("IfTagEquals"), &Entity< CBlip >::AllWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CBlip >::AllWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CBlip >::AllWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CBlip >::AllWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CBlip >::AllWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CBlip >::AllWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CBlip >::AllWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CBlip >::AllWhereTagNotContains) + ); + + cns.Bind(_SC("Checkpoint"), Table(vm) + .Func(_SC("IfActive"), &Entity< CCheckpoint >::AllActive) + .Func(_SC("IfTagEquals"), &Entity< CCheckpoint >::AllWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CCheckpoint >::AllWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CCheckpoint >::AllWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CCheckpoint >::AllWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CCheckpoint >::AllWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CCheckpoint >::AllWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CCheckpoint >::AllWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CCheckpoint >::AllWhereTagNotContains) + ); + + cns.Bind(_SC("Keybind"), Table(vm) + .Func(_SC("IfActive"), &Entity< CKeybind >::AllActive) + .Func(_SC("IfTagEquals"), &Entity< CKeybind >::AllWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CKeybind >::AllWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CKeybind >::AllWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CKeybind >::AllWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CKeybind >::AllWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CKeybind >::AllWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CKeybind >::AllWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CKeybind >::AllWhereTagNotContains) + ); + + cns.Bind(_SC("Object"), Table(vm) + .Func(_SC("IfActive"), &Entity< CObject >::AllActive) + .Func(_SC("IfTagEquals"), &Entity< CObject >::AllWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CObject >::AllWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CObject >::AllWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CObject >::AllWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CObject >::AllWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CObject >::AllWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CObject >::AllWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CObject >::AllWhereTagNotContains) + ); + + cns.Bind(_SC("Pickup"), Table(vm) + .Func(_SC("IfActive"), &Entity< CPickup >::AllActive) + .Func(_SC("IfTagEquals"), &Entity< CPickup >::AllWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CPickup >::AllWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CPickup >::AllWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CPickup >::AllWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CPickup >::AllWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CPickup >::AllWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CPickup >::AllWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CPickup >::AllWhereTagNotContains) + ); + + cns.Bind(_SC("Player"), Table(vm) + .Func(_SC("IfActive"), &Entity< CPlayer >::AllActive) + .Func(_SC("IfTagEquals"), &Entity< CPlayer >::AllWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CPlayer >::AllWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CPlayer >::AllWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CPlayer >::AllWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CPlayer >::AllWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CPlayer >::AllWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CPlayer >::AllWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CPlayer >::AllWhereTagNotContains) + ); + + cns.Bind(_SC("Vehicle"), Table(vm) + .Func(_SC("IfActive"), &Entity< CVehicle >::AllActive) + .Func(_SC("IfTagEquals"), &Entity< CVehicle >::AllWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CVehicle >::AllWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CVehicle >::AllWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CVehicle >::AllWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CVehicle >::AllWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CVehicle >::AllWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CVehicle >::AllWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CVehicle >::AllWhereTagNotContains) + ); + + RootTable(vm).Bind(_SC("SqCollect"), cns); + + Table ens(vm); + + ens.Bind(_SC("Blip"), Table(vm) + .Func(_SC("IfActive"), &Entity< CBlip >::EachActive) + .Func(_SC("IfTagEquals"), &Entity< CBlip >::EachWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CBlip >::EachWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CBlip >::EachWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CBlip >::EachWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CBlip >::EachWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CBlip >::EachWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CBlip >::EachWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CBlip >::EachWhereTagNotContains) + ); + + ens.Bind(_SC("Checkpoint"), Table(vm) + .Func(_SC("IfActive"), &Entity< CCheckpoint >::EachActive) + .Func(_SC("IfTagEquals"), &Entity< CCheckpoint >::EachWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CCheckpoint >::EachWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CCheckpoint >::EachWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CCheckpoint >::EachWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CCheckpoint >::EachWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CCheckpoint >::EachWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CCheckpoint >::EachWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CCheckpoint >::EachWhereTagNotContains) + ); + + ens.Bind(_SC("Keybind"), Table(vm) + .Func(_SC("IfActive"), &Entity< CKeybind >::EachActive) + .Func(_SC("IfTagEquals"), &Entity< CKeybind >::EachWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CKeybind >::EachWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CKeybind >::EachWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CKeybind >::EachWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CKeybind >::EachWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CKeybind >::EachWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CKeybind >::EachWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CKeybind >::EachWhereTagNotContains) + ); + + ens.Bind(_SC("Object"), Table(vm) + .Func(_SC("IfActive"), &Entity< CObject >::EachActive) + .Func(_SC("IfTagEquals"), &Entity< CObject >::EachWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CObject >::EachWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CObject >::EachWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CObject >::EachWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CObject >::EachWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CObject >::EachWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CObject >::EachWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CObject >::EachWhereTagNotContains) + ); + + ens.Bind(_SC("Pickup"), Table(vm) + .Func(_SC("IfActive"), &Entity< CPickup >::EachActive) + .Func(_SC("IfTagEquals"), &Entity< CPickup >::EachWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CPickup >::EachWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CPickup >::EachWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CPickup >::EachWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CPickup >::EachWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CPickup >::EachWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CPickup >::EachWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CPickup >::EachWhereTagNotContains) + ); + + ens.Bind(_SC("Player"), Table(vm) + .Func(_SC("IfActive"), &Entity< CPlayer >::EachActive) + .Func(_SC("IfTagEquals"), &Entity< CPlayer >::EachWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CPlayer >::EachWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CPlayer >::EachWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CPlayer >::EachWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CPlayer >::EachWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CPlayer >::EachWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CPlayer >::EachWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CPlayer >::EachWhereTagNotContains) + ); + + ens.Bind(_SC("Vehicle"), Table(vm) + .Func(_SC("IfActive"), &Entity< CVehicle >::EachActive) + .Func(_SC("IfTagEquals"), &Entity< CVehicle >::EachWhereTagEquals) + .Func(_SC("IfTagNotEquals"), &Entity< CVehicle >::EachWhereTagNotEquals) + .Func(_SC("IfTagBegins"), &Entity< CVehicle >::EachWhereTagBegins) + .Func(_SC("IfTagNotBegins"), &Entity< CVehicle >::EachWhereTagNotBegins) + .Func(_SC("IfTagEnds"), &Entity< CVehicle >::EachWhereTagEnds) + .Func(_SC("IfTagNotEnds"), &Entity< CVehicle >::EachWhereTagNotEnds) + .Func(_SC("IfTagContains"), &Entity< CVehicle >::EachWhereTagContains) + .Func(_SC("IfTagNotContains"), &Entity< CVehicle >::EachWhereTagNotContains) + ); + + RootTable(vm).Bind(_SC("SqForeach"), ens); +} + +} // Namespace:: Algo + +// ================================================================================================ +void Register_Algo(HSQUIRRELVM vm) +{ + Algo::Register(vm); +} } // Namespace:: SqMod diff --git a/source/Base/Algo.hpp b/source/Base/Algo.hpp index 07e1ca04..e5f13105 100644 --- a/source/Base/Algo.hpp +++ b/source/Base/Algo.hpp @@ -2,7 +2,14 @@ #define _BASE_ALGO_HPP_ // ------------------------------------------------------------------------------------------------ -#include +#include "Core.hpp" + +// ------------------------------------------------------------------------------------------------ +#include +#include + +// ------------------------------------------------------------------------------------------------ +#define SQMOD_VALID_TAG_STR(t) if (!t) { STHROWF("The specified tag is invalid"); } // ------------------------------------------------------------------------------------------------ namespace SqMod { @@ -23,6 +30,1200 @@ void Collect(Iterator first, Iterator last, Inspector inspect, Collector collect } } +/* ------------------------------------------------------------------------------------------------ + * Collect all elements within the specified range where the tag matches the specified one. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Collector > +void CollectIfTagEquals(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Collector collect, + CSStr str) +{ + for (; first != last; ++first) + { + if (inspect(*first) && retrieve(*first).compare(str) == 0) + { + collect(*first); + } + } +} + +/* ------------------------------------------------------------------------------------------------ + * Collect all elements within the specified range where the tag does not match the specified one. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Collector > +void CollectIfTagNotEquals(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Collector collect, + CSStr str) +{ + for (; first != last; ++first) + { + if (inspect(*first) && retrieve(*first).compare(str) != 0) + { + collect(*first); + } + } +} + +/* ------------------------------------------------------------------------------------------------ + * Collect all elements within the specified range where the tag begins with the specified string. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Collector > +void CollectIfTagBegins(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Collector collect, + CSStr str, std::size_t len) +{ + for (; first != last; ++first) + { + if (!inspect(*first)) + { + continue; + } + // Retrieve the tag + const String & tag = retrieve(*first); + // Compare the tag + if (tag.size() > len && tag.compare(0, len, str) == 0) + { + collect(*first); + } + } +} + +/* ------------------------------------------------------------------------------------------------ + * Collect all elements within the specified range where the tag does not begin with the specified + * string. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Collector > +void CollectIfTagNotBegins(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Collector collect, + CSStr str, std::size_t len) +{ + for (; first != last; ++first) + { + if (!inspect(*first)) + { + continue; + } + // Retrieve the tag + const String & tag = retrieve(*first); + // Compare the tag + if (tag.size() > len && tag.compare(0, len, str) != 0) + { + collect(*first); + } + } +} + +/* ------------------------------------------------------------------------------------------------ + * Collect all elements within the specified range where the tag ends with the specified string. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Collector > +void CollectIfTagEnds(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Collector collect, + CSStr str, std::size_t len) +{ + for (; first != last; ++first) + { + if (!inspect(*first)) + { + continue; + } + // Retrieve the tag + const String & tag = retrieve(*first); + // Compare the tag + if (tag.size() > len && tag.compare(tag.size() - len, len, str) == 0) + { + collect(*first); + } + } +} + +/* ------------------------------------------------------------------------------------------------ + * Collect all elements within the specified range where the tag does not end with the specified + * string. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Collector > +void CollectIfTagNotEnds(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Collector collect, + CSStr str, std::size_t len) +{ + for (; first != last; ++first) + { + if (!inspect(*first)) + { + continue; + } + // Retrieve the tag + const String & tag = retrieve(*first); + // Compare the tag + if (tag.size() > len && tag.compare(tag.size() - len, len, str) != 0) + { + collect(*first); + } + } +} + +/* ------------------------------------------------------------------------------------------------ + * Collect all elements within the specified range where the tag contains the specified string. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Collector > +void CollectIfTagContains(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Collector collect, + CSStr str) +{ + for (; first != last; ++first) + { + if (inspect(*first) && retrieve(*first).find(str) != String::npos) + { + collect(*first); + } + } +} + +/* ------------------------------------------------------------------------------------------------ + * Collect all elements within the specified range where the tag does not contain the specified + * string. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Collector > +void CollectIfTagNotContains(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Collector collect, + CSStr str) +{ + for (; first != last; ++first) + { + if (inspect(*first) && retrieve(*first).find(str) == String::npos) + { + collect(*first); + } + } +} + +/* ------------------------------------------------------------------------------------------------ + * Find the first element within the specified range where the tag matches the specified one. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Receiver > +bool FindIfTagEquals(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Receiver receive, + CSStr str) +{ + for (; first != last; ++first) + { + if (inspect(*first) && retrieve(*first).compare(str) == 0) + { + receive(*first); + return true; + } + } + return false; +} + +/* ------------------------------------------------------------------------------------------------ + * Find the first element within the specified range where the tag does not match the specified one. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Receiver > +bool FindIfTagNotEquals(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Receiver receive, + CSStr str) +{ + for (; first != last; ++first) + { + if (inspect(*first) && retrieve(*first).compare(str) != 0) + { + receive(*first); + return true; + } + } + return false; +} + +/* ------------------------------------------------------------------------------------------------ + * Find the first element within the specified range where the tag begins with the specified string. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Receiver > +bool FindIfTagBegins(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Receiver receive, + CSStr str, std::size_t len) +{ + for (; first != last; ++first) + { + if (!inspect(*first)) + { + continue; + } + // Retrieve the tag + const String & tag = retrieve(*first); + // Compare the tag + if (tag.size() > len && tag.compare(0, len, str) == 0) + { + receive(*first); + return true; + } + } + return false; +} + +/* ------------------------------------------------------------------------------------------------ + * Find the first element within the specified range where the tag does not begin with the + * specified string. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Receiver > +bool FindIfTagNotBegins(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Receiver receive, + CSStr str, std::size_t len) +{ + for (; first != last; ++first) + { + if (!inspect(*first)) + { + continue; + } + // Retrieve the tag + const String & tag = retrieve(*first); + // Compare the tag + if (tag.size() > len && tag.compare(0, len, str) != 0) + { + receive(*first); + return true; + } + } + return false; +} + +/* ------------------------------------------------------------------------------------------------ + * Find the first element within the specified range where the tag ends with the specified string. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Receiver > +bool FindIfTagEnds(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Receiver receive, + CSStr str, std::size_t len) +{ + for (; first != last; ++first) + { + if (!inspect(*first)) + { + continue; + } + // Retrieve the tag + const String & tag = retrieve(*first); + // Compare the tag + if (tag.size() > len && tag.compare(tag.size() - len, len, str) == 0) + { + receive(*first); + return true; + } + } + return false; +} + +/* ------------------------------------------------------------------------------------------------ + * Find the first element within the specified range where the tag does not end with the specified + * string. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Receiver > +bool FindIfTagNotEnds(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Receiver receive, + CSStr str, std::size_t len) +{ + for (; first != last; ++first) + { + if (!inspect(*first)) + { + continue; + } + // Retrieve the tag + const String & tag = retrieve(*first); + // Compare the tag + if (tag.size() > len && tag.compare(tag.size() - len, len, str) != 0) + { + receive(*first); + return true; + } + } + return false; +} + +/* ------------------------------------------------------------------------------------------------ + * Find the first element within the specified range where the tag contains the specified string. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Receiver > +bool FindIfTagContains(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Receiver receive, + CSStr str) +{ + for (; first != last; ++first) + { + if (inspect(*first) && retrieve(*first).find(str) != String::npos) + { + receive(*first); + return true; + } + } + return false; +} + +/* ------------------------------------------------------------------------------------------------ + * Find the first element within the specified range where the tag does not contain the specified + * string. +*/ +template < typename Iterator, typename Inspector, typename Retriever, typename Receiver > +bool FindIfTagNotContains(Iterator first, Iterator last, + Inspector inspect, Retriever retrieve, Receiver receive, + CSStr str) +{ + for (; first != last; ++first) + { + if (inspect(*first) && retrieve(*first).find(str) == String::npos) + { + receive(*first); + return true; + } + } + return false; +} + +/* ------------------------------------------------------------------------------------------------ + * Used to work with entity instances in a template fashion. +*/ +template < typename T > struct InstSpec; + +/* ------------------------------------------------------------------------------------------------ + * Specialization for the Blip entity type. +*/ +template <> struct InstSpec< CBlip > +{ + // -------------------------------------------------------------------------------------------- + typedef Core::Blips Instances; // Container to store instances of this entity type. + typedef Core::Blips::value_type Instance; // Type that manages this type of entity instance. + + // -------------------------------------------------------------------------------------------- + static constexpr int Max = SQMOD_BLIP_POOL; // Maximum identifier for this entity type. + + // -------------------------------------------------------------------------------------------- + static constexpr CSStr LcName = "blip"; // Lowercase name of this entity type. + static constexpr CSStr UcName = "Blip"; // Uppercase name of this entity type. + + /* -------------------------------------------------------------------------------------------- + * Iterator to the beginning of the instance container. + */ + static inline Instances::const_iterator CBegin() + { + return Core::Get().GetBlips().cbegin(); + } + + /* -------------------------------------------------------------------------------------------- + * Iterator to the ending of the instance container. + */ + static inline Instances::const_iterator CEnd() + { + return Core::Get().GetBlips().cend(); + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Specialization for the Checkpoint entity type. +*/ +template <> struct InstSpec< CCheckpoint > +{ + // -------------------------------------------------------------------------------------------- + typedef Core::Checkpoints Instances; // Container to store instances of this entity type. + typedef Core::Checkpoints::value_type Instance; // Type that manages this type of entity instance. + + // -------------------------------------------------------------------------------------------- + static constexpr int Max = SQMOD_CHECKPOINT_POOL; // Maximum identifier for this entity type. + + // -------------------------------------------------------------------------------------------- + static constexpr CSStr LcName = "checkpoint"; // Lowercase name of this entity type. + static constexpr CSStr UcName = "Checkpoint"; // Uppercase name of this entity type. + + /* -------------------------------------------------------------------------------------------- + * Iterator to the beginning of the instance container. + */ + static inline Instances::const_iterator CBegin() + { + return Core::Get().GetCheckpoints().cbegin(); + } + + /* -------------------------------------------------------------------------------------------- + * Iterator to the ending of the instance container. + */ + static inline Instances::const_iterator CEnd() + { + return Core::Get().GetCheckpoints().cend(); + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Specialization for the Keybind entity type. +*/ +template <> struct InstSpec< CKeybind > +{ + // -------------------------------------------------------------------------------------------- + typedef Core::Keybinds Instances; // Container to store instances of this entity type. + typedef Core::Keybinds::value_type Instance; // Type that manages this type of entity instance. + + // -------------------------------------------------------------------------------------------- + static constexpr int Max = SQMOD_KEYBIND_POOL; // Maximum identifier for this entity type. + + // -------------------------------------------------------------------------------------------- + static constexpr CSStr LcName = "keybind"; // Lowercase name of this entity type. + static constexpr CSStr UcName = "Keybind"; // Uppercase name of this entity type. + + /* -------------------------------------------------------------------------------------------- + * Iterator to the beginning of the instance container. + */ + static inline Instances::const_iterator CBegin() + { + return Core::Get().GetKeybinds().cbegin(); + } + + /* -------------------------------------------------------------------------------------------- + * Iterator to the ending of the instance container. + */ + static inline Instances::const_iterator CEnd() + { + return Core::Get().GetKeybinds().cend(); + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Specialization for the Object entity type. +*/ +template <> struct InstSpec< CObject > +{ + // -------------------------------------------------------------------------------------------- + typedef Core::Objects Instances; // Container to store instances of this entity type. + typedef Core::Objects::value_type Instance; // Type that manages this type of entity instance. + + // -------------------------------------------------------------------------------------------- + static constexpr int Max = SQMOD_OBJECT_POOL; // Maximum identifier for this entity type. + + // -------------------------------------------------------------------------------------------- + static constexpr CSStr LcName = "object"; // Lowercase name of this entity type. + static constexpr CSStr UcName = "Object"; // Uppercase name of this entity type. + + /* -------------------------------------------------------------------------------------------- + * Iterator to the beginning of the instance container. + */ + static inline Instances::const_iterator CBegin() + { + return Core::Get().GetObjects().cbegin(); + } + + /* -------------------------------------------------------------------------------------------- + * Iterator to the ending of the instance container. + */ + static inline Instances::const_iterator CEnd() + { + return Core::Get().GetObjects().cend(); + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Specialization for the Pickup entity type. +*/ +template <> struct InstSpec< CPickup > +{ + // -------------------------------------------------------------------------------------------- + typedef Core::Pickups Instances; // Container to store instances of this entity type. + typedef Core::Pickups::value_type Instance; // Type that manages this type of entity instance. + + // -------------------------------------------------------------------------------------------- + static constexpr int Max = SQMOD_PICKUP_POOL; // Maximum identifier for this entity type. + + // -------------------------------------------------------------------------------------------- + static constexpr CSStr LcName = "pickup"; // Lowercase name of this entity type. + static constexpr CSStr UcName = "Pickup"; // Uppercase name of this entity type. + + /* -------------------------------------------------------------------------------------------- + * Iterator to the beginning of the instance container. + */ + static inline Instances::const_iterator CBegin() + { + return Core::Get().GetPickups().cbegin(); + } + + /* -------------------------------------------------------------------------------------------- + * Iterator to the ending of the instance container. + */ + static inline Instances::const_iterator CEnd() + { + return Core::Get().GetPickups().cend(); + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Specialization for the Player entity type. +*/ +template <> struct InstSpec< CPlayer > +{ + // -------------------------------------------------------------------------------------------- + typedef Core::Players Instances; // Container to store instances of this entity type. + typedef Core::Players::value_type Instance; // Type that manages this type of entity instance. + + // -------------------------------------------------------------------------------------------- + static constexpr int Max = SQMOD_PLAYER_POOL; // Maximum identifier for this entity type. + + // -------------------------------------------------------------------------------------------- + static constexpr CSStr LcName = "player"; // Lowercase name of this entity type. + static constexpr CSStr UcName = "Player"; // Uppercase name of this entity type. + + /* -------------------------------------------------------------------------------------------- + * Iterator to the beginning of the instance container. + */ + static inline Instances::const_iterator CBegin() + { + return Core::Get().GetPlayers().cbegin(); + } + + /* -------------------------------------------------------------------------------------------- + * Iterator to the ending of the instance container. + */ + static inline Instances::const_iterator CEnd() + { + return Core::Get().GetPlayers().cend(); + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Specialization for the Vehicle entity type. +*/ +template <> struct InstSpec< CVehicle > +{ + // -------------------------------------------------------------------------------------------- + typedef Core::Vehicles Instances; // Container to store instances of this entity type. + typedef Core::Vehicles::value_type Instance; // Type that manages this type of entity instance. + + // -------------------------------------------------------------------------------------------- + static constexpr int Max = SQMOD_VEHICLE_POOL; // Maximum identifier for this entity type. + + // -------------------------------------------------------------------------------------------- + static constexpr CSStr LcName = "vehicle"; // Lowercase name of this entity type. + static constexpr CSStr UcName = "Vehicle"; // Uppercase name of this entity type. + + /* -------------------------------------------------------------------------------------------- + * Iterator to the beginning of the instance container. + */ + static inline Instances::const_iterator CBegin() + { + return Core::Get().GetVehicles().cbegin(); + } + + /* -------------------------------------------------------------------------------------------- + * Iterator to the ending of the instance container. + */ + static inline Instances::const_iterator CEnd() + { + return Core::Get().GetVehicles().cend(); + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Functor to check if an instance is valid. +*/ +template < typename T > struct ValidInstFunc +{ + /* -------------------------------------------------------------------------------------------- + * Function call operator. + */ + bool operator () (const typename InstSpec< T >::Instance & inst) const + { + return VALID_ENTITY(inst.mID); + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Functor to retrieve the entity tag. +*/ +template < typename T > struct InstTagFunc +{ + /* -------------------------------------------------------------------------------------------- + * Function call operator. + */ + const String & operator () (const typename InstSpec< T >::Instance & inst) const + { + return inst.mInst->GetTag(); + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Functor to append the entity instance object at the back of an array. +*/ +template < typename T > struct AppendElemFunc +{ + // -------------------------------------------------------------------------------------------- + const SQInteger mIdx; // Array index after pushing one object on the stack. + HSQUIRRELVM mVM; // The VM to use when pushing the object. + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + AppendElemFunc(SQInteger idx = -2, HSQUIRRELVM vm = DefaultVM::Get()) + : mIdx(idx), mVM(vm) + { + /* ... */ + } + + /* -------------------------------------------------------------------------------------------- + * Function call operator. + */ + void operator () (const typename InstSpec< T >::Instance & inst) const + { + // Push the script object on the stack + sq_pushobject(mVM, inst.mObj.GetObject()); + // Append the object at the back of the array + if (SQ_FAILED(sq_arrayappend(mVM, mIdx))) + { + STHROWF("Unable to append %s instance to the list", InstSpec< T >::LcName); + } + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Functor to retrieve the entity tag. +*/ +template < typename T > struct RecvElemFunc +{ + // -------------------------------------------------------------------------------------------- + Object mObj; // Reference to the received object. + + /* -------------------------------------------------------------------------------------------- + * Default constructor. + */ + RecvElemFunc() + : mObj() + { + /* ... */ + } + + /* -------------------------------------------------------------------------------------------- + * Function call operator. + */ + void operator () (const typename InstSpec< T >::Instance & inst) + { + mObj = inst.mObj; + } + + /* -------------------------------------------------------------------------------------------- + * Implicit cast to the managed object. + */ + operator Object () + { + return mObj; + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Functor to forward the the received element to a callback. +*/ +template < typename T > struct ForwardElemFunc +{ +public: + + // -------------------------------------------------------------------------------------------- + Function mFunc; // The script callback to forward the element. + Uint32 mCount; // The number of elements forwarded by this functor. + + /* -------------------------------------------------------------------------------------------- + * Base constructor. + */ + ForwardElemFunc(Object & env, Function & func) + : mFunc(env.GetVM(), env, func.GetFunc()), mCount(0) + { + if (mFunc.IsNull()) + { + STHROWF("Invalid script callback"); + } + } + + /* -------------------------------------------------------------------------------------------- + * Function call operator. + */ + void operator () (const typename InstSpec< T >::Instance & inst) + { + mFunc.Execute(inst.mObj); + ++mCount; // Only successful forwards are counted! + } +}; + +/* ------------------------------------------------------------------------------------------------ + * Shared utilities for entities in order to avoid duplicate code. +*/ +template < typename T > struct Entity +{ +public: + + // -------------------------------------------------------------------------------------------- + typedef T Type; // The type of entity that we're working with. + typedef InstSpec< T > Inst; // The type of entity instance to work with. + + // -------------------------------------------------------------------------------------------- + typedef ValidInstFunc< T > ValidInst; + typedef InstTagFunc< T > InstTag; + typedef AppendElemFunc< T > AppendElem; + typedef RecvElemFunc< T > RecvElem; + typedef ForwardElemFunc< T > ForwardElem; + +public: + + /* -------------------------------------------------------------------------------------------- + * Default constructor. + */ + Entity() = delete; + + /* -------------------------------------------------------------------------------------------- + * Copy constructor. + */ + Entity(const Entity & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move constructor. + */ + Entity(Entity && o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Destructor. + */ + ~Entity() = delete; + + /* -------------------------------------------------------------------------------------------- + * Copy assignment operator. + */ + Entity & operator = (const Entity & o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Move assignment operator. + */ + Entity & operator = (Entity && o) = delete; + + /* -------------------------------------------------------------------------------------------- + * Find the entity that matches the specified identifier. + */ + static inline const Object & FindByID(Int32 id) + { + // Perform a range check on the specified identifier + if (INVALID_ENTITYEX(id, Inst::Max)) + { + STHROWF("The specified %s identifier is invalid: %d", Inst::LcName, id); + } + // Obtain the ends of the entity pool + typename Inst::Instances::const_iterator itr = Inst::CBegin(); + typename Inst::Instances::const_iterator end = Inst::CEnd(); + // Process each entity in the pool + for (; itr != end; ++itr) + { + // Does the identifier match the specified one? + if (itr->mID == id) + { + return itr->mObj; // Stop searching and return this entity + } + } + // Unable to locate a player matching the specified identifier + return NullObject(); + } + + /* -------------------------------------------------------------------------------------------- + * Find all active entities of this type. + */ + static inline Array AllActive() + { + const StackGuard sg; + // Allocate an empty array on the stack + sq_newarray(DefaultVM::Get(), 0); + // Process each entity in the pool + Collect(Inst::CBegin(), Inst::CEnd(), ValidInst(), AppendElem()); + // Return the array at the top of the stack + return Var< Array >(DefaultVM::Get(), -1).value; + } + + /* -------------------------------------------------------------------------------------------- + * Collect all entities of this type where the tag matches the specified one. + */ + static inline Array AllWhereTagEquals(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Remember the current stack size + const StackGuard sg; + // Allocate an empty array on the stack + sq_newarray(DefaultVM::Get(), 0); + // Process each entity in the pool + CollectIfTagEquals(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), AppendElem(), tag); + // Return the array at the top of the stack + return Var< Array >(DefaultVM::Get(), -1).value; + } + + /* -------------------------------------------------------------------------------------------- + * Collect all entities of this type where the tag does not match the specified one. + */ + static inline Array AllWhereTagNotEquals(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Remember the current stack size + const StackGuard sg; + // Allocate an empty array on the stack + sq_newarray(DefaultVM::Get(), 0); + // Process each entity in the pool + CollectIfTagNotEquals(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), AppendElem(), tag); + // Return the array at the top of the stack + return Var< Array >(DefaultVM::Get(), -1).value; + } + + /* -------------------------------------------------------------------------------------------- + * Collect all entities of this type where the tag begins with the specified string. + */ + static inline Array AllWhereTagBegins(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Remember the current stack size + const StackGuard sg; + // Allocate an empty array on the stack + sq_newarray(DefaultVM::Get(), 0); + // Process each entity in the pool + CollectIfTagBegins(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), AppendElem(), tag, std::strlen(tag)); + // Return the array at the top of the stack + return Var< Array >(DefaultVM::Get(), -1).value; + } + + /* -------------------------------------------------------------------------------------------- + * Collect all entities of this type where the does not begin with the specified string. + */ + static inline Array AllWhereTagNotBegins(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Remember the current stack size + const StackGuard sg; + // Allocate an empty array on the stack + sq_newarray(DefaultVM::Get(), 0); + // Process each entity in the pool + CollectIfTagNotBegins(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), AppendElem(), tag, std::strlen(tag)); + // Return the array at the top of the stack + return Var< Array >(DefaultVM::Get(), -1).value; + } + + /* -------------------------------------------------------------------------------------------- + * Collect all entities of this type where the tag ends with the specified string. + */ + static inline Array AllWhereTagEnds(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Remember the current stack size + const StackGuard sg; + // Allocate an empty array on the stack + sq_newarray(DefaultVM::Get(), 0); + // Process each entity in the pool + CollectIfTagEnds(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), AppendElem(), tag, std::strlen(tag)); + // Return the array at the top of the stack + return Var< Array >(DefaultVM::Get(), -1).value; + } + + /* -------------------------------------------------------------------------------------------- + * Collect all entities of this type where the tag does not end with the specified string. + */ + static inline Array AllWhereTagNotEnds(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Remember the current stack size + const StackGuard sg; + // Allocate an empty array on the stack + sq_newarray(DefaultVM::Get(), 0); + // Process each entity in the pool + CollectIfTagNotEnds(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), AppendElem(), tag, std::strlen(tag)); + // Return the array at the top of the stack + return Var< Array >(DefaultVM::Get(), -1).value; + } + + /* -------------------------------------------------------------------------------------------- + * Collect all entities of this type where the tag contains the specified string. + */ + static inline Array AllWhereTagContains(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Remember the current stack size + const StackGuard sg; + // Allocate an empty array on the stack + sq_newarray(DefaultVM::Get(), 0); + // Process each entity in the pool + CollectIfTagContains(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), AppendElem(), tag); + // Return the array at the top of the stack + return Var< Array >(DefaultVM::Get(), -1).value; + } + + /* -------------------------------------------------------------------------------------------- + * Collect all entities of this type where the tag does not contain the specified string. + */ + static inline Array AllWhereTagNotContains(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Remember the current stack size + const StackGuard sg; + // Allocate an empty array on the stack + sq_newarray(DefaultVM::Get(), 0); + // Process each entity in the pool + CollectIfTagNotContains(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), AppendElem(), tag); + // Return the array at the top of the stack + return Var< Array >(DefaultVM::Get(), -1).value; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the first entity of this type where the tag matches the specified one. + */ + static inline Object FirstWhereTagEquals(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element receiver + RecvElem recv; + // Process each entity in the pool + FindIfTagEquals(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), recv, tag); + // Return the received element, if any + return recv; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the first entity of this type where the tag does not match the specified one. + */ + static inline Object FirstWhereTagNotEquals(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element receiver + RecvElem recv; + // Process each entity in the pool + FindIfTagNotEquals(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), recv, tag); + // Return the received element, if any + return recv; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the first entity of this type where the tag begins with the specified string. + */ + static inline Object FirstWhereTagBegins(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element receiver + RecvElem recv; + // Process each entity in the pool + CollectIfTagBegins(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), recv, tag, std::strlen(tag)); + // Return the received element, if any + return recv; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the first entity of this type where the does not begin with the specified string. + */ + static inline Object FirstWhereTagNotBegins(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element receiver + RecvElem recv; + // Process each entity in the pool + FindIfTagNotBegins(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), recv, tag, std::strlen(tag)); + // Return the received element, if any + return recv; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the first entity of this type where the tag ends with the specified string. + */ + static inline Object FirstWhereTagEnds(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element receiver + RecvElem recv; + // Process each entity in the pool + FindIfTagEnds(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), recv, tag, std::strlen(tag)); + // Return the received element, if any + return recv; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the first entity of this type where the tag does not end with the specified string. + */ + static inline Object FirstWhereTagNotEnds(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element receiver + RecvElem recv; + // Process each entity in the pool + FindIfTagNotEnds(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), recv, tag, std::strlen(tag)); + // Return the received element, if any + return recv; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the first entity of this type where the tag contains the specified string. + */ + static inline Object FirstWhereTagContains(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element receiver + RecvElem recv; + // Process each entity in the pool + FindIfTagContains(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), recv, tag); + // Return the received element, if any + return recv; + } + + /* -------------------------------------------------------------------------------------------- + * Retrieve the first entity of this type where the tag does not contain the specified string. + */ + static inline Object FirstWhereTagNotContains(CSStr tag) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element receiver + RecvElem recv; + // Process each entity in the pool + FindIfTagNotContains(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), recv, tag); + // Return the received element, if any + return recv; + } + + /* -------------------------------------------------------------------------------------------- + * Process all active entities of this type. + */ + static inline Uint32 EachActive(Object & env, Function & func) + { + // Create a new element forwarder + ForwardElem fwd(env, func); + // Process each entity in the pool + Collect(Inst::CBegin(), Inst::CEnd(), ValidInst(), fwd); + // Return the forward count + return fwd.mCount; + } + + /* -------------------------------------------------------------------------------------------- + * Process all entities of this type where the tag matches the specified one. + */ + static inline Uint32 EachWhereTagEquals(CSStr tag, Object & env, Function & func) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element forwarder + ForwardElem fwd(env, func); + // Process each entity in the pool + CollectIfTagEquals(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), fwd, tag); + // Return the forward count + return fwd.mCount; + } + + /* -------------------------------------------------------------------------------------------- + * Process all entities of this type where the tag does not match the specified one. + */ + static inline Uint32 EachWhereTagNotEquals(CSStr tag, Object & env, Function & func) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element forwarder + ForwardElem fwd(env, func); + // Process each entity in the pool + CollectIfTagNotEquals(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), fwd, tag); + // Return the forward count + return fwd.mCount; + } + + /* -------------------------------------------------------------------------------------------- + * Process all entities of this type where the tag begins with the specified string. + */ + static inline Uint32 EachWhereTagBegins(CSStr tag, Object & env, Function & func) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element forwarder + ForwardElem fwd(env, func); + // Process each entity in the pool + CollectIfTagBegins(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), fwd, tag, std::strlen(tag)); + // Return the forward count + return fwd.mCount; + } + + /* -------------------------------------------------------------------------------------------- + * Process all entities of this type where the does not begin with the specified string. + */ + static inline Uint32 EachWhereTagNotBegins(CSStr tag, Object & env, Function & func) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element forwarder + ForwardElem fwd(env, func); + // Process each entity in the pool + CollectIfTagNotBegins(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), fwd, tag, std::strlen(tag)); + // Return the forward count + return fwd.mCount; + } + + /* -------------------------------------------------------------------------------------------- + * Process all entities of this type where the tag ends with the specified string. + */ + static inline Uint32 EachWhereTagEnds(CSStr tag, Object & env, Function & func) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element forwarder + ForwardElem fwd(env, func); + // Process each entity in the pool + CollectIfTagEnds(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), fwd, tag, std::strlen(tag)); + // Return the forward count + return fwd.mCount; + } + + /* -------------------------------------------------------------------------------------------- + * Process all entities of this type where the tag does not end with the specified string. + */ + static inline Uint32 EachWhereTagNotEnds(CSStr tag, Object & env, Function & func) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element forwarder + ForwardElem fwd(env, func); + // Process each entity in the pool + CollectIfTagNotEnds(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), fwd, tag, std::strlen(tag)); + // Return the forward count + return fwd.mCount; + } + + /* -------------------------------------------------------------------------------------------- + * Process all entities of this type where the tag contains the specified string. + */ + static inline Uint32 EachWhereTagContains(CSStr tag, Object & env, Function & func) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element forwarder + ForwardElem fwd(env, func); + // Process each entity in the pool + CollectIfTagContains(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), fwd, tag); + // Return the forward count + return fwd.mCount; + } + + /* -------------------------------------------------------------------------------------------- + * Process all entities of this type where the tag does not contain the specified string. + */ + static inline Uint32 EachWhereTagNotContains(CSStr tag, Object & env, Function & func) + { + SQMOD_VALID_TAG_STR(tag) + // Create a new element forwarder + ForwardElem fwd(env, func); + // Process each entity in the pool + CollectIfTagNotContains(Inst::CBegin(), Inst::CEnd(), + ValidInst(), InstTag(), fwd, tag); + // Return the forward count + return fwd.mCount; + } +}; + } // Namespace:: Algo } // Namespace:: SqMod diff --git a/source/Entity/Blip.cpp b/source/Entity/Blip.cpp index 78d162d8..d1f0a065 100644 --- a/source/Entity/Blip.cpp +++ b/source/Entity/Blip.cpp @@ -1,6 +1,5 @@ // ------------------------------------------------------------------------------------------------ #include "Entity/Blip.hpp" -#include "Base/Algo.hpp" #include "Core.hpp" // ------------------------------------------------------------------------------------------------ @@ -287,100 +286,6 @@ static Object & Blip_Create(Int32 index, Int32 world, const Vector3 & pos, Int32 header, payload); } -// ------------------------------------------------------------------------------------------------ -static const Object & Blip_FindByID(Int32 id) -{ - // Perform a range check on the specified identifier - if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL)) - STHROWF("The specified blip identifier is invalid: %d", id); - // Obtain the ends of the entity pool - Core::Blips::const_iterator itr = Core::Get().GetBlips().cbegin(); - Core::Blips::const_iterator end = Core::Get().GetBlips().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does the identifier match the specified one? - if (itr->mID == id) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a blip matching the specified identifier - return NullObject(); -} - -static const Object & Blip_FindByTag(CSStr tag) -{ - // Perform a validity check on the specified tag - if (!tag || *tag == '\0') - { - STHROWF("The specified blip tag is invalid: null/empty"); - } - // Obtain the ends of the entity pool - Core::Blips::const_iterator itr = Core::Get().GetBlips().cbegin(); - Core::Blips::const_iterator end = Core::Get().GetBlips().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does this entity even exist and does the tag match the specified one? - if (itr->mInst != nullptr && itr->mInst->GetTag().compare(tag) == 0) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a blip matching the specified tag - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static const Object & Blip_FindBySprID(Int32 sprid) -{ - // Perform a range check on the specified identifier - if (sprid < 0) - { - STHROWF("The specified sprite identifier is invalid: %d", sprid); - } - // Obtain the ends of the entity pool - Core::Blips::const_iterator itr = Core::Get().GetBlips().cbegin(); - Core::Blips::const_iterator end = Core::Get().GetBlips().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does the identifier match the specified one? - if (itr->mSprID == sprid) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a blip matching the specified identifier - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static Array Blip_FindActive() -{ - const StackGuard sg; - // Allocate an empty array on the stack - sq_newarray(DefaultVM::Get(), 0); - // Process each entity in the pool - Algo::Collect(Core::Get().GetBlips().cbegin(), Core::Get().GetBlips().cend(), - [](Core::Blips::const_reference inst) -> bool { - return VALID_ENTITY(inst.mID); - }, - [](Core::Blips::const_reference inst) -> void { - // Push the script object on the stack - sq_pushobject(DefaultVM::Get(), inst.mObj.GetObject()); - // Append the object at the back of the array - if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -2))) - { - STHROWF("Unable to append entity instance to the list"); - } - } - ); - // Return the array at the top of the stack - return Var< Array >(DefaultVM::Get(), -1).value; -} - // ================================================================================================ void Register_CBlip(HSQUIRRELVM vm) { @@ -418,11 +323,6 @@ void Register_CBlip(HSQUIRRELVM vm) .Prop(_SC("Green"), &CBlip::GetColorG) .Prop(_SC("Blue"), &CBlip::GetColorB) .Prop(_SC("Alpha"), &CBlip::GetColorA) - // Static Functions - .StaticFunc(_SC("FindByID"), &Blip_FindByID) - .StaticFunc(_SC("FindByTag"), &Blip_FindByTag) - .StaticFunc(_SC("FindActive"), &Blip_FindActive) - .StaticFunc(_SC("FindBySprID"), &Blip_FindBySprID) // Static Overloads .StaticOverload< Object & (*)(Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32) > (_SC("CreateEx"), &Blip_CreateEx) diff --git a/source/Entity/Checkpoint.cpp b/source/Entity/Checkpoint.cpp index adafa230..0ac7273e 100644 --- a/source/Entity/Checkpoint.cpp +++ b/source/Entity/Checkpoint.cpp @@ -1,7 +1,6 @@ // ------------------------------------------------------------------------------------------------ #include "Entity/Checkpoint.hpp" #include "Entity/Player.hpp" -#include "Base/Algo.hpp" #include "Base/Color4.hpp" #include "Base/Vector3.hpp" #include "Core.hpp" @@ -482,79 +481,6 @@ static Object & Checkpoint_Create(CPlayer & player, Int32 world, bool sphere, co color.r, color.g, color.b, color.a, radius, header, payload); } -// ------------------------------------------------------------------------------------------------ -static const Object & Checkpoint_FindByID(Int32 id) -{ - // Perform a range check on the specified identifier - if (INVALID_ENTITYEX(id, SQMOD_CHECKPOINT_POOL)) - { - STHROWF("The specified checkpoint identifier is invalid: %d", id); - } - // Obtain the ends of the entity pool - Core::Checkpoints::const_iterator itr = Core::Get().GetCheckpoints().cbegin(); - Core::Checkpoints::const_iterator end = Core::Get().GetCheckpoints().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does the identifier match the specified one? - if (itr->mID == id) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a checkpoint matching the specified identifier - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static const Object & Checkpoint_FindByTag(CSStr tag) -{ - // Perform a validity check on the specified tag - if (!tag || *tag == '\0') - { - STHROWF("The specified checkpoint tag is invalid: null/empty"); - } - // Obtain the ends of the entity pool - Core::Checkpoints::const_iterator itr = Core::Get().GetCheckpoints().cbegin(); - Core::Checkpoints::const_iterator end = Core::Get().GetCheckpoints().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does this entity even exist and does the tag match the specified one? - if (itr->mInst != nullptr && itr->mInst->GetTag().compare(tag) == 0) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a checkpoint matching the specified tag - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static Array Checkpoint_FindActive() -{ - const StackGuard sg; - // Allocate an empty array on the stack - sq_newarray(DefaultVM::Get(), 0); - // Process each entity in the pool - Algo::Collect(Core::Get().GetCheckpoints().cbegin(), Core::Get().GetCheckpoints().cend(), - [](Core::Checkpoints::const_reference inst) -> bool { - return VALID_ENTITY(inst.mID); - }, - [](Core::Checkpoints::const_reference inst) -> void { - // Push the script object on the stack - sq_pushobject(DefaultVM::Get(), inst.mObj.GetObject()); - // Append the object at the back of the array - if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -2))) - { - STHROWF("Unable to append entity instance to the list"); - } - } - ); - // Return the array at the top of the stack - return Var< Array >(DefaultVM::Get(), -1).value; -} - // ================================================================================================ void Register_CCheckpoint(HSQUIRRELVM vm) { @@ -603,10 +529,6 @@ void Register_CCheckpoint(HSQUIRRELVM vm) (_SC("SetColor"), &CCheckpoint::SetColorEx) .Overload< void (CCheckpoint::*)(Uint8, Uint8, Uint8, Uint8) const > (_SC("SetColor"), &CCheckpoint::SetColorEx) - // Static Functions - .StaticFunc(_SC("FindByID"), &Checkpoint_FindByID) - .StaticFunc(_SC("FindByTag"), &Checkpoint_FindByTag) - .StaticFunc(_SC("FindActive"), &Checkpoint_FindActive) // Static Overloads .StaticOverload< Object & (*)(CPlayer &, Int32, bool, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32) > (_SC("CreateEx"), &Checkpoint_CreateEx) diff --git a/source/Entity/Keybind.cpp b/source/Entity/Keybind.cpp index 08de5d4e..9d7c8b61 100644 --- a/source/Entity/Keybind.cpp +++ b/source/Entity/Keybind.cpp @@ -1,6 +1,5 @@ // ------------------------------------------------------------------------------------------------ #include "Entity/Keybind.hpp" -#include "Base/Algo.hpp" #include "Core.hpp" // ------------------------------------------------------------------------------------------------ @@ -180,79 +179,6 @@ static Object & Keybind_Create(bool release, Int32 primary, Int32 secondary, Int return Core::Get().NewKeybind(-1, release, primary, secondary, alternative, header, payload); } -// ------------------------------------------------------------------------------------------------ -static const Object & Keybind_FindByID(Int32 id) -{ - // Perform a range check on the specified identifier - if (INVALID_ENTITYEX(id, SQMOD_KEYBIND_POOL)) - { - STHROWF("The specified keybind identifier is invalid: %d", id); - } - // Obtain the ends of the entity pool - Core::Keybinds::const_iterator itr = Core::Get().GetKeybinds().cbegin(); - Core::Keybinds::const_iterator end = Core::Get().GetKeybinds().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does the identifier match the specified one? - if (itr->mID == id) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a keybind matching the specified identifier - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static const Object & Keybind_FindByTag(CSStr tag) -{ - // Perform a validity check on the specified tag - if (!tag || *tag == '\0') - { - STHROWF("The specified keybind tag is invalid: null/empty"); - } - // Obtain the ends of the entity pool - Core::Keybinds::const_iterator itr = Core::Get().GetKeybinds().cbegin(); - Core::Keybinds::const_iterator end = Core::Get().GetKeybinds().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does this entity even exist and does the tag match the specified one? - if (itr->mInst != nullptr && itr->mInst->GetTag().compare(tag) == 0) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a keybind matching the specified tag - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static Array Keybind_FindActive() -{ - const StackGuard sg; - // Allocate an empty array on the stack - sq_newarray(DefaultVM::Get(), 0); - // Process each entity in the pool - Algo::Collect(Core::Get().GetKeybinds().cbegin(), Core::Get().GetKeybinds().cend(), - [](Core::Keybinds::const_reference inst) -> bool { - return VALID_ENTITY(inst.mID); - }, - [](Core::Keybinds::const_reference inst) -> void { - // Push the script object on the stack - sq_pushobject(DefaultVM::Get(), inst.mObj.GetObject()); - // Append the object at the back of the array - if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -2))) - { - STHROWF("Unable to append entity instance to the list"); - } - } - ); - // Return the array at the top of the stack - return Var< Array >(DefaultVM::Get(), -1).value; -} - // ------------------------------------------------------------------------------------------------ static SQInteger Keybind_UnusedSlot() { @@ -287,9 +213,6 @@ void Register_CKeybind(HSQUIRRELVM vm) .Prop(_SC("Third"), &CKeybind::GetThird) .Prop(_SC("Release"), &CKeybind::IsRelease) // Static Functions - .StaticFunc(_SC("FindByID"), &Keybind_FindByID) - .StaticFunc(_SC("FindByTag"), &Keybind_FindByTag) - .StaticFunc(_SC("FindActive"), &Keybind_FindActive) .StaticFunc(_SC("UnusedSlot"), &Keybind_UnusedSlot) // Static Overloads .StaticOverload< Object & (*)(Int32, bool, Int32, Int32, Int32) > diff --git a/source/Entity/Object.cpp b/source/Entity/Object.cpp index d5e897ae..d03930ce 100644 --- a/source/Entity/Object.cpp +++ b/source/Entity/Object.cpp @@ -1,7 +1,6 @@ // ------------------------------------------------------------------------------------------------ #include "Entity/Object.hpp" #include "Entity/Player.hpp" -#include "Base/Algo.hpp" #include "Base/Quaternion.hpp" #include "Base/Vector3.hpp" #include "Core.hpp" @@ -808,77 +807,6 @@ static Object & Object_Create(Int32 model, Int32 world, const Vector3 & pos, Int return Core::Get().NewObject(model, world, pos.x, pos.y, pos.z, alpha, header, payload); } -// ------------------------------------------------------------------------------------------------ -static const Object & Object_FindByID(Int32 id) -{ - // Perform a range check on the specified identifier - if (INVALID_ENTITYEX(id, SQMOD_OBJECT_POOL)) - { - STHROWF("The specified object identifier is invalid: %d", id); - } - // Obtain the ends of the entity pool - Core::Objects::const_iterator itr = Core::Get().GetObjects().cbegin(); - Core::Objects::const_iterator end = Core::Get().GetObjects().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does the identifier match the specified one? - if (itr->mID == id) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a object matching the specified identifier - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static const Object & Object_FindByTag(CSStr tag) -{ - // Perform a validity check on the specified tag - if (!tag || *tag == '\0') - STHROWF("The specified object tag is invalid: null/empty"); - // Obtain the ends of the entity pool - Core::Objects::const_iterator itr = Core::Get().GetObjects().cbegin(); - Core::Objects::const_iterator end = Core::Get().GetObjects().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does this entity even exist and does the tag match the specified one? - if (itr->mInst != nullptr && itr->mInst->GetTag().compare(tag) == 0) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a object matching the specified tag - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static Array Object_FindActive() -{ - const StackGuard sg; - // Allocate an empty array on the stack - sq_newarray(DefaultVM::Get(), 0); - // Process each entity in the pool - Algo::Collect(Core::Get().GetObjects().cbegin(), Core::Get().GetObjects().cend(), - [](Core::Objects::const_reference inst) -> bool { - return VALID_ENTITY(inst.mID); - }, - [](Core::Objects::const_reference inst) -> void { - // Push the script object on the stack - sq_pushobject(DefaultVM::Get(), inst.mObj.GetObject()); - // Append the object at the back of the array - if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -2))) - { - STHROWF("Unable to append entity instance to the list"); - } - } - ); - // Return the array at the top of the stack - return Var< Array >(DefaultVM::Get(), -1).value; -} - // ================================================================================================ void Register_CObject(HSQUIRRELVM vm) { @@ -980,10 +908,6 @@ void Register_CObject(HSQUIRRELVM vm) (_SC("RotateByEuler"), &CObject::RotateByEuler) .Overload< void (CObject::*)(Float32, Float32, Float32, Uint32) const > (_SC("RotateByEuler"), &CObject::RotateByEulerEx) - // Static Functions - .StaticFunc(_SC("FindByID"), &Object_FindByID) - .StaticFunc(_SC("FindByTag"), &Object_FindByTag) - .StaticFunc(_SC("FindActive"), &Object_FindActive) // Static Overloads .StaticOverload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Int32) > (_SC("CreateEx"), &Object_CreateEx) diff --git a/source/Entity/Pickup.cpp b/source/Entity/Pickup.cpp index 06fd1ec9..4206edcf 100644 --- a/source/Entity/Pickup.cpp +++ b/source/Entity/Pickup.cpp @@ -1,7 +1,6 @@ // ------------------------------------------------------------------------------------------------ #include "Entity/Pickup.hpp" #include "Entity/Player.hpp" -#include "Base/Algo.hpp" #include "Base/Vector3.hpp" #include "Core.hpp" @@ -368,79 +367,6 @@ static Object & Pickup_Create(Int32 model, Int32 world, Int32 quantity, const Ve header, payload); } -// ------------------------------------------------------------------------------------------------ -static const Object & Pickup_FindByID(Int32 id) -{ - // Perform a range check on the specified identifier - if (INVALID_ENTITYEX(id, SQMOD_PICKUP_POOL)) - { - STHROWF("The specified pickup identifier is invalid: %d", id); - } - // Obtain the ends of the entity pool - Core::Pickups::const_iterator itr = Core::Get().GetPickups().cbegin(); - Core::Pickups::const_iterator end = Core::Get().GetPickups().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does the identifier match the specified one? - if (itr->mID == id) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a pickup matching the specified identifier - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static const Object & Pickup_FindByTag(CSStr tag) -{ - // Perform a validity check on the specified tag - if (!tag || *tag == '0') - { - STHROWF("The specified pickup tag is invalid: null/empty"); - } - // Obtain the ends of the entity pool - Core::Pickups::const_iterator itr = Core::Get().GetPickups().cbegin(); - Core::Pickups::const_iterator end = Core::Get().GetPickups().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does this entity even exist and does the tag match the specified one? - if (itr->mInst != nullptr && itr->mInst->GetTag().compare(tag) == 0) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a pickup matching the specified tag - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static Array Pickup_FindActive() -{ - const StackGuard sg; - // Allocate an empty array on the stack - sq_newarray(DefaultVM::Get(), 0); - // Process each entity in the pool - Algo::Collect(Core::Get().GetPickups().cbegin(), Core::Get().GetPickups().cend(), - [](Core::Pickups::const_reference inst) -> bool { - return VALID_ENTITY(inst.mID); - }, - [](Core::Pickups::const_reference inst) -> void { - // Push the script object on the stack - sq_pushobject(DefaultVM::Get(), inst.mObj.GetObject()); - // Append the object at the back of the array - if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -2))) - { - STHROWF("Unable to append entity instance to the list"); - } - } - ); - // Return the array at the top of the stack - return Var< Array >(DefaultVM::Get(), -1).value; -} - // ================================================================================================ void Register_CPickup(HSQUIRRELVM vm) { @@ -482,10 +408,6 @@ void Register_CPickup(HSQUIRRELVM vm) .Func(_SC("Refresh"), &CPickup::Refresh) .Func(_SC("SetPos"), &CPickup::SetPositionEx) .Func(_SC("SetPosition"), &CPickup::SetPositionEx) - // Static Functions - .StaticFunc(_SC("FindByID"), &Pickup_FindByID) - .StaticFunc(_SC("FindByTag"), &Pickup_FindByTag) - .StaticFunc(_SC("FindActive"), &Pickup_FindActive) // Static Overloads .StaticOverload< Object & (*)(Int32, Int32, Int32, Float32, Float32, Float32, Int32, bool) > (_SC("CreateEx"), &Pickup_CreateEx) diff --git a/source/Entity/Player.cpp b/source/Entity/Player.cpp index 8454f5ab..55999adf 100644 --- a/source/Entity/Player.cpp +++ b/source/Entity/Player.cpp @@ -1,7 +1,6 @@ // ------------------------------------------------------------------------------------------------ #include "Entity/Player.hpp" #include "Entity/Vehicle.hpp" -#include "Base/Algo.hpp" #include "Base/Color3.hpp" #include "Base/Color4.hpp" #include "Base/Vector3.hpp" @@ -2062,110 +2061,6 @@ SQInteger CPlayer::AnnounceEx(HSQUIRRELVM vm) return 0; } -// ------------------------------------------------------------------------------------------------ -static const Object & Player_FindByID(Int32 id) -{ - // Perform a range check on the specified identifier - if (INVALID_ENTITYEX(id, SQMOD_PLAYER_POOL)) - { - STHROWF("The specified player identifier is invalid: %d", id); - } - // Obtain the ends of the entity pool - Core::Players::const_iterator itr = Core::Get().GetPlayers().cbegin(); - Core::Players::const_iterator end = Core::Get().GetPlayers().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does the identifier match the specified one? - if (itr->mID == id) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a player matching the specified identifier - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static const Object & Player_FindByTag(CSStr tag) -{ - // Perform a validity check on the specified tag - if (!tag || *tag == '\0') - { - STHROWF("The specified player tag is invalid: null/empty"); - } - // Obtain the ends of the entity pool - Core::Players::const_iterator itr = Core::Get().GetPlayers().cbegin(); - Core::Players::const_iterator end = Core::Get().GetPlayers().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does this entity even exist and does the tag match the specified one? - if (itr->mInst != nullptr && itr->mInst->GetTag().compare(tag) == 0) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a player matching the specified tag - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static Array Player_FindActive() -{ - const StackGuard sg; - // Allocate an empty array on the stack - sq_newarray(DefaultVM::Get(), 0); - // Process each entity in the pool - Algo::Collect(Core::Get().GetPlayers().cbegin(), Core::Get().GetPlayers().cend(), - [](Core::Players::const_reference inst) -> bool { - return VALID_ENTITY(inst.mID); - }, - [](Core::Players::const_reference inst) -> void { - // Push the script object on the stack - sq_pushobject(DefaultVM::Get(), inst.mObj.GetObject()); - // Append the object at the back of the array - if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -2))) - { - STHROWF("Unable to append entity instance to the list"); - } - } - ); - // Return the array at the top of the stack - return Var< Array >(DefaultVM::Get(), -1).value; -} - -// ------------------------------------------------------------------------------------------------ -static const Object & Player_FindAuto(Object & by) -{ - switch (by.GetType()) - { - case OT_INTEGER: - { - return Core::Get().GetPlayer(by.Cast< Int32 >()).mObj; - } break; - case OT_FLOAT: - { - return Core::Get().GetPlayer(std::round(by.Cast< Float32 >())).mObj; - } break; - case OT_STRING: - { - // Obtain the argument as a string - String str(by.Cast< String >()); - // Attempt to locate the player with this name - Int32 id = _Func->GetPlayerIdFromName(&str[0]); - // Was there a player with this name? - if (VALID_ENTITYEX(id, SQMOD_PLAYER_POOL)) - { - Core::Get().GetPlayer(id).mObj; - } - } break; - default: STHROWF("Unsupported search identifier"); - } - // Default to a null object - return NullObject(); -} - // ================================================================================================ void Register_CPlayer(HSQUIRRELVM vm) { @@ -2334,11 +2229,6 @@ void Register_CPlayer(HSQUIRRELVM vm) .SquirrelFunc(_SC("AnnounceEx"), &CPlayer::AnnounceEx) .SquirrelFunc(_SC("Text"), &CPlayer::Announce) .SquirrelFunc(_SC("TextEx"), &CPlayer::AnnounceEx) - // Static Functions - .StaticFunc(_SC("Find"), &Player_FindAuto) - .StaticFunc(_SC("FindByID"), &Player_FindByID) - .StaticFunc(_SC("FindByTag"), &Player_FindByTag) - .StaticFunc(_SC("FindActive"), &Player_FindActive) ); } diff --git a/source/Entity/Vehicle.cpp b/source/Entity/Vehicle.cpp index 44986deb..fa912b13 100644 --- a/source/Entity/Vehicle.cpp +++ b/source/Entity/Vehicle.cpp @@ -1,7 +1,6 @@ // ------------------------------------------------------------------------------------------------ #include "Entity/Vehicle.hpp" #include "Entity/Player.hpp" -#include "Base/Algo.hpp" #include "Base/Quaternion.hpp" #include "Base/Vector2.hpp" #include "Base/Vector3.hpp" @@ -1625,79 +1624,6 @@ static Object & Vehicle_Create(Int32 model, Int32 world, const Vector3 & pos, Fl header, payload); } -// ------------------------------------------------------------------------------------------------ -static const Object & Vehicle_FindByID(Int32 id) -{ - // Perform a range check on the specified identifier - if (INVALID_ENTITYEX(id, SQMOD_VEHICLE_POOL)) - { - STHROWF("The specified vehicle identifier is invalid: %d", id); - } - // Obtain the ends of the entity pool - Core::Vehicles::const_iterator itr = Core::Get().GetVehicles().cbegin(); - Core::Vehicles::const_iterator end = Core::Get().GetVehicles().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does the identifier match the specified one? - if (itr->mID == id) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a vehicle matching the specified identifier - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static const Object & Vehicle_FindByTag(CSStr tag) -{ - // Perform a validity check on the specified tag - if (!tag || *tag == '\0') - { - STHROWF("The specified vehicle tag is invalid: null/empty"); - } - // Obtain the ends of the entity pool - Core::Vehicles::const_iterator itr = Core::Get().GetVehicles().cbegin(); - Core::Vehicles::const_iterator end = Core::Get().GetVehicles().cend(); - // Process each entity in the pool - for (; itr != end; ++itr) - { - // Does this entity even exist and does the tag match the specified one? - if (itr->mInst != nullptr && itr->mInst->GetTag().compare(tag) == 0) - { - return itr->mObj; // Stop searching and return this entity - } - } - // Unable to locate a vehicle matching the specified tag - return NullObject(); -} - -// ------------------------------------------------------------------------------------------------ -static Array Vehicle_FindActive() -{ - const StackGuard sg; - // Allocate an empty array on the stack - sq_newarray(DefaultVM::Get(), 0); - // Process each entity in the pool - Algo::Collect(Core::Get().GetVehicles().cbegin(), Core::Get().GetVehicles().cend(), - [](Core::Vehicles::const_reference inst) -> bool { - return VALID_ENTITY(inst.mID); - }, - [](Core::Vehicles::const_reference inst) -> void { - // Push the script object on the stack - sq_pushobject(DefaultVM::Get(), inst.mObj.GetObject()); - // Append the object at the back of the array - if (SQ_FAILED(sq_arrayappend(DefaultVM::Get(), -2))) - { - STHROWF("Unable to append entity instance to the list"); - } - } - ); - // Return the array at the top of the stack - return Var< Array >(DefaultVM::Get(), -1).value; -} - // ================================================================================================ void Register_CVehicle(HSQUIRRELVM vm) { @@ -1855,10 +1781,6 @@ void Register_CVehicle(HSQUIRRELVM vm) (_SC("Embark"), &CVehicle::Embark) .Overload< bool (CVehicle::*)(CPlayer &, Int32, bool, bool) const > (_SC("Embark"), &CVehicle::Embark) - // Static Functions - .StaticFunc(_SC("FindByID"), &Vehicle_FindByID) - .StaticFunc(_SC("FindByTag"), &Vehicle_FindByTag) - .StaticFunc(_SC("FindActive"), &Vehicle_FindActive) // Static Overloads .StaticOverload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Float32, Int32, Int32) > (_SC("CreateEx"), &Vehicle_CreateEx)