Skip to content

Commit b3423c4

Browse files
authored
feat(core): VGUI (#73)
In this PR we'll add VGUI to Swiftly and allow developers to create hud texts and much more!
2 parents c65e71d + 2cb016e commit b3423c4

File tree

31 files changed

+1162
-72
lines changed

31 files changed

+1162
-72
lines changed

AMBuilder

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ for sdk_target in MMSPlugin.sdk_targets:
4949
"-Wno-array-bounds",
5050
"-Wno-int-to-pointer-cast",
5151
"-Wno-sign-compare",
52+
"-Wno-write-strings",
5253
"-fexceptions",
5354
]
5455
binary.compiler.cflags += [
@@ -58,6 +59,7 @@ for sdk_target in MMSPlugin.sdk_targets:
5859
"-Wno-array-bounds",
5960
"-Wno-int-to-pointer-cast",
6061
"-Wno-sign-compare",
62+
"-Wno-write-strings",
6163
"-fexceptions",
6264
]
6365
binary.compiler.postlink += [

plugin_files/translations/translation.core.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,15 @@
6060
"de": "Beenden"
6161
},
6262
"menu.footer": {
63-
"en": "{CYCLE_BUTTON} - Cycle | {USE_BUTTON} - Select | Page {PAGE}/{MAXPAGES}",
64-
"ro": "{CYCLE_BUTTON} - Schimbă | {USE_BUTTON} - Selectează | Pagina {PAGE}/{MAXPAGES}",
65-
"pl": "{CYCLE_BUTTON} - Przeglądaj | {USE_BUTTON} - Wybierz | Strona {PAGE}/{MAXPAGES}",
66-
"de": "{CYCLE_BUTTON} - Durchblättern | {USE_BUTTON} - Auswählen | Seite {PAGE}/{MAXPAGES}"
63+
"en": "{CYCLE_BUTTON} - Cycle | {USE_BUTTON} - Select\nPage {PAGE}/{MAXPAGES}",
64+
"ro": "{CYCLE_BUTTON} - Schimbă | {USE_BUTTON} - Selectează\nPagina {PAGE}/{MAXPAGES}",
65+
"pl": "{CYCLE_BUTTON} - Przeglądaj | {USE_BUTTON} - Wybierz\nStrona {PAGE}/{MAXPAGES}",
66+
"de": "{CYCLE_BUTTON} - Durchblättern | {USE_BUTTON} - Auswählen\nSeite {PAGE}/{MAXPAGES}"
6767
},
6868
"menu.footer.nooption": {
69-
"en": "{CYCLE_BUTTON} - Cycle | {USE_BUTTON} - Select | {EXIT_BUTTON} - Exit | Page {PAGE}/{MAXPAGES}",
70-
"ro": "{CYCLE_BUTTON} - Schimbă | {USE_BUTTON} - Selectează | {EXIT_BUTTON} - Ieșire | Pagina {PAGE}/{MAXPAGES}",
71-
"pl": "{CYCLE_BUTTON} - Przeglądaj | {USE_BUTTON} - Wybierz | {EXIT_BUTTON} - Wyjście | Strona {PAGE}/{MAXPAGES}",
72-
"de": "{CYCLE_BUTTON} - Durchblättern | {USE_BUTTON} - Auswählen | {EXIT_BUTTON} - Beenden | Seite {PAGE}/{MAXPAGES}"
69+
"en": "{CYCLE_BUTTON} - Cycle | {USE_BUTTON} - Select\n{EXIT_BUTTON} - Exit | Page {PAGE}/{MAXPAGES}",
70+
"ro": "{CYCLE_BUTTON} - Schimbă | {USE_BUTTON} - Selectează\n{EXIT_BUTTON} - Ieșire | Pagina {PAGE}/{MAXPAGES}",
71+
"pl": "{CYCLE_BUTTON} - Przeglądaj | {USE_BUTTON} - Wybierz\n{EXIT_BUTTON} - Wyjście | Strona {PAGE}/{MAXPAGES}",
72+
"de": "{CYCLE_BUTTON} - Durchblättern | {USE_BUTTON} - Auswählen\n{EXIT_BUTTON} - Beenden | Seite {PAGE}/{MAXPAGES}"
7373
}
7474
}

src/core/commands.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,7 @@ void SwiftlyCommand(const CCommandContext& context, const CCommand& args)
841841
SwiftlyResourceMonitorManager(slot, context, args[2], args[3]);
842842
else if (subcmd == "status")
843843
SwiftlyStatus(slot, context);
844-
else if(subcmd == "chat")
844+
else if (subcmd == "chat")
845845
SwiftlyChatManager(slot, context, args[2]);
846846
else
847847
ShowSwiftlyCommandHelp(slot, context);

src/engine/gameevents/gameevents.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "../../plugins/PluginManager.h"
77
#include "../../player/playermanager/PlayerManager.h"
88
#include "../../vendor/dynlib/module.h"
9+
#include "../vgui/VGUI.h"
910

1011
#include <rapidjson/document.h>
1112
#include <rapidjson/error/en.h>
@@ -57,6 +58,10 @@ void EventManager::RegisterGameEvents()
5758
if (!g_gameEventManager->FindListener(this, ev.c_str()))
5859
g_gameEventManager->AddListener(this, ev.c_str(), true);
5960
}
61+
62+
if (!g_gameEventManager->FindListener(this, "player_spawn"))
63+
g_gameEventManager->AddListener(this, "player_spawn", true);
64+
6065
PLUGIN_PRINT("Game Events", "Game events have been succesfully loaded.\n");
6166
loadedGameEvents = true;
6267
}
@@ -125,8 +130,10 @@ bool EventManager::OnFireEvent(IGameEvent* pEvent, bool bDontBroadcast)
125130
{
126131
auto slot = pEvent->GetPlayerSlot("userid");
127132
Player* player = g_playerManager->GetPlayer(slot);
128-
if (player)
133+
if (player) {
129134
player->SetFirstSpawn(false);
135+
player->EnsureCustomView(1);
136+
}
130137
}
131138
if (result != EventResult::Continue)
132139
{
@@ -140,6 +147,8 @@ bool EventManager::OnFireEvent(IGameEvent* pEvent, bool bDontBroadcast)
140147
RETURN_META_VALUE(MRES_IGNORED, true);
141148
}
142149

