- movesprite

This commit is contained in:
Christoph Oelckers 2020-05-06 09:15:15 +02:00
parent 68de42075e
commit c11963b41a
5 changed files with 146 additions and 124 deletions

View file

@ -1040,6 +1040,12 @@ int32_t deletesprite(int16_t spritenum);
int32_t changespritesect(int16_t spritenum, int16_t newsectnum);
int32_t changespritestat(int16_t spritenum, int16_t newstatnum);
int32_t setsprite(int16_t spritenum, const vec3_t *) ATTRIBUTE((nonnull(2)));
inline int32_t setsprite(int16_t spritenum, int x, int y, int z)
{
vec3_t v = { x,y,z };
return setsprite(spritenum, &v);
}
int32_t setspritez(int16_t spritenum, const vec3_t *) ATTRIBUTE((nonnull(2)));
int32_t spriteheightofsptr(uspriteptr_t spr, int32_t *height, int32_t alsotileyofs);

View file

@ -77,6 +77,17 @@ extern int32_t clipmoveboxtracenum;
int32_t clipmove(vec3_t *const pos, int16_t *const sectnum, int32_t xvect, int32_t yvect, int32_t const walldist, int32_t const ceildist,
int32_t const flordist, uint32_t const cliptype) ATTRIBUTE((nonnull(1, 2)));
inline int clipmove(int* x, int* y, int* z, short* sect, int xv, int yv, int wal, int ceil, int flor, int ct)
{
vec3_t xyz = { *x,*y,*z };
int retval = clipmove(&xyz, sect, xv, yv, wal, ceil, flor, ct);
*x = xyz.x;
*y = xyz.y;
*z = xyz.z;
return retval;
}
int32_t clipmovex(vec3_t *const pos, int16_t *const sectnum, int32_t xvect, int32_t yvect, int32_t const walldist, int32_t const ceildist,
int32_t const flordist, uint32_t const cliptype, uint8_t const noslidep) ATTRIBUTE((nonnull(1, 2)));
int pushmove(vec3_t *const vect, int16_t *const sectnum, int32_t const walldist, int32_t const ceildist, int32_t const flordist,

View file

@ -621,6 +621,131 @@ SKIPWALLCHECK:
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
int movesprite(short spritenum, int xchange, int ychange, int zchange, unsigned int cliptype)
{
int daz, h, oldx, oldy;
short retval, dasectnum, a, cd;
char bg;
bg = badguy(&sprite[spritenum]);
if (sprite[spritenum].statnum == 5 || (bg && sprite[spritenum].xrepeat < 4))
{
sprite[spritenum].x += (xchange * TICSPERFRAME) >> 2;
sprite[spritenum].y += (ychange * TICSPERFRAME) >> 2;
sprite[spritenum].z += (zchange * TICSPERFRAME) >> 2;
if (bg)
setsprite(spritenum, sprite[spritenum].x, sprite[spritenum].y, sprite[spritenum].z);
return 0;
}
dasectnum = sprite[spritenum].sectnum;
daz = sprite[spritenum].z;
h = ((tilesiz[sprite[spritenum].picnum].y * sprite[spritenum].yrepeat) << 1);
daz -= h;
if (bg)
{
oldx = sprite[spritenum].x;
oldy = sprite[spritenum].y;
if (sprite[spritenum].xrepeat > 60)
retval = clipmove(&sprite[spritenum].x, &sprite[spritenum].y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 1024L, (4 << 8), (4 << 8), cliptype);
else
{
if (g_gameType & GAMEFLAG_RRALL)
cd = 192;
else if (sprite[spritenum].picnum == LIZMAN)
cd = 292;
#if 0 // TRANSITIONAL the needed infrastructure for this is too different for now
else if ((actortype[sprite[spritenum].picnum] & 3))
#else
else if (A_CheckSpriteFlags(spritenum, SFLAG_BADGUY))
#endif
cd = sprite[spritenum].clipdist << 2;
else
cd = 192;
retval = clipmove(&sprite[spritenum].x, &sprite[spritenum].y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), cd, (4 << 8), (4 << 8), cliptype);
}
bool rr = (g_gameType & GAMEFLAG_RRALL);
// conditional code from hell...
if (dasectnum < 0 || (dasectnum >= 0 &&
((hittype[spritenum].actorstayput >= 0 && hittype[spritenum].actorstayput != dasectnum) ||
(!rr &&
(
((sprite[spritenum].picnum == BOSS2) && sprite[spritenum].pal == 0 && sector[dasectnum].lotag != 3) ||
((sprite[spritenum].picnum == BOSS1 || sprite[spritenum].picnum == BOSS2) && sector[dasectnum].lotag == ST_1_ABOVE_WATER) ||
(sector[dasectnum].lotag == ST_1_ABOVE_WATER && (sprite[spritenum].picnum == LIZMAN || (sprite[spritenum].picnum == LIZTROOP && sprite[spritenum].zvel == 0)))
)
)
)))
{
sprite[spritenum].x = oldx;
sprite[spritenum].y = oldy;
if (sector[dasectnum].lotag == ST_1_ABOVE_WATER && (rr || sprite[spritenum].picnum == LIZMAN))
sprite[spritenum].ang = (krand() & 2047);
else if ((hittype[spritenum].temp_data[0] & 3) == 1 && (rr || sprite[spritenum].picnum != COMMANDER))
sprite[spritenum].ang = (krand() & 2047);
setsprite(spritenum, oldx, oldy, sprite[spritenum].z);
if (dasectnum < 0) dasectnum = 0;
return (16384 + dasectnum);
}
if ((retval & 49152) >= 32768 && (hittype[spritenum].cgg == 0)) sprite[spritenum].ang += 768;
}
else
{
if (sprite[spritenum].statnum == 4)
retval =
clipmove(&sprite[spritenum].x, &sprite[spritenum].y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 8L, (4 << 8), (4 << 8), cliptype);
else
retval =
clipmove(&sprite[spritenum].x, &sprite[spritenum].y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), (int)(sprite[spritenum].clipdist << 2), (4 << 8), (4 << 8), cliptype);
}
if (dasectnum >= 0)
if ((dasectnum != sprite[spritenum].sectnum))
changespritesect(spritenum, dasectnum);
daz = sprite[spritenum].z + ((zchange * TICSPERFRAME) >> 3);
if ((daz > hittype[spritenum].ceilingz) && (daz <= hittype[spritenum].floorz))
sprite[spritenum].z = daz;
else
if (retval == 0)
return(16384 + dasectnum);
return(retval);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
short ssp(short i, unsigned int cliptype) //The set sprite function
{
spritetype* s;
int movetype;
s = &sprite[i];
movetype = movesprite(i,
(s->xvel * (sintable[(s->ang + 512) & 2047])) >> 14,
(s->xvel * (sintable[s->ang & 2047])) >> 14, s->zvel,
cliptype);
return (movetype == 0);
}
//---------------------------------------------------------------------------
//
//

