#pragma once #include #include #include #include namespace f4mp { struct MessageType { enum : u16 { Hit = LIBRG_EVENT_LAST + 1u, FireWeapon, SpawnEntity, SyncEntity, SpawnBuilding, RemoveBuilding, Speak }; }; struct EntityType { enum : u32 { Player = 0, NPC }; }; struct HitData { u32 hitter, hittee; f32 damage; }; struct SpawnEntityData { u32 formID; zpl_vec3 position; zpl_vec3 angles; u32 entityID; u32 ownerEntityID; }; struct SyncEntityData { u32 formID; zpl_vec3 position; zpl_vec3 angles; f64 syncedTime; }; struct SpawnBuildingData { u32 ownerEntityID; u32 formID; u32 baseFormID; // HACK: 0 if it's just a transform update zpl_vec3 position; zpl_vec3 angles; }; struct RemoveBuildingData { u64 uniqueFormID; }; struct TransformData { u32 formID; zpl_vec3 position; zpl_vec3 angles; }; struct SpeakData { u32 clientEntityID; u32 speakerFormID; // 0 if client u32 topicInfoFormID; }; struct AppearanceData { bool female; std::vector weights; std::string hairColor; std::vector headParts; std::vector morphSetValue; std::vector morphRegionData1; std::vector> morphRegionData2; std::vector morphSetData1; std::vector morphSetData2; void Clear() { headParts.clear(); morphSetValue.clear(); morphRegionData1.clear(); morphRegionData2.clear(); morphSetData1.clear(); morphSetData2.clear(); } }; struct WornItemsData { std::vector data1; std::vector data2; void Clear() { //data.clear(); data1.clear(); data2.clear(); } }; // TODO: the ones for tuple seem to be broken class Utils { private: template static void WriteForTuple(librg_data* data, const T& value) { Write(data, value); } template static void WriteForTuple(librg_data* data, const T& value, Ts... values) { Write(data, value); WriteForTuple(data, values...); } template static void WriteTuple(librg_data* data, const T& tuple, std::index_sequence) { WriteForTuple(data, std::get(tuple)...); } template static void ReadForTuple(librg_data* data, T& value) { Read(data, value); } template static void ReadForTuple(librg_data* data, T& value, Ts... values) { Read(data, value); ReadForTuple(data, values...); } template static void ReadTuple(librg_data* data, T& tuple, std::index_sequence) { ReadForTuple(data, std::get(tuple)...); } public: template static void Write(librg_data* data, const T& value); template static void Write(librg_data* data, const std::vector& values) { //_MESSAGE("size: %u", values.size()); librg_data_wu32(data, static_cast(values.size())); for (const T& value : values) { Write(data, value); } } template static void Write(librg_data* data, const std::tuple& values) { static constexpr auto size = std::tuple_size>::value; WriteTuple(data, values, std::make_index_sequence{}); } static void Write(librg_data* data, const bool& value) { //_MESSAGE("%s", value ? "true" : "false"); librg_data_wb8(data, value); } static void Write(librg_data* data, const u8& value) { //_MESSAGE("%u", value); librg_data_wu8(data, value); } static void Write(librg_data* data, const u32& value) { //_MESSAGE("%u", value); librg_data_wu32(data, value); } static void Write(librg_data* data, const f32& value) { //_MESSAGE("%f", value); librg_data_wf32(data, value); } static void Write(librg_data* data, const f64& value) { librg_data_wf64(data, value); } static void Write(librg_data* data, const std::string& value) { //_MESSAGE("%s", value.c_str()); librg_data_wu32(data, static_cast(value.size())); for (char ch : value) { librg_data_wb8(data, ch); } } template static void Read(librg_data* data, T& value); template static void Read(librg_data* data, std::vector& values) { values.resize(librg_data_ru32(data)); for (T& value : values) { Read(data, value); } } template static void Read(librg_data* data, std::tuple& values) { static constexpr auto size = std::tuple_size>::value; ReadTuple(data, values, std::make_index_sequence{}); } static void Read(librg_data* data, bool& value) { value = !!librg_data_rb8(data); } static void Read(librg_data* data, u8& value) { value = librg_data_ru8(data); } static void Read(librg_data* data, u32& value) { value = librg_data_ru32(data); } static void Read(librg_data* data, f32& value) { value = librg_data_rf32(data); } static void Read(librg_data* data, f64& value) { value = librg_data_rf64(data); } static void Read(librg_data* data, std::string& value) { value.resize(librg_data_ru32(data)); for (char& ch : value) { ch = librg_data_rb8(data); } } }; template std::string Lower(const T& string) { std::string lower = string; for (size_t i = 0; i < lower.length(); i++) { lower[i] = tolower(lower[i]); } return lower; } u64 GetUniqueFormID(u32 ownerEntityID, u32 entityFormID); }