From 734affbb0c911e2cdb7c1d93312a6de327c62630 Mon Sep 17 00:00:00 2001 From: driAn Date: Sat, 29 Oct 2005 17:00:43 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@79 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/clientgame.cpp | 14 +- source/src/cube.h | 9 +- source/src/physics.cpp | 34 +++- source/src/protos.h | 5 +- source/src/renderextras.cpp | 16 +- source/src/rendergl.cpp | 2 +- source/src/rendermd3.cpp | 2 +- source/src/weapon.cpp | 327 ++++++++++++++++++------------------ 8 files changed, 211 insertions(+), 198 deletions(-) diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index 30ba5697..cde5ff4e 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -315,13 +315,13 @@ void mphysents() loopv(physents) if(physents[i]) { physent *p = physents[i]; - if(p->throwed) movephysent(p); - if(lastmillis - p->millis >= 5000) - { - explode_nade(physents[i]); - physents.remove(i); - i--; - }; + if(p->throwed) moveplayer(p, 2, false); + if(lastmillis - p->millis >= p->lifetime) + { + explode_nade(physents[i]); + physents.remove(i); + i--; + }; }; }; diff --git a/source/src/cube.h b/source/src/cube.h index 3c55d5d9..b7a1187f 100644 --- a/source/src/cube.h +++ b/source/src/cube.h @@ -165,14 +165,17 @@ struct dynent // players & monsters bool reloading, hasarmour; int primary; //primary gun int nextprimary; - md3state animstate[3]; + md3state animstate[3]; + + int gravity; + bool bounce; }; struct physent : dynent // inheritance: tons of unused stuff, but makes life easier { - vec rot; - int millis; + int millis, lifetime; bool throwed; + bool enabled; dynent *owner; }; diff --git a/source/src/physics.cpp b/source/src/physics.cpp index e3ecf662..6ffbd38c 100644 --- a/source/src/physics.cpp +++ b/source/src/physics.cpp @@ -132,7 +132,10 @@ bool collide(dynent *d, bool spawn, float drop, float rise) const float space = d->o.z-d->eyeheight-lo; if(space<0) { - if(space>-0.01) d->o.z = lo+d->eyeheight; // stick on step + if(space>-0.01) + { + d->o.z = lo+d->eyeheight; // stick on step + } else if(space>-1.26f) d->o.z += rise; // rise thru stair else return false; } @@ -197,7 +200,7 @@ void moveplayer(dynent *pl, int moveres, bool local, int curtime) d.x = (float)(pl->move*cos(rad(pl->yaw-90))); d.y = (float)(pl->move*sin(rad(pl->yaw-90))); - d.z = 0; + d.z = (float) pl->bounce ? pl->vel.z : 0; if(floating || water) { @@ -226,7 +229,7 @@ void moveplayer(dynent *pl, int moveres, bool local, int curtime) if(floating) // just apply velocity { vadd(pl->o, d); - if(pl->jumpnext) { pl->jumpnext = false; pl->vel.z = 2; } + if(pl->jumpnext) { pl->jumpnext = false; pl->vel.z = 2; } } else // apply velocity with collision { @@ -257,14 +260,15 @@ void moveplayer(dynent *pl, int moveres, bool local, int curtime) if(local) playsoundc(S_LAND); else if(pl->monsterstate) playsound(S_LAND, &pl->o); }; - pl->timeinair = 0; + pl->timeinair = 0; + if(pl->bounce) pl->vel.z *= 0.7f; } else { pl->timeinair += curtime; }; - const float gravity = 20; + const float gravity = pl->bounce ? pl->gravity : 20; const float f = 1.0f/moveres; float dropf = ((gravity-1)+pl->timeinair/15.0f); // incorrect, but works fine if(water) { dropf = 5; pl->timeinair = 0; }; // float slowly down in water @@ -281,17 +285,31 @@ void moveplayer(dynent *pl, int moveres, bool local, int curtime) // player stuck, try slide along y axis pl->blocked = true; pl->o.x -= f*d.x; - if(collide(pl, false, drop, rise)) { d.x = 0; continue; }; + if(collide(pl, false, drop, rise)) + { + d.x = 0; + if(pl->bounce) pl->vel.x = -pl->vel.x; + continue; + }; pl->o.x += f*d.x; // still stuck, try x axis pl->o.y -= f*d.y; - if(collide(pl, false, drop, rise)) { d.y = 0; continue; }; + if(collide(pl, false, drop, rise)) + { + d.y = 0; + if(pl->bounce) pl->vel.y = -pl->vel.y; + continue; + }; pl->o.y += f*d.y; // try just dropping down pl->moving = false; pl->o.x -= f*d.x; pl->o.y -= f*d.y; - if(collide(pl, false, drop, rise)) { d.y = d.x = 0; continue; }; + if(collide(pl, false, drop, rise)) + { + d.y = d.x = 0; + continue; + }; pl->o.z -= f*d.z; break; }; diff --git a/source/src/protos.h b/source/src/protos.h index 60d5c8f3..22ce90d1 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -37,7 +37,7 @@ extern void writeservercfg(); extern void gl_init(int w, int h); extern void cleangl(); extern void gl_drawframe(int w, int h, float changelod, float curfps); -extern bool installtex(int tnum, char *texname, int &xs, int &ys, bool clamp = false); +extern bool installtex(int tnum, char *texname, int &xs, int &ys, bool clamp = false, bool highqual=false); extern void mipstats(int a, int b, int c); extern void vertf(float v1, float v2, float v3, sqr *ls, float t1, float t2); extern void addstrip(int tex, int start, int n); @@ -234,7 +234,8 @@ extern void moveprojectiles(float time); extern void projreset(); extern dynent *playerincrosshair(); extern int reloadtime(int gun); -extern int attackdelay(int gun); +extern int attackdelay(int gun); +extern int magsize(int gun); extern int kick_rot(int gun); extern int kick_back(int gun); diff --git a/source/src/renderextras.cpp b/source/src/renderextras.cpp index 69af7559..ff337051 100644 --- a/source/src/renderextras.cpp +++ b/source/src/renderextras.cpp @@ -104,7 +104,7 @@ void renderspheres(int time) { glDepthMask(GL_FALSE); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBindTexture(GL_TEXTURE_2D, 4); for(sphere *p, **pp = &slist; p = *pp;) @@ -129,7 +129,7 @@ void renderspheres(int time) } else { - p->size += time/100.0f; + p->size += time/30.0f; pp = &p->next; }; }; @@ -361,7 +361,7 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat draw_textf("%d", 90, 827, 2, player1->health); if(player1->armour) draw_textf("%d", 390, 827, 2, player1->armour); //draw_textf("%d", 690, 827, 2, player1->mag[player1->gunselect]); - if (!player1->reloading && player1->gunselect!=GUN_KNIFE) + if (player1->gunselect!=GUN_KNIFE) { //draw_textf("%d", 690, 827, 2, player1->mag[player1->gunselect]); char gunstats [64]; @@ -370,15 +370,14 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat //clean up pointer? //delete gunstats; } - else if(player1->reloading) draw_textf("reload", 690, 827, 2, 0); glPopMatrix(); glPushMatrix(); glOrtho(0, VIRTW, VIRTH, 0, -1, 1); glDisable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA); - glColor4f(1.0f, 1.0f, 1.0f, (float) (sin(lastmillis/100)+1)/2); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(1.0f, 1.0f, 1.0f, (float) 0.2f+(sin(lastmillis/100)+1)/2); if(player1->health <= 20) { @@ -392,7 +391,7 @@ void gl_drawhud(int w, int h, int curfps, int nquads, int curvert, bool underwat int r = 64; if(g>2) { g -= 3; r = 128; }; - if(!player1->ammo[player1->gunselect] && !player1->mag[player1->gunselect]) + if(player1->ammo[player1->gunselect] < magsize(player1->gunselect)) { glEnable(GL_BLEND); drawicon((float)(g*64), (float)r, 1220, 1650); @@ -476,7 +475,6 @@ void rendershotlines() glEnable(GL_TEXTURE_2D); glPopMatrix(); - }; }; @@ -485,7 +483,7 @@ void renderphysents() loopv(physents) { physent *d = physents[i]; - if(d && d->throwed) rendermodel("vwep/grenade", 0, 1, 0, 1.5f, d->o.x, d->o.z, d->o.y, d->yaw, d->pitch, false, 2.0f, 100, 0, 0); + if(d && d->throwed) rendermodel("vwep/grenade", 0, 1, 0, 0.2f, d->o.x, d->o.z, d->o.y, 0, 0, false, 2.0f, 100, 0, 0); }; }; diff --git a/source/src/rendergl.cpp b/source/src/rendergl.cpp index fb674810..27e60f3f 100644 --- a/source/src/rendergl.cpp +++ b/source/src/rendergl.cpp @@ -67,7 +67,7 @@ void cleangl() if(qsphere) gluDeleteQuadric(qsphere); }; -bool installtex(int tnum, char *texname, int &xs, int &ys, bool clamp) +bool installtex(int tnum, char *texname, int &xs, int &ys, bool clamp, bool highqual=false) { SDL_Surface *s = IMG_Load(texname); if(!s) { conoutf("couldn't load texture %s", (int)texname); return false; }; diff --git a/source/src/rendermd3.cpp b/source/src/rendermd3.cpp index d1e6f31d..279d7614 100644 --- a/source/src/rendermd3.cpp +++ b/source/src/rendermd3.cpp @@ -307,7 +307,7 @@ void md3skin(char *objname, char *skin) // called by the {lower|upper|head}.cfg { int xs, ys; sprintf_sd(path)("%s/%s", basedir, skin); // 'skin' is a relative url - installtex(FIRSTMD3 + numskins, path, xs, ys); + installtex(FIRSTMD3 + numskins, path, xs, ys, true); mesh->tex = numskins; numskins++; }; diff --git a/source/src/weapon.cpp b/source/src/weapon.cpp index 99ce00a8..30bcc5c5 100644 --- a/source/src/weapon.cpp +++ b/source/src/weapon.cpp @@ -6,52 +6,25 @@ struct guninfo { short sound, reload, reloadtime, attackdelay, damage, projspee const int SGRAYS = 20; //down from 20 (defualt) const float SGSPREAD = 2; -vec sg[SGRAYS]; - -//FIXME!!! -VAR(pistol_rot, 0, 6, 100); VAR(pistol_back, 0, 5, 100); -VAR(shotgun_rot, 0, 10, 100); VAR(shotgun_back, 0, 10, 100); -VAR(subgun_rot, 0, 3, 100); VAR(subgun_back, 0, 2, 100); -VAR(sniper_rot, 0, 3, 100); VAR(sniper_back, 0, 2, 100); -VAR(assult_rot, 0, 4, 100); VAR(assult_back, 0, 2, 100); +vec sg[SGRAYS]; //change the particales guninfo guns[NUMGUNS] = { { S_KNIFE, S_NULL, 0, 250, 50, 0, 0, 1, 1, 1, 0, 0, "knife" }, - { S_PISTOL, S_RPISTOL, 1400, 170, 20, 0, 0, 80, 10, 8, pistol_rot, pistol_back, "pistol" }, // *SGRAYS + { S_PISTOL, S_RPISTOL, 1400, 170, 20, 0, 0, 80, 10, 8, 6, 5, "pistol" }, // *SGRAYS - { S_SHOTGUN, S_RSHOTGUN, 2400, 1000, 6, 0, 0, 1, 35, 7, shotgun_rot, shotgun_back, "shotgun" }, //reload time is for 1 shell from 7 too powerful to 6 + { S_SHOTGUN, S_RSHOTGUN, 2400, 1000, 6, 0, 0, 1, 35, 7, 9, 9, "shotgun" }, //reload time is for 1 shell from 7 too powerful to 6 - { S_SUBGUN, S_RSUBGUN, 1650, 80, 17, 0, 0, 70, 15, 30, subgun_rot, subgun_back, "subgun" }, + { S_SUBGUN, S_RSUBGUN, 1650, 80, 17, 0, 0, 70, 15, 30, 1, 2, "subgun" }, - { S_SNIPER, S_RSNIPER, 1950, 1500, 72, 0, 0, 60, 50, 5, sniper_rot, sniper_back, "sniper" }, + { S_SNIPER, S_RSNIPER, 1950, 1500, 72, 0, 0, 60, 50, 5, 4, 4, "sniper" }, - { S_ASSULT, S_RASSULT, 2000, 130, 20, 0, 0, 20, 40, 20, assult_rot, assult_back, "assult" }, //recoil was 44 + { S_ASSULT, S_RASSULT, 2000, 130, 20, 0, 0, 20, 40, 20, 0, 2, "assult" }, //recoil was 44 - { S_GRENADE, S_NULL, 0, 2000, 180, 30, 6, 1, 1, 1, 3, 1, "grenade" }, + { S_GRENADE, S_NULL, 1000, 2000, 130, 30, 6, 1, 1, 1, 3, 1, "grenade" }, }; - -void updatekickback() { -guninfo tmp[NUMGUNS] = -{ - { S_KNIFE, S_NULL, 0, 250, 50, 0, 0, 1, 1, 1, 0, 0, "knife" }, - - { S_PISTOL, S_RPISTOL, 1400, 170, 20, 0, 0, 20, 10, 8, pistol_rot, pistol_back, "pistol" }, // *SGRAYS - - { S_SHOTGUN, S_RSHOTGUN, 2400, 1100, 6, 0, 0, 1, 35, 7, shotgun_rot, shotgun_back, "shotgun" }, //reload time is for 1 shell from 7 too powerful to 6 - - { S_SUBGUN, S_RSUBGUN, 1650, 90, 14, 0, 0, 45, 15, 30, subgun_rot, subgun_back, "subgun" }, - - { S_SNIPER, S_RSNIPER, 1950, 1500, 72, 0, 0, 60, 50, 5, sniper_rot, sniper_back, "sniper" }, - - { S_ASSULT, S_RASSULT, 2000, 130, 33, 0, 0, 90, 40, 20, assult_rot, assult_back, "assult" }, //recoil was 44 - - { S_GRENADE, S_NULL, 0, 2000, 40, 30, 6, 1, 1, 1, 3, 1, "grenade" }, -}; -guns=tmp; -};COMMAND(updatekickback, ARG_NONE); //weapon selection @@ -150,6 +123,7 @@ COMMAND(reload,ARG_NONE); int reloadtime(int gun) { return guns[gun].reloadtime; }; int attackdelay(int gun) { return guns[gun].attackdelay; }; +int magsize(int gun) { return guns[gun].magsize; }; int kick_rot(int gun) { return guns[gun].mdl_kick_rot; }; int kick_back(int gun) { return guns[gun].mdl_kick_back; }; @@ -334,87 +308,101 @@ extern float rad(float x); bool nade_activated = false; physent *curnade; -void thrownade(dynent *d, vec &to, bool prepare) +void thrownade(dynent *d, vec &to, dynent *nade = NULL, int nadesec = 0) { physent *p; - if(prepare) p = (physent *)gp()->alloc(sizeof(physent)); - else if(curnade) p = curnade; - else return; + if(nade) p = nade; + else p = (physent *)gp()->alloc(sizeof(physent)); // allocate new nade p->owner = d; - if(!prepare) - { - p->yaw = 270; - p->pitch = 0; - p->roll = 0; - p->maxspeed = 16; //16 max speed, 14 max with armour - p->outsidemap = false; - p->inwater = false; - p->radius = 0.2f; - p->eyeheight = 0.3; - p->aboveeye = 0.0f; - p->frags = 0; - p->plag = 0; - p->ping = 0; - p->lastupdate = lastmillis; - p->enemy = NULL; - p->monsterstate = 0; - p->name[0] = p->team[0] = 0; - p->blocked = false; - p->lifesequence = 0; - p->state = CS_ALIVE; - p->shots = 0; - p->reloading = false; - p->nextprimary = 1; - p->hasarmour = false; + p->yaw = 270; + p->pitch = 0; + p->roll = 0; + p->maxspeed = 35; //16 max speed, 14 max with armour + p->outsidemap = false; + p->inwater = false; + p->radius = 0.2f; + p->eyeheight = 0.3f; + p->aboveeye = 0.0f; + p->frags = 0; + p->plag = 0; + p->ping = 0; + p->lastupdate = lastmillis; + p->enemy = NULL; + p->monsterstate = 0; + p->name[0] = p->team[0] = 0; + p->blocked = false; + p->lifesequence = 0; + p->state = CS_ALIVE; + p->shots = 0; + p->reloading = false; + p->nextprimary = 1; + p->hasarmour = false; + + p->k_left = false; + p->k_right = false; + p->k_up = false; + p->k_down = false; + p->jumpnext = false; + p->strafe = 0; + p->move = 0; + + p->bounce = true; + p->gravity = 20; + + p->timeinair = 0; + p->throwed = true; + p->onfloor = false; + p->lifetime = 3000; + + p->o = d->o; + p->o.z += d->eyeheight; + + p->vel.x = sin(rad(d->yaw)); + p->vel.y = -cos(rad(d->yaw)); + p->vel.z = 0; + + //float speed = min(135, d->pitch+45)/135; + float speed = sin(rad((d->pitch+90)/2)); + p->vel.x *= speed; + p->vel.y *= speed; + + p->vel.z = speed; +// p->vel.z = (d->pitch+90)/180*2.5f; + //p->vel.z = cos(rad(d->pitch+90)); + //vmul(p->vel, 2.0f); - p->k_left = false; - p->k_right = false; - p->k_up = false; - p->k_down = false; - p->jumpnext = false; - p->strafe = 0; - p->move = 0; - - p->timeinair = 0; - p->throwed = true; - p->onfloor = false; - - p->o = d->o; - - p->vel.x = sin(rad(d->yaw)); - p->vel.y = -cos(rad(d->yaw)); - p->vel.z = 0; - - float speed = (d->pitch+90)/180; - p->vel.x *= speed; - p->vel.y *= speed; - - p->vel.z = (d->pitch+90)/180; - vmul(p->vel, 2.2f); - - vadd(p->o, p->vel); vadd(p->o, p->vel); //vadd(p->o, p->vel); vadd(p->o, p->vel); - } - else + if(!nade) // add new one { p->millis = lastmillis; - physents.add(p); + physents.add(p); }; +}; +void activate_nade() +{ + physent *p = (physent *)gp()->alloc(sizeof(physent)); + p->owner = player1; + p->millis = lastmillis; + p->lifetime = 3000; + p->throwed = false; + p->enabled = true; curnade = p; - nade_activated = prepare; + physents.add(p); + + nade_activated = true; }; extern void explode_nade(physent *i) -{ - /*struct projectile { vec o, to; float speed; dynent *owner; int gun; bool inuse, local; }; - - projectile p; - p.o = - - splash(projectile *p, vec &v, vec &vold, int notthisplayer, int notthismonster, int qdam);*/ - +{ if(!i) return; + if(!i->throwed) + { + vec o = i->owner->o; + vec dist = { 0.1f, 0.1f, 0.1f }; + vadd(o, dist); + thrownade(i->owner, o, i); + }; newprojectile(i->o, i->o, 1, true, i->owner, GUN_GRENADE); }; @@ -444,12 +432,10 @@ void shootv(int gun, vec &from, vec &to, dynent *d, bool local, int nadesec) case GUN_GRENADE: pspeed = guns[gun].projspeed; //newprojectile(from, to, (float)pspeed, local, d, gun); - thrownade(d, to, d==player1 ? d->attacking : false); - if(curnade) - { - curnade->millis = lastmillis - nadesec; - - }; + if(d==player1 && curnade) + thrownade(d, to, curnade); + else + thrownade(d, to, NULL, nadesec); break; case GUN_SNIPER: @@ -484,7 +470,7 @@ void raydamage(dynent *o, vec &from, vec &to, dynent *d, int i) void spreadandrecoil(vec & from, vec & to, dynent * d) { //nothing special for a knife - if (d->gunselect==GUN_KNIFE) return; + if (d->gunselect==GUN_KNIFE || d->gunselect==GUN_GRENADE) return; //spread vdist(dist, unitv, from, to); @@ -553,68 +539,75 @@ void spreadandrecoil(vec & from, vec & to, dynent * d) vadd(d->vel, recoil); if(d->pitch<80.0f) d->pitch += guns[d->gunselect].recoil*0.05f; */ -}; - -void shoot(dynent *d, vec &targ) +}; + +void shoot(dynent *d, vec &targ) { - if(d==player1 && d->gunselect==GUN_GRENADE) // throw nade at mouse release - { - if(d->attacking && !nade_activated) - { - thrownade(d, targ, true); - return; - } - else if(d->attacking && nade_activated) return; - else if(!d->attacking && nade_activated) d->attacking = true; - } - int attacktime = lastmillis-d->lastaction; - if(d->reloading && (attacktimegunwait)) return; - else if(attacktimegunwait) return; - d->gunwait = 0; - d->reloading = false; + bool grenade_throw = d->gunselect==GUN_GRENADE && !d->attacking && nade_activated; + int attacktime = lastmillis-d->lastaction; + if(d->reloading && (attacktimegunwait) && !grenade_throw) return; + else if(attacktimegunwait) return; + d->gunwait = 0; + d->reloading = false; + if(grenade_throw) + { + d->attacking = true; + nade_activated = false; + d->gunwait = guns[d->gunselect].attackdelay; + } + else if(d->gunselect==GUN_GRENADE && d->attacking && nade_activated) return; if(!d->attacking) { d->shots = 0; return; - }; - if(!(d->gunselect==GUN_SUBGUN || d->gunselect==GUN_ASSULT)) d->attacking = false; //makes sub/assult autos - else - { - d->shots++; - }; - d->lastaction = lastmillis; - d->lastattackgun = d->gunselect; - if(!d->mag[d->gunselect]) { playsoundc(S_NOAMMO); d->gunwait = 250; d->lastattackgun = -1; return; }; - if(d->gunselect) d->mag[d->gunselect]--; - vec from = d->o; - vec to = targ; - from.z -= 0.2f; // below eye - - spreadandrecoil(from,to,d); - - vdist(dist, unitv, from, to); - vdiv(unitv, dist); - - if(d->gunselect==GUN_KNIFE) - { - vmul(unitv, 3); // punch range - to = from; - vadd(to, unitv); - }; - if(d->gunselect==GUN_SHOTGUN) createrays(from, to); - - //if(d->quadmillis && attacktime>200) playsoundc(S_ITEMPUP); - shootv(d->gunselect, from, to, d, true); - addmsg(1, 9, SV_SHOT, 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), (int) (d==player1 && d->gunselect==GUN_GRENADE ? lastmillis-curnade->millis : 0) ); - d->gunwait = guns[d->gunselect].attackdelay; - - if(guns[d->gunselect].projspeed) return; - - loopv(players) - { - dynent *o = players[i]; - if(!o) continue; - raydamage(o, from, to, d, i); - }; - + }; + if(!(d->gunselect==GUN_SUBGUN || d->gunselect==GUN_ASSULT)) d->attacking = false; //makes sub/assult autos + else + { + d->shots++; + }; + d->lastaction = lastmillis; + d->lastattackgun = d->gunselect; + if(!d->mag[d->gunselect]) { playsoundc(S_NOAMMO); d->gunwait = 250; d->lastattackgun = -1; return; }; + + if(d->gunselect==GUN_GRENADE && !grenade_throw) + { + activate_nade(); + d->attacking = true; + return; + } + + if(d->gunselect) d->mag[d->gunselect]--; + + vec from = d->o; + vec to = targ; + from.z -= 0.2f; // below eye + + spreadandrecoil(from,to,d); + + vdist(dist, unitv, from, to); + vdiv(unitv, dist); + + if(d->gunselect==GUN_KNIFE) + { + vmul(unitv, 3); // punch range + to = from; + vadd(to, unitv); + }; + if(d->gunselect==GUN_SHOTGUN) createrays(from, to); + + //if(d->quadmillis && attacktime>200) playsoundc(S_ITEMPUP); + shootv(d->gunselect, from, to, d, 0); + addmsg(1, 9, SV_SHOT, 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), (int) grenade_throw ? lastmillis-curnade->millis : 0 ); + d->gunwait = guns[d->gunselect].attackdelay; + + if(guns[d->gunselect].projspeed) return; + + loopv(players) + { + dynent *o = players[i]; + if(!o) continue; + raydamage(o, from, to, d, i); + }; + };