mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Add reversed weather
- Negative speed weather will spawn from a floor in a sector with a sky ceiling, and go up into the ceiling. - (Not really the same as reverse gravity weather in that aspect, because that would be for sky floors.) - Fixed invert precipitation flag for linedef type 8 being completely unimplemented. (How long has it been like this...?) - Fix swapping weather on the fly having reversed momz
This commit is contained in:
parent
35cc746adf
commit
6106ce1624
4 changed files with 108 additions and 68 deletions
|
|
@ -277,6 +277,7 @@ void P_RespawnSpecials(void);
|
|||
|
||||
mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);
|
||||
|
||||
void P_CalculatePrecipFloor(precipmobj_t *mobj);
|
||||
void P_RecalcPrecipInSector(sector_t *sector);
|
||||
void P_PrecipitationEffects(void);
|
||||
|
||||
|
|
|
|||
155
src/p_mobj.c
155
src/p_mobj.c
|
|
@ -3760,19 +3760,22 @@ animonly:
|
|||
P_CyclePlayerMobjState(mobj);
|
||||
}
|
||||
|
||||
static void CalculatePrecipFloor(precipmobj_t *mobj)
|
||||
void P_CalculatePrecipFloor(precipmobj_t *mobj)
|
||||
{
|
||||
// recalculate floorz each time
|
||||
const sector_t *mobjsecsubsec;
|
||||
|
||||
if (mobj && mobj->subsector && mobj->subsector->sector)
|
||||
mobjsecsubsec = mobj->subsector->sector;
|
||||
else
|
||||
return;
|
||||
|
||||
mobj->floorz = P_GetSectorFloorZAt(mobjsecsubsec, mobj->x, mobj->y);
|
||||
|
||||
if (mobjsecsubsec->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
fixed_t topheight;
|
||||
fixed_t height;
|
||||
|
||||
for (rover = mobjsecsubsec->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
|
|
@ -3783,9 +3786,9 @@ static void CalculatePrecipFloor(precipmobj_t *mobj)
|
|||
if (!(rover->flags & FF_BLOCKOTHERS) && !(rover->flags & FF_SWIMMABLE))
|
||||
continue;
|
||||
|
||||
topheight = P_GetFFloorTopZAt(rover, mobj->x, mobj->y);
|
||||
if (topheight > mobj->floorz)
|
||||
mobj->floorz = topheight;
|
||||
height = P_GetFFloorTopZAt(rover, mobj->x, mobj->y);
|
||||
if (height > mobj->floorz)
|
||||
mobj->floorz = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3800,7 +3803,7 @@ void P_RecalcPrecipInSector(sector_t *sector)
|
|||
sector->moved = true; // Recalc lighting and things too, maybe
|
||||
|
||||
for (psecnode = sector->touching_preciplist; psecnode; psecnode = psecnode->m_thinglist_next)
|
||||
CalculatePrecipFloor(psecnode->m_thing);
|
||||
P_CalculatePrecipFloor(psecnode->m_thing);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -3817,13 +3820,15 @@ void P_NullPrecipThinker(precipmobj_t *mobj)
|
|||
|
||||
void P_PrecipThinker(precipmobj_t *mobj)
|
||||
{
|
||||
boolean flip = (mobj->precipflags & PCF_FLIP);
|
||||
|
||||
P_CycleStateAnimation((mobj_t *)mobj);
|
||||
|
||||
if (mobj->state == &states[S_RAINRETURN])
|
||||
{
|
||||
// Reset to ceiling!
|
||||
P_SetPrecipMobjState(mobj, mobj->info->spawnstate);
|
||||
mobj->z = mobj->ceilingz;
|
||||
mobj->z = (flip) ? (mobj->floorz) : (mobj->ceilingz);
|
||||
mobj->momz = -mobj->info->speed;
|
||||
mobj->precipflags &= ~PCF_SPLASH;
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
|
|
@ -3858,18 +3863,20 @@ void P_PrecipThinker(precipmobj_t *mobj)
|
|||
if (mobj->precipflags & PCF_SPLASH)
|
||||
return;
|
||||
|
||||
mobj->z += mobj->momz;
|
||||
|
||||
// adjust height
|
||||
if ((mobj->z += mobj->momz) <= mobj->floorz)
|
||||
if ((flip) ? (mobj->z >= mobj->ceilingz) : (mobj->z <= mobj->floorz))
|
||||
{
|
||||
if ((mobj->info->deathstate == S_NULL) || (mobj->precipflags & PCF_PIT)) // no splashes on sky or bottomless pits
|
||||
{
|
||||
mobj->z = mobj->ceilingz;
|
||||
mobj->z = (flip) ? (mobj->floorz) : (mobj->ceilingz);
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
}
|
||||
else
|
||||
{
|
||||
P_SetPrecipMobjState(mobj, mobj->info->deathstate);
|
||||
mobj->z = mobj->floorz;
|
||||
mobj->z = (flip) ? (mobj->ceilingz) : (mobj->floorz);
|
||||
mobj->precipflags |= PCF_SPLASH;
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
}
|
||||
|
|
@ -10341,8 +10348,8 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
|
|||
{
|
||||
const mobjinfo_t *info = &mobjinfo[type];
|
||||
state_t *st;
|
||||
fixed_t start_z = INT32_MIN;
|
||||
precipmobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
|
||||
fixed_t starting_floorz;
|
||||
|
||||
mobj->type = type;
|
||||
mobj->info = info;
|
||||
|
|
@ -10364,8 +10371,8 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
|
|||
// set subsector and/or block links
|
||||
P_SetPrecipitationThingPosition(mobj);
|
||||
|
||||
mobj->floorz = starting_floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y);
|
||||
mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y);
|
||||
mobj->floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y);
|
||||
mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y);
|
||||
|
||||
mobj->floorrover = NULL;
|
||||
mobj->ceilingrover = NULL;
|
||||
|
|
@ -10373,17 +10380,34 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
|
|||
mobj->z = z;
|
||||
mobj->momz = -info->speed;
|
||||
|
||||
if (info->speed < 0)
|
||||
{
|
||||
mobj->precipflags |= PCF_FLIP;
|
||||
}
|
||||
|
||||
start_z = mobj->floorz;
|
||||
|
||||
mobj->thinker.function.acp1 = (actionf_p1)P_NullPrecipThinker;
|
||||
P_AddThinker(THINK_PRECIP, &mobj->thinker);
|
||||
|
||||
CalculatePrecipFloor(mobj);
|
||||
P_CalculatePrecipFloor(mobj);
|
||||
|
||||
if (mobj->floorz != starting_floorz)
|
||||
mobj->precipflags |= PCF_FOF;
|
||||
else if (GETSECSPECIAL(mobj->subsector->sector->special, 1) == 7
|
||||
|| GETSECSPECIAL(mobj->subsector->sector->special, 1) == 6
|
||||
|| mobj->subsector->sector->floorpic == skyflatnum)
|
||||
mobj->precipflags |= PCF_PIT;
|
||||
if (mobj->floorz != start_z)
|
||||
{
|
||||
; //mobj->precipflags |= PCF_FOF;
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 special = GETSECSPECIAL(mobj->subsector->sector->special, 1);
|
||||
boolean sFlag = (mobj->precipflags & PCF_FLIP) ? (mobj->subsector->sector->flags & SF_FLIPSPECIAL_CEILING) : (mobj->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR);
|
||||
boolean pitFloor = ((special == 6 || special == 7) && sFlag);
|
||||
boolean skyFloor = (mobj->precipflags & PCF_FLIP) ? (mobj->subsector->sector->ceilingpic == skyflatnum) : (mobj->subsector->sector->floorpic == skyflatnum);
|
||||
|
||||
if (pitFloor || skyFloor)
|
||||
{
|
||||
mobj->precipflags |= PCF_PIT;
|
||||
}
|
||||
}
|
||||
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
|
||||
|
|
@ -10588,13 +10612,19 @@ consvar_t cv_itemrespawn = CVAR_INIT ("respawnitem", "On", CV_NETVAR, CV_OnOff,
|
|||
void P_SpawnPrecipitation(void)
|
||||
{
|
||||
INT32 i, j, k;
|
||||
mobjtype_t type = precipprops[curWeather].type;
|
||||
UINT8 randomstates = (UINT8)mobjinfo[type].damage;
|
||||
|
||||
const mobjtype_t type = precipprops[curWeather].type;
|
||||
const UINT8 randomstates = (UINT8)mobjinfo[type].damage;
|
||||
const boolean flip = (mobjinfo[type].speed < 0);
|
||||
|
||||
fixed_t basex, basey, x, y, z, height;
|
||||
UINT16 numparticles = 0;
|
||||
boolean condition = false;
|
||||
|
||||
subsector_t *precipsector = NULL;
|
||||
precipmobj_t *rainmo = NULL;
|
||||
|
||||
if (dedicated || !cv_drawdist_precip.value || curWeather == PRECIP_NONE) // SRB2Kart
|
||||
if (dedicated || !cv_drawdist_precip.value || type == MT_NULL)
|
||||
return;
|
||||
|
||||
// Use the blockmap to narrow down our placing patterns
|
||||
|
|
@ -10603,58 +10633,63 @@ void P_SpawnPrecipitation(void)
|
|||
basex = bmaporgx + (i % bmapwidth) * MAPBLOCKSIZE;
|
||||
basey = bmaporgy + (i / bmapwidth) * MAPBLOCKSIZE;
|
||||
|
||||
x = basex + ((M_RandomKey(MAPBLOCKUNITS << 3) << FRACBITS) >> 3);
|
||||
y = basey + ((M_RandomKey(MAPBLOCKUNITS << 3) << FRACBITS) >> 3);
|
||||
|
||||
precipsector = R_PointInSubsectorOrNull(x, y);
|
||||
|
||||
// No sector? Stop wasting time,
|
||||
// move on to the next entry in the blockmap
|
||||
if (!precipsector)
|
||||
continue;
|
||||
|
||||
// Not in a sector with visible sky?
|
||||
condition = (precipsector->sector->ceilingpic == skyflatnum);
|
||||
|
||||
if (precipsector->sector->flags & SF_INVERTPRECIP)
|
||||
{
|
||||
UINT16 numparticles = 0;
|
||||
condition = !condition;
|
||||
}
|
||||
|
||||
x = basex + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3);
|
||||
y = basey + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3);
|
||||
if (!condition)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
precipsector = R_PointInSubsectorOrNull(x, y);
|
||||
height = precipsector->sector->ceilingheight - precipsector->sector->floorheight;
|
||||
|
||||
// No sector? Stop wasting time,
|
||||
// move on to the next entry in the blockmap
|
||||
if (!precipsector)
|
||||
continue;
|
||||
// Exists, but is too small for reasonable precipitation.
|
||||
if (height < 64<<FRACBITS)
|
||||
continue;
|
||||
|
||||
// Not in a sector with visible sky?
|
||||
if (precipsector->sector->ceilingpic != skyflatnum)
|
||||
continue;
|
||||
// Hack around a quirk of this entire system, where taller sectors look like they get less precipitation.
|
||||
numparticles = 1 + (height / (MAPBLOCKUNITS<<4<<FRACBITS));
|
||||
|
||||
height = precipsector->sector->ceilingheight - precipsector->sector->floorheight;
|
||||
// Don't set z properly yet...
|
||||
z = (flip) ? (precipsector->sector->floorheight) : (precipsector->sector->ceilingheight);
|
||||
|
||||
// Exists, but is too small for reasonable precipitation.
|
||||
if (height < 64<<FRACBITS)
|
||||
continue;
|
||||
for (j = 0; j < numparticles; j++)
|
||||
{
|
||||
rainmo = P_SpawnPrecipMobj(x, y, z, type);
|
||||
|
||||
// Hack around a quirk of this entire system, where taller sectors look like they get less precipitation.
|
||||
numparticles = 1 + (height / (MAPBLOCKUNITS<<4<<FRACBITS));
|
||||
|
||||
// Don't set z properly yet...
|
||||
z = precipsector->sector->ceilingheight;
|
||||
|
||||
for (j = 0; j < numparticles; j++)
|
||||
if (randomstates > 0)
|
||||
{
|
||||
rainmo = P_SpawnPrecipMobj(x, y, z, type);
|
||||
UINT8 mrand = M_RandomByte();
|
||||
UINT8 threshold = UINT8_MAX / (randomstates + 1);
|
||||
statenum_t st = mobjinfo[type].spawnstate;
|
||||
|
||||
if (randomstates > 0)
|
||||
for (k = 0; k < randomstates; k++)
|
||||
{
|
||||
UINT8 mrand = M_RandomByte();
|
||||
UINT8 threshold = UINT8_MAX / (randomstates + 1);
|
||||
statenum_t st = mobjinfo[type].spawnstate;
|
||||
|
||||
for (k = 0; k < randomstates; k++)
|
||||
if (mrand < (threshold * (k+1)))
|
||||
{
|
||||
if (mrand < (threshold * (k+1)))
|
||||
{
|
||||
P_SetPrecipMobjState(rainmo, st+k+1);
|
||||
break;
|
||||
}
|
||||
P_SetPrecipMobjState(rainmo, st+k+1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Randomly assign a height, now that floorz is set.
|
||||
rainmo->z = M_RandomRange(rainmo->floorz>>FRACBITS, rainmo->ceilingz>>FRACBITS)<<FRACBITS;
|
||||
}
|
||||
|
||||
// Randomly assign a height, now that floorz is set.
|
||||
rainmo->z = M_RandomRange(rainmo->floorz >> FRACBITS, rainmo->ceilingz >> FRACBITS) << FRACBITS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
11
src/p_mobj.h
11
src/p_mobj.h
|
|
@ -262,12 +262,11 @@ typedef enum
|
|||
// PRECIPITATION flags ?! ?! ?!
|
||||
//
|
||||
typedef enum {
|
||||
PCF_INVISIBLE = 1, // Don't draw.
|
||||
PCF_PIT = 1<<1, // Above pit.
|
||||
PCF_FOF = 1<<2, // Above FOF.
|
||||
PCF_MOVINGFOF = 1<<3, // Above MOVING FOF (this means we need to keep floorz up to date...)
|
||||
PCF_SPLASH = 1<<4, // Splashed on the ground, return to the ceiling after the animation's over
|
||||
PCF_THUNK = 1<<5, // Ran the thinker this tic.
|
||||
PCF_THUNK = 1, // Ran the thinker this tic.
|
||||
PCF_SPLASH = 1<<1, // Splashed on the ground, return to the ceiling after the animation's over
|
||||
PCF_INVISIBLE = 1<<2, // Don't draw.
|
||||
PCF_PIT = 1<<3, // Above pit.
|
||||
PCF_FLIP = 1<<4, // Spawning from floor, moving upwards.
|
||||
} precipflag_t;
|
||||
|
||||
// Map Object definition.
|
||||
|
|
|
|||
|
|
@ -1851,8 +1851,13 @@ void P_SwitchWeather(preciptype_t newWeather)
|
|||
precipmobj->sprite = precipmobj->state->sprite;
|
||||
precipmobj->frame = precipmobj->state->frame;
|
||||
|
||||
precipmobj->momz = mobjinfo[swap].speed;
|
||||
precipmobj->precipflags &= ~PCF_INVISIBLE;
|
||||
precipmobj->momz = -mobjinfo[swap].speed;
|
||||
precipmobj->precipflags &= ~(PCF_INVISIBLE|PCF_FLIP);
|
||||
|
||||
if (precipmobj->momz > 0)
|
||||
{
|
||||
precipmobj->precipflags |= PCF_FLIP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue