1 $frame die1 die2 draw duck duckwalk duckjump duckidle idle
\r
2 $frame jump pain1 pain2 shoot taunt run runbackwards
\r
3 $frame strafeleft straferight dead1 dead2 forwardright
\r
4 $frame forwardleft backright backleft
\r
6 // changes by LordHavoc on 03/29/04 and 03/30/04 at Vermeulen's request
\r
7 // merged player_run and player_stand to player_anim
\r
8 // added death animations to player_anim
\r
9 // can now spawn thrown weapons from anywhere, not just from players
\r
10 // thrown weapons now fade out after 20 seconds
\r
11 // created PlayerGib function
\r
12 // PlayerDie no longer uses hitloc or damage
\r
13 // PlayerDie now supports dying animations as well as gibbing
\r
14 // cleaned up PlayerDie a lot
\r
17 void player_cooloff();
\r
18 void BodyFakePhysics()
\r
20 self.think = BodyFakePhysics;
\r
21 self.nextthink = time;
\r
28 void CopyBody2(float keepvelocity, float testbody)
\r
30 local entity oldself;
\r
31 if (self.effects & EF_NODRAW)
\r
35 self.angles = oldself.angles;
\r
36 self.avelocity = oldself.avelocity;
\r
37 self.classname = "body";
\r
38 self.mass = oldself.mass;
\r
39 self.damageforcescale = oldself.damageforcescale;
\r
40 self.effects = oldself.effects;
\r
41 self.event_damage = oldself.event_damage;
\r
42 self.frame = oldself.frame;
\r
43 self.health = oldself.health;
\r
44 self.model = oldself.model;
\r
45 self.modelindex = oldself.modelindex;
\r
46 self.movetype = oldself.movetype;
\r
47 self.nextthink = oldself.nextthink;
\r
48 self.skin = oldself.skin;
\r
49 self.solid = oldself.solid;
\r
50 self.takedamage = oldself.takedamage;
\r
51 self.think = oldself.think;
\r
52 if (keepvelocity == 1)
\r
53 self.velocity = oldself.velocity;
\r
54 self.fade_time = oldself.fade_time;
\r
55 self.fade_rate = oldself.fade_rate;
\r
56 //self.weapon = oldself.weapon;
\r
57 setorigin(self, oldself.origin);
\r
58 setsize(self, oldself.mins, oldself.maxs);//'-16 -16 -24', '16 16 5');
\r
59 self.oldorigin = oldself.origin;
\r
60 // move any fire burning me to the corpse
\r
61 if(oldself.onfire != world)
\r
63 self.onfire = oldself.onfire; // corpse is now on fire
\r
64 self.onfire.enemy = self; // burn corpse instead of me when I respawn
\r
65 oldself.onfire = world; // I'm not on fire anymore
\r
66 setattachment(self.onfire, self, "");
\r
71 self.armorvalue = oldself.armorvalue;
\r
72 self.think = BodyFakePhysics;
\r
73 self.nextthink = time;
\r
79 void CopyBody(float keepvelocity)
\r
81 CopyBody2(keepvelocity, FALSE);
\r
84 void player_anim (void)
\r
86 if (self.deadflag != DEAD_NO)
\r
88 if (time > self.dead_time)
\r
90 if (self.maxs_z > 5)
\r
91 setsize(self, '-16 -16 -24', '16 16 5');
\r
92 self.frame = self.dead_frame;
\r
95 self.frame = self.die_frame;
\r
99 if (self.is_feigning == 1)
\r
101 self.frame = self.die_frame;
\r
107 if (self.movement_x * self.movement_x + self.movement_y * self.movement_y > 20)
\r
108 self.frame = $duckwalk;
\r
110 self.frame = $duckidle;
\r
112 else if ((self.movement_x * self.movement_x + self.movement_y * self.movement_y) > 20)
\r
114 if (self.movement_x > 0 && self.movement_y == 0)
\r
118 else if (self.movement_x < 0 && self.movement_y == 0)
\r
119 self.frame = $runbackwards;
\r
120 else if (self.movement_x == 0 && self.movement_y > 0)
\r
121 self.frame = $straferight;
\r
122 else if (self.movement_x == 0 && self.movement_y < 0)
\r
123 self.frame = $strafeleft;
\r
124 else if (self.movement_x > 0 && self.movement_y > 0)
\r
125 self.frame = $forwardright;
\r
126 else if (self.movement_x > 0 && self.movement_y < 0)
\r
127 self.frame = $forwardleft;
\r
128 else if (self.movement_x < 0 && self.movement_y > 0)
\r
129 self.frame = $backright;
\r
130 else if (self.movement_x < 0 && self.movement_y < 0)
\r
131 self.frame = $backleft;
\r
135 else if (self.pain_finished > time)
\r
136 self.frame = self.pain_frame;
\r
137 else if (self.attack_finished > time)
\r
138 self.frame = $shoot;
\r
140 self.frame = $idle;
\r
142 if (!(self.flags & FL_ONGROUND))
\r
145 self.frame = $duckwalk;
\r
147 self.frame = $jump;
\r
150 //End change by Supajoe on 11:44 PM EST 11/16/03 (Subject: Player animations)
\r
153 void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
\r
155 local float take, save;
\r
156 te_blood (hitloc, force, damage);
\r
157 // damage resistance (ignore most of the damage from a bullet or similar)
\r
158 damage = max(damage - 5, 1);
\r
159 save = bound(0, damage * 0.6, self.armorvalue);
\r
160 take = bound(0, damage - save, damage);
\r
161 self.armorvalue = self.armorvalue - save;
\r
162 self.health = self.health - take;
\r
163 self.dmg_save = self.dmg_save + save;
\r
164 self.dmg_take = self.dmg_take + take;
\r
165 self.dmg_inflictor = inflictor;
\r
166 if (self.health <= -50)
\r
168 // don't use any animations as a gib
\r
170 self.dead_frame = 0;
\r
171 self.die_frame = 0;
\r
172 // view just above the floor
\r
173 self.view_ofs = '0 0 4';
\r
175 // make a juicy mess
\r
176 te_bloodshower (self.origin + self.mins, self.origin + self.maxs, 800, 1000);
\r
177 te_bloodshower (self.origin + self.mins, self.origin + self.maxs, 400, 1000);
\r
179 // make a meaty mess
\r
180 TossGib (self, "models/gibs/eye.md3", self.origin, self.velocity,0);
\r
181 TossGib (world, "models/gibs/bloodyskull.md3", self.origin, '0 0 600',0);
\r
183 TossGib (world, "models/gibs/gib1.md3", self.origin, self.velocity,0);
\r
184 //TossGib (world, "models/gibs/gib2.md3", self.origin, self.velocity,0);
\r
185 TossGib (world, "models/gibs/gib1.mdl", self.origin, self.velocity,0);
\r
186 //TossGib (world, "models/gibs/gib3.md3", self.origin, self.velocity,0);
\r
187 TossGib (world, "models/gibs/gib2.mdl", self.origin, self.velocity,0);
\r
188 //TossGib (world, "models/gibs/gib4.md3", self.origin, self.velocity,0);
\r
189 TossGib (world, "models/gibs/gib3.mdl", self.origin, self.velocity,0);
\r
191 // these destory on impact
\r
192 TossGib (world, "models/gibs/gib5.md3", self.origin, '-500 0 450',1);
\r
193 //TossGib (world, "models/gibs/gib6.md3", self.origin, '0 500 450',1);
\r
194 TossGib (world, "models/gibs/chunk.mdl", self.origin, '0 -500 450',1);
\r
195 TossGib (world, "models/gibs/chunk.mdl", self.origin, '500 0 450',1);
\r
196 TossGib (world, "models/gibs/chunk.mdl", self.origin, self.velocity,1);
\r
197 TossGib (world, "models/gibs/chunk.mdl", self.origin, '0 0 450',1);
\r
199 sound (trace_ent, CHAN_VOICE, "misc/gib.wav", 1, ATTN_NORM);
\r
204 void PlayerKilled (float unnatural_death, entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
\r
206 if(self.class == CLASS_SPY)
\r
209 // fixes death while reloading glitch
\r
210 inflictor.reload_time = 0;
\r
211 // fixes flash effects staying after death bug
\r
212 self.FlashTime = 0;
\r
213 stuffcmd(inflictor, "v_cshift 0 0 0 0\n");
\r
216 SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.wpn5.weapon);//self.weapon);
\r
217 // print an obituary message
\r
218 Obituary (attacker, self, deathtype);
\r
219 // Drop flag or any carried item
\r
220 TeamFortress_RemoveTimers ();
\r
221 // Make sure corpse cant take tfgoal items
\r
223 // make the corpse upright (not tilted)
\r
227 self.avelocity = '0 0 0';
\r
228 // no weapon when dead
\r
229 self.weaponmodel = "";
\r
231 // view from the floor
\r
232 self.view_ofs = '0 0 -8';
\r
234 self.movetype = MOVETYPE_TOSS;
\r
235 // shootable corpse
\r
236 self.solid = SOLID_CORPSE;
\r
237 // don't stick to the floor
\r
238 self.flags = self.flags - (self.flags & FL_ONGROUND);
\r
240 self.deadflag = DEAD_DYING;
\r
241 // when to allow respawn
\r
242 self.death_time = time + 0.5;
\r
243 // when to switch to the dead_frame
\r
244 self.dead_time = time + 2;
\r
245 if(!unnatural_death)
\r
247 if (random() < 0.5)
\r
249 self.die_frame = $die1;
\r
250 self.dead_frame = $dead1;
\r
254 self.die_frame = $die2;
\r
255 self.dead_frame = $dead2;
\r
260 self.die_frame = $dead2;
\r
261 self.dead_frame = $dead2;
\r
262 if(self.health > -1)
\r
265 // start the animation
\r
267 // set damage function to corpse damage
\r
268 self.event_damage = PlayerCorpseDamage;
\r
269 // call the corpse damage function just in case it wants to gib
\r
270 self.event_damage(inflictor, attacker, 0, deathtype, hitloc, force);
\r
271 // set up to fade out later
\r
272 SUB_SetFade (self, time + 12 + random () * 4, 1);
\r
275 float PlayerShouldDie (entity inflictor, entity attacker, float damage, float deathtype)
\r
277 // returns true if player should die from this source of damage.
\r
278 // If so, don't block this damage in any way
\r
283 if( deathtype == DEATH_FALL
\r
284 || deathtype == DEATH_TELEFRAG
\r
285 || deathtype == DEATH_DROWN
\r
286 || deathtype == DEATH_HURTTRIGGER
\r
287 || deathtype == DEATH_LAVA
\r
288 || deathtype == DEATH_SLIME
\r
289 || deathtype == DEATH_KILL
\r
290 || deathtype == DEATH_CLASSCHANGE
\r
291 // || deathtype == DEATH_BURNING
\r
292 || deathtype == DEATH_LASERGATE
\r
299 void PlayerDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
\r
301 local float take, save, damagearmor;
\r
303 te_blood (hitloc, force, damage);
\r
304 if (self.pain_finished < time) //Don't switch pain sequences like crazy
\r
306 if (random() > 0.5)
\r
307 self.pain_frame = $pain1;
\r
309 self.pain_frame = $pain2;
\r
310 self.pain_finished = time + 0.5; //Supajoe
\r
313 if(self.class == CLASS_MEDIC)
\r
315 if(deathtype == DEATH_BURNING)
\r
316 damage = 0; // being on fire or near burning targets does nothing to medics
\r
317 // the flame thrower, flame rockets, and hotbombs also do minimal damage
\r
318 else if(deathtype == WEP_FLAMER ||
\r
319 deathtype == WEP_ROCKET_INCENDIARY ||
\r
320 deathtype == WEP_HOTBOMBS)
\r
321 damage = damage * cvar("g_balance_class_medic_flame_takedamage");
\r
324 // how much damage to deal to armor
\r
325 damagearmor = bound(0, damage * 0.2 * (self.armorvalue / 50) * cvar("g_balance_armor_takedamage"), self.armorvalue);
\r
326 // how much damage armor blocks
\r
327 save = bound(0, damage * (self.armorvalue / 100) * cvar("g_balance_armor_effectiveness"), damage);
\r
328 // how much damage to deal to player
\r
329 take = bound(0, damage - save, damage);
\r
331 // if being telefragged or killed by a death trigger etc, don't block that
\r
332 if(PlayerShouldDie(inflictor, attacker, damage, deathtype))
\r
335 take = damage; // deal full damage
\r
339 // keep the damage the armor allowed through, and further reduce it if the player is using the shield
\r
340 if(self.class == CLASS_SCOUT)
\r
341 take = SpecialShieldProtect(take);
\r
345 sound (self, CHAN_IMPACT, "misc/armorimpact.wav", 1, ATTN_NORM);
\r
347 sound (self, CHAN_IMPACT, "misc/bodyimpact1.wav", 1, ATTN_NORM);
\r
349 sound (self, CHAN_IMPACT, "misc/bodyimpact2.wav", 1, ATTN_NORM);
\r
352 TossGib (world, "models/gibs/chunk.mdl", hitloc, force * -0.1,1);
\r
354 TossGib (world, "models/gibs/chunk.mdl", hitloc, force * -0.1,1);
\r
356 if (!(self.flags & FL_GODMODE))
\r
358 self.armorvalue = self.armorvalue - damagearmor;
\r
359 self.health = self.health - take;
\r
362 DelayHealthRegen(self);
\r
363 DelayArmorRegen(self);
\r
366 self.dmg_save = self.dmg_save + max(save - 10, 0);
\r
367 self.dmg_take = self.dmg_take + max(take - 10, 0);
\r
368 self.dmg_inflictor = inflictor;
\r
369 if (self.health <= 2)
\r
371 PlayerKilled(FALSE, inflictor, attacker, damage, deathtype, hitloc, force);
\r
373 // make the corpse upright (not tilted)
\r
377 self.avelocity = '0 0 0';
\r
378 // no weapon when dead
\r
379 self.weaponmodel = "";
\r
381 // view from the floor
\r
382 self.view_ofs = '0 0 -8';
\r
384 self.movetype = MOVETYPE_TOSS;
\r
385 // shootable corpse
\r
386 self.solid = SOLID_CORPSE;
\r
387 // don't stick to the floor
\r
388 self.flags = self.flags - (self.flags & FL_ONGROUND);
\r
390 self.deadflag = DEAD_DYING;
\r
391 // when to allow respawn
\r
392 self.death_time = time + 0.5;
\r
393 // when to switch to the dead_frame
\r
394 self.dead_time = time + 2;
\r
395 if (random() < 0.5)
\r
397 self.die_frame = $die1;
\r
398 self.dead_frame = $dead1;
\r
402 self.die_frame = $die2;
\r
403 self.dead_frame = $dead2;
\r
405 // start the animation
\r
407 // set damage function to corpse damage
\r
408 self.event_damage = PlayerCorpseDamage;
\r
409 // call the corpse damage function just in case it wants to gib
\r
410 self.event_damage(inflictor, attacker, 0, deathtype, hitloc, force);
\r
411 // set up to fade out later
\r
412 SUB_SetFade (self, time + 12 + random () * 4, 1);
\r