Merge branch 'Mario/door_rotating_fix' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / gamemodes / sv_rules.qc
1 #include "sv_rules.qh"
2
3 #include <server/spawnpoints.qh>
4 #include <server/teamplay.qh>
5
6 void GameRules_teams(bool value)
7 {
8     if (value) {
9         serverflags |= SERVERFLAG_TEAMPLAY;
10         teamplay = 1;
11         cvar_set("teamplay", "2");  // DP needs this for sending proper getstatus replies.
12         Team_InitTeams();
13         GameRules_spawning_teams(true);
14     } else {
15         serverflags &= ~SERVERFLAG_TEAMPLAY;
16         teamplay = 0;
17         cvar_set("teamplay", "0");  // DP needs this for sending proper getstatus replies.
18         GameRules_spawning_teams(false);
19     }
20 }
21
22 void GameRules_spawning_teams(bool value)
23 {
24     have_team_spawns = value ? -1 : 0;
25 }
26
27 bool _GameRules_score_enabled = true;
28 void GameRules_score_enabled(bool value)
29 {
30     _GameRules_score_enabled = value;
31 }
32
33 bool GameRules_limit_score_initialized;
34 void GameRules_limit_score(int limit)
35 {
36     if (GameRules_limit_score_initialized) return;
37     if (autocvar_g_campaign) return;
38     if (limit < 0) return;
39     cvar_set("fraglimit", ftos(limit));
40     GameRules_limit_score_initialized = true;
41 }
42
43 bool GameRules_limit_lead_initialized;
44 void GameRules_limit_lead(int limit)
45 {
46     if (GameRules_limit_lead_initialized) return;
47     if (autocvar_g_campaign) return;
48     if (limit < 0) return;
49     cvar_set("leadlimit", ftos(limit));
50     GameRules_limit_lead_initialized = true;
51 }
52
53 bool GameRules_limit_time_initialized;
54 void GameRules_limit_time(int limit)
55 {
56     if (GameRules_limit_time_initialized) return;
57     if (autocvar_g_campaign) return;
58     if (limit < 0) return;
59     cvar_set("timelimit", ftos(limit));
60     GameRules_limit_time_initialized = true;
61 }
62
63 bool GameRules_limit_time_qualifying_initialized;
64 void GameRules_limit_time_qualifying(int limit)
65 {
66     if (GameRules_limit_time_qualifying_initialized) return;
67     if (autocvar_g_campaign) return;
68     if (limit < 0) return;
69     cvar_set("g_race_qualifying_timelimit", ftos(limit));
70     GameRules_limit_time_qualifying_initialized = true;
71 }
72
73 void GameRules_limit_fallbacks()
74 {
75     GameRules_limit_score(autocvar_fraglimit_override);
76     GameRules_limit_lead(autocvar_leadlimit_override);
77     GameRules_limit_time(autocvar_timelimit_override);
78 }
79
80 void _GameRules_scoring_begin(int teams, float spprio, float stprio)
81 {
82     ScoreRules_basics(teams, spprio, stprio, _GameRules_score_enabled);
83 }
84 void _GameRules_scoring_field(entity i, string label, int scoreflags)
85 {
86     ScoreInfo_SetLabel_PlayerScore(i, label, scoreflags);
87 }
88 void _GameRules_scoring_field_team(float i, string label, int scoreflags)
89 {
90     ScoreInfo_SetLabel_TeamScore(i, label, scoreflags);
91 }
92 void _GameRules_scoring_end()
93 {
94     ScoreRules_basics_end();
95 }
96
97 .bool m_GameRules_scoring_vip;
98 void GameRules_scoring_vip(entity player, bool value)
99 {
100     player.m_GameRules_scoring_vip = value;
101 }
102 bool GameRules_scoring_is_vip(entity player)
103 {
104     return player.m_GameRules_scoring_vip;
105 }
106
107 // Uses client.float_field to accumulate and consume float score and adds score to the player as int (rounded)
108 // only when at least one unit of score has been accumulated. It works with negative score too
109 // Float scores can't be used as score because they aren't supported by the QC score networking system
110 // and online server browsers (e.g. qstat)
111 float _GameRules_scoring_add_float2int(entity client, entity sp, float value, .float float_field, float score_factor)
112 {
113         client.(float_field) += value;
114         float score_counter = client.(float_field) / score_factor;
115         if (score_counter >= -0.5 && score_counter < 0.5)
116                 return 0;
117
118         // NOTE: this code works for subtracting score too
119         int points = floor(score_counter + 0.5);
120         client.(float_field) -= points * score_factor;
121         if (!points)
122                 return 0;
123         return PlayerScore_Add(client, sp, points);
124 }
125
126 float _GameRules_scoring_add(entity client, entity sp, float value)
127 {
128     return PlayerScore_Add(client, sp, value);
129 }
130 float _GameRules_scoring_add_team(entity client, entity sp, int st, float value)
131 {
132     return PlayerTeamScore_Add(client, sp, st, value);
133 }