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);
|
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_RecalcPrecipInSector(sector_t *sector);
|
||||||
void P_PrecipitationEffects(void);
|
void P_PrecipitationEffects(void);
|
||||||
|
|
||||||
|
|
|
||||||
155
src/p_mobj.c
155
src/p_mobj.c
|
|
@ -3760,19 +3760,22 @@ animonly:
|
||||||
P_CyclePlayerMobjState(mobj);
|
P_CyclePlayerMobjState(mobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CalculatePrecipFloor(precipmobj_t *mobj)
|
void P_CalculatePrecipFloor(precipmobj_t *mobj)
|
||||||
{
|
{
|
||||||
// recalculate floorz each time
|
// recalculate floorz each time
|
||||||
const sector_t *mobjsecsubsec;
|
const sector_t *mobjsecsubsec;
|
||||||
|
|
||||||
if (mobj && mobj->subsector && mobj->subsector->sector)
|
if (mobj && mobj->subsector && mobj->subsector->sector)
|
||||||
mobjsecsubsec = mobj->subsector->sector;
|
mobjsecsubsec = mobj->subsector->sector;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mobj->floorz = P_GetSectorFloorZAt(mobjsecsubsec, mobj->x, mobj->y);
|
mobj->floorz = P_GetSectorFloorZAt(mobjsecsubsec, mobj->x, mobj->y);
|
||||||
|
|
||||||
if (mobjsecsubsec->ffloors)
|
if (mobjsecsubsec->ffloors)
|
||||||
{
|
{
|
||||||
ffloor_t *rover;
|
ffloor_t *rover;
|
||||||
fixed_t topheight;
|
fixed_t height;
|
||||||
|
|
||||||
for (rover = mobjsecsubsec->ffloors; rover; rover = rover->next)
|
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))
|
if (!(rover->flags & FF_BLOCKOTHERS) && !(rover->flags & FF_SWIMMABLE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
topheight = P_GetFFloorTopZAt(rover, mobj->x, mobj->y);
|
height = P_GetFFloorTopZAt(rover, mobj->x, mobj->y);
|
||||||
if (topheight > mobj->floorz)
|
if (height > mobj->floorz)
|
||||||
mobj->floorz = topheight;
|
mobj->floorz = height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3800,7 +3803,7 @@ void P_RecalcPrecipInSector(sector_t *sector)
|
||||||
sector->moved = true; // Recalc lighting and things too, maybe
|
sector->moved = true; // Recalc lighting and things too, maybe
|
||||||
|
|
||||||
for (psecnode = sector->touching_preciplist; psecnode; psecnode = psecnode->m_thinglist_next)
|
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)
|
void P_PrecipThinker(precipmobj_t *mobj)
|
||||||
{
|
{
|
||||||
|
boolean flip = (mobj->precipflags & PCF_FLIP);
|
||||||
|
|
||||||
P_CycleStateAnimation((mobj_t *)mobj);
|
P_CycleStateAnimation((mobj_t *)mobj);
|
||||||
|
|
||||||
if (mobj->state == &states[S_RAINRETURN])
|
if (mobj->state == &states[S_RAINRETURN])
|
||||||
{
|
{
|
||||||
// Reset to ceiling!
|
// Reset to ceiling!
|
||||||
P_SetPrecipMobjState(mobj, mobj->info->spawnstate);
|
P_SetPrecipMobjState(mobj, mobj->info->spawnstate);
|
||||||
mobj->z = mobj->ceilingz;
|
mobj->z = (flip) ? (mobj->floorz) : (mobj->ceilingz);
|
||||||
mobj->momz = -mobj->info->speed;
|
mobj->momz = -mobj->info->speed;
|
||||||
mobj->precipflags &= ~PCF_SPLASH;
|
mobj->precipflags &= ~PCF_SPLASH;
|
||||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||||
|
|
@ -3858,18 +3863,20 @@ void P_PrecipThinker(precipmobj_t *mobj)
|
||||||
if (mobj->precipflags & PCF_SPLASH)
|
if (mobj->precipflags & PCF_SPLASH)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mobj->z += mobj->momz;
|
||||||
|
|
||||||
// adjust height
|
// 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
|
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);
|
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
P_SetPrecipMobjState(mobj, mobj->info->deathstate);
|
P_SetPrecipMobjState(mobj, mobj->info->deathstate);
|
||||||
mobj->z = mobj->floorz;
|
mobj->z = (flip) ? (mobj->ceilingz) : (mobj->floorz);
|
||||||
mobj->precipflags |= PCF_SPLASH;
|
mobj->precipflags |= PCF_SPLASH;
|
||||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
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];
|
const mobjinfo_t *info = &mobjinfo[type];
|
||||||
state_t *st;
|
state_t *st;
|
||||||
|
fixed_t start_z = INT32_MIN;
|
||||||
precipmobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
|
precipmobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
|
||||||
fixed_t starting_floorz;
|
|
||||||
|
|
||||||
mobj->type = type;
|
mobj->type = type;
|
||||||
mobj->info = info;
|
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
|
// set subsector and/or block links
|
||||||
P_SetPrecipitationThingPosition(mobj);
|
P_SetPrecipitationThingPosition(mobj);
|
||||||
|
|
||||||
mobj->floorz = starting_floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y);
|
mobj->floorz = P_GetSectorFloorZAt (mobj->subsector->sector, x, y);
|
||||||
mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y);
|
mobj->ceilingz = P_GetSectorCeilingZAt(mobj->subsector->sector, x, y);
|
||||||
|
|
||||||
mobj->floorrover = NULL;
|
mobj->floorrover = NULL;
|
||||||
mobj->ceilingrover = 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->z = z;
|
||||||
mobj->momz = -info->speed;
|
mobj->momz = -info->speed;
|
||||||
|
|
||||||
|
if (info->speed < 0)
|
||||||
|
{
|
||||||
|
mobj->precipflags |= PCF_FLIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_z = mobj->floorz;
|
||||||
|
|
||||||
mobj->thinker.function.acp1 = (actionf_p1)P_NullPrecipThinker;
|
mobj->thinker.function.acp1 = (actionf_p1)P_NullPrecipThinker;
|
||||||
P_AddThinker(THINK_PRECIP, &mobj->thinker);
|
P_AddThinker(THINK_PRECIP, &mobj->thinker);
|
||||||
|
|
||||||
CalculatePrecipFloor(mobj);
|
P_CalculatePrecipFloor(mobj);
|
||||||
|
|
||||||
if (mobj->floorz != starting_floorz)
|
if (mobj->floorz != start_z)
|
||||||
mobj->precipflags |= PCF_FOF;
|
{
|
||||||
else if (GETSECSPECIAL(mobj->subsector->sector->special, 1) == 7
|
; //mobj->precipflags |= PCF_FOF;
|
||||||
|| GETSECSPECIAL(mobj->subsector->sector->special, 1) == 6
|
}
|
||||||
|| mobj->subsector->sector->floorpic == skyflatnum)
|
else
|
||||||
mobj->precipflags |= PCF_PIT;
|
{
|
||||||
|
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);
|
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||||
|
|
||||||
|
|
@ -10588,13 +10612,19 @@ consvar_t cv_itemrespawn = CVAR_INIT ("respawnitem", "On", CV_NETVAR, CV_OnOff,
|
||||||
void P_SpawnPrecipitation(void)
|
void P_SpawnPrecipitation(void)
|
||||||
{
|
{
|
||||||
INT32 i, j, k;
|
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;
|
fixed_t basex, basey, x, y, z, height;
|
||||||
|
UINT16 numparticles = 0;
|
||||||
|
boolean condition = false;
|
||||||
|
|
||||||
subsector_t *precipsector = NULL;
|
subsector_t *precipsector = NULL;
|
||||||
precipmobj_t *rainmo = 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;
|
return;
|
||||||
|
|
||||||
// Use the blockmap to narrow down our placing patterns
|
// Use the blockmap to narrow down our placing patterns
|
||||||
|
|
@ -10603,58 +10633,63 @@ void P_SpawnPrecipitation(void)
|
||||||
basex = bmaporgx + (i % bmapwidth) * MAPBLOCKSIZE;
|
basex = bmaporgx + (i % bmapwidth) * MAPBLOCKSIZE;
|
||||||
basey = bmaporgy + (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);
|
if (!condition)
|
||||||
y = basey + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3);
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
precipsector = R_PointInSubsectorOrNull(x, y);
|
height = precipsector->sector->ceilingheight - precipsector->sector->floorheight;
|
||||||
|
|
||||||
// No sector? Stop wasting time,
|
// Exists, but is too small for reasonable precipitation.
|
||||||
// move on to the next entry in the blockmap
|
if (height < 64<<FRACBITS)
|
||||||
if (!precipsector)
|
continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
// Not in a sector with visible sky?
|
// Hack around a quirk of this entire system, where taller sectors look like they get less precipitation.
|
||||||
if (precipsector->sector->ceilingpic != skyflatnum)
|
numparticles = 1 + (height / (MAPBLOCKUNITS<<4<<FRACBITS));
|
||||||
continue;
|
|
||||||
|
|
||||||
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.
|
for (j = 0; j < numparticles; j++)
|
||||||
if (height < 64<<FRACBITS)
|
{
|
||||||
continue;
|
rainmo = P_SpawnPrecipMobj(x, y, z, type);
|
||||||
|
|
||||||
// Hack around a quirk of this entire system, where taller sectors look like they get less precipitation.
|
if (randomstates > 0)
|
||||||
numparticles = 1 + (height / (MAPBLOCKUNITS<<4<<FRACBITS));
|
|
||||||
|
|
||||||
// Don't set z properly yet...
|
|
||||||
z = precipsector->sector->ceilingheight;
|
|
||||||
|
|
||||||
for (j = 0; j < numparticles; j++)
|
|
||||||
{
|
{
|
||||||
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();
|
if (mrand < (threshold * (k+1)))
|
||||||
UINT8 threshold = UINT8_MAX / (randomstates + 1);
|
|
||||||
statenum_t st = mobjinfo[type].spawnstate;
|
|
||||||
|
|
||||||
for (k = 0; k < randomstates; k++)
|
|
||||||
{
|
{
|
||||||
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 ?! ?! ?!
|
// PRECIPITATION flags ?! ?! ?!
|
||||||
//
|
//
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PCF_INVISIBLE = 1, // Don't draw.
|
PCF_THUNK = 1, // Ran the thinker this tic.
|
||||||
PCF_PIT = 1<<1, // Above pit.
|
PCF_SPLASH = 1<<1, // Splashed on the ground, return to the ceiling after the animation's over
|
||||||
PCF_FOF = 1<<2, // Above FOF.
|
PCF_INVISIBLE = 1<<2, // Don't draw.
|
||||||
PCF_MOVINGFOF = 1<<3, // Above MOVING FOF (this means we need to keep floorz up to date...)
|
PCF_PIT = 1<<3, // Above pit.
|
||||||
PCF_SPLASH = 1<<4, // Splashed on the ground, return to the ceiling after the animation's over
|
PCF_FLIP = 1<<4, // Spawning from floor, moving upwards.
|
||||||
PCF_THUNK = 1<<5, // Ran the thinker this tic.
|
|
||||||
} precipflag_t;
|
} precipflag_t;
|
||||||
|
|
||||||
// Map Object definition.
|
// Map Object definition.
|
||||||
|
|
|
||||||
|
|
@ -1851,8 +1851,13 @@ void P_SwitchWeather(preciptype_t newWeather)
|
||||||
precipmobj->sprite = precipmobj->state->sprite;
|
precipmobj->sprite = precipmobj->state->sprite;
|
||||||
precipmobj->frame = precipmobj->state->frame;
|
precipmobj->frame = precipmobj->state->frame;
|
||||||
|
|
||||||
precipmobj->momz = mobjinfo[swap].speed;
|
precipmobj->momz = -mobjinfo[swap].speed;
|
||||||
precipmobj->precipflags &= ~PCF_INVISIBLE;
|
precipmobj->precipflags &= ~(PCF_INVISIBLE|PCF_FLIP);
|
||||||
|
|
||||||
|
if (precipmobj->momz > 0)
|
||||||
|
{
|
||||||
|
precipmobj->precipflags |= PCF_FLIP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue