Skip to content

Commit 03c4197

Browse files
committed
Release 0.1.0
2 parents cf67f7c + 68411a9 commit 03c4197

File tree

13 files changed

+579
-2
lines changed

13 files changed

+579
-2
lines changed

README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,22 @@
11
# Class manager
22

3-
Allows you to perform various operations on player classes
3+
Allows you to perform various operations on player classes:
4+
5+
* Enable class
6+
* Disable class
7+
* Set class limit
8+
9+
Each action can be applied to:
10+
11+
* Allies team
12+
* Axis team
13+
* Both teams
14+
15+
### Supported Games
16+
17+
* Day of Defeat: Source
18+
19+
### Installation
20+
21+
* Download latest [release](https://github.com/dronelektron/class-manager/releases) (compiled for SourceMod 1.10)
22+
* Extract "plugins" and "translations" folders to "addons/sourcemod" folder of your server

build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
PLUGIN_NAME="class-manager"
44

5-
spcomp scripting/$PLUGIN_NAME.sp -o plugins/$PLUGIN_NAME.smx
5+
spcomp scripting/$PLUGIN_NAME.sp scripting/modules/*.sp -i scripting/include -o plugins/$PLUGIN_NAME.smx

scripting/class-manager.sp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
#include <sourcemod>
2+
#undef REQUIRE_PLUGIN
3+
#include <adminmenu>
4+
5+
#pragma semicolon 1
6+
#pragma newdecls required
7+
8+
#include "class"
9+
#include "team"
10+
#include "message"
11+
#include "menu"
212

313
public Plugin myinfo = {
414
name = "Class manager",
@@ -7,3 +17,35 @@ public Plugin myinfo = {
717
version = "0.1.0",
818
url = ""
919
}
20+
21+
char ADMIN_MENU[] = "adminmenu";
22+
TopMenu g_adminMenu = null;
23+
24+
public void OnPluginStart() {
25+
FindClassLimitConVars();
26+
LoadTranslations("class-manager.phrases");
27+
28+
TopMenu topMenu;
29+
30+
if (LibraryExists(ADMIN_MENU) && (topMenu = GetAdminTopMenu()) != null) {
31+
OnAdminMenuReady(topMenu);
32+
}
33+
}
34+
35+
public void OnLibraryRemoved(const char[] name) {
36+
if (StrEqual(name, ADMIN_MENU, false)) {
37+
g_adminMenu = null;
38+
}
39+
}
40+
41+
public void OnAdminMenuReady(Handle aTopMenu) {
42+
TopMenu topMenu = TopMenu.FromHandle(aTopMenu);
43+
44+
if (topMenu == g_adminMenu) {
45+
return;
46+
}
47+
48+
g_adminMenu = topMenu;
49+
50+
AddClassManagerToAdminMenu();
51+
}

scripting/include/class.inc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#if defined _class_included
2+
#endinput
3+
#endif
4+
#define _class_included
5+
6+
enum {
7+
Class_Unknown = -1,
8+
Class_Rifleman,
9+
Class_Assault,
10+
Class_Support,
11+
Class_Sniper,
12+
Class_Mg,
13+
Class_Rocket
14+
}

scripting/include/menu.inc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#if defined _menu_included
2+
#endinput
3+
#endif
4+
#define _menu_included
5+
6+
#define TEXT_BUFFER_MAX_SIZE 1024
7+
8+
#define CLASS_MANAGER "Class manager"
9+
#define RIFLEMAN "Rifleman"
10+
#define ASSAULT "Assault"
11+
#define SUPPORT "Support"
12+
#define SNIPER "Sniper"
13+
#define MG "Mg"
14+
#define ROCKET "Rocket"
15+
#define SELECT_ACTION "Select action"
16+
#define ENABLE_CLASS "Enable class"
17+
#define DISABLE_CLASS "Disable class"
18+
#define SET_CLASS_LIMIT "Set class limit"
19+
#define SELECT_TEAM "Select team"
20+
#define ALLIES "Allies"
21+
#define AXIS "Axis"
22+
#define BOTH_TEAMS "Both teams"

scripting/include/message.inc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#if defined _message_included
2+
#endinput
3+
#endif
4+
#define _message_included
5+
6+
#define PREFIX "[Class manager] "

scripting/include/team.inc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#if defined _team_included
2+
#endinput
3+
#endif
4+
#define _team_included
5+
6+
enum {
7+
Team_Unassigned = 0,
8+
Team_Spectator,
9+
Team_Allies,
10+
Team_Axis
11+
}

scripting/modules/convar.sp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
static char g_limitAlliesConVarNames[][] = {
2+
"mp_limit_allies_rifleman",
3+
"mp_limit_allies_assault",
4+
"mp_limit_allies_support",
5+
"mp_limit_allies_sniper",
6+
"mp_limit_allies_mg",
7+
"mp_limit_allies_rocket"
8+
};
9+
10+
static char g_limitAxisConVarNames[][] = {
11+
"mp_limit_axis_rifleman",
12+
"mp_limit_axis_assault",
13+
"mp_limit_axis_support",
14+
"mp_limit_axis_sniper",
15+
"mp_limit_axis_mg",
16+
"mp_limit_axis_rocket"
17+
};
18+
19+
static ConVar g_limitAlliesConVars[Class_Rocket + 1] = {null, ...};
20+
static ConVar g_limitAxisConVars[Class_Rocket + 1] = {null, ...};
21+
22+
void FindClassLimitConVars() {
23+
for (int i = Class_Rifleman; i <= Class_Rocket; i++) {
24+
g_limitAlliesConVars[i] = FindConVar(g_limitAlliesConVarNames[i]);
25+
g_limitAxisConVars[i] = FindConVar(g_limitAxisConVarNames[i]);
26+
27+
g_limitAlliesConVars[i].AddChangeHook(ConVarChanged_ClassLimit);
28+
g_limitAxisConVars[i].AddChangeHook(ConVarChanged_ClassLimit);
29+
}
30+
}
31+
32+
void ConVarChanged_ClassLimit(ConVar conVar, char[] oldValue, char[] newValue) {
33+
int team;
34+
int class;
35+
int limit = StringToInt(newValue);
36+
37+
GetConVarTeamAndClass(conVar, team, class);
38+
NotifyAboutClassLimitChange(team, class, limit);
39+
MovePlayersToSpectator(team, class, limit);
40+
}
41+
42+
void GetConVarTeamAndClass(ConVar conVar, int& team, int& class) {
43+
team = Team_Unassigned;
44+
class = Class_Unknown;
45+
46+
for (int i = Class_Rifleman; i <= Class_Rocket; i++) {
47+
if (conVar == g_limitAlliesConVars[i]) {
48+
team = Team_Allies;
49+
class = i;
50+
51+
break;
52+
}
53+
54+
if (conVar == g_limitAxisConVars[i]) {
55+
team = Team_Axis;
56+
class = i;
57+
58+
break;
59+
}
60+
}
61+
}
62+
63+
void SetConVarValue(int team, int class, int limit) {
64+
if (team == Team_Allies) {
65+
g_limitAlliesConVars[class].SetInt(limit);
66+
} else if (team == Team_Axis) {
67+
g_limitAxisConVars[class].SetInt(limit);
68+
}
69+
}

scripting/modules/menu.sp

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
static TopMenuObject g_classManagerCategory = INVALID_TOPMENUOBJECT;
2+
static TopMenuObject g_menuItemClasses[Class_Rocket + 1] = {INVALID_TOPMENUOBJECT, ...};
3+
4+
static int g_selectedClass[MAXPLAYERS + 1] = {Class_Unknown, ...};
5+
static int g_selectedLimit[MAXPLAYERS + 1] = {-1, ...};
6+
7+
static char teamNames[][] = {ALLIES, AXIS};
8+
static char classNames[][] = {RIFLEMAN, ASSAULT, SUPPORT, SNIPER, MG, ROCKET};
9+
10+
void AddClassManagerToAdminMenu() {
11+
g_classManagerCategory = g_adminMenu.AddCategory(CLASS_MANAGER, TopMenuHandler_ClassManager);
12+
13+
if (g_classManagerCategory == INVALID_TOPMENUOBJECT) {
14+
return;
15+
}
16+
17+
for (int class = Class_Rifleman; class <= Class_Rocket; class++) {
18+
g_menuItemClasses[class] = g_adminMenu.AddItem(classNames[class], TopMenuHandler_ClassManager, g_classManagerCategory);
19+
}
20+
}
21+
22+
public void TopMenuHandler_ClassManager(TopMenu topmenu, TopMenuAction action, TopMenuObject topobj_id, int param, char[] buffer, int maxlength) {
23+
if (action == TopMenuAction_DisplayOption) {
24+
if (topobj_id == g_classManagerCategory) {
25+
Format(buffer, maxlength, "%T", CLASS_MANAGER, param);
26+
27+
return;
28+
}
29+
30+
for (int class = Class_Rifleman; class <= Class_Rocket; class++) {
31+
if (topobj_id == g_menuItemClasses[class]) {
32+
Format(buffer, maxlength, "%T", classNames[class], param);
33+
34+
break;
35+
}
36+
}
37+
} else if (action == TopMenuAction_DisplayTitle) {
38+
if (topobj_id == g_classManagerCategory) {
39+
Format(buffer, maxlength, "%T", CLASS_MANAGER, param);
40+
}
41+
} else if (action == TopMenuAction_SelectOption) {
42+
for (int class = Class_Rifleman; class <= Class_Rocket; class++) {
43+
if (topobj_id == g_menuItemClasses[class]) {
44+
g_selectedClass[param] = class;
45+
CreateClassActionMenu(param);
46+
47+
break;
48+
}
49+
}
50+
}
51+
}
52+
53+
void CreateClassActionMenu(int client) {
54+
Menu menu = new Menu(MenuHandler_ClassAction);
55+
56+
menu.SetTitle("%T", SELECT_ACTION, client);
57+
58+
AddTranslatedMenuItem(menu, ENABLE_CLASS, ENABLE_CLASS, client);
59+
AddTranslatedMenuItem(menu, DISABLE_CLASS, DISABLE_CLASS, client);
60+
AddTranslatedMenuItem(menu, SET_CLASS_LIMIT, SET_CLASS_LIMIT, client);
61+
62+
menu.ExitBackButton = true;
63+
menu.Display(client, MENU_TIME_FOREVER);
64+
}
65+
66+
int MenuHandler_ClassAction(Menu menu, MenuAction action, int param1, int param2) {
67+
if (action == MenuAction_Select) {
68+
char info[TEXT_BUFFER_MAX_SIZE];
69+
70+
menu.GetItem(param2, info, sizeof(info));
71+
72+
if (StrEqual(info, ENABLE_CLASS)) {
73+
g_selectedLimit[param1] = -1;
74+
75+
CreateTeamMenu(param1);
76+
} else if (StrEqual(info, DISABLE_CLASS)) {
77+
g_selectedLimit[param1] = 0;
78+
79+
CreateTeamMenu(param1);
80+
} else if (StrEqual(info, SET_CLASS_LIMIT)) {
81+
CreateClassLimitMenu(param1);
82+
}
83+
} else {
84+
MenuHandler_Default(menu, action, param1, param2);
85+
}
86+
87+
return 0;
88+
}
89+
90+
void CreateClassLimitMenu(int client) {
91+
Menu menu = new Menu(MenuHandler_ClassLimit);
92+
char info[TEXT_BUFFER_MAX_SIZE];
93+
94+
menu.SetTitle("%T", SET_CLASS_LIMIT, client);
95+
96+
for (int i = 1; i <= MaxClients; i++) {
97+
IntToString(i, info, sizeof(info));
98+
99+
menu.AddItem(info, info);
100+
}
101+
102+
menu.ExitBackButton = true;
103+
menu.Display(client, MENU_TIME_FOREVER);
104+
}
105+
106+
int MenuHandler_ClassLimit(Menu menu, MenuAction action, int param1, int param2) {
107+
if (action == MenuAction_Select) {
108+
char info[TEXT_BUFFER_MAX_SIZE];
109+
110+
menu.GetItem(param2, info, sizeof(info));
111+
g_selectedLimit[param1] = StringToInt(info);
112+
113+
CreateTeamMenu(param1);
114+
} else {
115+
MenuHandler_Default(menu, action, param1, param2);
116+
}
117+
118+
return 0;
119+
}
120+
121+
void CreateTeamMenu(int client) {
122+
Menu menu = new Menu(MenuHandler_TeamAction);
123+
124+
menu.SetTitle("%T", "Select team", client);
125+
126+
AddTranslatedMenuItem(menu, ALLIES, ALLIES, client);
127+
AddTranslatedMenuItem(menu, AXIS, AXIS, client);
128+
AddTranslatedMenuItem(menu, BOTH_TEAMS, BOTH_TEAMS, client);
129+
130+
menu.ExitBackButton = true;
131+
menu.Display(client, MENU_TIME_FOREVER);
132+
}
133+
134+
int MenuHandler_TeamAction(Menu menu, MenuAction action, int param1, int param2) {
135+
if (action == MenuAction_Select) {
136+
char info[TEXT_BUFFER_MAX_SIZE];
137+
int class = g_selectedClass[param1];
138+
int limit = g_selectedLimit[param1];
139+
140+
menu.GetItem(param2, info, sizeof(info));
141+
142+
if (StrEqual(info, ALLIES)) {
143+
SetConVarValue(Team_Allies, class, limit);
144+
} else if (StrEqual(info, AXIS)) {
145+
SetConVarValue(Team_Axis, class, limit);
146+
} else if (StrEqual(info, BOTH_TEAMS)) {
147+
SetConVarValue(Team_Allies, class, limit);
148+
SetConVarValue(Team_Axis, class, limit);
149+
}
150+
} else {
151+
MenuHandler_Default(menu, action, param1, param2);
152+
}
153+
154+
return 0;
155+
}
156+
157+
void MenuHandler_Default(Menu menu, MenuAction action, int param1, int param2) {
158+
if (action == MenuAction_End) {
159+
delete menu;
160+
} else if (action == MenuAction_Cancel) {
161+
if (param2 == MenuCancel_ExitBack && g_adminMenu != null) {
162+
g_adminMenu.Display(param1, TopMenuPosition_LastCategory);
163+
}
164+
}
165+
}
166+
167+
void AddTranslatedMenuItem(Menu menu, char[] info, any ...) {
168+
char item[TEXT_BUFFER_MAX_SIZE];
169+
170+
VFormat(item, sizeof(item), "%T", 3);
171+
172+
menu.AddItem(info, item);
173+
}

scripting/modules/message.sp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
void NotifyAboutClassLimitChange(int team, int class, int limit) {
2+
PrintToChatAll("%s%t", PREFIX, "Class limit was changed", classNames[class], teamNames[team - 2], limit);
3+
}
4+
5+
void NotifyAboutSpectatorTeam(int client) {
6+
PrintToChat(client, "%s%t", PREFIX, "You was moved to spectator team");
7+
}

0 commit comments

Comments
 (0)