]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/mutators/mutator/campcheck/campcheck.qc
Merge branch 'master' into TimePath/notifications
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mutators / mutator / campcheck / campcheck.qc
1 #ifdef IMPLEMENTATION
2 float autocvar_g_campcheck_damage;
3 float autocvar_g_campcheck_distance;
4 float autocvar_g_campcheck_interval;
5
6 REGISTER_MUTATOR(campcheck, cvar("g_campcheck"));
7
8 .float campcheck_nextcheck;
9 .float campcheck_traveled_distance;
10
11 MUTATOR_HOOKFUNCTION(campcheck, PlayerDies)
12 {
13         Kill_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CPID_CAMPCHECK);
14         return false;
15 }
16
17 MUTATOR_HOOKFUNCTION(campcheck, PlayerDamage_Calculate)
18 {
19         if(IS_PLAYER(frag_target))
20         if(IS_PLAYER(frag_attacker))
21         if(frag_attacker != frag_target)
22         {
23                 frag_target.campcheck_traveled_distance = autocvar_g_campcheck_distance;
24                 frag_attacker.campcheck_traveled_distance = autocvar_g_campcheck_distance;
25         }
26
27         return false;
28 }
29
30 MUTATOR_HOOKFUNCTION(campcheck, PlayerPreThink)
31 {SELFPARAM();
32         if(!gameover)
33         if(!warmup_stage) // don't consider it camping during warmup?
34         if(time >= game_starttime)
35         if(IS_PLAYER(self))
36         if(IS_REAL_CLIENT(self)) // bots may camp, but that's no reason to constantly kill them
37         if(!IS_DEAD(self))
38         if(!STAT(FROZEN, self))
39         if(!PHYS_INPUT_BUTTON_CHAT(self))
40         if(autocvar_g_campcheck_interval)
41         {
42                 vector dist;
43
44                 // calculate player movement (in 2 dimensions only, so jumping on one spot doesn't count as movement)
45                 dist = self.prevorigin - self.origin;
46                 dist.z = 0;
47                 self.campcheck_traveled_distance += fabs(vlen(dist));
48
49                 if((autocvar_g_campaign && !campaign_bots_may_start) || (time < game_starttime) || (round_handler_IsActive() && !round_handler_IsRoundStarted()))
50                 {
51                         self.campcheck_nextcheck = time + autocvar_g_campcheck_interval * 2;
52                         self.campcheck_traveled_distance = 0;
53                 }
54
55                 if(time > self.campcheck_nextcheck)
56                 {
57                         if(self.campcheck_traveled_distance < autocvar_g_campcheck_distance)
58                         {
59                                 Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_CAMPCHECK);
60                                 if(self.vehicle)
61                                         Damage(self.vehicle, self, self, autocvar_g_campcheck_damage * 2, DEATH_CAMP.m_id, self.vehicle.origin, '0 0 0');
62                                 else
63                                         Damage(self, self, self, bound(0, autocvar_g_campcheck_damage, self.health + self.armorvalue * autocvar_g_balance_armor_blockpercent + 5), DEATH_CAMP.m_id, self.origin, '0 0 0');
64                         }
65                         self.campcheck_nextcheck = time + autocvar_g_campcheck_interval;
66                         self.campcheck_traveled_distance = 0;
67                 }
68
69                 return false;
70         }
71
72         self.campcheck_nextcheck = time + autocvar_g_campcheck_interval; // one of the above checks failed, so keep the timer up to date
73         return false;
74 }
75
76 MUTATOR_HOOKFUNCTION(campcheck, PlayerSpawn)
77 {SELFPARAM();
78         self.campcheck_nextcheck = time + autocvar_g_campcheck_interval * 2;
79         self.campcheck_traveled_distance = 0;
80
81         return false;
82 }
83
84 MUTATOR_HOOKFUNCTION(campcheck, BuildMutatorsString)
85 {
86         ret_string = strcat(ret_string, ":CampCheck");
87         return false;
88 }
89 #endif