150+
void RegisterTimeout(int64_t delay, std::function<void()> cb);
151+
143152
bool EventManager::OnPostFireEvent(IGameEvent* pEvent, bool bDontBroadcast)
144153
{
145154
if (!pEvent)
@@ -152,6 +161,14 @@ bool EventManager::OnPostFireEvent(IGameEvent* pEvent, bool bDontBroadcast)
152161
std::string eventName = realGameEvent->GetName();
153162

154163
std::string prettyEventName = gameEventsRegister[eventName];
164+
165+
if(prettyEventName == "OnRoundStart") {
166+
RegisterTimeout(100, []() -> void {
167+
g_pVGUI->RegenerateScreenPanels();
168+
g_pVGUI->RegenerateScreenTexts();
169+
});
170+
}
171+
155172
if (!prettyEventName.empty())
156173
{
157174
PluginEvent* event = new PluginEvent("core", realGameEvent, nullptr);

src/engine/vgui/ScreenPanel.cpp

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#include "ScreenPanel.h"
2+
3+
ScreenPanel::ScreenPanel()
4+
{
5+
}
6+
7+
ScreenPanel::~ScreenPanel()
8+
{
9+
if(pScreenEntity.IsValid()) {
10+
pScreenEntity->Despawn();
11+
}
12+
}
13+
14+
void ScreenPanel::Create(Color color, int size)
15+
{
16+
m_col = color;
17+
m_size = size;
18+
19+
pScreenEntity.Set((CPointWorldText*)(CreateEntityByName("point_worldtext").GetPtr()));
20+
if(!pScreenEntity) return;
21+
22+
CEntityKeyValues* pMenuKV = new CEntityKeyValues();
23+
24+
pMenuKV->SetBool("enabled", false);
25+
pMenuKV->SetFloat("world_units_per_pixel", (0.25 / 300) * size);
26+
pMenuKV->SetInt("justify_horizontal", 0);
27+
pMenuKV->SetInt("justify_vertical", 2);
28+
pMenuKV->SetInt("reorient_mode", 0);
29+
pMenuKV->SetInt("fullbright", 1);
30+
pMenuKV->SetFloat("font_size", size);
31+
pMenuKV->SetColor("color", color);
32+
33+
pScreenEntity->DispatchSpawn(pMenuKV);
34+
}
35+
36+
void ScreenPanel::SetupViewForPlayer(Player* player)
37+
{
38+
m_player = player;
39+
40+
if(!pScreenEntity) return;
41+
if(!player) return;
42+
if(player->IsFakeClient()) return;
43+
44+
CBaseViewModel* pViewModel = player->EnsureCustomView(1);
45+
if(!pViewModel) return;
46+
47+
pScreenEntity->SetParent(pViewModel);
48+
pScreenEntity->m_hOwnerEntity(pViewModel->GetRefEHandle());
49+
}
50+
51+
void ScreenPanel::SetText(std::string text)
52+
{
53+
m_text = text;
54+
55+
if(!pScreenEntity) return;
56+
57+
pScreenEntity->SetText(m_text.c_str());
58+
pScreenEntity->Enable();
59+
}
60+
61+
void ScreenPanel::SetPosition(float posX, float posY)
62+
{
63+
m_posX = posX;
64+
m_posY = posY;
65+
66+
if(!m_player) return;
67+
if(m_player->IsFakeClient()) return;
68+
69+
CCSPlayerPawn* pawn = m_player->GetPlayerPawn();
70+
if(!pawn) return;
71+
if(pawn->m_lifeState() == 2) {
72+
if(m_player->GetPlayerController()->m_bControllingBot()) {
73+
return;
74+
} else {
75+
auto pPawn = m_player->GetPawn();
76+
if(!pPawn) return;
77+
78+
auto observerPawn = pPawn->m_pObserverServices->m_hObserverTarget();
79+
if(!observerPawn) return;
80+
81+
auto observerController = ((CCSPlayerPawn*)(observerPawn.Get()))->m_hOriginalController();
82+
if(!observerController) return;
83+
84+
auto observer = g_playerManager->GetPlayer(observerController->entindex() - 1);
85+
if(!observer) return;
86+
pawn = observer->GetPlayerPawn();
87+
}
88+
}
89+
if(!pawn) return;
90+
91+
QAngle eyeAngles = pawn->m_angEyeAngles();
92+
Vector fwd, right, up;
93+
AngleVectors(eyeAngles, &fwd, &right, &up);
94+
95+
Vector eyePos(0.0, 0.0, 0.0);
96+
eyePos += fwd * 7.12;
97+
eyePos += right * (-9.3 + (posX * 18.66));
98+
eyePos += up * (-4.82 + (posY * 10.47));
99+
100+
QAngle ang(0, eyeAngles.y + 270, 90 - eyeAngles.x);
101+
102+
eyePos += pawn->m_CBodyComponent->m_pSceneNode->m_vecAbsOrigin() + Vector(0, 0, pawn->m_vecViewOffset->m_vecZ());
103+
104+
pScreenEntity->Teleport(&eyePos, &ang, nullptr);
105+
}
106+
107+
bool ScreenPanel::IsValidEntity()
108+
{
109+
return pScreenEntity.IsValid();
110+
}
111+
112+
void ScreenPanel::RegeneratePanel(bool recreate)
113+
{
114+
if(recreate) {
115+
if(pScreenEntity.IsValid()) pScreenEntity->Despawn();
116+
117+
Create(m_col, m_size);
118+
SetupViewForPlayer(m_player);
119+
SetText(m_text);
120+
SetPosition(m_posX, m_posY);
121+
} else {
122+
SetupViewForPlayer(m_player);
123+
SetPosition(m_posX, m_posY);
124+
}
125+
}
126+
127+
Player* ScreenPanel::GetPlayer()
128+
{
129+
return m_player;
130+
}
131+
132+
int ScreenPanel::GetEntityIndex()
133+
{
134+
if(!pScreenEntity) return 0;
135+
136+
return pScreenEntity->GetEntityIndex().Get();
137+
}
138+
139+
bool ScreenPanel::IsRenderingTo(CHandle<CBaseEntity> renderingTo)
140+
{
141+
return renderingTo == pRenderingTo;
142+
}
143+
144+
void ScreenPanel::SetRenderingTo(CBaseEntity* ent)
145+
{
146+
pRenderingTo.Set(ent);
147+
}

src/engine/vgui/ScreenPanel.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#ifndef _engine_vgui_screenpanel_h
2+
#define _engine_vgui_screenpanel_h
3+
4+
#include <string>
5+
#include "../../plugins/core/scripting.h"
6+
#include "../../player/playermanager/PlayerManager.h"
7+
8+
#include <public/entity2/entitykeyvalues.h>
9+
#include "../../sdk/entity/CPointWorldText.h"
10+
#include "../../sdk/entity/CBaseViewModel.h"
11+
12+
class ScreenPanel
13+
{
14+
private:
15+
CHandle<CPointWorldText> pScreenEntity;
16+
CHandle<CBaseEntity> pRenderingTo;
17+
18+
Color m_col;
19+
int m_size;
20+
Player* m_player;
21+
float m_posX;
22+
float m_posY;
23+
std::string m_text;
24+
25+
public:
26+
ScreenPanel();
27+
~ScreenPanel();
28+
29+
void Create(Color color, int size = 75);
30+
void SetupViewForPlayer(Player* player);
31+
void SetText(std::string text);
32+
void SetPosition(float posX = 0.0, float posY = 0.0);
33+
void SetRenderingTo(CBaseEntity* ent);
34+
void RegeneratePanel(bool recreate = true);
35+
36+
bool IsValidEntity();
37+
Player* GetPlayer();
38+
int GetEntityIndex();
39+
bool IsRenderingTo(CHandle<CBaseEntity> renderingTo);
40+
};
41+
42+
#endif

0 commit comments

Comments
 (0)