View file

@ -149,6 +149,7 @@ typedef struct
uint8_t lightcount, filler[3];
#endif
} actor_t;
#define temp_data t_data
// this struct needs to match the beginning of actor_t above
typedef struct

View file

@ -131,133 +131,12 @@ static int32_t A_CheckNeedZUpdate(int32_t spriteNum, int32_t zChange, int32_t *p
return 0;
}
int movesprite(short spritenum, int xchange, int ychange, int zchange, unsigned int cliptype);
int32_t A_MoveSprite(int32_t spriteNum, vec3_t const * const change, uint32_t clipType)
{
spritetype *const pSprite = &sprite[spriteNum];
int const isEnemy = A_CheckEnemySprite(pSprite);
vec2_t const oldPos = *(vec2_t *)pSprite;
if (pSprite->statnum == STAT_MISC || (isEnemy && pSprite->xrepeat < 4))
{
pSprite->x += change->x;
pSprite->y += change->y;
pSprite->z += change->z;
if (isEnemy)
setsprite(spriteNum, (vec3_t *)pSprite);
return 0;
}
int32_t clipDist;
if (isEnemy)
{
if (RR)
clipDist = 192;
else if (pSprite->xrepeat > 60)
clipDist = 1024;
else if (pSprite->picnum == TILE_LIZMAN)
clipDist = 292;
else if (A_CheckSpriteFlags(spriteNum, SFLAG_BADGUY))
clipDist = pSprite->clipdist<<2;
else
clipDist = 192;
}
else
{
if (pSprite->statnum == STAT_PROJECTILE)
clipDist = 8;
else if (RR)
clipDist = 128;
else
clipDist = pSprite->clipdist<<2;
}
int16_t newSectnum = pSprite->sectnum;
int32_t newZ = pSprite->z - 2 * tilesiz[pSprite->picnum].y * pSprite->yrepeat;
int const oldZ = pSprite->z;
// Handle horizontal movement first.
pSprite->z = newZ;
int returnValue =
clipmove((vec3_t *)pSprite, &newSectnum, change->x << 13, change->y << 13, clipDist, ZOFFSET6, ZOFFSET6, clipType);
pSprite->z = oldZ;
if (isEnemy)
{
// Handle potential stayput condition (map-provided or hard-coded).
if (newSectnum < 0
|| ((actor[spriteNum].actorstayput >= 0 && actor[spriteNum].actorstayput != newSectnum)
|| (!RR && ((pSprite->picnum == TILE_BOSS2 && pSprite->pal == 0 && sector[newSectnum].lotag != ST_3)
|| ((pSprite->picnum == TILE_BOSS1 || pSprite->picnum == TILE_BOSS2) && sector[newSectnum].lotag == ST_1_ABOVE_WATER)
|| (sector[newSectnum].lotag == ST_1_ABOVE_WATER
&& (pSprite->picnum == TILE_LIZMAN || (pSprite->picnum == TILE_LIZTROOP && pSprite->zvel == 0)))))
))
{
*(vec2_t *) pSprite = oldPos;
if ((newSectnum >= 0 && sector[newSectnum].lotag == ST_1_ABOVE_WATER && (RR || pSprite->picnum == TILE_LIZMAN))
|| ((AC_COUNT(actor[spriteNum].t_data)&3) == 1 && (RR || pSprite->picnum != TILE_COMMANDER)))
pSprite->ang = krand2()&2047;
setsprite(spriteNum, (vec3_t *)pSprite);
if (newSectnum < 0)
newSectnum = 0;
return 16384+newSectnum;
}
if ((returnValue&49152) >= 32768 && actor[spriteNum].cgg==0)
pSprite->ang += 768;
}
if (newSectnum == -1)
{
newSectnum = pSprite->sectnum;
// Printf("%s:%d wtf\n",__FILE__,__LINE__);
}
else if (newSectnum != pSprite->sectnum)
{
changespritesect(spriteNum, newSectnum);
// A_GetZLimits(spritenum);
}
Bassert(newSectnum == pSprite->sectnum);
int const doZUpdate = A_CheckNeedZUpdate(spriteNum, change->z, &newZ);
// Update sprite's z positions and (for TROR) maybe the sector number.
if (doZUpdate)
{
pSprite->z = newZ;
#ifdef YAX_ENABLE
if (doZUpdate < 0)
{
// If we passed a TROR no-SE7 water boundary, signal to the outside
// that the ceiling/floor was not hit. However, this is not enough:
// later, code checks for (retval&49152)!=49152
// [i.e. not "was ceiling or floor hit", but "was no sprite hit"]
// and calls G_WeaponHitCeilingOrFloor() then, so we need to set
// actor[].flags |= SFLAG_DIDNOSE7WATER in A_CheckNeedZUpdate()
// previously.
// XXX: Why is this contrived data flow necessary? (If at all.)
changespritesect(spriteNum, -doZUpdate-1);
return 0;
}
if (yax_getbunch(newSectnum, (change->z>0))>=0
&& (SECTORFLD(newSectnum,stat, (change->z>0))&yax_waltosecmask(clipType))==0)
{
setspritez(spriteNum, (vec3_t *)pSprite);
}
#endif
}
else if (returnValue == 0)
returnValue = 16384+newSectnum;
return returnValue;
return movesprite(spriteNum, change->x, change->y, change->z, clipType);
}
int32_t block_deletesprite = 0;