]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/mutators/mutator_spawnsystem.qc
89455b081d73d76f64794b4451bd888c936402f2
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / mutator_spawnsystem.qc
1 .float spawnsys_timer;
2 .vector spawnsys_deathloc;
3
4 MUTATOR_HOOKFUNCTION(spawn_PlayerDies)
5 {
6         self.spawnsys_deathloc = self.origin;
7         
8         return FALSE;
9 }
10
11 MUTATOR_HOOKFUNCTION(spawn_PlayerSpawn)
12 {
13         if(autocvar_g_spawnsystem_delay_death)
14                 self.spawnsys_timer = time + autocvar_g_spawnsystem_delay_death;
15
16         if not(autocvar_g_spawnsystem)
17                 return FALSE;
18
19         entity team_mate, best_mate = world;
20         vector best_spot = '0 0 0';
21         float pc = 0, best_dist = 0, dist = 0;
22         FOR_EACH_PLAYER(team_mate)
23         {
24                 if((autocvar_g_spawnsystem_check_health >= 0 && team_mate.health >= autocvar_g_balance_health_regenstable) || autocvar_g_spawnsystem_check_health == 0)
25                 if(team_mate.deadflag == DEAD_NO)
26                 if(team_mate.spawnsys_timer < time)
27                 if(!IsDifferentTeam(self, team_mate))
28                 if(team_mate.freezetag_frozen == 0)
29                 if(team_mate != self)
30                 {
31                         tracebox(team_mate.origin, PL_MIN, PL_MAX, team_mate.origin - '0 0 100', MOVE_WORLDONLY, team_mate);
32                         if(trace_fraction != 1.0)
33                         if not(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
34                         {
35                                 pc = pointcontents(trace_endpos + '0 0 1');
36                                 if(pc == CONTENT_EMPTY)
37                                 {
38                                         if(vlen(team_mate.velocity) > 5)
39                                                 fixedmakevectors(vectoangles(team_mate.velocity));
40                                         else
41                                                 fixedmakevectors(team_mate.angles);
42
43                                         for(pc = 0; pc != 5; ++pc) // test 5 diffrent spots close to mate
44                                         {
45                                                 switch(pc)
46                                                 {
47                                                         case 0:
48                                                                 tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin + v_right * 128, MOVE_NORMAL, team_mate);
49                                                                 break;
50                                                         case 1:
51                                                                 tracebox(team_mate.origin , PL_MIN, PL_MAX,team_mate.origin - v_right * 128 , MOVE_NORMAL, team_mate);
52                                                                 break;
53                                                         case 2:
54                                                                 tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin + v_right * 64 - v_forward * 64, MOVE_NORMAL, team_mate);
55                                                                 break;
56                                                         case 3:
57                                                                 tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin - v_right * 64 - v_forward * 64, MOVE_NORMAL, team_mate);
58                                                                 break;
59                                                         case 4:
60                                                                 tracebox(team_mate.origin , PL_MIN, PL_MAX, team_mate.origin - v_forward * 128, MOVE_NORMAL, team_mate);
61                                                                 break;
62                                                 }
63
64                                                 if(trace_fraction == 1.0)
65                                                 {
66                                                         traceline(trace_endpos + '0 0 4', trace_endpos - '0 0 100', MOVE_NORMAL, team_mate);
67                                                         if(trace_fraction != 1.0)
68                                                         {
69                                                                 if(autocvar_g_spawnsystem_closetodeath)
70                                                                 {
71                                                                         dist = vlen(trace_endpos - self.spawnsys_deathloc);
72                                                                         if(dist < best_dist || best_dist == 0)
73                                                                         {
74                                                                                 best_dist = dist;
75                                                                                 best_spot = trace_endpos;
76                                                                                 best_mate = team_mate;
77                                                                         }
78                                                                 }
79                                                                 else
80                                                                 {
81                                                                         setorigin(self, trace_endpos);
82                                                                         self.angles = team_mate.angles;
83                                                                         team_mate.spawnsys_timer = time + autocvar_g_spawnsystem_delay;
84                                                                         return 0;
85                                                                 }
86                                                         }
87                                                 }
88                                         }
89                                 }
90                         }
91                 }
92         }
93
94         if(autocvar_g_spawnsystem_closetodeath)
95         if(best_dist)
96         {
97                 setorigin(self, best_spot);
98                 self.angles = best_mate.angles;
99                 self.fixangle = TRUE;
100                 best_mate.spawnsys_timer = time + autocvar_g_spawnsystem_delay;
101         }
102         
103         return FALSE;
104 }
105
106 MUTATOR_DEFINITION(mutator_spawnsystem)
107 {
108         MUTATOR_HOOK(PlayerDies, spawn_PlayerDies, CBC_ORDER_ANY);
109         MUTATOR_HOOK(PlayerSpawn, spawn_PlayerSpawn, CBC_ORDER_ANY);
110
111         return FALSE;
112 }