From e83927c2f8ca77b2d64d7ac9f51503551cbcce19 Mon Sep 17 00:00:00 2001 From: terminx Date: Tue, 6 Aug 2013 23:53:34 +0000 Subject: [PATCH] Refactor projectiles a bit. Tested with all of the original weapons and with the weapons in the Duke 64 mod. git-svn-id: https://svn.eduke32.com/eduke32@3992 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/source/actors.c | 674 +++++++++++++++++--------------- polymer/eduke32/source/actors.h | 1 + polymer/eduke32/source/player.c | 577 ++++++++++++++------------- 3 files changed, 641 insertions(+), 611 deletions(-) diff --git a/polymer/eduke32/source/actors.c b/polymer/eduke32/source/actors.c index e3c7e45eb..4f6f072aa 100644 --- a/polymer/eduke32/source/actors.c +++ b/polymer/eduke32/source/actors.c @@ -2644,9 +2644,274 @@ static void Proj_BounceOffWall(spritetype *s, int32_t j) s->ang = ((k<<1) - s->ang)&2047; } +#define PROJ_DECAYVELOCITY s->xvel >>= 1, s->zvel >>= 1 + +ACTOR_STATIC void Proj_MoveCustom(int32_t i) +{ + const projectile_t *const proj = &SpriteProjectile[i]; + spritetype *const s = &sprite[i]; + vec3_t davect; + int32_t j=0; + + if (proj->pal >= 0) + s->pal = proj->pal; + + switch (proj->workslike & PROJECTILE_TYPE_MASK) + { + case PROJECTILE_HITSCAN: + if (!G_HaveActor(sprite[i].picnum)) + return; + { + int32_t x, p = A_FindPlayer(s, &x); + A_Execute(i, p, x); + } + return; + + case PROJECTILE_KNEE: + case PROJECTILE_BLOOD: + A_DeleteSprite(i); + return; + + default: + case PROJECTILE_RPG: + Bmemcpy(&davect, s, sizeof(vec3_t)); + + if (proj->flashcolor) + G_AddGameLight(0, i, ((s->yrepeat*tilesizy[s->picnum])<<1), 2048, proj->flashcolor, PR_LIGHT_PRIO_LOW_GAME); + + if (proj->workslike & PROJECTILE_BOUNCESOFFWALLS && s->yvel < 1) + { + A_DoProjectileEffects(i, NULL, 1); + A_DeleteSprite(i); + return; + } + + if (proj->workslike & PROJECTILE_COOLEXPLOSION1 && ++s->shade >= 40) + { + A_DeleteSprite(i); + return; + } + + s->zvel -= proj->drop; + + if (proj->workslike & PROJECTILE_SPIT && s->zvel < 6144) + s->zvel += g_spriteGravity-112; + + A_GetZLimits(i); + + if (proj->trail >= 0) + { + int32_t cnt; + + for (cnt=0; cnt<=proj->tnum; cnt++) + { + j = A_Spawn(i, proj->trail); + + sprite[j].z += (proj->toffset<<8); + + if (proj->txrepeat >= 0) + sprite[j].xrepeat=proj->txrepeat; + + if (proj->tyrepeat >= 0) + sprite[j].yrepeat=proj->tyrepeat; + } + } + + { + int32_t cnt = proj->movecnt; + int32_t k = s->xvel; + int32_t ll = s->zvel; + + if (sector[s->sectnum].lotag == ST_2_UNDERWATER) + { + k >>= 1; + ll >>= 1; + } + + do + { + vec3_t tmpvect; + Bmemcpy(&davect, s, sizeof(vec3_t)); + + tmpvect.x = (k*(sintable[(s->ang+512)&2047]))>>14; + tmpvect.y = (k*(sintable[s->ang&2047]))>>14; + tmpvect.z = ll; + + j = A_MoveSprite(i, &tmpvect, CLIPMASK1); + } while (!j && --cnt > 0); + } + + if (!(proj->workslike & PROJECTILE_BOUNCESOFFWALLS) && + s->yvel >= 0 && sprite[s->yvel].sectnum != MAXSECTORS) + if (FindDistance2D(s->x-sprite[s->yvel].x, s->y-sprite[s->yvel].y) < 256) + j = 49152|s->yvel; + + actor[i].movflag = j; + + if (s->sectnum < 0) + { + A_DeleteSprite(i); + return; + } + + if (proj->workslike & PROJECTILE_TIMED && proj->range > 0) + { + if (++actor[i].t_data[8] > proj->range) + { + if (proj->workslike & PROJECTILE_EXPLODEONTIMER) + A_DoProjectileEffects(i, &davect, 1); + + A_DeleteSprite(i); + return; + } + } + + if ((j&49152) != 49152 && !(proj->workslike & PROJECTILE_BOUNCESOFFWALLS)) + G_WeaponHitCeilingOrFloor(i, s, &j); + + if (proj->workslike & PROJECTILE_WATERBUBBLES && sector[s->sectnum].lotag == ST_2_UNDERWATER && rnd(140)) + A_Spawn(i, WATERBUBBLE); + + if (j != 0) + { + int32_t k; + + if (proj->workslike & PROJECTILE_COOLEXPLOSION1) + { + s->xvel = 0; + s->zvel = 0; + } + + switch (j&49152) + { + case 49152: + j &= (MAXSPRITES-1); + + if (proj->workslike & PROJECTILE_BOUNCESOFFSPRITES) + { + s->yvel--; + + k = getangle(sprite[j].x-s->x, sprite[j].y-s->y)+(sprite[j].cstat&16 ? 0 : 512); + s->ang = ((k<<1) - s->ang)&2047; + + if (proj->bsound >= 0) + A_PlaySound(proj->bsound, i); + + if (proj->workslike & PROJECTILE_LOSESVELOCITY) + PROJ_DECAYVELOCITY; + + if (!(proj->workslike & PROJECTILE_FORCEIMPACT)) + return; + } + + A_DamageObject(j, i); + + if (sprite[j].picnum == APLAYER) + { + int32_t p = sprite[j].yvel; + + A_PlaySound(PISTOL_BODYHIT, j); + + if (proj->workslike & PROJECTILE_SPIT) + P_HandleBeingSpitOn(g_player[p].ps); + } + + if (proj->workslike & PROJECTILE_RPG_IMPACT) + { + actor[j].owner = s->owner; + actor[j].picnum = s->picnum; + actor[j].extra += proj->extra; + + A_DoProjectileEffects(i, &davect, 0); + + if (!(proj->workslike & PROJECTILE_FORCEIMPACT)) + { + A_DeleteSprite(i); + return; + } + } + + if (proj->workslike & PROJECTILE_FORCEIMPACT) + return; + break; + + case 32768: + j &= (MAXWALLS-1); + + if (proj->workslike & PROJECTILE_BOUNCESOFFMIRRORS && + (wall[j].overpicnum == MIRROR || wall[j].picnum == MIRROR)) + { + Proj_BounceOffWall(s, j); + s->owner = i; + A_Spawn(i, TRANSPORTERSTAR); + return; + } + else + { + setsprite(i, &davect); + A_DamageWall(i, j, (vec3_t *) s, s->picnum); + + if (proj->workslike & PROJECTILE_BOUNCESOFFWALLS) + { + if (wall[j].overpicnum != MIRROR && wall[j].picnum != MIRROR) + s->yvel--; + + Proj_BounceOffWall(s, j); + + if (proj->bsound >= 0) + A_PlaySound(proj->bsound, i); + + if (proj->workslike & PROJECTILE_LOSESVELOCITY) + PROJ_DECAYVELOCITY; + + return; + } + } + break; + + case 16384: + setsprite(i, &davect); + + if (s->zvel < 0) + { + if (sector[s->sectnum].ceilingstat&1 && sector[s->sectnum].ceilingpal == 0) + { + A_DeleteSprite(i); + return; + } + + Sect_DamageCeiling(s->sectnum); + } + + if (proj->workslike & PROJECTILE_BOUNCESOFFWALLS) + { + A_DoProjectileBounce(i); + A_SetSprite(i, CLIPMASK1); + + s->yvel--; + + if (proj->bsound >= 0) + A_PlaySound(proj->bsound, i); + + if (proj->workslike & PROJECTILE_LOSESVELOCITY) + PROJ_DECAYVELOCITY; + + return; + } + break; + } + + A_DoProjectileEffects(i, &davect, 1); + A_DeleteSprite(i); + return; + } + return; + } +} + ACTOR_STATIC void G_MoveWeapons(void) { - int32_t i = headspritestat[STAT_PROJECTILE], j=0, k, q; + int32_t i = headspritestat[STAT_PROJECTILE], j=0, k; int32_t x, ll; while (i >= 0) @@ -2661,261 +2926,9 @@ ACTOR_STATIC void G_MoveWeapons(void) Bmemcpy(&actor[i].bpos.x, s, sizeof(vec3_t)); /* Custom projectiles */ - if (A_CheckSpriteFlags(i,SPRITE_PROJECTILE)) + if (A_CheckSpriteFlags(i, SPRITE_PROJECTILE)) { - const projectile_t *const proj = &SpriteProjectile[i]; - - if (proj->pal >= 0) - s->pal = proj->pal; - - if (proj->workslike & PROJECTILE_KNEE) - KILLIT(i); - - if (proj->workslike & PROJECTILE_RPG) - { - // if (proj->workslike & COOLEXPLOSION1) - // if( g_sounds[WIERDSHOT_FLY].num == 0 ) - // A_PlaySound(WIERDSHOT_FLY,i); - - Bmemcpy(&davect,s,sizeof(vec3_t)); - - if (proj->flashcolor) - G_AddGameLight(0, i, ((s->yrepeat*tilesizy[s->picnum])<<1), 2048, proj->flashcolor, PR_LIGHT_PRIO_LOW_GAME); - - if (proj->workslike & PROJECTILE_BOUNCESOFFWALLS && s->yvel < 1) - { - A_DoProjectileEffects(i, NULL, 1); - KILLIT(i); - } - - if (proj->workslike & PROJECTILE_COOLEXPLOSION1 && ++s->shade >= 40) - KILLIT(i); - - s->zvel -= proj->drop; - - if (proj->workslike & PROJECTILE_SPIT && s->zvel < 6144) - s->zvel += g_spriteGravity-112; - - A_GetZLimits(i); - - if (proj->trail >= 0) - { - int32_t cnt; - - for (cnt=0; cnt<=proj->tnum; cnt++) - { - j = A_Spawn(i,proj->trail); - - sprite[j].z += (proj->toffset<<8); - - if (proj->txrepeat >= 0) - sprite[j].xrepeat=proj->txrepeat; - - if (proj->tyrepeat >= 0) - sprite[j].yrepeat=proj->tyrepeat; - } - } - - { - int32_t cnt = proj->movecnt; - - k = s->xvel; - ll = s->zvel; - - if (sector[s->sectnum].lotag == ST_2_UNDERWATER) - { - k >>= 1; - ll >>= 1; - } - - do - { - vec3_t tmpvect; - Bmemcpy(&davect, s, sizeof(vec3_t)); - - tmpvect.x = (k*(sintable[(s->ang+512)&2047]))>>14; - tmpvect.y = (k*(sintable[s->ang&2047]))>>14; - tmpvect.z = ll; - - j = A_MoveSprite(i, &tmpvect, CLIPMASK1); - } - while (!j && --cnt > 0); - } - - if (!(proj->workslike & PROJECTILE_BOUNCESOFFWALLS) && - s->yvel >= 0 && sprite[s->yvel].sectnum != MAXSECTORS) - if (FindDistance2D(s->x-sprite[s->yvel].x,s->y-sprite[s->yvel].y) < 256) - j = 49152|s->yvel; - - actor[i].movflag = j; - - if (s->sectnum < 0) - KILLIT(i); - - if (proj->workslike & PROJECTILE_TIMED && proj->range > 0) - { - if (++actor[i].t_data[8] > proj->range) - { - if (proj->workslike & PROJECTILE_EXPLODEONTIMER) - A_DoProjectileEffects(i, &davect, 1); - - KILLIT(i); - } - } - - if ((j&49152) != 49152 && !(proj->workslike & PROJECTILE_BOUNCESOFFWALLS)) - G_WeaponHitCeilingOrFloor(i, s, &j); - - if (proj->workslike & PROJECTILE_WATERBUBBLES && sector[s->sectnum].lotag == ST_2_UNDERWATER && rnd(140)) - A_Spawn(i,WATERBUBBLE); - - if (j != 0) - { - if (proj->workslike & PROJECTILE_COOLEXPLOSION1) - { - s->xvel = 0; - s->zvel = 0; - } - - if ((j&49152) == 49152) - { - j &= (MAXSPRITES-1); - - if (proj->workslike & PROJECTILE_BOUNCESOFFSPRITES) - { - s->yvel--; - - k = getangle(sprite[j].x-s->x,sprite[j].y-s->y)+(sprite[j].cstat&16?0:512); - s->ang = ((k<<1) - s->ang)&2047; - - if (proj->bsound >= 0) - A_PlaySound(proj->bsound,i); - - if (proj->workslike & PROJECTILE_LOSESVELOCITY) - { - s->xvel >>= 1; - s->zvel >>= 1; - } - - if (!(proj->workslike & PROJECTILE_FORCEIMPACT)) - goto BOLT; - } - - A_DamageObject(j,i); - - if (sprite[j].picnum == APLAYER) - { - int32_t p = sprite[j].yvel; - - A_PlaySound(PISTOL_BODYHIT,j); - - if (proj->workslike & PROJECTILE_SPIT) - P_HandleBeingSpitOn(g_player[p].ps); - } - - if (proj->workslike & PROJECTILE_RPG_IMPACT) - { - - actor[j].owner = s->owner; - actor[j].picnum = s->picnum; - actor[j].extra += proj->extra; - - A_DoProjectileEffects(i, &davect, 0); - - if (!(proj->workslike & PROJECTILE_FORCEIMPACT)) - KILLIT(i); - } - - if (proj->workslike & PROJECTILE_FORCEIMPACT) - goto BOLT; - } - else if ((j&49152) == 32768) - { - j &= (MAXWALLS-1); - - if (proj->workslike & PROJECTILE_BOUNCESOFFMIRRORS && - (wall[j].overpicnum == MIRROR || wall[j].picnum == MIRROR)) - { - Proj_BounceOffWall(s, j); - s->owner = i; - A_Spawn(i,TRANSPORTERSTAR); - goto BOLT; - } - else - { - setsprite(i,&davect); - A_DamageWall(i,j,(vec3_t *)s,s->picnum); - - if (proj->workslike & PROJECTILE_BOUNCESOFFWALLS) - { - if (wall[j].overpicnum != MIRROR && wall[j].picnum != MIRROR) - s->yvel--; - - Proj_BounceOffWall(s, j); - - if (proj->bsound >= 0) - A_PlaySound(proj->bsound,i); - - if (proj->workslike & PROJECTILE_LOSESVELOCITY) - { - s->xvel >>= 1; - s->zvel >>= 1; - } - goto BOLT; - } - } - } - else if ((j&49152) == 16384) - { - setsprite(i, &davect); - - if (s->zvel < 0) - { - if (sector[s->sectnum].ceilingstat&1 && sector[s->sectnum].ceilingpal == 0) - KILLIT(i); - - Sect_DamageCeiling(s->sectnum); - } - - if (proj->workslike & PROJECTILE_BOUNCESOFFWALLS) - { - A_DoProjectileBounce(i); - A_SetSprite(i, CLIPMASK1); - - s->yvel--; - - if (proj->bsound >= 0) - A_PlaySound(proj->bsound,i); - - if (proj->workslike & PROJECTILE_LOSESVELOCITY) - { - s->xvel >>= 1; - s->zvel >>= 1; - } - - goto BOLT; - } - } - - if (proj->workslike & PROJECTILE_HITSCAN) - { - if (!G_HaveActor(sprite[i].picnum)) - goto BOLT; - { - int32_t p = A_FindPlayer(s,&x); - A_Execute(i,p,x); - } - goto BOLT; - } - - if (proj->workslike & PROJECTILE_RPG) - { - A_DoProjectileEffects(i, &davect, 1); - KILLIT(i); - } - } - } - + Proj_MoveCustom(i); goto BOLT; } @@ -2925,6 +2938,7 @@ ACTOR_STATIC void G_MoveWeapons(void) case RADIUSEXPLOSION__STATIC: case KNEE__STATIC: KILLIT(i); +/* case TONGUE__STATIC: T1 = sintable[(T2)&2047]>>9; T2 += 32; @@ -2960,6 +2974,7 @@ ACTOR_STATIC void G_MoveWeapons(void) sprite[q].picnum = INNERJAW+1; goto BOLT; +*/ case FREEZEBLAST__STATIC: if (s->yvel < 1 || s->extra < 2 || (s->xvel|s->zvel) == 0) @@ -3050,14 +3065,15 @@ ACTOR_STATIC void G_MoveWeapons(void) s->zvel = 0; } - if ((j&49152) == 49152) + switch (j&49152) { + case 49152: j &= (MAXSPRITES-1); if (s->picnum == FREEZEBLAST && sprite[j].pal == 1) if (A_CheckEnemySprite(&sprite[j]) || sprite[j].picnum == APLAYER) { - j = A_Spawn(i,TRANSPORTERSTAR); + j = A_Spawn(i, TRANSPORTERSTAR); sprite[j].pal = 1; sprite[j].xrepeat = 32; sprite[j].yrepeat = 32; @@ -3065,33 +3081,33 @@ ACTOR_STATIC void G_MoveWeapons(void) KILLIT(i); } - A_DamageObject(j,i); + A_DamageObject(j, i); - if (sprite[j].picnum == APLAYER) - { - int32_t p = sprite[j].yvel; - A_PlaySound(PISTOL_BODYHIT,j); + if (sprite[j].picnum == APLAYER) + { + int32_t p = sprite[j].yvel; + A_PlaySound(PISTOL_BODYHIT, j); - if (s->picnum == SPIT) - P_HandleBeingSpitOn(g_player[p].ps); - } - } - else if ((j&49152) == 32768) - { + if (s->picnum == SPIT) + P_HandleBeingSpitOn(g_player[p].ps); + } + break; + + case 32768: j &= (MAXWALLS-1); if (s->picnum != RPG && s->picnum != FREEZEBLAST && s->picnum != SPIT && - (wall[j].overpicnum == MIRROR || wall[j].picnum == MIRROR)) + (wall[j].overpicnum == MIRROR || wall[j].picnum == MIRROR)) { Proj_BounceOffWall(s, j); s->owner = i; - A_Spawn(i,TRANSPORTERSTAR); + A_Spawn(i, TRANSPORTERSTAR); goto BOLT; } else { - setsprite(i,&davect); - A_DamageWall(i,j,(vec3_t *)s,s->picnum); + setsprite(i, &davect); + A_DamageWall(i, j, (vec3_t *) s, s->picnum); if (s->picnum == FREEZEBLAST) { @@ -3105,10 +3121,10 @@ ACTOR_STATIC void G_MoveWeapons(void) goto BOLT; } } - } - else if ((j&49152) == 16384) - { - setsprite(i,&davect); + break; + + case 16384: + setsprite(i, &davect); if (s->zvel < 0) { @@ -3123,70 +3139,84 @@ ACTOR_STATIC void G_MoveWeapons(void) { A_DoProjectileBounce(i); A_SetSprite(i, CLIPMASK1); + s->extra >>= 1; - if (s->xrepeat > 8) - s->xrepeat -= 2; - if (s->yrepeat > 8) - s->yrepeat -= 2; s->yvel--; + + if (s->xrepeat > 8) + { + s->xrepeat -= 2; + + if (s->yrepeat > 8) + s->yrepeat -= 2; + } + goto BOLT; } + break; + default: + break; } - if (s->picnum != SPIT) + switch (DYNAMICTILEMAP(s->picnum)) { - if (s->picnum == RPG) + case SPIT__STATIC: + case COOLEXPLOSION1__STATIC: + case FREEZEBLAST__STATIC: + case FIRELASER__STATIC: + break; + + case RPG__STATIC: + k = A_Spawn(i, EXPLOSION2); + A_PlaySound(RPG_EXPLODE, k); + Bmemcpy(&sprite[k], &davect, sizeof(vec3_t)); + + if (s->xrepeat < 10) { - k = A_Spawn(i,EXPLOSION2); - A_PlaySound(RPG_EXPLODE,k); - Bmemcpy(&sprite[k],&davect,sizeof(vec3_t)); - - if (s->xrepeat < 10) - { - sprite[k].xrepeat = 6; - sprite[k].yrepeat = 6; - } - else if ((j&49152) == 16384) - { - if (s->zvel > 0) - A_Spawn(i,EXPLOSION2BOT); - else - { - sprite[k].cstat |= 8; - sprite[k].z += (48<<8); - } - } - - if (s->xrepeat >= 10) - { - x = s->extra; - A_RadiusDamage(i,g_rpgBlastRadius, x>>2,x>>1,x-(x>>2),x); - } + sprite[k].xrepeat = 6; + sprite[k].yrepeat = 6; + } + else if ((j&49152) == 16384) + { + if (s->zvel > 0) + A_Spawn(i, EXPLOSION2BOT); else { - x = s->extra+(g_globalRandom&3); - A_RadiusDamage(i,(g_rpgBlastRadius>>1),x>>2,x>>1,x-(x>>2),x); + sprite[k].cstat |= 8; + sprite[k].z += (48<<8); } } - else if (s->picnum == SHRINKSPARK) + + if (s->xrepeat >= 10) { - A_Spawn(i,SHRINKEREXPLOSION); - A_PlaySound(SHRINKER_HIT,i); - A_RadiusDamage(i,g_shrinkerBlastRadius,0,0,0,0); + x = s->extra; + A_RadiusDamage(i, g_rpgBlastRadius, x>>2, x>>1, x-(x>>2), x); } - else if (s->picnum != COOLEXPLOSION1 && s->picnum != FREEZEBLAST && s->picnum != FIRELASER) + else { - k = A_Spawn(i,EXPLOSION2); - sprite[k].xrepeat = sprite[k].yrepeat = s->xrepeat>>1; - if ((j&49152) == 16384) + x = s->extra+(g_globalRandom&3); + A_RadiusDamage(i, (g_rpgBlastRadius>>1), x>>2, x>>1, x-(x>>2), x); + } + break; + + case SHRINKSPARK__STATIC: + A_Spawn(i, SHRINKEREXPLOSION); + A_PlaySound(SHRINKER_HIT, i); + A_RadiusDamage(i, g_shrinkerBlastRadius, 0, 0, 0, 0); + break; + + default: + k = A_Spawn(i, EXPLOSION2); + sprite[k].xrepeat = sprite[k].yrepeat = s->xrepeat>>1; + if ((j&49152) == 16384) + { + if (s->zvel < 0) { - if (s->zvel < 0) - { - sprite[k].cstat |= 8; - sprite[k].z += (72<<8); - } + sprite[k].cstat |= 8; + sprite[k].z += (72<<8); } } + break; } if (s->picnum != COOLEXPLOSION1) diff --git a/polymer/eduke32/source/actors.h b/polymer/eduke32/source/actors.h index 71e3b2ec4..d5260dbbe 100644 --- a/polymer/eduke32/source/actors.h +++ b/polymer/eduke32/source/actors.h @@ -289,6 +289,7 @@ enum pflags_t { PROJECTILE_FORCEIMPACT = 0x00040000, PROJECTILE_REALCLIPDIST = 0x00080000, PROJECTILE_ACCURATE = 0x00100000, + PROJECTILE_TYPE_MASK = PROJECTILE_HITSCAN|PROJECTILE_RPG|PROJECTILE_KNEE|PROJECTILE_BLOOD, }; extern tiledata_t g_tile[MAXTILES]; diff --git a/polymer/eduke32/source/player.c b/polymer/eduke32/source/player.c index a058b5d22..54d6f5d02 100644 --- a/polymer/eduke32/source/player.c +++ b/polymer/eduke32/source/player.c @@ -821,28 +821,274 @@ static void Proj_HandleKnee(hitdata_t *hit, int32_t i, int32_t p, int32_t atwith } #define MinibossScale(s) (((s)*sprite[i].yrepeat)/80) + +static int32_t A_ShootCustom(const int32_t i, const int32_t atwith, int16_t sa, vec3_t * const srcvect) +{ + /* Custom projectiles */ + projectile_t *const proj = &ProjectileData[atwith]; + int32_t j, k = -1, l; + int32_t vel, zvel = 0; + hitdata_t hit; + spritetype *const s = &sprite[i]; + const int16_t sect = s->sectnum; + const int32_t p = (s->picnum == APLAYER) ? s->yvel : -1; + DukePlayer_t *const ps = p >= 0 ? g_player[p].ps : NULL; + +#ifdef POLYMER + if (proj->flashcolor) + { + int32_t x = ((sintable[(s->ang + 512) & 2047]) >> 7), y = ((sintable[(s->ang) & 2047]) >> 7); + + s->x += x; + s->y += y; + G_AddGameLight(0, i, PHEIGHT, 8192, proj->flashcolor, PR_LIGHT_PRIO_MAX_GAME); + actor[i].lightcount = 2; + s->x -= x; + s->y -= y; + } +#endif // POLYMER + + if (proj->offset == 0) + proj->offset = 1; + + switch (proj->workslike & PROJECTILE_TYPE_MASK) + { + case PROJECTILE_HITSCAN: + if (s->extra >= 0) s->shade = proj->shade; + + if (p >= 0) + P_PreFireHitscan(i, p, atwith, srcvect, &zvel, &sa, + proj->workslike & PROJECTILE_ACCURATE_AUTOAIM, + !(proj->workslike & PROJECTILE_ACCURATE)); + else + A_PreFireHitscan(s, srcvect, &zvel, &sa, + !(proj->workslike & PROJECTILE_ACCURATE)); + + if (Proj_DoHitscan(i, (proj->cstat >= 0) ? proj->cstat : 256 + 1, + srcvect, zvel, sa, &hit)) + return -1; + + if (proj->range > 0 && klabs(srcvect->x - hit.pos.x) + klabs(srcvect->y - hit.pos.y) > proj->range) + return -1; + + if (proj->trail >= 0) + A_HitscanProjTrail(srcvect, &hit.pos, sa, atwith); + + if (proj->workslike & PROJECTILE_WATERBUBBLES) + { + if ((krand() & 15) == 0 && sector[hit.sect].lotag == ST_2_UNDERWATER) + A_DoWaterTracers(hit.pos.x, hit.pos.y, hit.pos.z, + srcvect->x, srcvect->y, srcvect->z, 8 - (ud.multimode >> 1)); + } + + if (p >= 0) + { + k = Proj_InsertShotspark(&hit, i, atwith, 10, sa, Proj_GetExtra(atwith)); + + if (P_PostFireHitscan(p, k, &hit, i, atwith, zvel, + atwith, proj->decal, atwith, 1 + 2) < 0) + return -1; + } + else + { + k = A_PostFireHitscan(&hit, i, atwith, sa, Proj_GetExtra(atwith), + atwith, atwith); + } + + if ((krand() & 255) < 4 && proj->isound >= 0) + S_PlaySound3D(proj->isound, k, &hit.pos); + + return -1; + + case PROJECTILE_RPG: + if (s->extra >= 0) s->shade = proj->shade; + + vel = proj->vel; + + j = -1; + + if (p >= 0) + { + j = GetAutoAimAngle(i, p, atwith, 8 << 8, 0 + 2, srcvect, vel, &zvel, &sa); + + if (j < 0) + zvel = (100 - ps->horiz - ps->horizoff)*(proj->vel / 8); + + if (proj->sound >= 0) + A_PlaySound(proj->sound, i); + } + else + { + if (!(proj->workslike & PROJECTILE_NOAIM)) + { + j = A_FindPlayer(s, NULL); + sa = getangle(g_player[j].ps->opos.x - srcvect->x, g_player[j].ps->opos.y - srcvect->y); + + l = safeldist(g_player[j].ps->i, s); + zvel = ((g_player[j].ps->opos.z - srcvect->z)*vel) / l; + + if (A_CheckEnemySprite(s) && (s->hitag&face_player_smart)) + sa = s->ang + (krand() & 31) - 16; + } + } + + if (p >= 0 && j >= 0) + l = j; + else l = -1; + + if (numplayers > 1 && g_netClient) return -1; + + zvel = A_GetShootZvel(zvel); + j = A_InsertSprite(sect, + srcvect->x + (sintable[(348 + sa + 512) & 2047] / proj->offset), + srcvect->y + (sintable[(sa + 348) & 2047] / proj->offset), + srcvect->z - (1 << 8), atwith, 0, 14, 14, sa, vel, zvel, i, 4); + + sprite[j].xrepeat = proj->xrepeat; + sprite[j].yrepeat = proj->yrepeat; + + if (proj->extra_rand > 0) + sprite[j].extra += (krand()&proj->extra_rand); + + if (!(proj->workslike & PROJECTILE_BOUNCESOFFWALLS)) + sprite[j].yvel = l; + else + { + if (proj->bounces >= 1) sprite[j].yvel = proj->bounces; + else sprite[j].yvel = g_numFreezeBounces; + sprite[j].zvel -= (2 << 4); + } + + if (proj->cstat >= 0) sprite[j].cstat = proj->cstat; + else sprite[j].cstat = 128; + + if (proj->clipdist != 255) sprite[j].clipdist = proj->clipdist; + else sprite[j].clipdist = 40; + + { + int32_t picnum = sprite[j].picnum; // why? + Bmemcpy(&SpriteProjectile[j], &ProjectileData[picnum], sizeof(projectile_t)); + } + + return j; + + case PROJECTILE_KNEE: + if (p >= 0) + { + zvel = (100 - ps->horiz - ps->horizoff) << 5; + srcvect->z += (6 << 8); + sa += 15; + } + else if (!(proj->workslike & PROJECTILE_NOAIM)) + { + int32_t x; + j = g_player[A_FindPlayer(s, &x)].ps->i; + zvel = ((sprite[j].z - srcvect->z) << 8) / (x + 1); + sa = getangle(sprite[j].x - srcvect->x, sprite[j].y - srcvect->y); + } + + Proj_DoHitscan(i, 0, srcvect, zvel, sa, &hit); + + if (hit.sect < 0) return -1; + + if (proj->range == 0) + proj->range = 1024; + + if (proj->range > 0 && klabs(srcvect->x - hit.pos.x) + klabs(srcvect->y - hit.pos.y) > proj->range) + return -1; + + Proj_HandleKnee(&hit, i, p, atwith, sa, + proj, atwith, + proj->extra_rand, + proj->spawns, proj->sound); + + return -1; + + case PROJECTILE_BLOOD: + sa += 64 - (krand() & 127); + if (p < 0) sa += 1024; + zvel = 1024 - (krand() & 2047); + + Proj_DoHitscan(i, 0, srcvect, zvel, sa, &hit); + + if (proj->range == 0) + proj->range = 1024; + + if (Proj_CheckBlood(srcvect, &hit, proj->range, + mulscale3(proj->yrepeat, tilesizy[proj->decal]) << 8)) + { + const walltype *const hitwal = &wall[hit.wall]; + + if (FindDistance2D(hitwal->x - wall[hitwal->point2].x, hitwal->y - wall[hitwal->point2].y) > + (mulscale3(proj->xrepeat + 8, tilesizx[proj->decal]))) + { + if (SectorContainsSE13(hitwal->nextsector)) + return -1; + + if (hitwal->nextwall >= 0 && wall[hitwal->nextwall].hitag != 0) + return -1; + + if (hitwal->hitag == 0 && proj->decal >= 0) + { + k = A_Spawn(i, proj->decal); + + if (!A_CheckSpriteFlags(k, SPRITE_DECAL)) + actor[k].flags |= SPRITE_DECAL; + + sprite[k].xvel = -1; + sprite[k].ang = getangle(hitwal->x - wall[hitwal->point2].x, + hitwal->y - wall[hitwal->point2].y) + 512; + Bmemcpy(&sprite[k], &hit.pos, sizeof(vec3_t)); + + Proj_DoRandDecalSize(k, atwith); + + sprite[k].z += sprite[k].yrepeat << 8; + + // sprite[k].cstat = 16+(krand()&12); + sprite[k].cstat = 16; + + if (krand() & 1) + sprite[k].cstat |= 4; + + if (krand() & 1) + sprite[k].cstat |= 8; + + sprite[k].shade = sector[sprite[k].sectnum].floorshade; + + sprite[k].x -= sintable[(sprite[k].ang + 2560) & 2047] >> 13; + sprite[k].y -= sintable[(sprite[k].ang + 2048) & 2047] >> 13; + + A_SetSprite(k, CLIPMASK0); + A_AddToDeleteQueue(k); + changespritestat(k, 5); + } + } + } + + return -1; + + default: + return -1; + } +} + int32_t A_ShootWithZvel(int32_t i, int32_t atwith, int32_t override_zvel) { int16_t sa; - int32_t j, k=-1, l; - int32_t vel, zvel = 0; - hitdata_t hit; vec3_t srcvect; spritetype *const s = &sprite[i]; - const int16_t sect = s->sectnum; - const int32_t p = (s->picnum == APLAYER) ? s->yvel : -1; DukePlayer_t *const ps = p >= 0 ? g_player[p].ps : NULL; + Bassert(atwith >= 0); + if (override_zvel != SHOOT_HARDCODED_ZVEL) { g_overrideShootZvel = 1; g_shootZvel = override_zvel; } else - { g_overrideShootZvel = 0; - } if (s->picnum == APLAYER) { @@ -870,279 +1116,38 @@ int32_t A_ShootWithZvel(int32_t i, int32_t atwith, int32_t override_zvel) } #ifdef POLYMER - if (atwith >= 0) - switch (DYNAMICTILEMAP(atwith)) - { - case FIRELASER__STATIC: - case SHOTGUN__STATIC: - case SHOTSPARK1__STATIC: - case CHAINGUN__STATIC: - case RPG__STATIC: - case MORTER__STATIC: + switch (DYNAMICTILEMAP(atwith)) + { + case FIRELASER__STATIC: + case SHOTGUN__STATIC: + case SHOTSPARK1__STATIC: + case CHAINGUN__STATIC: + case RPG__STATIC: + case MORTER__STATIC: { int32_t x = ((sintable[(s->ang+512)&2047])>>7), y = ((sintable[(s->ang)&2047])>>7); - s-> x += x; - s-> y += y; - G_AddGameLight(0, i, PHEIGHT, 8192, 255+(95<<8),PR_LIGHT_PRIO_MAX_GAME); + s->x += x; + s->y += y; + G_AddGameLight(0, i, PHEIGHT, 8192, 255+(95<<8), PR_LIGHT_PRIO_MAX_GAME); actor[i].lightcount = 2; - s-> x -= x; - s-> y -= y; + s->x -= x; + s->y -= y; } break; - } + } #endif // POLYMER } if (A_CheckSpriteTileFlags(atwith, SPRITE_PROJECTILE)) + return A_ShootCustom(i, atwith, sa, &srcvect); + else { - /* Custom projectiles */ - projectile_t *const proj = (Bassert(atwith >= 0), &ProjectileData[atwith]); + int32_t j, k = -1, l; + int32_t vel, zvel = 0; + hitdata_t hit; + const int16_t sect = s->sectnum; -#ifdef POLYMER - if (proj->flashcolor) - { - int32_t x = ((sintable[(s->ang+512)&2047])>>7), y = ((sintable[(s->ang)&2047])>>7); - - s-> x += x; - s-> y += y; - G_AddGameLight(0, i, PHEIGHT, 8192, proj->flashcolor,PR_LIGHT_PRIO_MAX_GAME); - actor[i].lightcount = 2; - s-> x -= x; - s-> y -= y; - } -#endif // POLYMER - - if (proj->offset == 0) - proj->offset = 1; - - if (proj->workslike & PROJECTILE_BLOOD || proj->workslike & PROJECTILE_KNEE) - { - if (proj->workslike & PROJECTILE_BLOOD) - { - sa += 64 - (krand()&127); - if (p < 0) sa += 1024; - zvel = 1024-(krand()&2047); - } - - if (proj->workslike & PROJECTILE_KNEE) - { - if (p >= 0) - { - zvel = (100-ps->horiz-ps->horizoff)<<5; - srcvect.z += (6<<8); - sa += 15; - } - else if (!(proj->workslike & PROJECTILE_NOAIM)) - { - int32_t x; - j = g_player[A_FindPlayer(s,&x)].ps->i; - zvel = ((sprite[j].z-srcvect.z)<<8) / (x+1); - sa = getangle(sprite[j].x-srcvect.x,sprite[j].y-srcvect.y); - } - } - - Proj_DoHitscan(i, 0, &srcvect, zvel, sa, &hit); - - if (proj->workslike & PROJECTILE_BLOOD) - { - if (proj->range == 0) - proj->range = 1024; - - if (Proj_CheckBlood(&srcvect, &hit, proj->range, - mulscale3(proj->yrepeat, tilesizy[proj->decal])<<8)) - { - const walltype *const hitwal = &wall[hit.wall]; - - if (FindDistance2D(hitwal->x-wall[hitwal->point2].x, hitwal->y-wall[hitwal->point2].y) > - (mulscale3(proj->xrepeat+8, tilesizx[proj->decal]))) - { - if (SectorContainsSE13(hitwal->nextsector)) - return -1; - - if (hitwal->nextwall >= 0 && wall[hitwal->nextwall].hitag != 0) - return -1; - - if (hitwal->hitag == 0) - { - if (proj->decal >= 0) - { - k = A_Spawn(i,proj->decal); - - if (!A_CheckSpriteFlags(k, SPRITE_DECAL)) - actor[k].flags |= SPRITE_DECAL; - - sprite[k].xvel = -1; - sprite[k].ang = getangle(hitwal->x-wall[hitwal->point2].x, - hitwal->y-wall[hitwal->point2].y)+512; - Bmemcpy(&sprite[k], &hit.pos, sizeof(vec3_t)); - - Proj_DoRandDecalSize(k, atwith); - - sprite[k].z += sprite[k].yrepeat<<8; - -// sprite[k].cstat = 16+(krand()&12); - sprite[k].cstat = 16; - if (krand()&1) - sprite[k].cstat |= 4; - if (krand()&1) - sprite[k].cstat |= 8; - - sprite[k].shade = sector[sprite[k].sectnum].floorshade; - - sprite[k].x -= sintable[(sprite[k].ang+2560)&2047]>>13; - sprite[k].y -= sintable[(sprite[k].ang+2048)&2047]>>13; - - A_SetSprite(k,CLIPMASK0); - A_AddToDeleteQueue(k); - changespritestat(k,5); - } - } - } - } - - return -1; - } - - if (hit.sect < 0) return -1; - - if (proj->range == 0 && (proj->workslike & PROJECTILE_KNEE)) - proj->range = 1024; - - if (proj->range > 0 && klabs(srcvect.x-hit.pos.x)+klabs(srcvect.y-hit.pos.y) > proj->range) - return -1; - - Proj_HandleKnee(&hit, i, p, atwith, sa, - proj, atwith, - proj->extra_rand, - proj->spawns, proj->sound); - return -1; - } - - if (proj->workslike & PROJECTILE_HITSCAN) - { - if (s->extra >= 0) s->shade = proj->shade; - - if (p >= 0) - P_PreFireHitscan(i, p, atwith, &srcvect, &zvel, &sa, - proj->workslike & PROJECTILE_ACCURATE_AUTOAIM, - !(proj->workslike & PROJECTILE_ACCURATE)); - else - A_PreFireHitscan(s, &srcvect, &zvel, &sa, - !(proj->workslike & PROJECTILE_ACCURATE)); - - if (Proj_DoHitscan(i, (proj->cstat >= 0) ? proj->cstat : 256+1, - &srcvect, zvel, sa, &hit)) - return -1; - - if (proj->range > 0 && klabs(srcvect.x-hit.pos.x)+klabs(srcvect.y-hit.pos.y) > proj->range) - return -1; - - if (proj->trail >= 0) - A_HitscanProjTrail(&srcvect,&hit.pos,sa,atwith); - - if (proj->workslike & PROJECTILE_WATERBUBBLES) - { - if ((krand()&15) == 0 && sector[hit.sect].lotag == ST_2_UNDERWATER) - A_DoWaterTracers(hit.pos.x,hit.pos.y,hit.pos.z, - srcvect.x,srcvect.y,srcvect.z,8-(ud.multimode>>1)); - } - - if (p >= 0) - { - k = Proj_InsertShotspark(&hit, i, atwith, 10, sa, Proj_GetExtra(atwith)); - - if (P_PostFireHitscan(p, k, &hit, i, atwith, zvel, - atwith, proj->decal, atwith, 1+2) < 0) - return -1; - } - else - { - k = A_PostFireHitscan(&hit, i, atwith, sa, Proj_GetExtra(atwith), - atwith, atwith); - } - - if ((krand()&255) < 4 && proj->isound >= 0) - S_PlaySound3D(proj->isound, k, &hit.pos); - - return -1; - } - - if (proj->workslike & PROJECTILE_RPG) - { - if (s->extra >= 0) s->shade = proj->shade; - - vel = proj->vel; - - j = -1; - - if (p >= 0) - { - j = GetAutoAimAngle(i, p, atwith, 8<<8, 0+2, &srcvect, vel, &zvel, &sa); - - if (j < 0) - zvel = (100-ps->horiz-ps->horizoff)*(proj->vel/8); - - if (proj->sound >= 0) - A_PlaySound(proj->sound,i); - } - else - { - if (!(proj->workslike & PROJECTILE_NOAIM)) - { - j = A_FindPlayer(s, NULL); - sa = getangle(g_player[j].ps->opos.x-srcvect.x,g_player[j].ps->opos.y-srcvect.y); - - l = safeldist(g_player[j].ps->i, s); - zvel = ((g_player[j].ps->opos.z-srcvect.z)*vel) / l; - - if (A_CheckEnemySprite(s) && (s->hitag&face_player_smart)) - sa = s->ang+(krand()&31)-16; - } - } - - if (p >= 0 && j >= 0) - l = j; - else l = -1; - - if (numplayers > 1 && g_netClient) return -1; - - zvel = A_GetShootZvel(zvel); - j = A_InsertSprite(sect, - srcvect.x+(sintable[(348+sa+512)&2047]/proj->offset), - srcvect.y+(sintable[(sa+348)&2047]/proj->offset), - srcvect.z-(1<<8),atwith,0,14,14,sa,vel,zvel,i,4); - - sprite[j].xrepeat=proj->xrepeat; - sprite[j].yrepeat=proj->yrepeat; - - if (proj->extra_rand > 0) - sprite[j].extra += (krand()&proj->extra_rand); - if (!(proj->workslike & PROJECTILE_BOUNCESOFFWALLS)) - sprite[j].yvel = l; - else - { - if (proj->bounces >= 1) sprite[j].yvel = proj->bounces; - else sprite[j].yvel = g_numFreezeBounces; - sprite[j].zvel -= (2<<4); - } - - if (proj->cstat >= 0) sprite[j].cstat = proj->cstat; - else sprite[j].cstat = 128; - if (proj->clipdist != 255) sprite[j].clipdist = proj->clipdist; - else sprite[j].clipdist = 40; - - { - int32_t picnum = sprite[j].picnum; - Bmemcpy(&SpriteProjectile[j], &ProjectileData[picnum], sizeof(projectile_t)); - } - - return j; - } - - } - else if (atwith >= 0) - { switch (DYNAMICTILEMAP(atwith)) { case BLOODSPLAT1__STATIC: @@ -1214,7 +1219,6 @@ int32_t A_ShootWithZvel(int32_t i, int32_t atwith, int32_t override_zvel) case SHOTSPARK1__STATIC: case SHOTGUN__STATIC: case CHAINGUN__STATIC: - if (s->extra >= 0) s->shade = -96; if (p >= 0) @@ -1252,7 +1256,6 @@ int32_t A_ShootWithZvel(int32_t i, int32_t atwith, int32_t override_zvel) return -1; case GROWSPARK__STATIC: - if (p >= 0) P_PreFireHitscan(i, p, atwith, &srcvect, &zvel, &sa, 1, 1); else @@ -1286,20 +1289,21 @@ int32_t A_ShootWithZvel(int32_t i, int32_t atwith, int32_t override_zvel) if (s->extra >= 0) s->shade = -96; - if (atwith == SPIT) vel = 292; - else + switch (atwith) { - if (atwith == COOLEXPLOSION1) - { - if (s->picnum == BOSS2) vel = 644; - else vel = 348; - srcvect.z -= (4<<7); - } - else - { - vel = 840; - srcvect.z -= (4<<7); - } + case SPIT__STATIC: + vel = 292; + break; + case COOLEXPLOSION1__STATIC: + if (s->picnum == BOSS2) vel = 644; + else vel = 348; + srcvect.z -= (4<<7); + break; + case FIRELASER__STATIC: + default: + vel = 840; + srcvect.z -= (4<<7); + break; } if (p >= 0) @@ -1690,13 +1694,8 @@ static int32_t P_DisplayFist(int32_t gs,int32_t snum) return 1; } - #define DRAWEAP_CENTER 262144 - -static inline int32_t weapsc(int32_t sc) -{ - return scale(sc, ud.weaponscale, 100); -} +#define weapsc(sc) scale(sc, ud.weaponscale, 100) static int32_t g_dts_yadd;