mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-05-04 07:52:22 +00:00
Merge branch 'model-gradients' into 'master'
Model gradients + model tilt adjustments See merge request KartKrew/Kart!157
This commit is contained in:
commit
921409224c
9 changed files with 397 additions and 92 deletions
|
|
@ -653,13 +653,12 @@ spritemd2found:
|
||||||
// 0.2126 to red
|
// 0.2126 to red
|
||||||
// 0.7152 to green
|
// 0.7152 to green
|
||||||
// 0.0722 to blue
|
// 0.0722 to blue
|
||||||
// (See this same define in k_kart.c!)
|
// (See this same define in hw_md2.c!)
|
||||||
#define SETBRIGHTNESS(brightness,r,g,b) \
|
#define SETBRIGHTNESS(brightness,r,g,b) \
|
||||||
brightness = (UINT8)(((1063*((UINT16)r)/5000) + (3576*((UINT16)g)/5000) + (361*((UINT16)b)/5000)) / 3)
|
brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000))
|
||||||
|
|
||||||
static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color)
|
static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color)
|
||||||
{
|
{
|
||||||
UINT8 i;
|
|
||||||
UINT16 w = gpatch->width, h = gpatch->height;
|
UINT16 w = gpatch->width, h = gpatch->height;
|
||||||
UINT32 size = w*h;
|
UINT32 size = w*h;
|
||||||
RGBA_t *image, *blendimage, *cur, blendcolor;
|
RGBA_t *image, *blendimage, *cur, blendcolor;
|
||||||
|
|
@ -684,102 +683,188 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
|
||||||
|
|
||||||
image = gpatch->mipmap.grInfo.data;
|
image = gpatch->mipmap.grInfo.data;
|
||||||
blendimage = blendgpatch->mipmap.grInfo.data;
|
blendimage = blendgpatch->mipmap.grInfo.data;
|
||||||
|
blendcolor = V_GetColor(0); // initialize
|
||||||
|
|
||||||
// Average all of the translation's colors
|
while (size--)
|
||||||
{
|
{
|
||||||
const UINT8 div = 6;
|
UINT16 brightness;
|
||||||
const UINT8 start = 4;
|
|
||||||
UINT32 r, g, b;
|
|
||||||
|
|
||||||
blendcolor = V_GetColor(colortranslations[color][start]);
|
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
|
||||||
r = (UINT32)(blendcolor.s.red*blendcolor.s.red);
|
if (skinnum == TC_RAINBOW)
|
||||||
g = (UINT32)(blendcolor.s.green*blendcolor.s.green);
|
|
||||||
b = (UINT32)(blendcolor.s.blue*blendcolor.s.blue);
|
|
||||||
|
|
||||||
for (i = 1; i < div; i++)
|
|
||||||
{
|
|
||||||
RGBA_t nextcolor = V_GetColor(colortranslations[color][start+i]);
|
|
||||||
r += (UINT32)(nextcolor.s.red*nextcolor.s.red);
|
|
||||||
g += (UINT32)(nextcolor.s.green*nextcolor.s.green);
|
|
||||||
b += (UINT32)(nextcolor.s.blue*nextcolor.s.blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
blendcolor.s.red = (UINT8)(FixedSqrt((r/div)<<FRACBITS)>>FRACBITS);
|
|
||||||
blendcolor.s.green = (UINT8)(FixedSqrt((g/div)<<FRACBITS)>>FRACBITS);
|
|
||||||
blendcolor.s.blue = (UINT8)(FixedSqrt((b/div)<<FRACBITS)>>FRACBITS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// rainbow support, could theoretically support boss ones too
|
|
||||||
if (skinnum == TC_RAINBOW)
|
|
||||||
{
|
|
||||||
while (size--)
|
|
||||||
{
|
{
|
||||||
if (image->s.alpha == 0 && blendimage->s.alpha == 0)
|
if (image->s.alpha == 0 && blendimage->s.alpha == 0)
|
||||||
{
|
{
|
||||||
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
|
|
||||||
cur->rgba = image->rgba;
|
cur->rgba = image->rgba;
|
||||||
|
cur++; image++; blendimage++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UINT32 tempcolor;
|
UINT16 imagebright, blendbright;
|
||||||
UINT16 imagebright, blendbright, finalbright, colorbright;
|
|
||||||
SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue);
|
SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue);
|
||||||
SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
|
SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
|
||||||
// slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway
|
// slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway
|
||||||
finalbright = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255;
|
brightness = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255;
|
||||||
SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue);
|
|
||||||
|
|
||||||
tempcolor = (finalbright*blendcolor.s.red)/colorbright;
|
|
||||||
tempcolor = min(255, tempcolor);
|
|
||||||
cur->s.red = (UINT8)tempcolor;
|
|
||||||
tempcolor = (finalbright*blendcolor.s.green)/colorbright;
|
|
||||||
tempcolor = min(255, tempcolor);
|
|
||||||
cur->s.green = (UINT8)tempcolor;
|
|
||||||
tempcolor = (finalbright*blendcolor.s.blue)/colorbright;
|
|
||||||
tempcolor = min(255, tempcolor);
|
|
||||||
cur->s.blue = (UINT8)tempcolor;
|
|
||||||
cur->s.alpha = image->s.alpha;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cur++; image++; blendimage++;
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
while (size--)
|
|
||||||
{
|
{
|
||||||
if (blendimage->s.alpha == 0)
|
if (blendimage->s.alpha == 0)
|
||||||
{
|
{
|
||||||
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
|
|
||||||
cur->rgba = image->rgba;
|
cur->rgba = image->rgba;
|
||||||
|
cur++; image++; blendimage++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
INT32 tempcolor;
|
SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
|
||||||
INT16 tempmult, tempalpha;
|
}
|
||||||
tempalpha = -(abs(blendimage->s.red-127)-127)*2;
|
}
|
||||||
if (tempalpha > 255)
|
|
||||||
tempalpha = 255;
|
|
||||||
else if (tempalpha < 0)
|
|
||||||
tempalpha = 0;
|
|
||||||
|
|
||||||
tempmult = (blendimage->s.red-127)*2;
|
// Calculate a sort of "gradient" for the skincolor
|
||||||
if (tempmult > 255)
|
// (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...)
|
||||||
tempmult = 255;
|
{
|
||||||
else if (tempmult < 0)
|
RGBA_t nextcolor;
|
||||||
tempmult = 0;
|
UINT8 firsti, secondi, mul;
|
||||||
|
UINT32 r, g, b;
|
||||||
|
|
||||||
tempcolor = (image->s.red*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.red)/255)) * blendimage->s.alpha)/255;
|
// Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors.
|
||||||
cur->s.red = (UINT8)tempcolor;
|
// Ensue horrible mess.
|
||||||
tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255;
|
if (skinnum == TC_RAINBOW)
|
||||||
cur->s.green = (UINT8)tempcolor;
|
{
|
||||||
tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255;
|
UINT16 brightdif = 256;
|
||||||
cur->s.blue = (UINT8)tempcolor;
|
UINT8 colorbrightnesses[16];
|
||||||
cur->s.alpha = image->s.alpha;
|
INT32 compare, m, d;
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
// Ignore pure white & pitch black
|
||||||
|
if (brightness > 253 || brightness < 2)
|
||||||
|
{
|
||||||
|
cur->rgba = image->rgba;
|
||||||
|
cur++; image++; blendimage++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
firsti = 0;
|
||||||
|
mul = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
RGBA_t tempc = V_GetColor(colortranslations[color][i]);
|
||||||
|
SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is)
|
||||||
|
continue;
|
||||||
|
compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness));
|
||||||
|
if (compare < brightdif)
|
||||||
|
{
|
||||||
|
brightdif = (UINT16)compare;
|
||||||
|
firsti = i; // best matching color that's equal brightness or darker
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
secondi = firsti+1; // next color in line
|
||||||
|
if (secondi == 16)
|
||||||
|
{
|
||||||
|
m = (INT16)brightness; // - 0;
|
||||||
|
d = (INT16)colorbrightnesses[firsti]; // - 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m = (INT16)brightness - (INT16)colorbrightnesses[secondi];
|
||||||
|
d = (INT16)colorbrightnesses[firsti] - (INT16)colorbrightnesses[secondi];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m >= d)
|
||||||
|
m = d-1;
|
||||||
|
|
||||||
|
// calculate the "gradient" multiplier based on how close this color is to the one next in line
|
||||||
|
if (m <= 0 || d <= 0)
|
||||||
|
mul = 0;
|
||||||
|
else
|
||||||
|
mul = 15 - ((m * 16) / d);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Thankfully, it's normally way more simple.
|
||||||
|
// Just convert brightness to a skincolor value, use remainder to find the gradient multipler
|
||||||
|
firsti = ((UINT8)(255-brightness) / 16);
|
||||||
|
secondi = firsti+1;
|
||||||
|
mul = ((UINT8)(255-brightness) % 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
cur++; image++; blendimage++;
|
blendcolor = V_GetColor(colortranslations[color][firsti]);
|
||||||
|
|
||||||
|
if (mul > 0 // If it's 0, then we only need the first color.
|
||||||
|
&& colortranslations[color][firsti] != colortranslations[color][secondi]) // Some colors have duplicate colors in a row, so let's just save the process
|
||||||
|
{
|
||||||
|
if (secondi == 16) // blend to black
|
||||||
|
nextcolor = V_GetColor(31);
|
||||||
|
else
|
||||||
|
nextcolor = V_GetColor(colortranslations[color][secondi]);
|
||||||
|
|
||||||
|
// Find difference between points
|
||||||
|
r = (UINT32)(nextcolor.s.red - blendcolor.s.red);
|
||||||
|
g = (UINT32)(nextcolor.s.green - blendcolor.s.green);
|
||||||
|
b = (UINT32)(nextcolor.s.blue - blendcolor.s.blue);
|
||||||
|
|
||||||
|
// Find the gradient of the two points
|
||||||
|
r = ((mul * r) / 16);
|
||||||
|
g = ((mul * g) / 16);
|
||||||
|
b = ((mul * b) / 16);
|
||||||
|
|
||||||
|
// Add gradient value to color
|
||||||
|
blendcolor.s.red += r;
|
||||||
|
blendcolor.s.green += g;
|
||||||
|
blendcolor.s.blue += b;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (skinnum == TC_RAINBOW)
|
||||||
|
{
|
||||||
|
UINT32 tempcolor;
|
||||||
|
UINT16 colorbright;
|
||||||
|
|
||||||
|
SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue);
|
||||||
|
if (colorbright == 0)
|
||||||
|
colorbright = 1; // no dividing by 0 please
|
||||||
|
|
||||||
|
tempcolor = (brightness * blendcolor.s.red) / colorbright;
|
||||||
|
tempcolor = min(255, tempcolor);
|
||||||
|
cur->s.red = (UINT8)tempcolor;
|
||||||
|
|
||||||
|
tempcolor = (brightness * blendcolor.s.green) / colorbright;
|
||||||
|
tempcolor = min(255, tempcolor);
|
||||||
|
cur->s.green = (UINT8)tempcolor;
|
||||||
|
|
||||||
|
tempcolor = (brightness * blendcolor.s.blue) / colorbright;
|
||||||
|
tempcolor = min(255, tempcolor);
|
||||||
|
cur->s.blue = (UINT8)tempcolor;
|
||||||
|
cur->s.alpha = image->s.alpha;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Color strength depends on image alpha
|
||||||
|
INT32 tempcolor;
|
||||||
|
|
||||||
|
tempcolor = ((image->s.red * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.red * blendimage->s.alpha) / 255);
|
||||||
|
tempcolor = min(255, tempcolor);
|
||||||
|
cur->s.red = (UINT8)tempcolor;
|
||||||
|
|
||||||
|
tempcolor = ((image->s.green * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.green * blendimage->s.alpha) / 255);
|
||||||
|
tempcolor = min(255, tempcolor);
|
||||||
|
cur->s.green = (UINT8)tempcolor;
|
||||||
|
|
||||||
|
tempcolor = ((image->s.blue * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.blue * blendimage->s.alpha) / 255);
|
||||||
|
tempcolor = min(255, tempcolor);
|
||||||
|
cur->s.blue = (UINT8)tempcolor;
|
||||||
|
cur->s.alpha = image->s.alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur++; image++; blendimage++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
@ -1091,11 +1176,11 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
||||||
#ifdef USE_FTRANSFORM_ANGLEZ
|
#ifdef USE_FTRANSFORM_ANGLEZ
|
||||||
// Slope rotation from Kart
|
// Slope rotation from Kart
|
||||||
p.anglez = 0.0f;
|
p.anglez = 0.0f;
|
||||||
if (spr->mobj->standingslope)
|
if (spr->mobj->modeltilt)
|
||||||
{
|
{
|
||||||
fixed_t tempz = spr->mobj->standingslope->normal.z;
|
fixed_t tempz = spr->mobj->modeltilt->normal.z;
|
||||||
fixed_t tempy = spr->mobj->standingslope->normal.y;
|
fixed_t tempy = spr->mobj->modeltilt->normal.y;
|
||||||
fixed_t tempx = spr->mobj->standingslope->normal.x;
|
fixed_t tempx = spr->mobj->modeltilt->normal.x;
|
||||||
fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx));
|
fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx));
|
||||||
p.anglez = FIXED_TO_FLOAT(tempangle);
|
p.anglez = FIXED_TO_FLOAT(tempangle);
|
||||||
tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy));
|
tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy));
|
||||||
|
|
|
||||||
14
src/k_kart.c
14
src/k_kart.c
|
|
@ -410,7 +410,7 @@ UINT8 colortranslations[MAXTRANSLATIONS][16] = {
|
||||||
// 0.0722 to blue
|
// 0.0722 to blue
|
||||||
// (See this same define in hw_md2.c!)
|
// (See this same define in hw_md2.c!)
|
||||||
#define SETBRIGHTNESS(brightness,r,g,b) \
|
#define SETBRIGHTNESS(brightness,r,g,b) \
|
||||||
brightness = (UINT8)(((1063*((UINT16)r)/5000) + (3576*((UINT16)g)/5000) + (361*((UINT16)b)/5000)) / 3)
|
brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000))
|
||||||
|
|
||||||
/** \brief Generates the rainbow colourmaps that are used when a player has the invincibility power
|
/** \brief Generates the rainbow colourmaps that are used when a player has the invincibility power
|
||||||
|
|
||||||
|
|
@ -4529,6 +4529,15 @@ static void K_MoveHeldObjects(player_t *player)
|
||||||
if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT)
|
if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT)
|
||||||
P_TeleportMove(cur, targx, targy, cur->z);
|
P_TeleportMove(cur, targx, targy, cur->z);
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (P_IsObjectOnGround(cur))
|
||||||
|
{
|
||||||
|
// Slope values are set in the function, but we DON'T want to use its return value.
|
||||||
|
P_CalculateShadowFloor(cur, cur->x, cur->y, cur->z,
|
||||||
|
cur->radius, cur->height, (cur->eflags & MFE_VERTICALFLIP), false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
cur = cur->hnext;
|
cur = cur->hnext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4618,6 +4627,9 @@ static void K_MoveHeldObjects(player_t *player)
|
||||||
|
|
||||||
P_TeleportMove(cur, targx, targy, targz);
|
P_TeleportMove(cur, targx, targy, targz);
|
||||||
K_FlipFromObject(cur, player->mo); // Update graviflip in real time thanks.
|
K_FlipFromObject(cur, player->mo); // Update graviflip in real time thanks.
|
||||||
|
#ifdef HWRENDER
|
||||||
|
cur->modeltilt = player->mo->modeltilt;
|
||||||
|
#endif
|
||||||
num = (num+1) % 2;
|
num = (num+1) % 2;
|
||||||
cur = cur->hnext;
|
cur = cur->hnext;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -227,6 +227,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
|
||||||
boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
|
boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
|
||||||
//void P_RunShields(void);
|
//void P_RunShields(void);
|
||||||
void P_RunOverlays(void);
|
void P_RunOverlays(void);
|
||||||
|
fixed_t P_CalculateShadowFloor(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player);
|
||||||
void P_RunShadows(void);
|
void P_RunShadows(void);
|
||||||
void P_MobjThinker(mobj_t *mobj);
|
void P_MobjThinker(mobj_t *mobj);
|
||||||
boolean P_RailThinker(mobj_t *mobj);
|
boolean P_RailThinker(mobj_t *mobj);
|
||||||
|
|
|
||||||
12
src/p_map.c
12
src/p_map.c
|
|
@ -2892,14 +2892,24 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
||||||
P_HandleSlopeLanding(thing, tmfloorslope);
|
P_HandleSlopeLanding(thing, tmfloorslope);
|
||||||
|
|
||||||
if (thing->momz <= 0)
|
if (thing->momz <= 0)
|
||||||
|
{
|
||||||
thing->standingslope = tmfloorslope;
|
thing->standingslope = tmfloorslope;
|
||||||
|
#ifdef HWRENDER
|
||||||
|
thing->modeltilt = thing->standingslope;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) {
|
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) {
|
||||||
if (!startingonground && tmceilingslope)
|
if (!startingonground && tmceilingslope)
|
||||||
P_HandleSlopeLanding(thing, tmceilingslope);
|
P_HandleSlopeLanding(thing, tmceilingslope);
|
||||||
|
|
||||||
if (thing->momz >= 0)
|
if (thing->momz >= 0)
|
||||||
|
{
|
||||||
thing->standingslope = tmceilingslope;
|
thing->standingslope = tmceilingslope;
|
||||||
|
#ifdef HWRENDER
|
||||||
|
thing->modeltilt = thing->standingslope;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // don't set standingslope if you're not going to clip against it
|
else // don't set standingslope if you're not going to clip against it
|
||||||
|
|
@ -4702,7 +4712,7 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
|
||||||
if (!(rover->flags & FF_EXISTS))
|
if (!(rover->flags & FF_EXISTS))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE)))
|
if (!((rover->flags & FF_SOLID) || (rover->flags & FF_QUICKSAND)) || (rover->flags & FF_SWIMMABLE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
topheight = *rover->topheight;
|
topheight = *rover->topheight;
|
||||||
|
|
|
||||||
205
src/p_mobj.c
205
src/p_mobj.c
|
|
@ -1848,6 +1848,9 @@ void P_XYMovement(mobj_t *mo)
|
||||||
// Now compare the Zs of the different quantizations
|
// Now compare the Zs of the different quantizations
|
||||||
if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later
|
if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later
|
||||||
mo->standingslope = oldslope;
|
mo->standingslope = oldslope;
|
||||||
|
#ifdef HWRENDER
|
||||||
|
mo->modeltilt = mo->standingslope;
|
||||||
|
#endif
|
||||||
P_SlopeLaunch(mo);
|
P_SlopeLaunch(mo);
|
||||||
|
|
||||||
//CONS_Printf("launched off of slope - ");
|
//CONS_Printf("launched off of slope - ");
|
||||||
|
|
@ -2421,6 +2424,9 @@ static boolean P_ZMovement(mobj_t *mo)
|
||||||
if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM))
|
if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM))
|
||||||
{
|
{
|
||||||
mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
|
mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
|
||||||
|
#ifdef HWRENDER
|
||||||
|
mo->modeltilt = mo->standingslope;
|
||||||
|
#endif
|
||||||
P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope);
|
P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -6199,13 +6205,178 @@ static void P_RemoveOverlay(mobj_t *thing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simplified version of a code bit in P_MobjFloorZ
|
||||||
|
static fixed_t P_ShadowSlopeZ(pslope_t *slope, fixed_t x, fixed_t y, fixed_t radius, boolean ceiling)
|
||||||
|
{
|
||||||
|
fixed_t testx, testy;
|
||||||
|
|
||||||
|
if (slope->d.x < 0)
|
||||||
|
testx = radius;
|
||||||
|
else
|
||||||
|
testx = -radius;
|
||||||
|
|
||||||
|
if (slope->d.y < 0)
|
||||||
|
testy = radius;
|
||||||
|
else
|
||||||
|
testy = -radius;
|
||||||
|
|
||||||
|
if ((slope->zdelta > 0) ^ !!(ceiling))
|
||||||
|
{
|
||||||
|
testx = -testx;
|
||||||
|
testy = -testy;
|
||||||
|
}
|
||||||
|
|
||||||
|
testx += x;
|
||||||
|
testy += y;
|
||||||
|
|
||||||
|
return P_GetZAt(slope, testx, testy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets standingslope/modeltilt, returns z position for shadows; used also for stuff like bananas
|
||||||
|
// (I would've preferred to be able to return both the slope & z, but I'll take what I can get...)
|
||||||
|
fixed_t P_CalculateShadowFloor(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player)
|
||||||
|
{
|
||||||
|
fixed_t newz;
|
||||||
|
sector_t *sec;
|
||||||
|
#ifdef ESLOPE
|
||||||
|
pslope_t *slope = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sec = R_PointInSubsector(x, y)->sector;
|
||||||
|
|
||||||
|
if (flip)
|
||||||
|
{
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (sec->c_slope)
|
||||||
|
{
|
||||||
|
slope = sec->c_slope;
|
||||||
|
newz = P_ShadowSlopeZ(slope, x, y, radius, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
newz = sec->ceilingheight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (sec->f_slope)
|
||||||
|
{
|
||||||
|
slope = sec->f_slope;
|
||||||
|
newz = P_ShadowSlopeZ(slope, x, y, radius, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
newz = sec->floorheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check FOFs for a better suited slope
|
||||||
|
if (sec->ffloors)
|
||||||
|
{
|
||||||
|
ffloor_t *rover;
|
||||||
|
|
||||||
|
for (rover = sec->ffloors; rover; rover = rover->next)
|
||||||
|
{
|
||||||
|
fixed_t top, bottom;
|
||||||
|
fixed_t d1, d2;
|
||||||
|
|
||||||
|
if (!(rover->flags & FF_EXISTS))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((!(((rover->flags & FF_BLOCKPLAYER && player)
|
||||||
|
|| (rover->flags & FF_BLOCKOTHERS && !player))
|
||||||
|
|| (rover->flags & FF_QUICKSAND))
|
||||||
|
|| (rover->flags & FF_SWIMMABLE)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (*rover->t_slope)
|
||||||
|
top = P_ShadowSlopeZ(*rover->t_slope, x, y, radius, false);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
top = *rover->topheight;
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (*rover->b_slope)
|
||||||
|
bottom = P_ShadowSlopeZ(*rover->b_slope, x, y, radius, true);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
bottom = *rover->bottomheight;
|
||||||
|
|
||||||
|
if (flip)
|
||||||
|
{
|
||||||
|
if (rover->flags & FF_QUICKSAND)
|
||||||
|
{
|
||||||
|
if (z < top && (z + height) > bottom)
|
||||||
|
{
|
||||||
|
if (newz > (z + height))
|
||||||
|
{
|
||||||
|
newz = (z + height);
|
||||||
|
slope = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
d1 = (z + height) - (top + ((bottom - top)/2));
|
||||||
|
d2 = z - (top + ((bottom - top)/2));
|
||||||
|
|
||||||
|
if (bottom < newz && abs(d1) < abs(d2))
|
||||||
|
{
|
||||||
|
newz = bottom;
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (*rover->b_slope)
|
||||||
|
slope = *rover->b_slope;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rover->flags & FF_QUICKSAND)
|
||||||
|
{
|
||||||
|
if (z < top && (z + height) > bottom)
|
||||||
|
{
|
||||||
|
if (newz < z)
|
||||||
|
{
|
||||||
|
newz = z;
|
||||||
|
slope = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
d1 = z - (bottom + ((top - bottom)/2));
|
||||||
|
d2 = (z + height) - (bottom + ((top - bottom)/2));
|
||||||
|
|
||||||
|
if (top > newz && abs(d1) < abs(d2))
|
||||||
|
{
|
||||||
|
newz = top;
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (*rover->t_slope)
|
||||||
|
slope = *rover->t_slope;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
mobj->standingslope = slope;
|
||||||
|
#endif
|
||||||
|
#ifdef HWRENDER
|
||||||
|
mobj->modeltilt = slope;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return newz;
|
||||||
|
}
|
||||||
|
|
||||||
void P_RunShadows(void)
|
void P_RunShadows(void)
|
||||||
{
|
{
|
||||||
mobj_t *mobj, *next, *dest;
|
mobj_t *mobj, *next, *dest;
|
||||||
|
|
||||||
for (mobj = shadowcap; mobj; mobj = next)
|
for (mobj = shadowcap; mobj; mobj = next)
|
||||||
{
|
{
|
||||||
fixed_t floorz;
|
boolean flip;
|
||||||
|
fixed_t newz;
|
||||||
|
|
||||||
next = mobj->hnext;
|
next = mobj->hnext;
|
||||||
P_SetTarget(&mobj->hnext, NULL);
|
P_SetTarget(&mobj->hnext, NULL);
|
||||||
|
|
@ -6216,16 +6387,22 @@ void P_RunShadows(void)
|
||||||
continue; // shouldn't you already be dead?
|
continue; // shouldn't you already be dead?
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mobj->target->player)
|
|
||||||
floorz = mobj->target->floorz;
|
|
||||||
else // FOR SOME REASON, plain floorz is not reliable for normal objects, only players?!
|
|
||||||
floorz = P_FloorzAtPos(mobj->target->x, mobj->target->y, mobj->target->z, mobj->target->height);
|
|
||||||
|
|
||||||
K_MatchGenericExtraFlags(mobj, mobj->target);
|
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||||
|
flip = (mobj->eflags & MFE_VERTICALFLIP);
|
||||||
|
|
||||||
if (((mobj->target->eflags & MFE_VERTICALFLIP) && mobj->target->z+mobj->target->height > mobj->target->ceilingz)
|
newz = P_CalculateShadowFloor(mobj, mobj->target->x, mobj->target->y, mobj->target->z,
|
||||||
|| (!(mobj->target->eflags & MFE_VERTICALFLIP) && mobj->target->z < floorz))
|
mobj->target->radius, mobj->target->height, flip, (mobj->target->player != NULL));
|
||||||
mobj->flags2 |= MF2_DONTDRAW;
|
|
||||||
|
if (flip)
|
||||||
|
{
|
||||||
|
if ((mobj->target->z + mobj->target->height) > newz)
|
||||||
|
mobj->flags2 |= MF2_DONTDRAW;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mobj->target->z < newz)
|
||||||
|
mobj->flags2 |= MF2_DONTDRAW;
|
||||||
|
}
|
||||||
|
|
||||||
// First scale to the same radius
|
// First scale to the same radius
|
||||||
P_SetScale(mobj, FixedDiv(mobj->target->radius, mobj->info->radius));
|
P_SetScale(mobj, FixedDiv(mobj->target->radius, mobj->info->radius));
|
||||||
|
|
@ -6237,13 +6414,12 @@ void P_RunShadows(void)
|
||||||
|
|
||||||
P_TeleportMove(mobj, dest->x, dest->y, mobj->target->z);
|
P_TeleportMove(mobj, dest->x, dest->y, mobj->target->z);
|
||||||
|
|
||||||
if (((mobj->eflags & MFE_VERTICALFLIP) && (mobj->ceilingz > mobj->z+mobj->height))
|
if ((flip && newz > (mobj->z + mobj->height)) || (!flip && newz < mobj->z))
|
||||||
|| (!(mobj->eflags & MFE_VERTICALFLIP) && (floorz < mobj->z)))
|
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
fixed_t prevz;
|
fixed_t prevz;
|
||||||
|
|
||||||
mobj->z = (mobj->eflags & MFE_VERTICALFLIP ? mobj->ceilingz : floorz);
|
mobj->z = newz;
|
||||||
|
|
||||||
for (i = 0; i < MAXFFLOORS; i++)
|
for (i = 0; i < MAXFFLOORS; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -6255,7 +6431,7 @@ void P_RunShadows(void)
|
||||||
// Check new position to see if you should still be on that ledge
|
// Check new position to see if you should still be on that ledge
|
||||||
P_TeleportMove(mobj, dest->x, dest->y, mobj->z);
|
P_TeleportMove(mobj, dest->x, dest->y, mobj->z);
|
||||||
|
|
||||||
mobj->z = (mobj->eflags & MFE_VERTICALFLIP ? mobj->ceilingz : floorz);
|
mobj->z = newz;
|
||||||
|
|
||||||
if (mobj->z == prevz)
|
if (mobj->z == prevz)
|
||||||
break;
|
break;
|
||||||
|
|
@ -8216,6 +8392,9 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius),
|
P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius),
|
||||||
mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z);
|
mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z);
|
||||||
P_SetScale(mobj, mobj->target->scale);
|
P_SetScale(mobj, mobj->target->scale);
|
||||||
|
#ifdef HWRENDER
|
||||||
|
mobj->modeltilt = mobj->target->modeltilt;
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
player_t *p = NULL;
|
player_t *p = NULL;
|
||||||
|
|
|
||||||
|
|
@ -370,6 +370,9 @@ typedef struct mobj_s
|
||||||
|
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?)
|
struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?)
|
||||||
|
#ifdef HWRENDER
|
||||||
|
struct pslope_s *modeltilt; // Slope used for model tilting. Also is not synched, this is totally visual.
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
boolean colorized; // Whether the mobj uses the rainbow colormap
|
boolean colorized; // Whether the mobj uses the rainbow colormap
|
||||||
|
|
|
||||||
|
|
@ -2144,7 +2144,12 @@ static void LoadMobjThinker(actionf_p1 thinker)
|
||||||
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
|
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
|
||||||
#ifdef ESLOPE
|
#ifdef ESLOPE
|
||||||
if (diff2 & MD2_SLOPE)
|
if (diff2 & MD2_SLOPE)
|
||||||
|
{
|
||||||
mobj->standingslope = P_SlopeById(READUINT16(save_p));
|
mobj->standingslope = P_SlopeById(READUINT16(save_p));
|
||||||
|
#ifdef HWRENDER
|
||||||
|
mobj->modeltilt = mobj->standingslope;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (diff2 & MD2_COLORIZED)
|
if (diff2 & MD2_COLORIZED)
|
||||||
mobj->colorized = READUINT8(save_p);
|
mobj->colorized = READUINT8(save_p);
|
||||||
|
|
|
||||||
|
|
@ -836,6 +836,9 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
|
||||||
if (P_MobjFlip(thing)*(thing->momz) < 0) { // falling, land on slope
|
if (P_MobjFlip(thing)*(thing->momz) < 0) { // falling, land on slope
|
||||||
thing->momz = -P_MobjFlip(thing);
|
thing->momz = -P_MobjFlip(thing);
|
||||||
thing->standingslope = slope;
|
thing->standingslope = slope;
|
||||||
|
#ifdef HWRENDER
|
||||||
|
thing->modeltilt = thing->standingslope;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -852,6 +855,9 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
|
||||||
thing->momz = -P_MobjFlip(thing);
|
thing->momz = -P_MobjFlip(thing);
|
||||||
|
|
||||||
thing->standingslope = slope;
|
thing->standingslope = slope;
|
||||||
|
#ifdef HWRENDER
|
||||||
|
thing->modeltilt = thing->standingslope;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1645,12 +1645,16 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj)
|
||||||
ghost->frame |= tr_trans50<<FF_TRANSSHIFT;
|
ghost->frame |= tr_trans50<<FF_TRANSSHIFT;
|
||||||
ghost->fuse = ghost->info->damage;
|
ghost->fuse = ghost->info->damage;
|
||||||
ghost->skin = mobj->skin;
|
ghost->skin = mobj->skin;
|
||||||
|
ghost->standingslope = mobj->standingslope;
|
||||||
|
#ifdef HWRENDER
|
||||||
|
ghost->modeltilt = mobj->modeltilt;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mobj->flags2 & MF2_OBJECTFLIP)
|
if (mobj->flags2 & MF2_OBJECTFLIP)
|
||||||
ghost->flags |= MF2_OBJECTFLIP;
|
ghost->flags |= MF2_OBJECTFLIP;
|
||||||
|
|
||||||
if (!(mobj->flags & MF_DONTENCOREMAP))
|
if (!(mobj->flags & MF_DONTENCOREMAP))
|
||||||
mobj->flags &= ~MF_DONTENCOREMAP;
|
ghost->flags &= ~MF_DONTENCOREMAP;
|
||||||
|
|
||||||
return ghost;
|
return ghost;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue