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
102 if (self.movement_x * self.movement_x + self.movement_y * self.movement_y > 20)
\r
103 self.frame = $duckwalk;
\r
105 self.frame = $duckidle;
\r
107 else if ((self.movement_x * self.movement_x + self.movement_y * self.movement_y) > 20)
\r
109 if (self.movement_x > 0 && self.movement_y == 0)
\r
113 else if (self.movement_x < 0 && self.movement_y == 0)
\r
114 self.frame = $runbackwards;
\r
115 else if (self.movement_x == 0 && self.movement_y > 0)
\r
116 self.frame = $straferight;
\r
117 else if (self.movement_x == 0 && self.movement_y < 0)
\r
118 self.frame = $strafeleft;
\r
119 else if (self.movement_x > 0 && self.movement_y > 0)
\r
120 self.frame = $forwardright;
\r
121 else if (self.movement_x > 0 && self.movement_y < 0)
\r
122 self.frame = $forwardleft;
\r
123 else if (self.movement_x < 0 && self.movement_y > 0)
\r
124 self.frame = $backright;
\r
125 else if (self.movement_x < 0 && self.movement_y < 0)
\r
126 self.frame = $backleft;
\r
130 else if (self.pain_finished > time)
\r
131 self.frame = self.pain_frame;
\r
132 else if (self.attack_finished > time)
\r
133 self.frame = $shoot;
\r
135 self.frame = $idle;
\r
137 if (!(self.flags & FL_ONGROUND))
\r
138 self.frame = $jump;
\r
140 //End change by Supajoe on 11:44 PM EST 11/16/03 (Subject: Player animations)
\r
143 void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
\r
145 local float take, save;
\r
146 te_blood (hitloc, force, damage);
\r
147 // damage resistance (ignore most of the damage from a bullet or similar)
\r
148 damage = max(damage - 5, 1);
\r
149 save = bound(0, damage * 0.6, self.armorvalue);
\r
150 take = bound(0, damage - save, damage);
\r
151 self.armorvalue = self.armorvalue - save;
\r
152 self.health = self.health - take;
\r
153 self.dmg_save = self.dmg_save + save;
\r
154 self.dmg_take = self.dmg_take + take;
\r
155 self.dmg_inflictor = inflictor;
\r
156 if (self.health <= -50)
\r
158 // don't use any animations as a gib
\r
160 self.dead_frame = 0;
\r
161 self.die_frame = 0;
\r
162 // view just above the floor
\r
163 self.view_ofs = '0 0 4';
\r
165 // make a juicy mess
\r
166 te_bloodshower (self.origin + self.mins, self.origin + self.maxs, 800, 1000);
\r
167 te_bloodshower (self.origin + self.mins, self.origin + self.maxs, 400, 1000);
\r
169 // make a meaty mess
\r
170 TossGib (self, "models/gibs/eye.md3", self.origin, self.velocity,0);
\r
171 TossGib (world, "models/gibs/bloodyskull.md3", self.origin, '0 0 600',0);
\r
173 TossGib (world, "models/gibs/gib1.md3", self.origin, self.velocity,0);
\r
174 TossGib (world, "models/gibs/gib2.md3", self.origin, self.velocity,0);
\r
175 TossGib (world, "models/gibs/gib3.md3", self.origin, self.velocity,0);
\r
176 TossGib (world, "models/gibs/gib4.md3", self.origin, self.velocity,0);
\r
178 // these destory on impact
\r
179 TossGib (world, "models/gibs/gib5.md3", self.origin, '-500 0 450',1);
\r
180 TossGib (world, "models/gibs/gib6.md3", self.origin, '0 500 450',1);
\r
181 TossGib (world, "models/gibs/chunk.mdl", self.origin, '0 -500 450',1);
\r
182 TossGib (world, "models/gibs/chunk.mdl", self.origin, '500 0 450',1);
\r
183 TossGib (world, "models/gibs/chunk.mdl", self.origin, self.velocity,1);
\r
184 TossGib (world, "models/gibs/chunk.mdl", self.origin, '0 0 450',1);
\r
186 sound (trace_ent, CHAN_VOICE, "misc/gib.wav", 1, ATTN_NORM);
\r
190 void PlayerKilled (float unnatural_death, entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
\r
192 if(self.class == CLASS_SPY)
\r
195 // fixes death while reloading glitch
\r
196 inflictor.reload_time = 0;
\r
197 // fixes flash effects staying after death bug
\r
198 self.FlashTime = 0;
\r
199 stuffcmd(inflictor, "v_cshift 0 0 0 0\n");
\r
202 SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.wpn5.weapon);//self.weapon);
\r
203 // print an obituary message
\r
204 Obituary (attacker, self, deathtype);
\r
205 // Drop flag or any carried item
\r
206 TeamFortress_RemoveTimers ();
\r
207 // Make sure corpse cant take tfgoal items
\r
209 // make the corpse upright (not tilted)
\r
213 self.avelocity = '0 0 0';
\r
214 // no weapon when dead
\r
215 self.weaponmodel = "";
\r
217 // view from the floor
\r
218 self.view_ofs = '0 0 -8';
\r
220 self.movetype = MOVETYPE_TOSS;
\r
221 // shootable corpse
\r
222 self.solid = SOLID_CORPSE;
\r
223 // don't stick to the floor
\r
224 self.flags = self.flags - (self.flags & FL_ONGROUND);
\r
226 self.deadflag = DEAD_DYING;
\r
227 // when to allow respawn
\r
228 self.death_time = time + 0.5;
\r
229 // when to switch to the dead_frame
\r
230 self.dead_time = time + 2;
\r
231 if(!unnatural_death)
\r
233 if (random() < 0.5)
\r
235 self.die_frame = $die1;
\r
236 self.dead_frame = $dead1;
\r
240 self.die_frame = $die2;
\r
241 self.dead_frame = $dead2;
\r
246 self.die_frame = $dead2;
\r
247 self.dead_frame = $dead2;
\r
248 if(self.health > -1)
\r
251 // start the animation
\r
253 // set damage function to corpse damage
\r
254 self.event_damage = PlayerCorpseDamage;
\r
255 // call the corpse damage function just in case it wants to gib
\r
256 self.event_damage(inflictor, attacker, 0, deathtype, hitloc, force);
\r
257 // set up to fade out later
\r
258 SUB_SetFade (self, time + 12 + random () * 4, 1);
\r
261 float PlayerShouldDie (entity inflictor, entity attacker, float damage, float deathtype)
\r
263 // returns true if player should die from this source of damage.
\r
264 // If so, don't block this damage in any way
\r
269 if( deathtype == DEATH_FALL
\r
270 || deathtype == DEATH_TELEFRAG
\r
271 || deathtype == DEATH_DROWN
\r
272 || deathtype == DEATH_HURTTRIGGER
\r
273 || deathtype == DEATH_LAVA
\r
274 || deathtype == DEATH_SLIME
\r
275 || deathtype == DEATH_KILL
\r
276 || deathtype == DEATH_CLASSCHANGE
\r
277 // || deathtype == DEATH_BURNING
\r
278 || deathtype == DEATH_LASERGATE
\r
285 void PlayerDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
\r
287 local float take, save, damagearmor;
\r
289 te_blood (hitloc, force, damage);
\r
290 if (self.pain_finished < time) //Don't switch pain sequences like crazy
\r
292 if (random() > 0.5)
\r
293 self.pain_frame = $pain1;
\r
295 self.pain_frame = $pain2;
\r
296 self.pain_finished = time + 0.5; //Supajoe
\r
299 if(self.class == CLASS_MEDIC)
\r
301 if(deathtype == DEATH_BURNING)
\r
302 damage = 0; // being on fire or near burning targets does nothing to medics
\r
303 // the flame thrower, flame rockets, and hotbombs also do minimal damage
\r
304 else if(deathtype == WEP_FLAMER ||
\r
305 deathtype == WEP_ROCKET_INCENDIARY ||
\r
306 deathtype == WEP_HOTBOMBS)
\r
307 damage = damage * cvar("g_balance_class_medic_flame_takedamage");
\r
310 // how much damage to deal to armor
\r
311 damagearmor = bound(0, damage * 0.2 * (self.armorvalue / 50) * cvar("g_balance_armor_takedamage"), self.armorvalue);
\r
312 // how much damage armor blocks
\r
313 save = bound(0, damage * (self.armorvalue / 100) * cvar("g_balance_armor_effectiveness"), damage);
\r
314 // how much damage to deal to player
\r
315 take = bound(0, damage - save, damage);
\r
317 // if being telefragged or killed by a death trigger etc, don't block that
\r
318 if(PlayerShouldDie(inflictor, attacker, damage, deathtype))
\r
321 take = damage; // deal full damage
\r
325 // keep the damage the armor allowed through, and further reduce it if the player is using the shield
\r
326 if(self.class == CLASS_SCOUT)
\r
327 take = SpecialShieldProtect(take);
\r
331 sound (self, CHAN_IMPACT, "misc/armorimpact.wav", 1, ATTN_NORM);
\r
333 sound (self, CHAN_IMPACT, "misc/bodyimpact1.wav", 1, ATTN_NORM);
\r
335 sound (self, CHAN_IMPACT, "misc/bodyimpact2.wav", 1, ATTN_NORM);
\r
338 TossGib (world, "models/gibs/chunk.mdl", hitloc, force * -0.1,1);
\r
340 TossGib (world, "models/gibs/chunk.mdl", hitloc, force * -0.1,1);
\r
342 if (!(self.flags & FL_GODMODE))
\r
344 self.armorvalue = self.armorvalue - damagearmor;
\r
345 self.health = self.health - take;
\r
348 DelayHealthRegen(self);
\r
349 DelayArmorRegen(self);
\r
352 self.dmg_save = self.dmg_save + max(save - 10, 0);
\r
353 self.dmg_take = self.dmg_take + max(take - 10, 0);
\r
354 self.dmg_inflictor = inflictor;
\r
355 if (self.health <= 2)
\r
357 PlayerKilled(FALSE, inflictor, attacker, damage, deathtype, hitloc, force);
\r