]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/vehicles/racer.qc
documented joints
[divverent/nexuiz.git] / data / qcsrc / server / vehicles / racer.qc
1 #define RACER_MIN '-40 -40 0'
2 #define RACER_MAX '40 40 44'
3
4 void racer_exit(float eject);
5 void racer_enter();
6
7 float  jetfromtag_power;
8 float  jetfromtag_normpower;
9 float  jetfromtag_nosolid;
10 vector jetfromtag_origin;
11
12 vector jetfromtag(string tagname,float jet_length,float air_power,float solid_power)
13 {
14     vector force_dir;
15     float  air_frac, solid_frac, air_pwr, solid_pwr;
16
17     jetfromtag_origin = gettaginfo(self,gettagindex(self,tagname));
18     v_forward = normalize(v_forward);
19
20     force_dir = jetfromtag_origin - v_forward * jet_length;
21     traceline(jetfromtag_origin, force_dir, MOVE_NORMAL, self);
22
23     solid_frac = 1 - trace_fraction;
24     air_frac   = trace_fraction;
25
26     if(solid_frac < 0.1)
27         jetfromtag_nosolid += 1;
28
29     solid_pwr = solid_frac * solid_power;
30     air_pwr   = air_frac * air_power;
31
32     jetfromtag_power     = solid_pwr + air_pwr;
33     jetfromtag_normpower = jetfromtag_power / (air_power+solid_power);
34     if(trace_fraction == 1)
35         return v_forward;
36     else
37         return v_forward * (jetfromtag_power + cvar("g_vehicle_racer_power_min"));
38 }
39
40 void racer_align4point(float spring_length,float spring_up,float blendrate)
41 {
42     vector fl_org,fl_force,fr_org,fr_force,bl_org,bl_force,br_org,br_force;
43     vector push_vector,align;
44     float fl_push, fr_push, bl_push, br_push;
45
46     jetfromtag_nosolid = 0;
47
48     fr_force = jetfromtag("tag_engine_fr",spring_length,cvar("g_vehicle_racer_power_air"), cvar("g_vehicle_racer_power_solid"));
49     fr_org   = jetfromtag_origin; fr_push = jetfromtag_normpower;
50
51     fl_force = jetfromtag("tag_engine_fl",spring_length,cvar("g_vehicle_racer_power_air"), cvar("g_vehicle_racer_power_solid"));
52     fl_org   = jetfromtag_origin; fl_push = jetfromtag_normpower;
53
54     br_force = jetfromtag("tag_engine_br",spring_length,cvar("g_vehicle_racer_power_air"), cvar("g_vehicle_racer_power_solid"));
55     br_org   = jetfromtag_origin; br_push = jetfromtag_normpower;
56
57     bl_force = jetfromtag("tag_engine_bl",spring_length,cvar("g_vehicle_racer_power_air"), cvar("g_vehicle_racer_power_solid"));
58     bl_org   = jetfromtag_origin; bl_push = jetfromtag_normpower;
59
60     push_vector = fr_force + fl_force + br_force + bl_force;
61
62     align = align;
63
64     align_x = (fl_push - bl_push);
65     align_x += (fr_push - br_push);
66     align_x *= 360;
67
68     align_z = (fl_push - fr_push);
69     align_z += (bl_push - br_push);
70     align_z *= 360;
71
72     self.angles_x *= 0.96;
73     self.angles_z *= 0.96;
74
75     self.angles_x += align_x * frametime;
76     self.angles_z += align_z * frametime;
77
78     self.velocity =  self.velocity + (push_vector * frametime);
79     self.velocity_z -= sv_gravity * frametime;
80 }
81
82 void racer_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
83 {
84     self.velocity += force;
85 }
86
87 float racer_pplug()
88 {
89     entity player,racer;
90     float ftmp,ftmp2;
91
92
93     player = self;
94     racer = self.vehicle;
95     player.fixangle = FALSE;
96
97     player.BUTTON_ZOOM = 0;
98     player.BUTTON_CROUCH = 0;
99
100     self = racer;
101
102     if(player.BUTTON_USE)
103     {
104         self = racer;
105         racer_exit(0);
106         self = player;
107         return 0;
108     }
109
110     racer.angles_x *= -1;
111     makevectors(racer.angles);
112     racer.angles_x *= -1;
113
114     // Turn Body
115     ftmp = cvar("g_vehicle_racer_turnspeed") / server_fps;
116     ftmp2 = ftmp * -1;
117
118     ftmp = bound(ftmp2,shortangle_f(player.v_angle_y - racer.angles_y,racer.angles_y),ftmp);
119
120     {
121         racer.angles_y = safeangle(racer.angles_y + ftmp);
122         if(player.BUTTON_JUMP)
123         {
124             player.BUTTON_JUMP = 0;
125             racer.velocity  = racer.velocity  + v_forward * 250 + v_up * 600;
126         }
127         else
128         {
129             if(vlen(player.movement) == 0)
130             {
131                 self = racer;
132                 ftmp = self.velocity_z;
133                 self.velocity = self.velocity - self.velocity * cvar("g_vehicle_racer_speed_stop");
134                 self.velocity_z = ftmp;
135             }
136             else
137             {
138
139                 if(player.movement_x != 0)
140                 {
141                     if(player.movement_x > 0)
142                         player.movement_x = 1;
143                     else if(player.movement_x < 0)
144                         player.movement_x = -1;
145                 }
146
147                 if(player.movement_y != 0)
148                 {
149                     if(player.movement_y < 0)
150                         player.movement_y = -1;
151                     else if(player.movement_y > 0)
152                         player.movement_y = 1;
153                 }
154
155                 self = racer;
156                 self.velocity  = self.velocity + ((v_right * player.movement_y) * cvar("g_vehicle_racer_speed_strafe")) * frametime;
157                 self.velocity  = self.velocity + ((v_forward * player.movement_x) * cvar("g_vehicle_racer_speed_forward")) * frametime;
158             }
159         }
160         self = racer;
161     }
162
163     vector df;
164
165     self = racer;
166
167     df = vlen(self.velocity) * cvar("g_vehicle_racer_downforce") * v_up;
168     self.velocity = self.velocity - df;
169     player.movement = racer.velocity;
170     racer_align4point(cvar("g_vehicle_racer_springlength"),100,cvar("g_vehicle_racer_inert"));
171
172     if(cvar("g_vehicle_racer_drag"))
173         self.velocity  = movelib_dragvec(cvar("g_vehicle_racer_drag"),cvar("g_vehicle_racer_dragexp"));
174
175     self = player;
176     player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
177     setorigin(player,racer.origin + '0 0 32');
178     player.velocity = racer.velocity;
179
180     return 1;
181 }
182
183 void racer_think()
184 {
185     movelib_beak_simple(cvar("g_vehicle_racer_speed_stop"));
186
187     self.nextthink = time;
188 }
189
190 void racer_enter()
191 {
192     self.owner = other;
193     self.owner.angles = self.angles;
194
195     //setattachment(other,self,"");
196     self.nextthink = 0;
197     self.think = SUB_Null;
198     self.owner.takedamage     = DAMAGE_NO;
199     self.owner.solid          = SOLID_NOT;
200     self.owner.movetype       = MOVETYPE_NOCLIP;
201     //setsize(self.owner,spiderbot_MIN,spiderbot_MAX);
202     self.owner.alpha          = -1;
203     self.owner.PlayerPhysplug = racer_pplug;
204     self.owner.vehicle        = self;
205     self.owner.event_damage   = SUB_Null;
206     //self.event_damage         = vehicle_stdproc_damage ;
207     self.colormap             = self.owner.colormap;
208     //self.tur_head.colormap    = self.owner.colormap;
209     //self.vehicle_hudmodel.viewmodelforclient = self.owner;
210     //self.owner.hud            = HUD_SPIDEBOT;
211     //self.owner.vehicle_health = (self.vehicle_health / cvar("g_vehicle_spiderbot_health"));
212     //self.owner.vehicle_shield = (self.vehicle_shield / cvar("g_vehicle_spiderbot_shield"));
213
214     //setorigin(self.owner,self.origin);
215     //setattachment(self.owner,self,"");
216     //setorigin(self.owner,'0 0 0');
217
218     msg_entity = other;
219     WriteByte (MSG_ONE, SVC_SETVIEWPORT);
220     WriteEntity( MSG_ONE, self.vehicle_viewport);
221
222     WriteByte (MSG_ONE, SVC_SETVIEWANGLES);  // 10 = SVC_SETVIEWANGLES
223     WriteAngle(MSG_ONE,  self.angles_x);    // tilt
224     WriteAngle(MSG_ONE,  self.angles_y);    // yaw
225     WriteAngle(MSG_ONE,  0);                // roll
226
227     //self.owner.view_ofs = '0 0 0';
228     //self.tur_head.nodrawtoclient = self.owner;
229 }
230
231 void racer_exit(float eject)
232 {
233     self.velocity = '0 0 0';
234
235     msg_entity = self.owner;
236     WriteByte (MSG_ONE, SVC_SETVIEWPORT);
237     WriteEntity( MSG_ONE, self.owner);
238
239     WriteByte (MSG_ONE, SVC_SETVIEWANGLES);  // 10 = SVC_SETVIEWANGLES
240     WriteAngle(MSG_ONE,  0);                // tilt
241     WriteAngle(MSG_ONE,  self.angles_y);    // yaw
242     WriteAngle(MSG_ONE,  0);                // roll
243
244     self.think = racer_think;
245     self.nextthink = time;
246
247     self.owner.takedamage     = DAMAGE_AIM;
248     self.owner.solid          = SOLID_SLIDEBOX;
249     self.owner.movetype       = MOVETYPE_WALK;
250
251     setsize(self.owner,PL_MIN,PL_MAX);
252
253     self.owner.alpha          = 1;
254     self.owner.PlayerPhysplug = SUB_Null;
255     self.owner.vehicle        = world;
256         self.owner.view_ofs       = PL_VIEW_OFS;
257         self.owner.event_damage   = PlayerDamage;
258         //self.owner.hud            = HUD_NORMAL;
259
260         self.colormap            = 1024;
261         //self.tur_head.colormap = 1024;
262
263         //self.vehicle_hudmodel.viewmodelforclient = self;
264         //self.tur_head.nodrawtoclient             = self;
265     setattachment(self.owner,world,"");
266
267         if(eject)
268         {
269             makevectors(self.angles);
270             setorigin(self.owner,self.origin + v_forward * 100);
271             self.owner.velocity = (v_up + v_forward * 0.25) * 750;
272         }
273         else
274         setorigin(self.owner,self.origin + '0 0 64' - v_forward * 200);
275
276     self.owner = world;
277 }
278
279
280 void racer_touch()
281 {
282     if(self.owner)
283     {
284         if(vlen(self.velocity) == 0)
285             return;
286
287         if(other.classname != "player")
288             return;
289
290         vector a;
291         a = normalize(other.origin - self.origin);
292         a = a - normalize(self.velocity);
293
294         return;
295     }
296
297     if(other.classname != "player")
298         return;
299
300     if(other.deadflag != DEAD_NO)
301         return;
302
303     if(other.vehicle != world)
304         return;
305
306     racer_enter();
307 }
308
309 /*
310 float racer_customizeentityforclient()
311 {
312     if(self.deadflag == DEAD_DEAD)
313         return FALSE;
314
315     return TRUE;
316 }
317 */
318
319 void racer_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force);
320 void racer_spawn()
321 {
322     self.think = racer_think;
323     self.nextthink = time;
324
325     //self.vehicle_health = CCVAR("_health");
326     //self.vehicle_shield = CCVAR("_shield");
327     //self.event_damage = vehicle_stdproc_damage;
328     self.event_damage = racer_damage;
329     //self.iscreature = TRUE;
330     self.scale = 0.5;
331     self.movetype   = MOVETYPE_FLY;
332     self.solid      = SOLID_SLIDEBOX;
333     //self.takedamage = DAMAGE_AIM;
334     self.touch      = racer_touch;
335     //self.alpha = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = 1;
336     self.alpha = 1;
337     //self.tur_head.angles = '0 0 0';
338         //self.colormap = 1024;
339         //self.tur_head.colormap = 1024;
340         self.deadflag    = DEAD_NO;
341     self.bot_attack = TRUE;
342     setorigin(self,self.origin + '0 0 128');
343     setsize(self,RACER_MIN*0.5,RACER_MAX*0.5);
344     setorigin(self,self.tur_aimpos);
345     pointparticles(particleeffectnum("teleport"), self.origin + '0 0 64', '0 0 0', 1);
346 }
347
348 void racer_blowup()
349 {
350     /*
351     sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
352     pointparticles(particleeffectnum("rocket_explode"), findbetterlocation (self.origin, 16), '0 0 0', 1);
353
354     //RadiusDamage (self, self.owner, self.owner.shot_dmg, self.owner.shot_dmg * 0.5, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
355     RadiusDamage (self, self, 250, 15, 250, world, 250, DEATH_TURRET, world);
356
357     self.alpha = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = -1;
358     self.nextthink  = time + 10;
359     self.think      = spiderbot_spawn;
360
361     setorigin(self,self.tur_aimpos);
362     */
363 }
364
365 void racer_die()
366 {
367
368     /*
369     self.health = 0;
370     self.event_damage = SUB_Null;
371     self.iscreature = FALSE;
372     self.solid      = SOLID_NOT;
373     self.takedamage = DAMAGE_NO;
374     self.touch      = SUB_Null;
375     self.nextthink  = time + random() * 2;
376     self.think      = spiderbot_blowup;
377     self.deadflag    = DEAD_DEAD;
378         self.vehicle_hudmodel.viewmodelforclient = self;
379         self.frame = 0;
380         self.tur_head.frame = 0;
381         */
382 }
383
384 void racer_dinit()
385 {
386
387     server_fps = (1 / sys_ticrate);
388
389     /*
390     addstat(STAT_HUD, AS_INT,  hud);
391         addstat(STAT_SPIDERBOT_ROCKETS, AS_INT,   rockets);
392         addstat(STAT_SPIDERBOT_RELOAD,  AS_FLOAT, rockets_reload);
393         addstat(STAT_SPIDERBOT_HEAT,    AS_FLOAT, vehicle_heat);
394         addstat(STAT_SPIDERBOT_HEALTH,  AS_FLOAT, vehicle_health);
395         addstat(STAT_SPIDERBOT_SHIELD,  AS_FLOAT, vehicle_shield);
396         */
397
398     if (self.netname == "")      self.netname     = "Race PoD";
399
400     self.vehicle_viewport = spawn();
401     self.event_damage = racer_damage;
402     //self.gravity = 2;
403     //self.vehicle_hudmodel = spawn();
404     //self.vehicle_flags = VHF_HASSHIELD | VHF_SHIELDREGEN | VHF_HEALTHREGEN;
405     //self.cvar_basename = "g_vehicle_spiderbot";
406
407     setmodel (self.vehicle_viewport, "models/null.md3");
408     setmodel(self,"models/racers/waka.dpm");
409
410     setattachment(self.vehicle_viewport,self,"");
411     //self.tur_head.customizeentityforclient = spiderbot_customizeentityforclient;
412
413     setorigin(self.vehicle_viewport,'-400 0 40');
414     self.tur_aimpos = self.origin;
415     racer_spawn();
416
417     //self.vehicle_die = spiderbot_die;
418     //self.vehicle_exit = spiderbot_exit;
419 }
420
421 void spawnfunc_racer()
422 {
423     g_turrets_common_precash();
424
425     precache_model ( "models/racers/waka.dpm");
426
427     self.think = racer_dinit;
428     self.nextthink = time + 0.5;
429 }