From 0a1172b75f571685c264a8b9d8ee224bbf11381f Mon Sep 17 00:00:00 2001 From: xolatile Date: Wed, 6 Aug 2025 22:54:55 +0200 Subject: Please do not hate me, it makes sense... --- src/fpsgame/weapon.cpp | 460 ++++++++++++++----------------------------------- 1 file changed, 128 insertions(+), 332 deletions(-) (limited to 'src/fpsgame/weapon.cpp') diff --git a/src/fpsgame/weapon.cpp b/src/fpsgame/weapon.cpp index 1bdb302..c486110 100644 --- a/src/fpsgame/weapon.cpp +++ b/src/fpsgame/weapon.cpp @@ -1,37 +1,27 @@ // weapon.cpp: all shooting and effects code, projectile management #include "game.h" -namespace game -{ +namespace game { static const int OFFSETMILLIS = 500; vec rays[MAXRAYS]; - - struct hitmsg - { + struct hitmsg { int target, lifesequence, info1, info2; ivec dir; }; vector hits; - ICOMMAND(getweapon, "", (), intret(player1->gunselect)); - - void gunselect(int gun, fpsent *d) - { - if(gun!=d->gunselect) - { + void gunselect(int gun, fpsent *d) { + if(gun!=d->gunselect) { addmsg(N_GUNSELECT, "rci", d, gun); playsound(S_WEAPLOAD, d == player1 ? NULL : &d->o); } d->gunselect = gun; } - - void nextweapon(int dir, bool force = false) - { + void nextweapon(int dir, bool force = false) { if(player1->state!=CS_ALIVE) return; dir = (dir < 0 ? NUMGUNS-1 : 1); int gun = player1->gunselect; - loopi(NUMGUNS) - { + loopi(NUMGUNS) { gun = (gun + dir)%NUMGUNS; if(force || player1->ammo[gun]) break; } @@ -39,50 +29,39 @@ namespace game else playsound(S_NOAMMO); } ICOMMAND(nextweapon, "ii", (int *dir, int *force), nextweapon(*dir, *force!=0)); - - int getweapon(const char *name) - { + int getweapon(const char *name) { const char *abbrevs[] = { "FI", "SG", "CG", "RL", "RI", "GL", "PI" }; if(isdigit(name[0])) return parseint(name); else loopi(sizeof(abbrevs)/sizeof(abbrevs[0])) if(!strcasecmp(abbrevs[i], name)) return i; return -1; } - - void setweapon(const char *name, bool force = false) - { + void setweapon(const char *name, bool force = false) { int gun = getweapon(name); if(player1->state!=CS_ALIVE || gunGUN_PISTOL) return; if(force || player1->ammo[gun]) gunselect(gun, player1); else playsound(S_NOAMMO); } ICOMMAND(setweapon, "si", (char *name, int *force), setweapon(name, *force!=0)); - - void cycleweapon(int numguns, int *guns, bool force = false) - { + void cycleweapon(int numguns, int *guns, bool force = false) { if(numguns<=0 || player1->state!=CS_ALIVE) return; int offset = 0; loopi(numguns) if(guns[i] == player1->gunselect) { offset = i+1; break; } - loopi(numguns) - { + loopi(numguns) { int gun = guns[(i+offset)%numguns]; - if(gun>=0 && gunammo[gun])) - { + if(gun>=0 && gunammo[gun])) { gunselect(gun, player1); return; } } playsound(S_NOAMMO); } - ICOMMAND(cycleweapon, "V", (tagval *args, int numargs), - { + ICOMMAND(cycleweapon, "V", (tagval *args, int numargs), { int numguns = min(numargs, 7); int guns[7]; loopi(numguns) guns[i] = getweapon(args[i].getstr()); cycleweapon(numguns, guns); }); - - void weaponswitch(fpsent *d) - { + void weaponswitch(fpsent *d) { if(d->state!=CS_ALIVE) return; int s = d->gunselect; if (s!=GUN_CG && d->ammo[GUN_CG]) s = GUN_CG; @@ -92,49 +71,36 @@ namespace game else if(s!=GUN_GL && d->ammo[GUN_GL]) s = GUN_GL; else if(s!=GUN_PISTOL && d->ammo[GUN_PISTOL]) s = GUN_PISTOL; else s = GUN_FIST; - gunselect(s, d); } - - ICOMMAND(weapon, "V", (tagval *args, int numargs), - { + ICOMMAND(weapon, "V", (tagval *args, int numargs), { if(player1->state!=CS_ALIVE) return; - loopi(7) - { + loopi(7) { const char *name = i < numargs ? args[i].getstr() : ""; - if(name[0]) - { + if(name[0]) { int gun = getweapon(name); if(gun >= GUN_FIST && gun <= GUN_PISTOL && gun != player1->gunselect && player1->ammo[gun]) { gunselect(gun, player1); return; } } else { weaponswitch(player1); return; } } playsound(S_NOAMMO); }); - - void offsetray(const vec &from, const vec &to, int spread, float range, vec &dest) - { + void offsetray(const vec &from, const vec &to, int spread, float range, vec &dest) { vec offset; do offset = vec(rndscale(1), rndscale(1), rndscale(1)).sub(0.5f); while(offset.squaredlen() > 0.5f*0.5f); offset.mul((to.dist(from)/1024)*spread); offset.z /= 2; dest = vec(offset).add(to); - if(dest != from) - { + if(dest != from) { vec dir = vec(dest).sub(from).normalize(); raycubepos(from, dir, dest, range, RAY_CLIPMAT|RAY_ALPHAPOLY); } } - - void createrays(int gun, const vec &from, const vec &to) // create random spread of rays - { + void createrays(int gun, const vec &from, const vec &to) { // create random spread of rays { loopi(guns[gun].rays) offsetray(from, to, guns[gun].spread, guns[gun].range, rays[i]); } - enum { BNC_GRENADE }; - - struct bouncer : physent - { + struct bouncer : physent { int lifetime, bounces; float lastyaw, roll; bool local; @@ -145,37 +111,26 @@ namespace game float offsetheight; int id; entitylight light; - - bouncer() : bounces(0), roll(0), variant(0) - { + bouncer() : bounces(0), roll(0), variant(0) { type = ENT_BOUNCE; } - - vec offsetpos() - { + vec offsetpos() { vec pos(o); - if(offsetmillis > 0) - { + if(offsetmillis > 0) { pos.add(vec(offset).mul(offsetmillis/float(OFFSETMILLIS))); if(offsetheight >= 0) pos.z = max(pos.z, o.z - max(offsetheight - eyeheight, 0.0f)); } return pos; } - - void limitoffset() - { + void limitoffset() { if(bouncetype == BNC_GRENADE && offsetmillis > 0 && offset.z < 0) offsetheight = raycube(vec(o.x + offset.x, o.y + offset.y, o.z), vec(0, 0, -1), -offset.z); else offsetheight = -1; } }; - vector bouncers; - vec hudgunorigin(int gun, const vec &from, const vec &to, fpsent *d); - - void newbouncer(const vec &from, const vec &to, bool local, int id, fpsent *owner, int type, int lifetime, int speed, entitylight *light = NULL) - { + void newbouncer(const vec &from, const vec &to, bool local, int id, fpsent *owner, int type, int lifetime, int speed, entitylight *light = NULL) { bouncer &bnc = *bouncers.add(new bouncer); bnc.o = from; bnc.radius = bnc.xradius = bnc.yradius = 1.5f; @@ -187,18 +142,13 @@ namespace game bnc.bouncetype = type; bnc.id = local ? lastmillis : id; if(light) bnc.light = *light; - bnc.collidetype = COLLIDE_ELLIPSE_PRECISE; - vec dir(to); dir.sub(from).safenormalize(); bnc.vel = dir; bnc.vel.mul(speed); - avoidcollision(&bnc, dir, owner, 0.1f); - - if(type==BNC_GRENADE) - { + if(type==BNC_GRENADE) { bnc.offset = hudgunorigin(GUN_GL, from, to, owner); if(owner==followingplayer(player1) && !isthirdperson()) bnc.offset.sub(owner->o).rescale(16).add(owner->o); } @@ -206,37 +156,27 @@ namespace game bnc.offset.sub(bnc.o); bnc.offsetmillis = OFFSETMILLIS; bnc.limitoffset(); - bnc.resetinterp(); } - - void bounced(physent *d, const vec &surface) - { + void bounced(physent *d, const vec &surface) { if(d->type != ENT_BOUNCE) return; bouncer *b = (bouncer *)d; if(b->bounces >= 2) return; b->bounces++; adddecal(DECAL_BLOOD, vec(b->o).sub(vec(surface).mul(b->radius)), surface, 2.96f/b->bounces, bvec(0x60, 0xFF, 0xFF), rnd(4)); } - - void updatebouncers(int time) - { - loopv(bouncers) - { + void updatebouncers(int time) { + loopv(bouncers) { bouncer &bnc = *bouncers[i]; - if(bnc.bouncetype==BNC_GRENADE && bnc.vel.magnitude() > 50.0f) - { + if(bnc.bouncetype==BNC_GRENADE && bnc.vel.magnitude() > 50.0f) { vec pos = bnc.offsetpos(); regular_particle_splash(PART_SMOKE, 1, 150, pos, 0x404040, 2.4f, 50, -20); } vec old(bnc.o); bool stopped = false; if(bnc.bouncetype==BNC_GRENADE) stopped = bounce(&bnc, 0.6f, 0.5f, 0.8f) || (bnc.lifetime -= time)<0; - - if(stopped) - { - if(bnc.bouncetype==BNC_GRENADE) - { + if(stopped) { + if(bnc.bouncetype==BNC_GRENADE) { int qdam = guns[GUN_GL].damage*(bnc.owner->quadmillis ? 4 : 1); hits.setsize(0); explode(bnc.local, bnc.owner, bnc.o, NULL, qdam, GUN_GL); @@ -247,24 +187,18 @@ namespace game } delete bouncers.remove(i--); } - else - { + else { bnc.roll += old.sub(bnc.o).magnitude()/(4*RAD); bnc.offsetmillis = max(bnc.offsetmillis-time, 0); bnc.limitoffset(); } } } - - void removebouncers(fpsent *owner) - { + void removebouncers(fpsent *owner) { loopv(bouncers) if(bouncers[i]->owner==owner) { delete bouncers[i]; bouncers.remove(i--); } } - void clearbouncers() { bouncers.deletecontents(); } - - struct projectile - { + struct projectile { vec dir, o, to, offset; float speed; fpsent *owner; @@ -275,11 +209,8 @@ namespace game entitylight light; }; vector projs; - void clearprojectiles() { projs.shrink(0); } - - void newprojectile(const vec &from, const vec &to, float speed, bool local, int id, fpsent *owner, int gun) - { + void newprojectile(const vec &from, const vec &to, float speed, bool local, int id, fpsent *owner, int gun) { projectile &p = projs.add(); p.dir = vec(to).sub(from).safenormalize(); p.o = from; @@ -293,69 +224,51 @@ namespace game p.offsetmillis = OFFSETMILLIS; p.id = local ? lastmillis : id; } - - void removeprojectiles(fpsent *owner) - { + void removeprojectiles(fpsent *owner) { // can't use loopv here due to strange GCC optimizer bug int len = projs.length(); loopi(len) if(projs[i].owner==owner) { projs.remove(i--); len--; } } - VARP(blood, 0, 1, 1); - - void damageeffect(int damage, fpsent *d, bool thirdperson) - { + void damageeffect(int damage, fpsent *d, bool thirdperson) { vec p = d->o; p.z += 0.6f*(d->eyeheight + d->aboveeye) - d->eyeheight; if(blood) particle_splash(PART_BLOOD, damage/10, 1000, p, 0x60FFFF, 2.96f); - if(thirdperson) - { + if(thirdperson) { defformatstring(ds, "%d", damage); particle_textcopy(d->abovehead(), ds, PART_TEXT, 2000, 0xFF4B19, 4.0f, -8); } } - - void spawnbouncer(const vec &p, const vec &vel, fpsent *d, int type, entitylight *light = NULL) - { - vec to(rnd(100)-50, rnd(100)-50, rnd(100)-50); - if(to.iszero()) to.z += 1; - to.normalize(); - to.add(p); - newbouncer(p, to, true, 0, d, type, rnd(1000)+1000, rnd(100)+20, light); - } - - void hit(int damage, dynent *d, fpsent *at, const vec &vel, int gun, float info1, int info2 = 1) - { - if(at==player1 && d!=at) - { + //~void spawnbouncer(const vec &p, const vec &vel, fpsent *d, int type, entitylight *light = NULL) + //~{ + //~vec to(rnd(100)-50, rnd(100)-50, rnd(100)-50); + //~if(to.iszero()) to.z += 1; + //~to.normalize(); + //~to.add(p); + //~newbouncer(p, to, true, 0, d, type, rnd(1000)+1000, rnd(100)+20, light); + //~} + void hit(int damage, dynent *d, fpsent *at, const vec &vel, int gun, float info1, int info2 = 1) { + if(at==player1 && d!=at) { extern int hitsound; if(hitsound && lasthit != lastmillis) playsound(S_HIT); lasthit = lastmillis; } - fpsent *f = (fpsent *)d; - f->lastpain = lastmillis; if(at->type==ENT_PLAYER && !isteam(at->team, f->team)) at->totaldamage += damage; - if(f->type==ENT_AI || !m_mp(gamemode) || f==at) f->hitpush(damage, vel, at, gun); - pwhit(gun, damage); - if(!m_mp(gamemode)) damaged(damage, f, at); - else - { + else { hitmsg &h = hits.add(); h.target = f->clientnum; h.lifesequence = f->lifesequence; h.info1 = int(info1*DMF); h.info2 = info2; h.dir = f==at ? ivec(0, 0, 0) : ivec(vec(vel).mul(DNF)); - if(at==player1) - { + if(at==player1) { damageeffect(damage, f); - if(f==player1) - { + if(f==player1) { damagecompass(damage, at ? at->o : f->o); playsound(S_PAIN6); } @@ -363,14 +276,10 @@ namespace game } } } - - void hitpush(int damage, dynent *d, fpsent *at, vec &from, vec &to, int gun, int rays) - { + void hitpush(int damage, dynent *d, fpsent *at, vec &from, vec &to, int gun, int rays) { hit(damage, d, at, vec(to).sub(from).safenormalize(), gun, from.dist(to), rays); } - - float projdist(dynent *o, vec &dir, const vec &v) - { + float projdist(dynent *o, vec &dir, const vec &v) { vec middle = o->o; middle.z += (o->aboveeye-o->eyeheight)/2; float dist = middle.dist(v, dir); @@ -378,68 +287,53 @@ namespace game if(dist<0) dist = 0; return dist; } - - void radialeffect(dynent *o, const vec &v, int qdam, fpsent *at, int gun) - { + void radialeffect(dynent *o, const vec &v, int qdam, fpsent *at, int gun) { if(o->state!=CS_ALIVE) return; vec dir; float dist = projdist(o, dir, v); - if(disto.reject(v, o->radius + guns[gun].exprad) || o==safe) continue; radialeffect(o, v, damage, owner, gun); } } - - void projsplash(projectile &p, vec &v, dynent *safe, int damage) - { - if(guns[p.gun].part) - { + void projsplash(projectile &p, vec &v, dynent *safe, int damage) { + if(guns[p.gun].part) { particle_splash(PART_SPARK, 100, 200, v, 0xB49B4B, 0.24f); playsound(S_FEXPLODE, &v); // no push? } - else - { + else { explode(p.local, p.owner, v, safe, damage, GUN_RL); adddecal(DECAL_SCORCH, v, vec(p.dir).neg(), guns[p.gun].exprad/2); } } - - void explodeeffects(int gun, fpsent *d, bool local, int id) - { + void explodeeffects(int gun, fpsent *d, bool local, int id) { if(local) return; - switch(gun) - { + switch(gun) { case GUN_RL: - loopv(projs) - { + loopv(projs) { projectile &p = projs[i]; - if(p.gun == gun && p.owner == d && p.id == id && !p.local) - { + if(p.gun == gun && p.owner == d && p.id == id && !p.local) { vec pos(p.o); pos.add(vec(p.offset).mul(p.offsetmillis/float(OFFSETMILLIS))); explode(p.local, p.owner, pos, NULL, 0, GUN_RL); @@ -450,11 +344,9 @@ namespace game } break; case GUN_GL: - loopv(bouncers) - { + loopv(bouncers) { bouncer &b = *bouncers[i]; - if(b.bouncetype == BNC_GRENADE && b.owner == d && b.id == id && !b.local) - { + if(b.bouncetype == BNC_GRENADE && b.owner == d && b.id == id && !b.local) { vec pos = b.offsetpos(); explode(b.local, b.owner, pos, NULL, 0, GUN_GL); adddecal(DECAL_SCORCH, pos, vec(0, 0, 1), guns[gun].exprad/2); @@ -467,9 +359,7 @@ namespace game break; } } - - bool projdamage(dynent *o, projectile &p, vec &v, int qdam) - { + bool projdamage(dynent *o, projectile &p, vec &v, int qdam) { if(o->state!=CS_ALIVE) return false; if(!intersect(o, p.o, v)) return false; projsplash(p, v, o, qdam); @@ -478,11 +368,8 @@ namespace game hit(qdam, o, p.owner, dir, p.gun, 0); return true; } - - void updateprojectiles(int time) - { - loopv(projs) - { + void updateprojectiles(int time) { + loopv(projs) { projectile &p = projs[i]; p.offsetmillis = max(p.offsetmillis-time, 0); int qdam = guns[p.gun].damage*(p.owner->quadmillis ? 4 : 1); @@ -492,37 +379,30 @@ namespace game vec v = vec(p.o).add(dv); bool exploded = false; hits.setsize(0); - if(p.local) - { + if(p.local) { vec halfdv = vec(dv).mul(0.5f), bo = vec(p.o).add(halfdv); float br = max(fabs(halfdv.x), fabs(halfdv.y)) + 1; - loopj(numdynents()) - { + loopj(numdynents()) { dynent *o = iterdynents(j); if(p.owner==o || o->o.reject(bo, o->radius + br)) continue; if(projdamage(o, p, v, qdam)) { exploded = true; break; } } } - if(!exploded) - { - if(dist<4) - { - if(p.o!=p.to) // if original target was moving, reevaluate endpoint - { + if(!exploded) { + if(dist<4) { + if(p.o!=p.to) { // if original target was moving, reevaluate endpoint { if(raycubepos(p.o, p.dir, p.to, 0, RAY_CLIPMAT|RAY_ALPHAPOLY)>=4) continue; } projsplash(p, v, NULL, qdam); exploded = true; } - else - { + else { vec pos(v); pos.add(vec(p.offset).mul(p.offsetmillis/float(OFFSETMILLIS))); regular_particle_splash(PART_SMOKE, 2, 300, pos, 0x404040, 2.4f, 50, -20); } } - if(exploded) - { + if(exploded) { if(p.local) addmsg(N_EXPLODE, "rci3iv", p.owner, lastmillis-maptime, p.gun, p.id-maptime, hits.length(), hits.length()*sizeof(hitmsg)/sizeof(int), hits.getbuf()); @@ -531,28 +411,20 @@ namespace game else p.o = v; } } - extern int chainsawhudgun; - VARP(muzzleflash, 0, 1, 1); VARP(muzzlelight, 0, 1, 1); - - void shoteffects(int gun, const vec &from, const vec &to, fpsent *d, bool local, int id, int prevaction) // create visual effect from a shot - { + void shoteffects(int gun, const vec &from, const vec &to, fpsent *d, bool local, int id, int prevaction) { // create visual effect from a shot { int sound = guns[gun].sound, pspeed = 25; - switch(gun) - { + switch(gun) { case GUN_FIST: if(d->type==ENT_PLAYER && chainsawhudgun) sound = S_CHAINSAW_ATTACK; break; - - case GUN_SG: - { + case GUN_SG: { if(!local) createrays(gun, from, to); if(muzzleflash && d->muzzle.x >= 0) particle_flare(d->muzzle, d->muzzle, 200, PART_MUZZLE_FLASH3, 0xFFFFFF, 2.75f, d); - loopi(guns[gun].rays) - { + loopi(guns[gun].rays) { if(d->quadmillis) particle_trail(PART_FLAME, 400, hudgunorigin(gun, from, rays[i], d), rays[i], 0x802010, 0.6f, 36); particle_splash(PART_SPARK, 20, 250, rays[i], 0xB49B4B, 0.24f); @@ -562,10 +434,8 @@ namespace game if(muzzlelight) adddynlight(hudgunorigin(gun, d->o, to, d), 30, vec(0.5f, 0.375f, 0.25f), 100, 100, DL_FLASH, 0, vec(0, 0, 0), d); break; } - case GUN_CG: - case GUN_PISTOL: - { + case GUN_PISTOL: { particle_splash(PART_SPARK, 200, 250, to, 0xB49B4B, 0.24f); if(d->quadmillis) particle_trail(PART_FLAME, 400, hudgunorigin(gun, from, to, d), to, 0x802010, 0.6f, 36); @@ -576,7 +446,6 @@ namespace game if(muzzlelight) adddynlight(hudgunorigin(gun, d->o, to, d), gun==GUN_CG ? 30 : 15, vec(0.5f, 0.375f, 0.25f), gun==GUN_CG ? 50 : 100, gun==GUN_CG ? 50 : 100, DL_FLASH, 0, vec(0, 0, 0), d); break; } - case GUN_RL: if(d->quadmillis) particle_trail(PART_FLAME, 400, hudgunorigin(gun, from, to, d), to, 0x802010, 0.6f, 36); @@ -585,9 +454,7 @@ namespace game pspeed = guns[gun].projspeed; newprojectile(from, to, (float)pspeed, local, id, d, gun); break; - - case GUN_GL: - { + case GUN_GL: { float dist = from.dist(to); vec up = to; up.z += dist/8; @@ -597,7 +464,6 @@ namespace game newbouncer(from, up, local, id, d, BNC_GRENADE, guns[gun].ttl, guns[gun].projspeed); break; } - case GUN_RIFLE: particle_splash(PART_SPARK, 200, 250, to, 0xB49B4B, 0.24f); if(d->quadmillis) @@ -609,13 +475,11 @@ namespace game if(muzzlelight) adddynlight(hudgunorigin(gun, d->o, to, d), 25, vec(0.5f, 0.375f, 0.25f), 75, 75, DL_FLASH, 0, vec(0, 0, 0), d); break; } - bool looped = false; if(d->attacksound >= 0 && d->attacksound != sound) d->stopattacksound(); if(d->idlesound >= 0) d->stopidlesound(); fpsent *h = followingplayer(player1); - switch(sound) - { + switch(sound) { case S_CHAINSAW_ATTACK: if(d->attacksound >= 0) looped = true; d->attacksound = sound; @@ -627,114 +491,89 @@ namespace game } if(d->quadmillis && lastmillis-prevaction>200 && !looped) playsound(S_ITEMPUP, d==h ? NULL : &d->o); } - - void particletrack(physent *owner, vec &o, vec &d) - { + void particletrack(physent *owner, vec &o, vec &d) { if(owner->type!=ENT_PLAYER && owner->type!=ENT_AI) return; fpsent *pl = (fpsent *)owner; if(pl->muzzle.x < 0 || pl->lastattackgun != pl->gunselect) return; float dist = o.dist(d); o = pl->muzzle; if(dist <= 0) d = o; - else - { + else { vecfromyawpitch(owner->yaw, owner->pitch, 1, 0, d); float newdist = raycube(owner->o, d, dist, RAY_CLIPMAT|RAY_ALPHAPOLY); d.mul(min(newdist, dist)).add(owner->o); } } - - void dynlighttrack(physent *owner, vec &o, vec &hud) - { + void dynlighttrack(physent *owner, vec &o, vec &hud) { if(owner->type!=ENT_PLAYER && owner->type!=ENT_AI) return; fpsent *pl = (fpsent *)owner; if(pl->muzzle.x < 0 || pl->lastattackgun != pl->gunselect) return; o = pl->muzzle; hud = owner == followingplayer(player1) ? vec(pl->o).add(vec(0, 0, 2)) : pl->muzzle; } - float intersectdist = 1e16f; - - bool intersect(dynent *d, const vec &from, const vec &to, float &dist) // if lineseg hits entity bounding box - { + bool intersect(dynent *d, const vec &from, const vec &to, float &dist) { // if lineseg hits entity bounding box { vec bottom(d->o), top(d->o); bottom.z -= d->eyeheight; top.z += d->aboveeye; return linecylinderintersect(from, to, bottom, top, d->radius, dist); } - - dynent *intersectclosest(const vec &from, const vec &to, fpsent *at, float &bestdist) - { + dynent *intersectclosest(const vec &from, const vec &to, fpsent *at, float &bestdist) { dynent *best = NULL; bestdist = 1e16f; - loopi(numdynents()) - { + loopi(numdynents()) { dynent *o = iterdynents(i); if(o==at || o->state!=CS_ALIVE) continue; float dist; if(!intersect(o, from, to, dist)) continue; - if(distgunselect].damage; if(d->quadmillis) qdam *= 4; dynent *o; float dist; - if(guns[d->gunselect].rays > 1) - { + if(guns[d->gunselect].rays > 1) { dynent *hits[MAXRAYS]; int maxrays = guns[d->gunselect].rays; - loopi(maxrays) - { + loopi(maxrays) { if((hits[i] = intersectclosest(from, rays[i], d, dist))) shorten(from, rays[i], dist); else adddecal(DECAL_BULLET, rays[i], vec(from).sub(rays[i]).safenormalize(), 2.0f); } - loopi(maxrays) if(hits[i]) - { + loopi(maxrays) if(hits[i]) { o = hits[i]; hits[i] = NULL; int numhits = 1; - for(int j = i+1; j < maxrays; j++) if(hits[j] == o) - { + for(int j = i+1; j < maxrays; j++) if(hits[j] == o) { hits[j] = NULL; numhits++; } hitpush(numhits*qdam, o, d, from, to, d->gunselect, numhits); } } - else if((o = intersectclosest(from, to, d, dist))) - { + else if((o = intersectclosest(from, to, d, dist))) { shorten(from, to, dist); hitpush(qdam, o, d, from, to, d->gunselect, 1); } else if(d->gunselect!=GUN_FIST) adddecal(DECAL_BULLET, to, vec(from).sub(to).safenormalize(), d->gunselect==GUN_RIFLE ? 3.0f : 2.0f); } - - void shoot(fpsent *d, const vec &targ) - { + void shoot(fpsent *d, const vec &targ) { int prevaction = d->lastaction, attacktime = lastmillis-prevaction; if(attacktimegunwait) return; d->gunwait = 0; if((d==player1 || d->ai) && !d->attacking) return; d->lastaction = lastmillis; d->lastattackgun = d->gunselect; - if(!d->ammo[d->gunselect]) - { - if(d==player1) - { + if(!d->ammo[d->gunselect]) { + if(d==player1) { msgsound(S_NOAMMO, d); d->gunwait = 600; d->lastattackgun = -1; @@ -743,9 +582,7 @@ namespace game return; } if(d->gunselect) d->ammo[d->gunselect]--; - pwshot(d->gunselect); /// PW - vec from = d->o, to = targ, dir = vec(to).sub(from).safenormalize(); float dist = to.dist(from); vec kickback = vec(dir).mul(guns[d->gunselect].kickamount*-2.5f); @@ -757,65 +594,48 @@ namespace game if(barrier > 0 && barrier < dist && (!shorten || barrier < shorten)) shorten = barrier; if(shorten) to = vec(dir).mul(shorten).add(from); - if(guns[d->gunselect].rays > 1) createrays(d->gunselect, from, to); else if(guns[d->gunselect].spread) offsetray(from, to, guns[d->gunselect].spread, guns[d->gunselect].range, to); - hits.setsize(0); - if(!guns[d->gunselect].projspeed) raydamage(from, to, d); - shoteffects(d->gunselect, from, to, d, true, 0, prevaction); - - if(d==player1 || d->ai) - { + if(d==player1 || d->ai) { addmsg(N_SHOOT, "rci2i6iv", d, lastmillis-maptime, d->gunselect, (int)(from.x*DMF), (int)(from.y*DMF), (int)(from.z*DMF), (int)(to.x*DMF), (int)(to.y*DMF), (int)(to.z*DMF), hits.length(), hits.length()*sizeof(hitmsg)/sizeof(int), hits.getbuf()); } - d->gunwait = guns[d->gunselect].attackdelay; if(d->gunselect == GUN_PISTOL && d->ai) d->gunwait += int(d->gunwait*(((101-d->skill)+rnd(111-d->skill))/100.f)); d->totalshots += guns[d->gunselect].damage*(d->quadmillis ? 4 : 1)*guns[d->gunselect].rays; } - - void adddynlights() - { - loopv(projs) - { + void adddynlights() { + loopv(projs) { projectile &p = projs[i]; if(p.gun!=GUN_RL) continue; vec pos(p.o); pos.add(vec(p.offset).mul(p.offsetmillis/float(OFFSETMILLIS))); adddynlight(pos, 20, vec(1, 0.75f, 0.5f)); } - loopv(bouncers) - { + loopv(bouncers) { bouncer &bnc = *bouncers[i]; if(bnc.bouncetype!=BNC_GRENADE) continue; vec pos = bnc.offsetpos(); adddynlight(pos, 8, vec(0.25f, 1, 1)); } } - static const char * const projnames[2] = { "projectiles/grenade", "projectiles/rocket" }; - void preloadbouncers() { loopi(sizeof(projnames)/sizeof(projnames[0])) preloadmodel(projnames[i]); } - - void renderbouncers() - { + void renderbouncers() { float yaw, pitch; - loopv(bouncers) - { + loopv(bouncers) { bouncer &bnc = *bouncers[i]; vec pos = bnc.offsetpos(); vec vel(bnc.vel); if(vel.magnitude() <= 25.0f) yaw = bnc.lastyaw; - else - { + else { vectoyawpitch(vel, yaw, pitch); yaw += 90; bnc.lastyaw = yaw; @@ -823,8 +643,7 @@ namespace game pitch = -bnc.roll; if(bnc.bouncetype==BNC_GRENADE) rendermodel(&bnc.light, "projectiles/grenade", ANIM_MAPMODEL|ANIM_LOOP, pos, yaw, pitch, MDL_CULL_VFC|MDL_CULL_OCCLUDED|MDL_LIGHT|MDL_LIGHT_FAST|MDL_DYNSHADOW); - else - { + else { const char *mdl = NULL; int cull = MDL_CULL_VFC|MDL_CULL_DIST|MDL_CULL_OCCLUDED; float fade = 1; @@ -833,12 +652,9 @@ namespace game } } } - - void renderprojectiles() - { + void renderprojectiles() { float yaw, pitch; - loopv(projs) - { + loopv(projs) { projectile &p = projs[i]; if(p.gun!=GUN_RL) continue; float dist = min(p.o.dist(p.to)/32.0f, 1.0f); @@ -852,12 +668,9 @@ namespace game rendermodel(&p.light, "projectiles/rocket", ANIM_MAPMODEL|ANIM_LOOP, v, yaw, pitch, MDL_CULL_VFC|MDL_CULL_OCCLUDED|MDL_LIGHT|MDL_LIGHT_FAST); } } - - void checkattacksound(fpsent *d, bool local) - { + void checkattacksound(fpsent *d, bool local) { int gun = -1; - switch(d->attacksound) - { + switch(d->attacksound) { case S_CHAINSAW_ATTACK: if(chainsawhudgun) gun = GUN_FIST; break; @@ -866,74 +679,57 @@ namespace game } if(gun >= 0 && gun < NUMGUNS && d->clientnum >= 0 && d->state == CS_ALIVE && - d->lastattackgun == gun && lastmillis - d->lastaction < guns[gun].attackdelay + 50) - { + d->lastattackgun == gun && lastmillis - d->lastaction < guns[gun].attackdelay + 50) { d->attackchan = playsound(d->attacksound, local ? NULL : &d->o, NULL, 0, -1, -1, d->attackchan); if(d->attackchan < 0) d->attacksound = -1; } else d->stopattacksound(); } - - void checkidlesound(fpsent *d, bool local) - { + void checkidlesound(fpsent *d, bool local) { int sound = -1, radius = 0; - if(d->clientnum >= 0 && d->state == CS_ALIVE) switch(d->gunselect) - { + if(d->clientnum >= 0 && d->state == CS_ALIVE) switch(d->gunselect) { case GUN_FIST: - if(chainsawhudgun && d->attacksound < 0) - { + if(chainsawhudgun && d->attacksound < 0) { sound = S_CHAINSAW_IDLE; radius = 50; } break; } - if(d->idlesound != sound) - { + if(d->idlesound != sound) { if(d->idlesound >= 0) d->stopidlesound(); - if(sound >= 0) - { + if(sound >= 0) { d->idlechan = playsound(sound, local ? NULL : &d->o, NULL, 0, -1, 100, d->idlechan, radius); if(d->idlechan >= 0) d->idlesound = sound; } } - else if(sound >= 0) - { + else if(sound >= 0) { d->idlechan = playsound(sound, local ? NULL : &d->o, NULL, 0, -1, -1, d->idlechan, radius); if(d->idlechan < 0) d->idlesound = -1; } } - - void removeweapons(fpsent *d) - { + void removeweapons(fpsent *d) { removebouncers(d); removeprojectiles(d); } - - void updateweapons(int curtime) - { + void updateweapons(int curtime) { updateprojectiles(curtime); pwcalcaccuracy(); if(player1->clientnum>=0 && player1->state==CS_ALIVE) shoot(player1, worldpos); // only shoot when connected to server updatebouncers(curtime); // need to do this after the player shoots so grenades don't end up inside player's BB next frame fpsent *following = followingplayer(); if(!following) following = player1; - loopv(players) - { + loopv(players) { fpsent *d = players[i]; checkattacksound(d, d==following); checkidlesound(d, d==following); } } - - void avoidweapons(ai::avoidset &obstacles, float radius) - { - loopv(projs) - { + void avoidweapons(ai::avoidset &obstacles, float radius) { + loopv(projs) { projectile &p = projs[i]; obstacles.avoidnear(NULL, p.o.z + guns[p.gun].exprad + 1, p.o, radius + guns[p.gun].exprad); } - loopv(bouncers) - { + loopv(bouncers) { bouncer &bnc = *bouncers[i]; if(bnc.bouncetype != BNC_GRENADE) continue; obstacles.avoidnear(NULL, bnc.o.z + guns[GUN_GL].exprad + 1, bnc.o, radius + guns[GUN_GL].exprad); -- cgit v1.2.3