diff --git a/code/client/src/core/modules/human.cpp b/code/client/src/core/modules/human.cpp index e71df881..9c76da31 100644 --- a/code/client/src/core/modules/human.cpp +++ b/code/client/src/core/modules/human.cpp @@ -4,6 +4,9 @@ #include #include +#include + +#include #include "game/helpers/controls.h" #include "game/helpers/human.h" @@ -14,13 +17,14 @@ #include "sdk/entities/c_car.h" #include "sdk/entities/c_player_2.h" #include "sdk/entities/c_vehicle.h" +#include "sdk/ue/game/camera/c_game_camera.h" #include "sdk/wrappers/c_human_2_car_wrapper.h" +#include "shared/game_rpc/add_weapon.h" #include "shared/game_rpc/human/human_changeskin.h" #include "shared/game_rpc/human/human_reload.h" #include "shared/game_rpc/human/human_setprops.h" #include "shared/game_rpc/human/human_shoot.h" -#include "shared/game_rpc/add_weapon.h" #include "vehicle.h" #include @@ -122,6 +126,38 @@ namespace MafiaMP::Core::Modules { tracking.human->SetRot({newRot.x, newRot.y, newRot.z, newRot.w}); } } + + const auto humanPtr = tracking.human; + const auto hp = updateData->_healthPercent; + const auto nickname = humanData->nickname; + gApplication->GetImGUI()->PushWidget([humanPtr, hp, nickname]() { + const auto displaySize = ImGui::GetIO().DisplaySize; + + auto gameCamera = SDK::ue::game::camera::C_GameCamera::GetInstanceInternal(); + if (!gameCamera) { + return; + } + auto camera = gameCamera->GetCamera(SDK::ue::game::camera::E_GameCameraID::CAMERA_PLAYER_MAIN_1); + if (!camera) { + return; + } + + auto camPos = camera->GetPos(); + static const auto headBoneHash = SDK::ue::sys::utils::C_HashName::ComputeHash("Head"); + SDK::ue::sys::math::C_Vector headPos = humanPtr->GetBoneWorldPos(headBoneHash); + float distFromCam = headPos.dist(camPos); + if (distFromCam <= 250.0f /* @todo: make configurable */) { + headPos.z += 0.335f + (distFromCam * 0.03f); + + SDK::ue::sys::math::C_Vector2 screenPos; + bool onScreen = false; + float unkFloat1, unkFloat2; + camera->GetScreenPos(screenPos, headPos, onScreen, &unkFloat1, &unkFloat2, true); + if (onScreen) { + Framework::External::ImGUI::Widgets::DrawNameTag({screenPos.x * displaySize.x, screenPos.y * displaySize.y}, nickname.empty() ? "Player" : nickname.c_str(), hp); + } + } + }); } }); } @@ -315,6 +351,8 @@ namespace MafiaMP::Core::Modules { auto updateData = e.get_mut(); auto humanData = e.get_mut(); + humanData->nickname = msg->GetNickname(); + const auto carPassenger = msg->GetCarPassenger(); if (carPassenger.carId) { updateData->carPassenger.carId = carPassenger.carId; diff --git a/code/client/src/core/modules/human.h b/code/client/src/core/modules/human.h index c0f381a6..d87702c8 100644 --- a/code/client/src/core/modules/human.h +++ b/code/client/src/core/modules/human.h @@ -4,15 +4,20 @@ #include "sdk/entities/c_player_2.h" -#include "game/streaming/entity_tracking_info.h" #include "game/overrides/character_controller.h" +#include "game/streaming/entity_tracking_info.h" #include "core/application.h" -#include #include +#include -enum CarEnterStates { STATE_OUTSIDE, STATE_ENTERING, STATE_LEAVING, STATE_INSIDE }; +enum CarEnterStates { + STATE_OUTSIDE, + STATE_ENTERING, + STATE_LEAVING, + STATE_INSIDE +}; namespace MafiaMP::Core::Modules { struct Human { @@ -33,8 +38,10 @@ namespace MafiaMP::Core::Modules { struct HumanData { struct CarPassenger { CarEnterStates enterState = STATE_OUTSIDE; - bool enterForced{}; - } carPassenger{}; + bool enterForced {}; + } carPassenger {}; + + std::string nickname; }; Human(flecs::world &world); @@ -55,7 +62,7 @@ namespace MafiaMP::Core::Modules { static flecs::entity GetHumanEntity(SDK::C_Human2 *ptr); - private: + private: static void InitRPCs(Application *app); }; } // namespace MafiaMP::Core::Modules diff --git a/code/client/src/game/helpers/human.cpp b/code/client/src/game/helpers/human.cpp index 092c1e77..0ba7a855 100644 --- a/code/client/src/game/helpers/human.cpp +++ b/code/client/src/game/helpers/human.cpp @@ -10,12 +10,12 @@ namespace MafiaMP::Game::Helpers { uint8_t Human::GetHealthPercent(SDK::C_Human2 *human) { float fHealth = human->GetHumanScript()->GetHealth(); float fHealthMax = human->GetHumanScript()->GetHealthMax(); - return (uint8_t)glm::clamp(fHealth / fHealthMax, 0.0f, 100.0f); + return (uint8_t)std::clamp((fHealth / fHealthMax) * 100.f, 0.0f, 100.0f); } void Human::SetHealthPercent(SDK::C_Human2 *human, float health) { float fHealthMax = human->GetHumanScript()->GetHealthMax(); - return human->GetHumanScript()->SetHealth(glm::clamp(health * fHealthMax, 0.0f, fHealthMax)); + return human->GetHumanScript()->SetHealth(std::clamp(health * fHealthMax, 0.0f, fHealthMax)); } bool Human::PutIntoCar(MafiaMP::Game::Overrides::CharacterController *charController, SDK::C_Car *car, int seat, bool force) { diff --git a/code/server/src/core/modules/human.cpp b/code/server/src/core/modules/human.cpp index a5b18b0c..950b2357 100644 --- a/code/server/src/core/modules/human.cpp +++ b/code/server/src/core/modules/human.cpp @@ -11,9 +11,9 @@ #include "core/builtins/player.h" -#include "shared/game_rpc/human/human_shoot.h" -#include "shared/game_rpc/human/human_reload.h" #include "shared/game_rpc/human/human_death.h" +#include "shared/game_rpc/human/human_reload.h" +#include "shared/game_rpc/human/human_shoot.h" #include @@ -28,10 +28,10 @@ namespace MafiaMP::Core::Modules { e.add(); - auto er = e.get_mut(); + auto er = e.get_mut(); er->collectRangeExemptEntitiesProc = [](flecs::entity e, Framework::World::Modules::Base::Streamer &streamer) { const auto updateData = e.get(); - + auto carEnt = Framework::CoreModules::GetWorldEngine()->WrapEntity(updateData->carPassenger.carId); if (carEnt.is_valid() && carEnt.is_alive()) { streamer.rangeExemptEntities.insert(carEnt.id()); @@ -50,8 +50,9 @@ namespace MafiaMP::Core::Modules { es->modEvents.spawnProc = [net](Framework::Networking::NetworkPeer *peer, uint64_t guid, flecs::entity e) { const auto frame = e.get(); + const auto s = e.get(); Shared::Messages::Human::HumanSpawn humanSpawn; - humanSpawn.FromParameters(frame->modelHash); + humanSpawn.FromParameters(frame->modelHash, s->nickname); humanSpawn.SetServerID(e.id()); const auto trackingMetadata = e.get(); @@ -98,9 +99,9 @@ namespace MafiaMP::Core::Modules { return; } - auto trackingMetadata = e.get_mut(); - const auto newData = msg->GetData(); - const auto& carPassenger = newData.carPassenger; + auto trackingMetadata = e.get_mut(); + const auto newData = msg->GetData(); + const auto &carPassenger = newData.carPassenger; // TODO improve this code if (trackingMetadata->carPassenger.carId != carPassenger.carId) { diff --git a/code/shared/messages/human/human_spawn.h b/code/shared/messages/human/human_spawn.h index 021528d9..580c9011 100644 --- a/code/shared/messages/human/human_spawn.h +++ b/code/shared/messages/human/human_spawn.h @@ -7,23 +7,26 @@ namespace MafiaMP::Shared::Messages::Human { class HumanSpawn final: public Framework::Networking::Messages::GameSyncMessage { private: uint64_t _spawnProfile; + SLNet::RakString _nickname; struct CarPassenger { - uint64_t carId{}; - int seatId{}; - } _carPassenger{}; + uint64_t carId {}; + int seatId {}; + } _carPassenger {}; public: uint8_t GetMessageID() const override { return MOD_HUMAN_SPAWN; } - void FromParameters(uint64_t spawnProfile) { + void FromParameters(uint64_t spawnProfile, const std::string &nickname) { _spawnProfile = spawnProfile; + _nickname = nickname.c_str(); } void Serialize(SLNet::BitStream *bs, bool write) override { bs->Serialize(write, _spawnProfile); + bs->Serialize(write, _nickname); bs->SerializeCompressed(write, _carPassenger); } @@ -35,8 +38,12 @@ namespace MafiaMP::Shared::Messages::Human { return _spawnProfile; } + std::string GetNickname() const { + return _nickname.C_String(); + } + void SetCarPassenger(uint64_t carId, int seatId) { - _carPassenger.carId = carId; + _carPassenger.carId = carId; _carPassenger.seatId = seatId; }