X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fclient%2Fdamage.qc;h=fe99d507b7e49dc27068cded9aac8820ac15fed3;hb=f63d2620d2bbf6946ed257f297332a743f977a7c;hp=3626c44c617408555c5bb4c4eaede028fe6399db;hpb=5733b1493c8c3fc14830f78122fe388e89f19338;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/client/damage.qc b/qcsrc/client/damage.qc index 3626c44c6..fe99d507b 100644 --- a/qcsrc/client/damage.qc +++ b/qcsrc/client/damage.qc @@ -1,16 +1,8 @@ #include "damage.qh" -#include "_all.qh" -#include "gibs.qh" -#include "prandom.qh" - -#include "vehicles/all.qh" - -#include "../common/constants.qh" -#include "../common/deathtypes.qh" +#include "../common/deathtypes/all.qh" #include "../common/movetypes/movetypes.qh" -#include "../common/util.qh" - +#include "../common/vehicles/all.qh" #include "../common/weapons/all.qh" .entity tag_entity; @@ -20,7 +12,7 @@ .bool isplayermodel; void DamageEffect_Think() -{ +{SELFPARAM(); // if particle distribution is enabled, slow ticrate by total number of damages if(autocvar_cl_damageeffect_distribute) self.nextthink = time + autocvar_cl_damageeffect_ticrate * self.owner.total_damages; @@ -49,11 +41,26 @@ void DamageEffect_Think() // now generate the particles vector org; org = gettaginfo(self, 0); // origin at attached location - pointparticles(self.team, org, '0 0 0', 1); + __pointparticles(self.team, org, '0 0 0', 1); } -void DamageEffect(vector hitorg, float thedamage, int type, int specnum) +string species_prefix(int specnum) { + switch(specnum) + { + case SPECIES_HUMAN: return ""; + case SPECIES_ALIEN: return "alien_"; + case SPECIES_ROBOT_SHINY: return "robot_"; + case SPECIES_ROBOT_RUSTY: return "robot_"; // use the same effects, only different gibs + case SPECIES_ROBOT_SOLID: return "robot_"; // use the same effects, only different gibs + case SPECIES_ANIMAL: return "animal_"; + case SPECIES_RESERVED: return "reserved_"; + default: return ""; + } +} + +void DamageEffect(vector hitorg, float thedamage, int type, int specnum) +{SELFPARAM(); // particle effects for players and objects damaged by weapons (eg: flames coming out of victims shot with rockets) int nearestbone = 0; @@ -99,7 +106,7 @@ void DamageEffect(vector hitorg, float thedamage, int type, int specnum) life = bound(autocvar_cl_damageeffect_lifetime_min, thedamage * autocvar_cl_damageeffect_lifetime, autocvar_cl_damageeffect_lifetime_max); - effectname = get_weaponinfo(DEATH_WEAPONOF(type)).netname; + effectname = DEATH_WEAPONOF(type).netname; if(substring(effectname, strlen(effectname) - 5, 5) == "BLOOD") { @@ -112,27 +119,25 @@ void DamageEffect(vector hitorg, float thedamage, int type, int specnum) else { return; } // objects don't bleed } - e = spawn(); - setmodel(e, "null"); // necessary to attach and read origin + e = new(damage); + make_pure(e); + setmodel(e, MDL_Null); // necessary to attach and read origin setattachment(e, self, gettaginfo_name); // attach to the given bone - e.classname = "damage"; e.owner = self; e.cnt = time + life; - e.team = particleeffectnum(effectname); + e.team = _particleeffectnum(effectname); e.think = DamageEffect_Think; e.nextthink = time; self.total_damages += 1; } -void Ent_DamageInfo(float isNew) +NET_HANDLE(ENT_CLIENT_DAMAGEINFO, bool isNew) { + make_pure(this); float thedamage, rad, edge, thisdmg; bool hitplayer = false; int species, forcemul; vector force, thisforce; - entity oldself; - - oldself = self; w_deathtype = ReadShort(); w_issilent = (w_deathtype & 0x8000); @@ -148,6 +153,8 @@ void Ent_DamageInfo(float isNew) force = decompressShortVector(ReadShort()); species = ReadByte(); + return = true; + if (!isNew) return; @@ -159,8 +166,9 @@ void Ent_DamageInfo(float isNew) else forcemul = 1; - for(self = findradius(w_org, rad + MAX_DAMAGEEXTRARADIUS); self; self = self.chain) + for(entity e = findradius(w_org, rad + MAX_DAMAGEEXTRARADIUS); e; e = e.chain) { + setself(e); // attached ents suck if(self.tag_entity) continue; @@ -211,8 +219,7 @@ void Ent_DamageInfo(float isNew) if(self.isplayermodel) hitplayer = true; // this impact damaged a player } - - self = oldself; + setself(this); if(DEATH_ISVEHICLE(w_deathtype)) { @@ -224,43 +231,41 @@ void Ent_DamageInfo(float isNew) setorigin(self, w_org + w_backoff * 2); // for sound() calls - switch(w_deathtype) + switch(DEATH_ENT(w_deathtype)) { case DEATH_VH_CRUSH: break; // spiderbot case DEATH_VH_SPID_MINIGUN: - string _snd; - _snd = strcat("weapons/ric", ftos(1 + rint(random() * 2)), ".waw"); - sound(self, CH_SHOTS, _snd, VOL_BASE, ATTEN_NORM); - pointparticles(particleeffectnum("spiderbot_minigun_impact"), self.origin, w_backoff * 1000, 1); + sound(self, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTEN_NORM); + pointparticles(EFFECT_SPIDERBOT_MINIGUN_IMPACT, self.origin, w_backoff * 1000, 1); break; case DEATH_VH_SPID_ROCKET: - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); - pointparticles(particleeffectnum("spiderbot_rocket_explode"), self.origin, w_backoff * 1000, 1); + sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM); + pointparticles(EFFECT_SPIDERBOT_ROCKET_EXPLODE, self.origin, w_backoff * 1000, 1); break; case DEATH_VH_SPID_DEATH: - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_MIN); - pointparticles(particleeffectnum("explosion_big"), self.origin, w_backoff * 1000, 1); + sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_MIN); + pointparticles(EFFECT_EXPLOSION_BIG, self.origin, w_backoff * 1000, 1); break; case DEATH_VH_WAKI_GUN: - sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTEN_NORM); - pointparticles(particleeffectnum("wakizashi_gun_impact"), self.origin, w_backoff * 1000, 1); + sound(self, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTEN_NORM); + pointparticles(EFFECT_RACER_IMPACT, self.origin, w_backoff * 1000, 1); break; case DEATH_VH_WAKI_ROCKET: - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); - pointparticles(particleeffectnum("wakizashi_rocket_explode"), self.origin, w_backoff * 1000, 1); + sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM); + pointparticles(EFFECT_RACER_ROCKET_EXPLODE, self.origin, w_backoff * 1000, 1); break; case DEATH_VH_WAKI_DEATH: - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_MIN); - pointparticles(particleeffectnum("explosion_big"), self.origin, w_backoff * 1000, 1); + sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_MIN); + pointparticles(EFFECT_EXPLOSION_BIG, self.origin, w_backoff * 1000, 1); break; case DEATH_VH_RAPT_CANNON: - sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTEN_NORM); - pointparticles(particleeffectnum("raptor_cannon_impact"), self.origin, w_backoff * 1000, 1); + sound(self, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTEN_NORM); + pointparticles(EFFECT_RAPTOR_CANNON_IMPACT, self.origin, w_backoff * 1000, 1); break; case DEATH_VH_RAPT_FRAGMENT: float i; @@ -271,20 +276,20 @@ void Ent_DamageInfo(float isNew) ang = vectoangles(vel); RaptorCBShellfragToss(w_org, vel, ang + '0 0 1' * (120 * i)); } - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); - pointparticles(particleeffectnum("raptor_bomb_spread"), self.origin, w_backoff * 1000, 1); + sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM); + pointparticles(EFFECT_RAPTOR_BOMB_SPREAD, self.origin, w_backoff * 1000, 1); break; case DEATH_VH_RAPT_BOMB: - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); - pointparticles(particleeffectnum("raptor_bomb_impact"), self.origin, w_backoff * 1000, 1); + sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM); + pointparticles(EFFECT_RAPTOR_BOMB_IMPACT, self.origin, w_backoff * 1000, 1); break; case DEATH_VH_RAPT_DEATH: - sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTEN_MIN); - pointparticles(particleeffectnum("explosion_big"), self.origin, w_backoff * 1000, 1); + sound(self, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTEN_MIN); + pointparticles(EFFECT_EXPLOSION_BIG, self.origin, w_backoff * 1000, 1); break; case DEATH_VH_BUMB_GUN: - sound(self, CH_SHOTS, "weapons/fireball_impact2.wav", VOL_BASE, ATTEN_NORM); - pointparticles(particleeffectnum("bigplasma_impact"), self.origin, w_backoff * 1000, 1); + sound(self, CH_SHOTS, SND_FIREBALL_IMPACT2, VOL_BASE, ATTEN_NORM); + pointparticles(EFFECT_BIGPLASMA_IMPACT, self.origin, w_backoff * 1000, 1); break; } } @@ -292,7 +297,6 @@ void Ent_DamageInfo(float isNew) if(DEATH_ISTURRET(w_deathtype)) { - string _snd; traceline(w_org - normalize(force) * 16, w_org + normalize(force) * 16, MOVE_NOMONSTERS, world); if(trace_plane_normal != '0 0 0') w_backoff = trace_plane_normal; @@ -301,42 +305,40 @@ void Ent_DamageInfo(float isNew) setorigin(self, w_org + w_backoff * 2); // for sound() calls - switch(w_deathtype) + switch(DEATH_ENT(w_deathtype)) { case DEATH_TURRET_EWHEEL: - sound(self, CH_SHOTS, "weapons/laserimpact.wav", VOL_BASE, ATTEN_MIN); - pointparticles(particleeffectnum("laser_impact"), self.origin, w_backoff * 1000, 1); + sound(self, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTEN_MIN); + pointparticles(EFFECT_BLASTER_IMPACT, self.origin, w_backoff * 1000, 1); break; case DEATH_TURRET_FLAC: - pointparticles(particleeffectnum("hagar_explode"), w_org, '0 0 0', 1); - _snd = strcat("weapons/hagexp", ftos(1 + rint(random() * 2)), ".waw"); - sound(self, CH_SHOTS, _snd, VOL_BASE, ATTEN_NORM); + pointparticles(EFFECT_HAGAR_EXPLODE, w_org, '0 0 0', 1); + sound(self, CH_SHOTS, SND_HAGEXP_RANDOM(), VOL_BASE, ATTEN_NORM); break; case DEATH_TURRET_MLRS: case DEATH_TURRET_HK: case DEATH_TURRET_WALK_ROCKET: case DEATH_TURRET_HELLION: - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_MIN); - pointparticles(particleeffectnum("rocket_explode"), self.origin, w_backoff * 1000, 1); + sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_MIN); + pointparticles(EFFECT_ROCKET_EXPLODE, self.origin, w_backoff * 1000, 1); break; case DEATH_TURRET_MACHINEGUN: case DEATH_TURRET_WALK_GUN: - _snd = strcat("weapons/ric", ftos(1 + rint(random() * 2)), ".waw"); - sound(self, CH_SHOTS, _snd, VOL_BASE, ATTEN_NORM); - pointparticles(particleeffectnum("machinegun_impact"), self.origin, w_backoff * 1000, 1); + sound(self, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTEN_NORM); + pointparticles(EFFECT_MACHINEGUN_IMPACT, self.origin, w_backoff * 1000, 1); break; case DEATH_TURRET_PLASMA: - sound(self, CH_SHOTS, "weapons/electro_impact.wav", VOL_BASE, ATTEN_MIN); - pointparticles(particleeffectnum("electro_impact"), self.origin, w_backoff * 1000, 1); + sound(self, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTEN_MIN); + pointparticles(EFFECT_ELECTRO_IMPACT, self.origin, w_backoff * 1000, 1); break; - case DEATH_TURRET_WALK_MEELE: - sound(self, CH_SHOTS, "weapons/ric1.wav", VOL_BASE, ATTEN_MIN); - pointparticles(particleeffectnum("TE_SPARK"), self.origin, w_backoff * 1000, 1); + case DEATH_TURRET_WALK_MELEE: + sound(self, CH_SHOTS, SND_RIC_RANDOM(), VOL_BASE, ATTEN_MIN); + pointparticles(EFFECT_TE_SPARK, self.origin, w_backoff * 1000, 1); break; case DEATH_TURRET_PHASER: @@ -353,7 +355,7 @@ void Ent_DamageInfo(float isNew) if(!DEATH_ISSPECIAL(w_deathtype)) if(!hitplayer || rad) // don't show ground impacts for hitscan weapons if a player was hit { - int hitwep = DEATH_WEAPONOFWEAPONDEATH(w_deathtype); + Weapon hitwep = DEATH_WEAPONOF(w_deathtype); w_random = prandom(); traceline(w_org - normalize(force) * 16, w_org + normalize(force) * 16, MOVE_NOMONSTERS, world); @@ -363,6 +365,8 @@ void Ent_DamageInfo(float isNew) w_backoff = -1 * normalize(force); setorigin(self, w_org + w_backoff * 2); // for sound() calls - if(!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)) { WEP_ACTION(hitwep, WR_IMPACTEFFECT); } + if(!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)) { + hitwep.wr_impacteffect(hitwep); + } } }