]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/round_handler.qc
Scoreboard: allow showing average scores per round
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / round_handler.qc
1 #include "round_handler.qh"
2
3 #include <common/mapobjects/triggers.qh>
4 #include <common/scores.qh>
5 #include <common/util.qh>
6 #include <server/campaign.qh>
7 #include <server/command/vote.qh>
8 #include <server/world.qh>
9
10 void round_handler_Think(entity this)
11 {
12         if (intermission_running)
13         {
14                 round_handler_Reset(0);
15                 round_handler_Remove();
16                 return;
17         }
18
19         if (time < game_starttime)
20         {
21                 round_handler_Reset(game_starttime);
22                 return;
23         }
24
25         game_stopped = false;
26
27         if (this.wait)
28         {
29                 this.wait = false;
30                 this.cnt = this.count + 1;  // init countdown
31                 round_starttime = time + this.count;
32                 reset_map(false);
33         }
34
35         if (this.cnt > 0)  // countdown running
36         {
37                 if (this.canRoundStart() && !(autocvar_g_campaign && !campaign_bots_may_start))
38                 {
39                         if (this.cnt == this.count + 1) round_starttime = time + this.count;
40                         int f = this.cnt - 1;
41                         if (f == 0)
42                         {
43                                 FOREACH_CLIENT((IS_PLAYER(it) || INGAME(it)), {
44                                         GameRules_scoring_add(it, ROUNDS_PL, 1);
45                                 });
46                                 this.cnt = 0;
47                                 this.round_endtime = (this.round_timelimit) ? time + this.round_timelimit : 0;
48                                 this.nextthink = time;
49                                 rounds_played++;
50                                 if (this.roundStart) this.roundStart();
51                                 return;
52                         }
53                         this.cnt = this.cnt - 1;
54                 }
55                 else
56                 {
57                         round_handler_Reset(0);
58                         round_starttime = -1; // can't start
59                 }
60                 this.nextthink = time + 1;  // canRoundStart every second
61         }
62         else
63         {
64                 if (this.canRoundEnd())
65                 {
66                         // schedule a new round
67                         this.wait = true;
68                         this.nextthink = time + this.delay;
69                 }
70                 else
71                 {
72                         this.nextthink = time;  // canRoundEnd every frame
73                 }
74         }
75 }
76
77 void round_handler_Init(float the_delay, float the_count, float the_round_timelimit)
78 {
79         entity this = round_handler;
80         this.delay = (the_delay > 0) ? the_delay : 0;
81         this.count = fabs(floor(the_count));
82         this.cnt = this.count + 1;
83         this.round_timelimit = (the_round_timelimit > 0) ? the_round_timelimit : 0;
84         round_limit = the_round_timelimit;
85 }
86
87 // NOTE: this is only needed because if round_handler spawns at time 1
88 // game_starttime isn't initialized yet
89 void round_handler_FirstThink(entity this)
90 {
91         round_starttime = max(time, game_starttime) + this.count;
92         setthink(this, round_handler_Think);
93         this.nextthink = max(time, game_starttime);
94 }
95
96 void round_handler_Spawn(bool() canRoundStart_func, bool() canRoundEnd_func, void() roundStart_func)
97 {
98         if (round_handler)
99         {
100                 backtrace("Can't spawn round_handler again!");
101                 return;
102         }
103         entity this = round_handler = new_pure(round_handler);
104
105         setthink(this, round_handler_FirstThink);
106         this.canRoundStart = canRoundStart_func;
107         this.canRoundEnd = canRoundEnd_func;
108         this.roundStart = roundStart_func;
109         this.wait = false;
110         round_handler_Init(5, 5, 180);
111         this.nextthink = time;
112 }
113
114 void round_handler_Reset(float next_think)
115 {
116         entity this = round_handler;
117         this.wait = false;
118         if (this.count)
119                 if (this.cnt < this.count + 1) this.cnt = this.count + 1;
120         this.nextthink = next_think;
121         if (next_think)
122         {
123                 if (next_think <= game_starttime) rounds_played = 0;
124                 round_starttime = next_think + this.count;
125         }
126 }
127
128 void round_handler_Remove()
129 {
130         delete(round_handler);
131         round_handler = NULL;
132 }