mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-10 16:52:16 +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.7152 to green
|
||||
// 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) \
|
||||
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)
|
||||
{
|
||||
UINT8 i;
|
||||
UINT16 w = gpatch->width, h = gpatch->height;
|
||||
UINT32 size = w*h;
|
||||
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;
|
||||
blendimage = blendgpatch->mipmap.grInfo.data;
|
||||
blendcolor = V_GetColor(0); // initialize
|
||||
|
||||
// Average all of the translation's colors
|
||||
while (size--)
|
||||
{
|
||||
const UINT8 div = 6;
|
||||
const UINT8 start = 4;
|
||||
UINT32 r, g, b;
|
||||
UINT16 brightness;
|
||||
|
||||
blendcolor = V_GetColor(colortranslations[color][start]);
|
||||
r = (UINT32)(blendcolor.s.red*blendcolor.s.red);
|
||||
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--)
|
||||
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
|
||||
if (skinnum == TC_RAINBOW)
|
||||
{
|
||||
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++; image++; blendimage++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 tempcolor;
|
||||
UINT16 imagebright, blendbright, finalbright, colorbright;
|
||||
UINT16 imagebright, blendbright;
|
||||
SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->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
|
||||
finalbright = (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;
|
||||
brightness = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255;
|
||||
}
|
||||
|
||||
cur++; image++; blendimage++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (size--)
|
||||
else
|
||||
{
|
||||
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++; image++; blendimage++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 tempcolor;
|
||||
INT16 tempmult, tempalpha;
|
||||
tempalpha = -(abs(blendimage->s.red-127)-127)*2;
|
||||
if (tempalpha > 255)
|
||||
tempalpha = 255;
|
||||
else if (tempalpha < 0)
|
||||
tempalpha = 0;
|
||||
SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
|
||||
}
|
||||
}
|
||||
|
||||
tempmult = (blendimage->s.red-127)*2;
|
||||
if (tempmult > 255)
|
||||
tempmult = 255;
|
||||
else if (tempmult < 0)
|
||||
tempmult = 0;
|
||||
// Calculate a sort of "gradient" for the skincolor
|
||||
// (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...)
|
||||
{
|
||||
RGBA_t nextcolor;
|
||||
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;
|
||||
cur->s.red = (UINT8)tempcolor;
|
||||
tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255;
|
||||
cur->s.green = (UINT8)tempcolor;
|
||||
tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255;
|
||||
cur->s.blue = (UINT8)tempcolor;
|
||||
cur->s.alpha = image->s.alpha;
|
||||
// Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors.
|
||||
// Ensue horrible mess.
|
||||
if (skinnum == TC_RAINBOW)
|
||||
{
|
||||
UINT16 brightdif = 256;
|
||||
UINT8 colorbrightnesses[16];
|
||||
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;
|
||||
|
|
@ -1091,11 +1176,11 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
|
|||
#ifdef USE_FTRANSFORM_ANGLEZ
|
||||
// Slope rotation from Kart
|
||||
p.anglez = 0.0f;
|
||||
if (spr->mobj->standingslope)
|
||||
if (spr->mobj->modeltilt)
|
||||
{
|
||||
fixed_t tempz = spr->mobj->standingslope->normal.z;
|
||||
fixed_t tempy = spr->mobj->standingslope->normal.y;
|
||||
fixed_t tempx = spr->mobj->standingslope->normal.x;
|
||||
fixed_t tempz = spr->mobj->modeltilt->normal.z;
|
||||
fixed_t tempy = spr->mobj->modeltilt->normal.y;
|
||||
fixed_t tempx = spr->mobj->modeltilt->normal.x;
|
||||
fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx));
|
||||
p.anglez = FIXED_TO_FLOAT(tempangle);
|
||||
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
|
||||
// (See this same define in hw_md2.c!)
|
||||
#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
|
||||
|
||||
|
|
@ -4529,6 +4529,15 @@ static void K_MoveHeldObjects(player_t *player)
|
|||
if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -4618,6 +4627,9 @@ static void K_MoveHeldObjects(player_t *player)
|
|||
|
||||
P_TeleportMove(cur, targx, targy, targz);
|
||||
K_FlipFromObject(cur, player->mo); // Update graviflip in real time thanks.
|
||||
#ifdef HWRENDER
|
||||
cur->modeltilt = player->mo->modeltilt;
|
||||
#endif
|
||||
num = (num+1) % 2;
|
||||
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);
|
||||
//void P_RunShields(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_MobjThinker(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);
|
||||
|
||||
if (thing->momz <= 0)
|
||||
{
|
||||
thing->standingslope = tmfloorslope;
|
||||
#ifdef HWRENDER
|
||||
thing->modeltilt = thing->standingslope;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) {
|
||||
if (!startingonground && tmceilingslope)
|
||||
P_HandleSlopeLanding(thing, tmceilingslope);
|
||||
|
||||
if (thing->momz >= 0)
|
||||
{
|
||||
thing->standingslope = tmceilingslope;
|
||||
#ifdef HWRENDER
|
||||
thing->modeltilt = thing->standingslope;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
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))
|
||||
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;
|
||||
|
||||
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
|
||||
if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later
|
||||
mo->standingslope = oldslope;
|
||||
#ifdef HWRENDER
|
||||
mo->modeltilt = mo->standingslope;
|
||||
#endif
|
||||
P_SlopeLaunch(mo);
|
||||
|
||||
//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))
|
||||
{
|
||||
mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope;
|
||||
#ifdef HWRENDER
|
||||
mo->modeltilt = mo->standingslope;
|
||||
#endif
|
||||
P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope);
|
||||
}
|
||||
#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)
|
||||
{
|
||||
mobj_t *mobj, *next, *dest;
|
||||
|
||||
for (mobj = shadowcap; mobj; mobj = next)
|
||||
{
|
||||
fixed_t floorz;
|
||||
boolean flip;
|
||||
fixed_t newz;
|
||||
|
||||
next = mobj->hnext;
|
||||
P_SetTarget(&mobj->hnext, NULL);
|
||||
|
|
@ -6216,16 +6387,22 @@ void P_RunShadows(void)
|
|||
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);
|
||||
flip = (mobj->eflags & MFE_VERTICALFLIP);
|
||||
|
||||
if (((mobj->target->eflags & MFE_VERTICALFLIP) && mobj->target->z+mobj->target->height > mobj->target->ceilingz)
|
||||
|| (!(mobj->target->eflags & MFE_VERTICALFLIP) && mobj->target->z < floorz))
|
||||
mobj->flags2 |= MF2_DONTDRAW;
|
||||
newz = P_CalculateShadowFloor(mobj, mobj->target->x, mobj->target->y, mobj->target->z,
|
||||
mobj->target->radius, mobj->target->height, flip, (mobj->target->player != NULL));
|
||||
|
||||
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
|
||||
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);
|
||||
|
||||
if (((mobj->eflags & MFE_VERTICALFLIP) && (mobj->ceilingz > mobj->z+mobj->height))
|
||||
|| (!(mobj->eflags & MFE_VERTICALFLIP) && (floorz < mobj->z)))
|
||||
if ((flip && newz > (mobj->z + mobj->height)) || (!flip && newz < mobj->z))
|
||||
{
|
||||
INT32 i;
|
||||
fixed_t prevz;
|
||||
|
||||
mobj->z = (mobj->eflags & MFE_VERTICALFLIP ? mobj->ceilingz : floorz);
|
||||
mobj->z = newz;
|
||||
|
||||
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
|
||||
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)
|
||||
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),
|
||||
mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z);
|
||||
P_SetScale(mobj, mobj->target->scale);
|
||||
#ifdef HWRENDER
|
||||
mobj->modeltilt = mobj->target->modeltilt;
|
||||
#endif
|
||||
|
||||
{
|
||||
player_t *p = NULL;
|
||||
|
|
|
|||
|
|
@ -370,6 +370,9 @@ typedef struct mobj_s
|
|||
|
||||
#ifdef ESLOPE
|
||||
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
|
||||
|
||||
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);
|
||||
#ifdef ESLOPE
|
||||
if (diff2 & MD2_SLOPE)
|
||||
{
|
||||
mobj->standingslope = P_SlopeById(READUINT16(save_p));
|
||||
#ifdef HWRENDER
|
||||
mobj->modeltilt = mobj->standingslope;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
if (diff2 & MD2_COLORIZED)
|
||||
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
|
||||
thing->momz = -P_MobjFlip(thing);
|
||||
thing->standingslope = slope;
|
||||
#ifdef HWRENDER
|
||||
thing->modeltilt = thing->standingslope;
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -852,6 +855,9 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
|
|||
thing->momz = -P_MobjFlip(thing);
|
||||
|
||||
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->fuse = ghost->info->damage;
|
||||
ghost->skin = mobj->skin;
|
||||
ghost->standingslope = mobj->standingslope;
|
||||
#ifdef HWRENDER
|
||||
ghost->modeltilt = mobj->modeltilt;
|
||||
#endif
|
||||
|
||||
if (mobj->flags2 & MF2_OBJECTFLIP)
|
||||
ghost->flags |= MF2_OBJECTFLIP;
|
||||
|
||||
if (!(mobj->flags & MF_DONTENCOREMAP))
|
||||
mobj->flags &= ~MF_DONTENCOREMAP;
|
||||
ghost->flags &= ~MF_DONTENCOREMAP;
|
||||
|
||||
return ghost;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue