From 79f2de1d181fd75b217377682c8b921975a084d9 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Thu, 11 Sep 2008 00:17:39 +0000 Subject: [PATCH] muzzle flashes on vweps git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@2508 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- packages/models/weapons/assault/world/md2.cfg | 4 ++ packages/models/weapons/grenade/world/md2.cfg | 1 + packages/models/weapons/knife/world/md2.cfg | 1 + packages/models/weapons/pistol/world/md2.cfg | 4 ++ packages/models/weapons/shotgun/md3.cfg | 2 +- packages/models/weapons/shotgun/world/md2.cfg | 4 ++ packages/models/weapons/sniper/world/md2.cfg | 4 ++ packages/models/weapons/subgun/world/md2.cfg | 4 ++ source/src/md2.h | 35 +++++++++++ source/src/protos.h | 3 +- source/src/rendermodel.cpp | 3 + source/src/renderparticles.cpp | 13 ++-- source/src/vertmodel.h | 63 +++++++++++++++++++ source/src/weapon.cpp | 4 +- source/src/weapon.h | 2 + 15 files changed, 140 insertions(+), 7 deletions(-) diff --git a/packages/models/weapons/assault/world/md2.cfg b/packages/models/weapons/assault/world/md2.cfg index f2d16e2d..0b51ec49 100644 --- a/packages/models/weapons/assault/world/md2.cfg +++ b/packages/models/weapons/assault/world/md2.cfg @@ -1,2 +1,6 @@ mdlscale 155 mdltrans 0 0 24 + +md2tag tag_muzzle -Y +md2emit tag_muzzle 11 50 75 + diff --git a/packages/models/weapons/grenade/world/md2.cfg b/packages/models/weapons/grenade/world/md2.cfg index f2d16e2d..e7d478a7 100644 --- a/packages/models/weapons/grenade/world/md2.cfg +++ b/packages/models/weapons/grenade/world/md2.cfg @@ -1,2 +1,3 @@ mdlscale 155 mdltrans 0 0 24 + diff --git a/packages/models/weapons/knife/world/md2.cfg b/packages/models/weapons/knife/world/md2.cfg index f2d16e2d..e7d478a7 100644 --- a/packages/models/weapons/knife/world/md2.cfg +++ b/packages/models/weapons/knife/world/md2.cfg @@ -1,2 +1,3 @@ mdlscale 155 mdltrans 0 0 24 + diff --git a/packages/models/weapons/pistol/world/md2.cfg b/packages/models/weapons/pistol/world/md2.cfg index f2d16e2d..71608cb2 100644 --- a/packages/models/weapons/pistol/world/md2.cfg +++ b/packages/models/weapons/pistol/world/md2.cfg @@ -1,2 +1,6 @@ mdlscale 155 mdltrans 0 0 24 + +md2tag tag_muzzle -Y +md2emit tag_muzzle 11 50 25 + diff --git a/packages/models/weapons/shotgun/md3.cfg b/packages/models/weapons/shotgun/md3.cfg index 643bbdfb..a0a4dd99 100644 --- a/packages/models/weapons/shotgun/md3.cfg +++ b/packages/models/weapons/shotgun/md3.cfg @@ -4,4 +4,4 @@ md3skin hands skin_hands.jpg md3anim "gun idle" 0 1 md3anim "gun shoot" 8 25 md3anim "gun reload" 0 1 -md3emit tag_muzzle 10 50 75 \ No newline at end of file +md3emit tag_muzzle 10 50 75 diff --git a/packages/models/weapons/shotgun/world/md2.cfg b/packages/models/weapons/shotgun/world/md2.cfg index f2d16e2d..0b51ec49 100644 --- a/packages/models/weapons/shotgun/world/md2.cfg +++ b/packages/models/weapons/shotgun/world/md2.cfg @@ -1,2 +1,6 @@ mdlscale 155 mdltrans 0 0 24 + +md2tag tag_muzzle -Y +md2emit tag_muzzle 11 50 75 + diff --git a/packages/models/weapons/sniper/world/md2.cfg b/packages/models/weapons/sniper/world/md2.cfg index f2d16e2d..78805176 100644 --- a/packages/models/weapons/sniper/world/md2.cfg +++ b/packages/models/weapons/sniper/world/md2.cfg @@ -1,2 +1,6 @@ mdlscale 155 mdltrans 0 0 24 + +md2tag tag_muzzle -Y +md2emit tag_muzzle 11 50 + diff --git a/packages/models/weapons/subgun/world/md2.cfg b/packages/models/weapons/subgun/world/md2.cfg index f2d16e2d..cddd06dc 100644 --- a/packages/models/weapons/subgun/world/md2.cfg +++ b/packages/models/weapons/subgun/world/md2.cfg @@ -1,2 +1,6 @@ mdlscale 155 mdltrans 0 0 24 + +md2tag tag_muzzle -Y +md2emit tag_muzzle 11 50 55 + diff --git a/source/src/md2.h b/source/src/md2.h index aae83660..a378c9ee 100644 --- a/source/src/md2.h +++ b/source/src/md2.h @@ -259,5 +259,40 @@ void md2anim(char *anim, char *frame, char *range, char *speed) loadingmd2->parts.last()->setanim(num, atoi(frame), atoi(range), atof(speed)); } +void md2tag(char *name, char *vert) +{ + if(!loadingmd2 || loadingmd2->parts.empty()) { conoutf("not loading an md2"); return; } + md2::part &mdl = *loadingmd2->parts.last(); + int vnum = -1; + if(isdigit(vert[0])) vnum = ATOI(vert); + else + { + int axis = 0, dir = 1; + for(char *s = vert; *s; s++) switch(*s) + { + case '+': dir = 1; break; + case '-': dir = -1; break; + case 'x': + case 'X': axis = 0; break; + case 'y': + case 'Y': axis = 1; break; + case 'z': + case 'Z': axis = 2; break; + } + if(!mdl.meshes.empty()) vnum = mdl.meshes[0]->findvert(axis, dir); + if(vnum < 0) { conoutf("could not find vertex %s", vert); return; } + } + if(!mdl.gentag(name, vnum)) { conoutf("could not find vertex %d", vnum); return; } +} + +void md2emit(char *tag, char *type, char *arg1, char *arg2) +{ + if(!loadingmd2 || loadingmd2->parts.empty()) { conoutf("not loading an md2"); return; }; + md2::part &mdl = *loadingmd2->parts.last(); + if(!mdl.addemitter(tag, ATOI(type), ATOI(arg1), ATOI(arg2))) { conoutf("could not find tag %s", tag); return; } +} + COMMAND(md2anim, ARG_4STR); +COMMAND(md2tag, ARG_2STR); +COMMAND(md2emit, ARG_4STR); diff --git a/source/src/protos.h b/source/src/protos.h index 962be9d0..295717db 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -452,7 +452,8 @@ enum PT_BULLETHOLE, PT_BLOOD, PT_STAIN, - PT_FLASH + PT_FLASH, + PT_HUDFLASH }; #define PT_DECAL_MASK ((1<weaponsel==d->lastattackweapon && lastmillis-d->lastaction < d->weaponsel->flashtime()) + anim |= ANIM_PARTICLE; } // FIXME: while networked my state as spectator seems to stay CS_DEAD, not CS_SPECTATE // flowtron: I fixed this for following at least (see followplayer()) diff --git a/source/src/renderparticles.cpp b/source/src/renderparticles.cpp index 2837c7fc..db6e6c08 100644 --- a/source/src/renderparticles.cpp +++ b/source/src/renderparticles.cpp @@ -185,7 +185,7 @@ void cleanupexplosion() } } -#define MAXPARTYPES 11 +#define MAXPARTYPES 12 struct particle { vec o, d; int fade, type; int millis; particle *next; }; particle *parlist[MAXPARTYPES], *parempty = NULL; @@ -261,6 +261,7 @@ static struct parttype { int type; float r, g, b; int gr, tex; float sz; } partt { PT_BULLETHOLE, 1.0f, 1.0f, 1.0f, 0, 3, 0.3f }, // hole decal { PT_STAIN, 0.5f, 0.0f, 0.0f, 0, 4, 0.6f }, // red: blood stain { PT_DECAL, 1.0f, 1.0f, 1.0f, 0, 5, 1.5f }, // scorch decal + { PT_HUDFLASH, 1.0f, 1.0f, 1.0f, 0, 6, 0.7f }, // hudgun muzzle flash { PT_FLASH, 1.0f, 1.0f, 1.0f, 0, 6, 0.7f }, // muzzle flash }; @@ -289,8 +290,10 @@ void render_particles(int time, int typemask) else glDisable(GL_TEXTURE_2D); switch(pt.type) { - case PT_FLASH: + case PT_HUDFLASH: sethudgunperspective(true); + // fall through + case PT_FLASH: glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR); glColor3f(pt.r, pt.g, pt.b); glBegin(GL_QUADS); @@ -339,6 +342,7 @@ void render_particles(int time, int typemask) { switch(pt.type) { + case PT_HUDFLASH: case PT_FLASH: { vec corners[4] = @@ -499,7 +503,7 @@ void render_particles(int time, int typemask) switch(pt.type) { - case PT_FLASH: + case PT_HUDFLASH: glEnd(); sethudgunperspective(false); break; @@ -510,6 +514,7 @@ void render_particles(int time, int typemask) case PT_BULLETHOLE: case PT_BLOOD: case PT_STAIN: + case PT_FLASH: glEnd(); break; @@ -533,7 +538,7 @@ void particle_emit(int type, int *args, int basetime, int seed, vec &p) if(type<0 || type>=MAXPARTYPES) return; parttype &pt = parttypes[type]; if(pt.type==PT_FIREBALL) particle_fireball(type, p); - else if(pt.type==PT_FLASH) + else if(pt.type==PT_FLASH || pt.type==PT_HUDFLASH) { if(lastmillis - basetime < args[0]) particle_flash(type, args[1]>0 ? args[1]/100.0f : 1.0f, seed%360, p); diff --git a/source/src/vertmodel.h b/source/src/vertmodel.h index 07dc06db..101cdbc5 100644 --- a/source/src/vertmodel.h +++ b/source/src/vertmodel.h @@ -193,6 +193,23 @@ struct vertmodel : model xtraverts += dynlen; } } + + int findvert(int axis, int dir) + { + if(axis<0 || axis>2) return -1; + int vert = -1; + float bestval = -1e16f; + loopi(numverts) + { + float val = verts[i][axis]*dir; + if(val > bestval) + { + vert = i; + bestval = val; + } + } + return vert; + } }; struct animinfo @@ -219,6 +236,21 @@ struct vertmodel : model tag() : name(NULL) {} ~tag() { DELETEA(name); } + + void identity() + { + transform[0][0] = 1; + transform[0][1] = 0; + transform[0][2] = 0; + + transform[1][0] = 0; + transform[1][1] = 1; + transform[1][2] = 0; + + transform[2][0] = 0; + transform[2][1] = 0; + transform[2][2] = 1; + } }; struct part @@ -268,6 +300,37 @@ struct vertmodel : model return false; } + bool gentag(const char *name, int vert, mesh *m = NULL) + { + if(!m) + { + if(meshes.empty()) return false; + m = meshes[0]; + } + if(vert < 0 || vert > m->numverts) return false; + + tag *ntags = new tag[(numtags + 1)*numframes]; + ntags[numtags].name = newstring(name); + loopi(numframes) + { + memcpy(&ntags[(numtags + 1)*i], &tags[numtags*i], numtags*sizeof(tag)); + + tag *t = &ntags[(numtags + 1)*i + numtags]; + t->pos = m->verts[m->numverts*i + vert]; + t->identity(); + } + loopi(numtags) tags[i].name = NULL; + + DELETEA(tags); + tags = ntags; + numtags++; + + DELETEA(links); + links = new part *[numtags]; + loopi(numtags) links[i] = NULL; + return true; + } + bool addemitter(const char *tag, int type, int arg1 = 0, int arg2 = 0) { loopi(numtags) if(!strcmp(tags[i].name, tag)) diff --git a/source/src/weapon.cpp b/source/src/weapon.cpp index 5492d4b1..63d107a2 100644 --- a/source/src/weapon.cpp +++ b/source/src/weapon.cpp @@ -443,6 +443,8 @@ weapon::weapon(struct playerent *owner, int type) : type(type), owner(owner), in const int weapon::weaponchangetime = 400; const float weapon::weaponbeloweye = 0.2f; +int weapon::flashtime() const { return max((int)info.attackdelay, 120)/4; } + void weapon::sendshoot(vec &from, vec &to) { if(owner!=player1) return; @@ -536,7 +538,7 @@ void weapon::renderhudmodel(int lastaction, int index) if(!intermission) wm.calcmove(unitv, lastaction); s_sprintfd(path)("weapons/%s", info.modelname); static int lastanim[2], lastswitch[2]; - bool emit = (wm.anim&ANIM_INDEX)==ANIM_GUN_SHOOT && (lastmillis - lastaction) < max((int)info.attackdelay, 120)/4; + bool emit = (wm.anim&ANIM_INDEX)==ANIM_GUN_SHOOT && (lastmillis - lastaction) < flashtime(); if(lastanim[index]!=(wm.anim|(type<<24))) { lastanim[index] = wm.anim|(type<<24); diff --git a/source/src/weapon.h b/source/src/weapon.h index 07b61de7..96490df8 100644 --- a/source/src/weapon.h +++ b/source/src/weapon.h @@ -44,6 +44,8 @@ struct weapon void renderhudmodel(int lastaction, int index = 0); static bool valid(int id); + + int flashtime() const; }; struct grenadeent;