]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/t_jumppads.qc
- drop flag when becomming specator
[divverent/nexuiz.git] / data / qcsrc / server / t_jumppads.qc
1 float PUSH_ONCE                 = 1;
2 float PUSH_SILENT               = 2;
3
4 .float pushltime;
5 void() trigger_push_touch =
6 {
7         local float flighttime, dist, grav;
8         local vector org;
9
10         // FIXME: add a .float for whether an entity should be tossed by jumppads
11         if (other.classname != "player")
12         if (other.classname != "corpse")
13         if (other.classname != "body")
14         if (other.classname != "gib")
15         if (other.classname != "missile")
16         if (other.classname != "casing")
17         if (other.classname != "grenade")
18         if (other.classname != "plasma")
19         if (other.classname != "plasma_prim")
20         if (other.classname != "plasma_chain")
21         if (other.classname != "droppedweapon")
22                 return;
23
24         if (other.deadflag && other.classname == "player")
25                 return;
26
27         if (!self.target)
28         {
29                 other.velocity = self.movedir;
30                 other.flags = other.flags - (other.flags & FL_ONGROUND);
31                 return;
32         }
33
34         org = other.origin;
35
36         if (other.classname == "player")
37         {
38                 local float i;
39                 local float found;
40                 if(self.pushltime < time)  // prevent "snorring" sound when a player hits the jumppad more than once
41                 {
42                         sound (other, CHAN_ITEM, "misc/jumppad.ogg", 1, ATTN_NORM);
43                         self.pushltime = time + 0.5;
44                 }
45                 found = FALSE;
46                 for(i = 0; i < other.jumppadcount && i < NUM_JUMPPADSUSED; ++i)
47                         if(other.(jumppadsused[i]) == self)
48                                 found = TRUE;
49                 if(!found)
50                 {
51                         other.(jumppadsused[math_mod(other.jumppadcount, NUM_JUMPPADSUSED)]) = self;
52                         other.jumppadcount = other.jumppadcount + 1;
53                 }
54         }
55
56         // figure out how long it will take to hit the point considering gravity
57         grav = cvar("sv_gravity");
58         flighttime = sqrt((self.enemy.origin_z - org_z) / (0.5 * grav));
59         if (!flighttime)
60                 return;
61
62         // how far in X and Y to move
63         self.movedir = (self.enemy.origin - org);
64         self.movedir_z = 0;
65         dist = vlen(self.movedir);
66
67         // finally calculate the velocity
68         self.movedir = normalize(self.movedir) * (dist / flighttime);
69         self.movedir_z = flighttime * grav;
70
71         other.flags = other.flags - (other.flags & FL_ONGROUND);
72         // reset tracking of oldvelocity for impact damage (sudden velocity changes)
73         other.oldvelocity = other.velocity = self.movedir;
74         // reset tracking of who pushed you into a hazard (for kill credit)
75         other.pushltime = 0;
76
77         if (other.classname == "missile")
78                 other.angles = vectoangles (other.velocity);
79
80         if (self.spawnflags & PUSH_ONCE)
81         {
82                 self.touch = SUB_Null;
83                 self.think = SUB_Remove;
84                 self.nextthink = time;
85         }
86 };
87
88 .vector dest;
89
90 void() trigger_push_findtarget =
91 {
92         local entity e;
93         local float grav;
94         local float flighttime;
95         local float dist;
96         local vector org;
97
98         // first calculate a typical start point for the jump
99         org = (self.absmin + self.absmax) * 0.5;
100         org_z = self.absmax_z - PL_MIN_z;
101
102         if (self.target)
103         {
104                 // find the target
105                 self.enemy = find(world, targetname, self.target);
106                 if (!self.enemy)
107                 {
108                         objerror("trigger_push: target not found\n");
109                         remove(self);
110                         return;
111                 }
112
113                 // figure out how long it will take to hit the point considering gravity
114                 grav = cvar("sv_gravity");
115                 flighttime = sqrt((self.enemy.origin_z - org_z) / (0.5 * grav));
116                 if (!flighttime)
117                 {
118                         objerror("trigger_push: jump pad with bad destination\n");
119                         remove(self);
120                         return;
121                 }
122
123                 // how far in X and Y to move
124                 self.movedir = (self.enemy.origin - org);
125                 self.movedir_z = 0;
126                 dist = vlen(self.movedir);
127
128                 // finally calculate the velocity
129                 self.movedir = normalize(self.movedir) * (dist / flighttime);
130                 self.movedir_z = flighttime * grav;
131         }
132         else
133                 flighttime = 0;
134
135         // calculate the destination and spawn a teleporter waypoint
136         e = spawn();
137         setorigin(e, org);
138         setsize(e, PL_MIN, PL_MAX);
139         e.velocity = self.movedir;
140         tracetoss(e, e);
141         self.dest = trace_endpos;
142         remove(e);
143
144         waypoint_spawnforteleporter(self, self.dest, flighttime);
145 };
146
147 void() trigger_push =
148 {
149         if (self.angles != '0 0 0')
150                 SetMovedir ();
151
152         self.solid = SOLID_TRIGGER;
153         setmodel (self, self.model);
154         self.movetype = MOVETYPE_NONE;
155         self.modelindex = 0;
156         self.model = "";
157
158         self.touch = trigger_push_touch;
159
160         // normal push setup
161         if (!self.speed)
162                 self.speed = 1000;
163         self.movedir = self.movedir * self.speed * 10;
164
165         // this must be called to spawn the teleport waypoints for bots
166         self.think = trigger_push_findtarget;
167         self.nextthink = time + 0.2;
168 };
169
170 void() target_push = {};
171 void() info_notnull = {};
172 void() target_position = {};