From 7a1b3096532f61f9aed2ad5215ae40c760a792d1 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 29 May 2016 20:47:08 +0100 Subject: [PATCH 01/42] Making Linedef type 7 less awful. More details (and test file) in merge request. --- src/p_spec.c | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 3ca697295..270f3dfa9 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5561,46 +5561,42 @@ void P_SpawnSpecials(INT32 fromnetsave) #endif case 7: // Flat alignment - if (lines[i].flags & ML_EFFECT4) // Align angle + if ((lines[i].flags & (ML_EFFECT1|ML_NOCLIMB)) != (ML_EFFECT1|ML_NOCLIMB)) // If you can do something... { - if (!(lines[i].flags & ML_EFFECT5)) // Align floor unless ALLTRIGGER flag is set - { - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) - sectors[s].spawn_flrpic_angle = sectors[s].floorpic_angle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y); - } + line_t line = lines[i]; + angle_t flatangle = 0; + if (!(line.flags & ML_EFFECT2)) // Change flat angles unless EFFECT2 flag is set + flatangle = R_PointToAngle2(line.v1->x, line.v1->y, line.v2->x, line.v2->y); - if (!(lines[i].flags & ML_BOUNCY)) // Align ceiling unless BOUNCY flag is set + for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) { - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) - sectors[s].spawn_ceilpic_angle = sectors[s].ceilingpic_angle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y); - } - } - else // Do offsets - { - if (!(lines[i].flags & ML_BLOCKMONSTERS)) // Align floor unless BLOCKMONSTERS flag is set - { - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + if (!(line.flags & ML_EFFECT1)) // Change floor flat unless EFFECT1 flag is set { - sectors[s].floor_xoffs += lines[i].dx; - sectors[s].floor_yoffs += lines[i].dy; + sectors[s].spawn_flrpic_angle = sectors[s].floorpic_angle = flatangle; + sectors[s].floor_xoffs += sides[line.sidenum[0]].textureoffset; + sectors[s].floor_yoffs += sides[line.sidenum[0]].rowoffset; // saved for netgames sectors[s].spawn_flr_xoffs = sectors[s].floor_xoffs; sectors[s].spawn_flr_yoffs = sectors[s].floor_yoffs; } - } - - if (!(lines[i].flags & ML_NOCLIMB)) // Align ceiling unless NOCLIMB flag is set - { - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + + if (!(line.flags & ML_NOCLIMB)) // Change ceiling flat unless NOCLIMB flag is set { - sectors[s].ceiling_xoffs += lines[i].dx; - sectors[s].ceiling_yoffs += lines[i].dy; + sectors[s].spawn_ceilpic_angle = sectors[s].ceilingpic_angle = flatangle; + sectors[s].ceiling_xoffs += sides[line.sidenum[0]].textureoffset; + sectors[s].ceiling_yoffs += sides[line.sidenum[0]].rowoffset; // saved for netgames sectors[s].spawn_ceil_xoffs = sectors[s].ceiling_xoffs; sectors[s].spawn_ceil_yoffs = sectors[s].ceiling_yoffs; } } } + else // Otherwise, print a helpful warning. Can I do no less? + { + CONS_Alert(CONS_WARNING, + M_GetText("Flat alignment linedef with tag %d doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"), + lines[i].tag); + } break; case 8: // Sector Parameters From a8248fb6c9855b79e0dda1918df86614144ad92e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 30 May 2016 22:44:23 +0100 Subject: [PATCH 02/42] Added new functionality, reorganised functionality from last commit, cursed a lot. Again, more info in merge request. --- src/p_spec.c | 80 +++++++++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 270f3dfa9..4f027f8d6 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -51,6 +51,9 @@ mobj_t *skyboxmo[2]; // Amount (dx, dy) vector linedef is shifted right to get scroll amount #define SCROLL_SHIFT 5 +// This must be updated whenever we up the max flat size - quicker to assume rather than figuring out the sqrt of the specific flat's filesize. +#define MAXFLATSIZE (2048<x, line.v1->y, line.v2->x, line.v2->y); - + angle_t flatangle = InvAngle(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y)); + fixed_t xoffs; + fixed_t yoffs; + + if (lines[i].flags & ML_NOKNUX) // Set offset through x and y texture offsets if NOKNUX flag is set + { + xoffs = sides[lines[i].sidenum[0]].textureoffset; + yoffs = sides[lines[i].sidenum[0]].rowoffset; + } + else // Otherwise, set calculated offsets such that line's v1 is the apparent origin + { + fixed_t cosinecomponent = FINECOSINE(flatangle>>ANGLETOFINESHIFT); + fixed_t sinecomponent = FINESINE(flatangle>>ANGLETOFINESHIFT); + xoffs = (-FixedMul(lines[i].v1->x, cosinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, sinecomponent) % MAXFLATSIZE); // No danger of overflow thanks to the strategically placed modulo operations. + yoffs = (FixedMul(lines[i].v1->x, sinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, cosinecomponent) % MAXFLATSIZE); // Ditto. + } + for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) { - if (!(line.flags & ML_EFFECT1)) // Change floor flat unless EFFECT1 flag is set + if (!(lines[i].flags & ML_NOSONIC)) // Modify floor flat alignment unless NOSONIC flag is set { sectors[s].spawn_flrpic_angle = sectors[s].floorpic_angle = flatangle; - sectors[s].floor_xoffs += sides[line.sidenum[0]].textureoffset; - sectors[s].floor_yoffs += sides[line.sidenum[0]].rowoffset; + sectors[s].floor_xoffs += xoffs; + sectors[s].floor_yoffs += yoffs; // saved for netgames sectors[s].spawn_flr_xoffs = sectors[s].floor_xoffs; sectors[s].spawn_flr_yoffs = sectors[s].floor_yoffs; } - if (!(line.flags & ML_NOCLIMB)) // Change ceiling flat unless NOCLIMB flag is set + if (!(lines[i].flags & ML_NOTAILS)) // Modify ceiling flat alignment unless NOTAILS flag is set { sectors[s].spawn_ceilpic_angle = sectors[s].ceilingpic_angle = flatangle; - sectors[s].ceiling_xoffs += sides[line.sidenum[0]].textureoffset; - sectors[s].ceiling_yoffs += sides[line.sidenum[0]].rowoffset; + sectors[s].ceiling_xoffs += xoffs; + sectors[s].ceiling_yoffs += yoffs; // saved for netgames sectors[s].spawn_ceil_xoffs = sectors[s].ceiling_xoffs; sectors[s].spawn_ceil_yoffs = sectors[s].ceiling_yoffs; @@ -5592,11 +5602,9 @@ void P_SpawnSpecials(INT32 fromnetsave) } } else // Otherwise, print a helpful warning. Can I do no less? - { CONS_Alert(CONS_WARNING, - M_GetText("Flat alignment linedef with tag %d doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"), + M_GetText("Flat alignment linedef (tag %d) doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"), lines[i].tag); - } break; case 8: // Sector Parameters From 577f9e8801dd820f2f0af586fefc65a5b3bce22f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 2 Jun 2016 22:46:27 +0100 Subject: [PATCH 03/42] Going beyond the scope of the branch: *Friction linedef effect is now - 1) controlled by x offset instead of length - offset of -100 is maximum iciness, offset of +483(!!!) is the maximum sludginess BUT things are scaled such that +100 is about the maximum sludginess any reasonable human being would want in a level, 0 is ORIG_FRICTION) 2) not reliant on a sector special to function (can be applied solely by tag to in-map sectors or solid FOF control sectors) --- src/p_spec.c | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 4f027f8d6..4812b39c3 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3650,9 +3650,9 @@ DoneSection2: // Process Section 3 switch (special) { - case 1: // Ice/Sludge + case 1: // N/A (formerly Ice/Sludge) case 2: // Wind/Current - case 3: // Ice/Sludge and Wind/Current + case 3: // N/A (formerly Ice/Sludge and Wind/Current) case 4: // Conveyor Belt break; @@ -6949,22 +6949,10 @@ void T_Friction(friction_t *f) sec = sectors + f->affectee; - // Make sure the sector type hasn't changed + // Get FOF control sector if (f->roverfriction) - { referrer = sectors + f->referrer; - if (!(GETSECSPECIAL(referrer->special, 3) == 1 - || GETSECSPECIAL(referrer->special, 3) == 3)) - return; - } - else - { - if (!(GETSECSPECIAL(sec->special, 3) == 1 - || GETSECSPECIAL(sec->special, 3) == 3)) - return; - } - // Assign the friction value to players on the floor, non-floating, // and clipped. Normally the object's friction value is kept at // ORIG_FRICTION and this thinker changes it for icy or muddy floors. @@ -7017,15 +7005,18 @@ static void P_SpawnFriction(void) size_t i; line_t *l = lines; register INT32 s; - fixed_t length; // line length controls magnitude + fixed_t strength; // frontside texture offset controls magnitude fixed_t friction; // friction value to be applied during movement INT32 movefactor; // applied to each player move to simulate inertia for (i = 0; i < numlines; i++, l++) if (l->special == 540) { - length = P_AproxDistance(l->dx, l->dy)>>FRACBITS; - friction = (0x1EB8*length)/0x80 + 0xD000; + strength = sides[l->sidenum[0]].textureoffset>>FRACBITS; + if (strength > 0) // sludge + strength = strength*2; // otherwise, the maximum sludginess value is +967... + + friction = ORIG_FRICTION - (0x1EB8*strength)/0x80; // ORIG_FRICTION is 0xE800 if (friction > FRACUNIT) friction = FRACUNIT; @@ -7036,9 +7027,9 @@ static void P_SpawnFriction(void) // the move distance is multiplied by 'friction/0x10000', so a // higher friction value actually means 'less friction'. - if (friction > ORIG_FRICTION) // ice + if (friction < ORIG_FRICTION) // ice movefactor = ((0x10092 - friction)*(0x70))/0x158; - else + else // sludge movefactor = ((friction - 0xDB34)*(0xA))/0x80; // killough 8/28/98: prevent odd situations @@ -7293,12 +7284,10 @@ void T_Pusher(pusher_t *p) { referrer = §ors[p->referrer]; - if (!(GETSECSPECIAL(referrer->special, 3) == 2 - || GETSECSPECIAL(referrer->special, 3) == 3)) + if (GETSECSPECIAL(referrer->special, 3) != 2) return; } - else if (!(GETSECSPECIAL(sec->special, 3) == 2 - || GETSECSPECIAL(sec->special, 3) == 3)) + else if (GETSECSPECIAL(sec->special, 3) != 2) return; // For constant pushers (wind/current) there are 3 situations: From fc0d6e5195ef60d95a7595c4d8a4249ed96f51ef Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 2 Jun 2016 23:30:50 +0100 Subject: [PATCH 04/42] Movefactor removed from Friction thinker. Smaller memory footprint, less processing, and no more potential corrupting of what some objects use as a memory dumping ground. --- src/p_spec.c | 33 +++++++-------------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 4812b39c3..e75ef3597 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -109,7 +109,7 @@ static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline); //static void P_AddBridgeThinker(line_t *sourceline, sector_t *sec); static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinkerlist_t *secthinkers); static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec); -static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer); +static void Add_Friction(INT32 friction, INT32 affectee, INT32 referrer); static void P_AddSpikeThinker(sector_t *sec, INT32 referrer); @@ -4879,7 +4879,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f f = (friction_t *)th; if (f->affectee == (INT32)sec2num) - Add_Friction(f->friction, f->movefactor, (INT32)(sec-sectors), f->affectee); + Add_Friction(f->friction, (INT32)(sec-sectors), f->affectee); } // Should this FOF have wind/current/pusher? else if(th->function.acp1 == (actionf_p1)T_Pusher) @@ -6911,18 +6911,16 @@ void T_Disappear(disappear_t *d) /** Adds friction thinker. * * \param friction Friction value, 0xe800 is normal. - * \param movefactor Inertia factor. * \param affectee Target sector. * \param roverfriction FOF or not * \sa T_Friction, P_SpawnFriction */ -static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer) +static void Add_Friction(INT32 friction, INT32 affectee, INT32 referrer) { friction_t *f = Z_Calloc(sizeof *f, PU_LEVSPEC, NULL); f->thinker.function.acp1 = (actionf_p1)T_Friction; f->friction = friction; - f->movefactor = movefactor; f->affectee = affectee; if (referrer != -1) @@ -6980,17 +6978,11 @@ void T_Friction(friction_t *f) if ((thing->friction == ORIG_FRICTION) // normal friction? || (f->friction < thing->friction)) - { thing->friction = f->friction; - thing->movefactor = f->movefactor; - } } else if (P_GetSpecialBottomZ(thing, sec, sec) == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction? || f->friction < thing->friction)) - { thing->friction = f->friction; - thing->movefactor = f->movefactor; - } } node = node->m_snext; } @@ -7007,7 +6999,6 @@ static void P_SpawnFriction(void) register INT32 s; fixed_t strength; // frontside texture offset controls magnitude fixed_t friction; // friction value to be applied during movement - INT32 movefactor; // applied to each player move to simulate inertia for (i = 0; i < numlines; i++, l++) if (l->special == 540) @@ -7016,6 +7007,9 @@ static void P_SpawnFriction(void) if (strength > 0) // sludge strength = strength*2; // otherwise, the maximum sludginess value is +967... + // The following might seem odd. At the time of movement, + // the move distance is multiplied by 'friction/0x10000', so a + // higher friction value actually means 'less friction'. friction = ORIG_FRICTION - (0x1EB8*strength)/0x80; // ORIG_FRICTION is 0xE800 if (friction > FRACUNIT) @@ -7023,21 +7017,8 @@ static void P_SpawnFriction(void) if (friction < 0) friction = 0; - // The following check might seem odd. At the time of movement, - // the move distance is multiplied by 'friction/0x10000', so a - // higher friction value actually means 'less friction'. - - if (friction < ORIG_FRICTION) // ice - movefactor = ((0x10092 - friction)*(0x70))/0x158; - else // sludge - movefactor = ((friction - 0xDB34)*(0xA))/0x80; - - // killough 8/28/98: prevent odd situations - if (movefactor < 32) - movefactor = 32; - for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) - Add_Friction(friction, movefactor, s, -1); + Add_Friction(friction, s, -1); } } From 55bb716c1e7886d84c19552a628aeb9105699198 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 3 Jun 2016 01:30:07 +0100 Subject: [PATCH 05/42] On FuriousFox's request: All waypoint sequences now use linedef frontside texture offset for speed and row offset for sequence, ending what is a very long reign of clusterfuck. --- src/p_spec.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index e75ef3597..6d874186f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3890,8 +3890,14 @@ DoneSection2: } // Grab speed and sequence values - speed = abs(lines[lineindex].dx)/8; - sequence = abs(lines[lineindex].dy)>>FRACBITS; + speed = abs(sides[lines[lineindex].sidenum[0]].textureoffset)/8; + sequence = abs(sides[lines[lineindex].sidenum[0]].rowoffset)>>FRACBITS; + + if (speed == 0) + { + CONS_Debug(DBG_GAMELOGIC, "ERROR: Waypoint sequence %d at zero speed.\n", sequence); + break; + } // scan the thinkers // to find the first waypoint @@ -3963,8 +3969,14 @@ DoneSection2: } // Grab speed and sequence values - speed = -(abs(lines[lineindex].dx)/8); // Negative means reverse - sequence = abs(lines[lineindex].dy)>>FRACBITS; + speed = -abs(sides[lines[lineindex].sidenum[0]].textureoffset)/8; // Negative means reverse + sequence = abs(sides[lines[lineindex].sidenum[0]].rowoffset)>>FRACBITS; + + if (speed == 0) + { + CONS_Debug(DBG_GAMELOGIC, "ERROR: Waypoint sequence %d at zero speed.\n", sequence); + break; + } // scan the thinkers // to find the last waypoint @@ -4101,8 +4113,14 @@ DoneSection2: } // Grab speed and sequence values - speed = abs(lines[lineindex].dx)/8; - sequence = abs(lines[lineindex].dy)>>FRACBITS; + speed = abs(sides[lines[lineindex].sidenum[0]].textureoffset)/8; + sequence = abs(sides[lines[lineindex].sidenum[0]].rowoffset)>>FRACBITS; + + if (speed == 0) + { + CONS_Debug(DBG_GAMELOGIC, "ERROR: Waypoint sequence %d at zero speed.\n", sequence); + break; + } // Find the closest waypoint // Find the preceding waypoint From 27f825f41b93cfada1378e23bea9b54cf8af0fc6 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 3 Jun 2016 02:23:27 +0100 Subject: [PATCH 06/42] Dedicated laser blocks flash less awfully now. --- src/p_spec.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 6d874186f..d82f2b2a4 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5271,7 +5271,7 @@ static inline void P_AddCameraScanner(sector_t *sourcesec, sector_t *actionsecto elevator->distance = FixedInt(AngleFixed(angle)); } -static const ffloortype_e laserflags = FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA; +static const ffloortype_e laserflags = FF_EXISTS|FF_RENDERALL|FF_NOSHADE|FF_EXTRA|FF_CUTEXTRA|FF_TRANSLUCENT; /** Flashes a laser block. * @@ -5292,9 +5292,11 @@ void T_LaserFlash(laserthink_t *flash) return; if (leveltime & 1) - ffloor->flags |= FF_RENDERALL; + //ffloor->flags |= FF_RENDERALL; + ffloor->alpha = 0xC0; else - ffloor->flags &= ~FF_RENDERALL; + //ffloor->flags &= ~FF_RENDERALL; + ffloor->alpha = 0x60; sourcesec = ffloor->master->frontsector; // Less to type! From 083350cab202f254ed47c08e0707d593d7bf22f1 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Thu, 2 Jun 2016 21:24:45 -0400 Subject: [PATCH 07/42] whitespace cleanup --- src/p_spec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index d82f2b2a4..ddad3cde3 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5584,7 +5584,7 @@ void P_SpawnSpecials(INT32 fromnetsave) angle_t flatangle = InvAngle(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y)); fixed_t xoffs; fixed_t yoffs; - + if (lines[i].flags & ML_NOKNUX) // Set offset through x and y texture offsets if NOKNUX flag is set { xoffs = sides[lines[i].sidenum[0]].textureoffset; @@ -5597,7 +5597,7 @@ void P_SpawnSpecials(INT32 fromnetsave) xoffs = (-FixedMul(lines[i].v1->x, cosinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, sinecomponent) % MAXFLATSIZE); // No danger of overflow thanks to the strategically placed modulo operations. yoffs = (FixedMul(lines[i].v1->x, sinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, cosinecomponent) % MAXFLATSIZE); // Ditto. } - + for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) { if (!(lines[i].flags & ML_NOSONIC)) // Modify floor flat alignment unless NOSONIC flag is set @@ -5609,7 +5609,7 @@ void P_SpawnSpecials(INT32 fromnetsave) sectors[s].spawn_flr_xoffs = sectors[s].floor_xoffs; sectors[s].spawn_flr_yoffs = sectors[s].floor_yoffs; } - + if (!(lines[i].flags & ML_NOTAILS)) // Modify ceiling flat alignment unless NOTAILS flag is set { sectors[s].spawn_ceilpic_angle = sectors[s].ceilingpic_angle = flatangle; From 5a0432816b47dc43cd37aa16a8aceb119ed30dbf Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 3 Jun 2016 15:44:21 +0100 Subject: [PATCH 08/42] Forgot to make this change; now the friction thinker is DEFINITELY using less memory. --- src/p_spec.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_spec.h b/src/p_spec.h index a8f9ac492..b90764f61 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -386,7 +386,6 @@ typedef struct { thinker_t thinker; ///< Thinker structure for friction. INT32 friction; ///< Friction value, 0xe800 = normal. - INT32 movefactor; ///< Inertia factor when adding to momentum. INT32 affectee; ///< Number of affected sector. INT32 referrer; ///< If roverfriction == true, then this will contain the sector # of the control sector where the effect was applied. UINT8 roverfriction; ///< flag for whether friction originated from a FOF or not From 1e6b213d6c3d2a7f83c0381f09f341b008e49647 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 3 Jun 2016 17:26:50 +0100 Subject: [PATCH 09/42] Okay, this is way beyond the scope of the branch... but low-friction surfaces (ice, oil, etc) now: * Actively impede your acceleration * Make your animation speeds faster whenever you're moving (to give off that Looney Tunes effect) The former change is something that was present in the few low-friction circumstances in the classics, and makes low-friction surfaces more of an active challenge. The latter change is just something I did for fun to more clearly communicate that things are different with the physics here. High friction surfaces DO NOT involve any of this, since it ended up basically cheesing their existing gameplay. --- src/p_mobj.c | 7 +++---- src/p_spec.c | 8 ++++++++ src/p_user.c | 15 ++++++++++++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 9e061950f..ec418fb93 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -285,7 +285,8 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) // Adjust the player's animation speed to match their velocity. if (!(disableSpeedAdjust || player->charflags & SF_NOSPEEDADJUST)) { - fixed_t speed = FixedDiv(player->speed, mobj->scale); + fixed_t speed = FixedDiv(player->speed, FixedMul(mobj->scale, player->mo->movefactor)); + if (player->panim == PA_ROLL) { if (speed > 16<friction = FRACUNIT - 0x100; - mo->movefactor = ((0x10092 - mo->friction)*(0x70))/0x158; } else mo->friction = ORIG_FRICTION; @@ -2658,7 +2658,6 @@ static boolean P_ZMovement(mobj_t *mo) // Stolen from P_SpawnFriction mo->friction = FRACUNIT - 0x100; - mo->movefactor = ((0x10092 - mo->friction)*(0x70))/0x158; } else if (mo->type == MT_FALLINGROCK) { @@ -7799,7 +7798,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->friction = ORIG_FRICTION; - mobj->movefactor = ORIG_FRICTION_FACTOR; + mobj->movefactor = ORIG_FRICTION; // All mobjs are created at 100% scale. mobj->scale = FRACUNIT; diff --git a/src/p_spec.c b/src/p_spec.c index ddad3cde3..d2ac5b6a9 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6998,11 +6998,19 @@ void T_Friction(friction_t *f) if ((thing->friction == ORIG_FRICTION) // normal friction? || (f->friction < thing->friction)) + { thing->friction = f->friction; + if (thing->player) + thing->movefactor = f->friction; + } } else if (P_GetSpecialBottomZ(thing, sec, sec) == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction? || f->friction < thing->friction)) + { thing->friction = f->friction; + if (thing->player) + thing->movefactor = f->friction; + } } node = node->m_snext; } diff --git a/src/p_user.c b/src/p_user.c index 02e3308d0..6aebbe642 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4673,6 +4673,9 @@ static void P_3dMovement(player_t *player) acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration; } + // Friction-scaled acceleration... + acceleration = FixedMul(acceleration<mo->movefactor)>>FRACBITS; + // Forward movement if (player->climbing) { @@ -6327,7 +6330,8 @@ static void P_SkidStuff(player_t *player) // If your push angle is more than this close to a full 180 degrees, trigger a skid. if (dang > ANGLE_157h) { - player->skidtime = TICRATE/2; + //player->skidtime = TICRATE/2; + player->skidtime = (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; S_StartSound(player->mo, sfx_skid); if (player->panim != PA_WALK) P_SetPlayerMobjState(player->mo, S_PLAY_WALK); @@ -6364,6 +6368,14 @@ static void P_MovePlayer(player_t *player) cmd = &player->cmd; runspd = FixedMul(player->runspeed, player->mo->scale); + // Let's have some movement speed fun on low-friction surfaces, JUST for players... (high friction surfaces shouldn't have any adjustment, since the acceleration in this game is super high and that ends up cheesing high-friction surfaces.) + player->mo->movefactor = FixedDiv(ORIG_FRICTION, player->mo->movefactor); + if (player->mo->movefactor < FRACUNIT) + player->mo->movefactor = 8*player->mo->movefactor - 7*FRACUNIT; + else + player->mo->movefactor = FRACUNIT; + runspd = FixedMul(runspd, player->mo->movefactor); + // Control relinquishing stuff! if (player->powers[pw_ingoop]) player->pflags |= PF_FULLSTASIS; @@ -6535,6 +6547,7 @@ static void P_MovePlayer(player_t *player) if (!player->mo->momx && !player->mo->momy && !player->mo->momz && player->panim == PA_WALK) P_SetPlayerMobjState(player->mo, S_PLAY_STND); + player->mo->movefactor = ORIG_FRICTION; // We're not going to do any more with this, so let's change it back for the next frame. ////////////////// //GAMEPLAY STUFF// From 52dd1c62c24649d9c68b4b95164cc339d463cf63 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 3 Jun 2016 18:01:24 +0100 Subject: [PATCH 10/42] Duplicated constant removal. --- src/p_mobj.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index ec418fb93..514952975 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1590,7 +1590,6 @@ void P_CheckGravity(mobj_t *mo, boolean affect) } #define STOPSPEED (FRACUNIT) -#define FRICTION (ORIG_FRICTION) // 0.90625 // // P_SceneryXYFriction @@ -1647,7 +1646,7 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy) // spinning friction if (player->pflags & PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH)) { - const fixed_t ns = FixedDiv(549*FRICTION,500*FRACUNIT); + const fixed_t ns = FixedDiv(549*ORIG_FRICTION,500*FRACUNIT); mo->momx = FixedMul(mo->momx, ns); mo->momy = FixedMul(mo->momy, ns); } From 6f291d667e0366285d992e599b7746654f7fbdeb Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 4 Jun 2016 18:59:24 +0100 Subject: [PATCH 11/42] Bustable blocks revamped. I'm on a roll! Linedef type 14 (Bustable block parameter) * Applied to one of the linedefs of any FOF's control sector * Concatenation of frontside textures is MT_ object type to spawn, defaults to MT_ROCKCRUMBLE1 if not present * Sound played when being busted is object type's activesound * Frontside x offset is spacing (in fracunits) of spawned particles, defaults to 32<sourceline; - if (SearchMarioNode(block->sector->touching_thinglist)) - sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture; - else - sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].toptexture; + if (!(masterline->flags & ML_NOCLIMB)) // Don't change the textures of a brick block, just a question block + { + if (SearchMarioNode(block->sector->touching_thinglist)) + sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture; + else + sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].toptexture; + } } // This is the Thwomp's 'brain'. It looks around for players nearby, and if @@ -2878,17 +2881,35 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) fixed_t leftx, rightx; fixed_t topy, bottomy; fixed_t topz; + fixed_t widthfactor, heightfactor; fixed_t a, b, c; mobjtype_t type = MT_ROCKCRUMBLE1; + fixed_t spacing = (32<master->frontsector->special, 3) >= 8) - type = MT_ROCKCRUMBLE1+(GETSECSPECIAL(rover->master->frontsector->special, 3)-7); +#define controlsec rover->master->frontsector + + for (i = 0; i < controlsec->linecount; i++) + { + if (controlsec->lines[i]->special == 14) // If we can use bustable block parameters, we will. + { + if (sides[controlsec->lines[i]->sidenum[0]].toptexture) + type = (mobjtype_t)sides[controlsec->lines[i]->sidenum[0]].toptexture; // Set as object type in p_setup.c... + if (sides[controlsec->lines[i]->sidenum[0]].textureoffset) + spacing = sides[controlsec->lines[i]->sidenum[0]].textureoffset; + if (sides[controlsec->lines[i]->sidenum[0]].rowoffset) + lifetime = (sides[controlsec->lines[i]->sidenum[0]].rowoffset>>FRACBITS); + flags = controlsec->lines[i]->flags; + break; // If someone has multiple parameter linedefs per control sector, TOUGH. + } + } + +#undef controlsec // soundorg z height never gets set normally, so MEH. sec->soundorg.z = sec->floorheight; - S_StartSound(&sec->soundorg, sfx_crumbl); + S_StartSound(&sec->soundorg, mobjinfo[type].activesound); // Find the outermost vertexes in the subsector for (i = 0; i < sec->linecount; i++) @@ -2907,23 +2928,32 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) bottommostvertex = i; } - leftx = sec->lines[leftmostvertex]->v1->x+(16<lines[leftmostvertex]->v1->x+(spacing>>1); rightx = sec->lines[rightmostvertex]->v1->x; - topy = sec->lines[topmostvertex]->v1->y-(16<lines[topmostvertex]->v1->y-(spacing>>1); bottomy = sec->lines[bottommostvertex]->v1->y; - topz = *rover->topheight-(16<topheight-(spacing>>1); - for (a = leftx; a < rightx; a += (32<>3; + heightfactor = (topz - *rover->bottomheight)>>2; + + for (a = leftx; a < rightx; a += spacing) { - for (b = topy; b > bottomy; b -= (32< bottomy; b -= spacing) { if (R_PointInSubsector(a, b)->sector == sec) { mobj_t *spawned = NULL; - for (c = topz; c > *rover->bottomheight; c -= (32< *rover->bottomheight; c -= spacing) { spawned = P_SpawnMobj(a, b, c, type); - spawned->fuse = 3*TICRATE; + if (flags & ML_EFFECT1) + { + P_InstaThrust(spawned, R_PointToAngle2(sec->soundorg.x, sec->soundorg.y, a, b), FixedDiv(P_AproxDistance(a - sec->soundorg.x, b - sec->soundorg.y), widthfactor)); + P_SetObjectMomZ(spawned, FixedDiv((c - *rover->bottomheight), heightfactor), false); + } + if (lifetime != -1) + spawned->fuse = lifetime; } } } diff --git a/src/p_mobj.c b/src/p_mobj.c index 514952975..80cbcb486 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3068,8 +3068,13 @@ nightsdone: if (rover->flags & FF_MARIO && !(mo->eflags & MFE_VERTICALFLIP) // if you were flipped, your head isn't actually hitting your ceilingz is it? && *rover->bottomheight == mo->ceilingz) // The player's head hit the bottom! + { // DO THE MARIO! - EV_MarioBlock(rover->master->frontsector, node->m_sector, *rover->topheight, mo); + if (rover->master->flags & ML_NOCLIMB) // Brick block! + EV_CrumbleChain(node->m_sector, rover); + else // Question block! + EV_MarioBlock(rover->master->frontsector, node->m_sector, *rover->topheight, mo); + } } } // Ugly ugly billions of braces! Argh! } diff --git a/src/p_setup.c b/src/p_setup.c index b36bf0b80..659c45ed8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1476,6 +1476,7 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum) break; } + case 14: // Bustable block parameter case 425: // Calls P_SetMobjState on calling mobj case 434: // Custom Power case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors diff --git a/src/p_spec.c b/src/p_spec.c index d2ac5b6a9..0112d02a7 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3712,7 +3712,7 @@ DoneSection2: } break; - case 7: // Bustable block sprite parameter + case 7: // N/A (formerly bustable block sprite parameters) case 8: case 9: case 10: From 58d0d2d5e9c208108010a80414845c0ea47a5241 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 4 Jun 2016 19:39:15 +0100 Subject: [PATCH 12/42] Completely forgot P_FindSpecialLineFromTag was a thing. Now Linedef type 14 doesn't need to be in the same sector, but requires a tag... --- src/p_floor.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 18126f263..d86b567df 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2890,18 +2890,18 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) #define controlsec rover->master->frontsector - for (i = 0; i < controlsec->linecount; i++) + if (controlsec->tag != 0) { - if (controlsec->lines[i]->special == 14) // If we can use bustable block parameters, we will. + size_t tagline = P_FindSpecialLineFromTag(14, controlsec->tag, -1); + if (tagline != -1) { - if (sides[controlsec->lines[i]->sidenum[0]].toptexture) - type = (mobjtype_t)sides[controlsec->lines[i]->sidenum[0]].toptexture; // Set as object type in p_setup.c... - if (sides[controlsec->lines[i]->sidenum[0]].textureoffset) - spacing = sides[controlsec->lines[i]->sidenum[0]].textureoffset; - if (sides[controlsec->lines[i]->sidenum[0]].rowoffset) - lifetime = (sides[controlsec->lines[i]->sidenum[0]].rowoffset>>FRACBITS); - flags = controlsec->lines[i]->flags; - break; // If someone has multiple parameter linedefs per control sector, TOUGH. + if (sides[lines[tagline].sidenum[0]].toptexture) + type = (mobjtype_t)sides[lines[tagline].sidenum[0]].toptexture; // Set as object type in p_setup.c... + if (sides[lines[tagline].sidenum[0]].textureoffset) + spacing = sides[lines[tagline].sidenum[0]].textureoffset; + if (sides[lines[tagline].sidenum[0]].rowoffset) + lifetime = (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS); + flags = lines[tagline].flags; } } From 7c7a8413c9ee6b6c29cc59297d5073d96c1a803f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 4 Jun 2016 20:02:11 +0100 Subject: [PATCH 13/42] Instead of hacking the existing Question Block thinker to ignore the object, let's just... not give the Brick Block a thinker in the first place. --- src/p_floor.c | 11 ++++------- src/p_spec.c | 3 ++- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index d86b567df..0656458eb 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1797,13 +1797,10 @@ static mobj_t *SearchMarioNode(msecnode_t *node) void T_MarioBlockChecker(levelspecthink_t *block) { line_t *masterline = block->sourceline; - if (!(masterline->flags & ML_NOCLIMB)) // Don't change the textures of a brick block, just a question block - { - if (SearchMarioNode(block->sector->touching_thinglist)) - sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture; - else - sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].toptexture; - } + if (SearchMarioNode(block->sector->touching_thinglist)) + sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture; + else + sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].toptexture; } // This is the Thwomp's 'brain'. It looks around for players nearby, and if diff --git a/src/p_spec.c b/src/p_spec.c index 0112d02a7..a4a069dd2 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4933,7 +4933,8 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f if ((flags & FF_MARIO)) { - P_AddBlockThinker(sec2, master); + if (!(master->flags & ML_NOCLIMB)) // Don't change the textures of a brick block, just a question block + P_AddBlockThinker(sec2, master); CheckForMarioBlocks = true; } From b688f5763b89a50bc1b80aae402b5f9052d5b009 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 4 Jun 2016 21:19:52 +0100 Subject: [PATCH 14/42] Particle randomisation added to bustable blocks. --- src/p_floor.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/p_floor.c b/src/p_floor.c index 0656458eb..c39a7b5b6 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -13,6 +13,7 @@ #include "doomdef.h" #include "doomstat.h" +#include "m_random.h" #include "p_local.h" #include "r_state.h" #include "s_sound.h" @@ -2944,6 +2945,12 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) for (c = topz; c > *rover->bottomheight; c -= spacing) { spawned = P_SpawnMobj(a, b, c, type); + + if (spawned->frame & FF_ANIMATE) + spawned->frame += P_RandomKey(spawned->state->var2); + + spawned->angle += P_RandomKey(36)*ANG1; // irrelevant for default objects but might make sense for some custom ones + if (flags & ML_EFFECT1) { P_InstaThrust(spawned, R_PointToAngle2(sec->soundorg.x, sec->soundorg.y, a, b), FixedDiv(P_AproxDistance(a - sec->soundorg.x, b - sec->soundorg.y), widthfactor)); From 7a3a293c96bdfd1f83cab89da4c649ea9c9e665b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 4 Jun 2016 21:23:15 +0100 Subject: [PATCH 15/42] Woops, forgot the 0. Now it takes advantage of the full range. --- src/p_floor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_floor.c b/src/p_floor.c index c39a7b5b6..cde657a18 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2949,7 +2949,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) if (spawned->frame & FF_ANIMATE) spawned->frame += P_RandomKey(spawned->state->var2); - spawned->angle += P_RandomKey(36)*ANG1; // irrelevant for default objects but might make sense for some custom ones + spawned->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones if (flags & ML_EFFECT1) { From 36da2e198d1116674d65fdf31f857ea65a008984 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 4 Jun 2016 22:08:51 +0100 Subject: [PATCH 16/42] At least this one wasn't my fault ( :P ) --- src/p_floor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_floor.c b/src/p_floor.c index cde657a18..01ae011ed 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2947,7 +2947,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) spawned = P_SpawnMobj(a, b, c, type); if (spawned->frame & FF_ANIMATE) - spawned->frame += P_RandomKey(spawned->state->var2); + spawned->frame += P_RandomKey(spawned->state->var1); spawned->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones From bdbfa178e6f95b678ead5416fb38248a35c4d02b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 4 Jun 2016 23:06:26 +0100 Subject: [PATCH 17/42] Compilation fixes. (Silly .o files sticking around...) --- src/p_floor.c | 13 +++++++++---- src/p_saveg.c | 2 -- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 01ae011ed..48d62f6f2 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2890,7 +2890,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) if (controlsec->tag != 0) { - size_t tagline = P_FindSpecialLineFromTag(14, controlsec->tag, -1); + INT32 tagline = P_FindSpecialLineFromTag(14, controlsec->tag, -1); if (tagline != -1) { if (sides[lines[tagline].sidenum[0]].toptexture) @@ -2898,7 +2898,12 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) if (sides[lines[tagline].sidenum[0]].textureoffset) spacing = sides[lines[tagline].sidenum[0]].textureoffset; if (sides[lines[tagline].sidenum[0]].rowoffset) - lifetime = (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS); + { + if (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS == -1) + lifetime = (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS); + else + lifetime = 0; + } flags = lines[tagline].flags; } } @@ -2956,8 +2961,8 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) P_InstaThrust(spawned, R_PointToAngle2(sec->soundorg.x, sec->soundorg.y, a, b), FixedDiv(P_AproxDistance(a - sec->soundorg.x, b - sec->soundorg.y), widthfactor)); P_SetObjectMomZ(spawned, FixedDiv((c - *rover->bottomheight), heightfactor), false); } - if (lifetime != -1) - spawned->fuse = lifetime; + + spawned->fuse = lifetime; } } } diff --git a/src/p_saveg.c b/src/p_saveg.c index 48f283bd3..c99e15cfb 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1434,7 +1434,6 @@ static inline void SaveFrictionThinker(const thinker_t *th, const UINT8 type) const friction_t *ht = (const void *)th; WRITEUINT8(save_p, type); WRITEINT32(save_p, ht->friction); - WRITEINT32(save_p, ht->movefactor); WRITEINT32(save_p, ht->affectee); WRITEINT32(save_p, ht->referrer); WRITEUINT8(save_p, ht->roverfriction); @@ -2369,7 +2368,6 @@ static inline void LoadFrictionThinker(actionf_p1 thinker) friction_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; ht->friction = READINT32(save_p); - ht->movefactor = READINT32(save_p); ht->affectee = READINT32(save_p); ht->referrer = READINT32(save_p); ht->roverfriction = READUINT8(save_p); From 482c1ce66556f4d7bea0b1f4b9b666e0bbd6a76e Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 5 Jun 2016 00:23:20 +0100 Subject: [PATCH 18/42] Speed pads are now nicer. Linedef type 4 now works as follows. * Frontside x offset is dash speed. * Effect 4 flag doesn't center the player. (same as before) * Effect 5 flag sends them off in rolling frames. (as a result there is only one speed pad sector type now, not two) * Frontside upper texture is sound to play on launch, defaults to sfx_spdpad when not given --- src/p_setup.c | 4 +++- src/p_spec.c | 46 +++++++++++++++++++++++++++++----------------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 659c45ed8..cfcc7d405 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1463,6 +1463,8 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum) sd->text[6] = 0; break; } + + case 4: // Speed pad parameters case 414: // Play SFX { sd->toptexture = sd->midtexture = sd->bottomtexture = 0; @@ -1476,7 +1478,7 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum) break; } - case 14: // Bustable block parameter + case 14: // Bustable block parameters case 425: // Calls P_SetMobjState on calling mobj case 434: // Custom Power case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors diff --git a/src/p_spec.c b/src/p_spec.c index a4a069dd2..1536b3c46 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2415,7 +2415,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { fixed_t sfxnum; - sfxnum = sides[line->sidenum[0]].toptexture; //P_AproxDistance(line->dx, line->dy)>>FRACBITS; + sfxnum = sides[line->sidenum[0]].toptexture; if (line->tag != 0 && line->flags & ML_EFFECT5) { @@ -3650,14 +3650,13 @@ DoneSection2: // Process Section 3 switch (special) { - case 1: // N/A (formerly Ice/Sludge) + case 1: // Unused case 2: // Wind/Current - case 3: // N/A (formerly Ice/Sludge and Wind/Current) + case 3: // Unused case 4: // Conveyor Belt break; - case 5: // Speed pad w/o spin - case 6: // Speed pad w/ spin + case 5: // Speed pad if (player->powers[pw_flashing] != 0 && player->powers[pw_flashing] < TICRATE/2) break; @@ -3669,7 +3668,13 @@ DoneSection2: fixed_t linespeed; lineangle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y); - linespeed = P_AproxDistance(lines[i].v2->x-lines[i].v1->x, lines[i].v2->y-lines[i].v1->y); + linespeed = sides[lines[i].sidenum[0]].textureoffset; + + if (linespeed == 0) + { + CONS_Debug(DBG_GAMELOGIC, "ERROR: Speed pad (tag %d) at zero speed.\n", sector->tag); + break; + } player->mo->angle = lineangle; @@ -3699,7 +3704,7 @@ DoneSection2: P_InstaThrust(player->mo, player->mo->angle, linespeed); - if (GETSECSPECIAL(sector->special, 3) == 6 && (player->charability2 == CA2_SPINDASH)) + if ((lines[i].flags & ML_EFFECT5) && (player->charability2 == CA2_SPINDASH)) // Roll! { if (!(player->pflags & PF_SPINNING)) player->pflags |= PF_SPINNING; @@ -3708,19 +3713,26 @@ DoneSection2: } player->powers[pw_flashing] = TICRATE/3; - S_StartSound(player->mo, sfx_spdpad); + + fixed_t sfxnum = sides[lines[i].sidenum[0]].toptexture; + + if (!sfxnum) + sfxnum = sfx_spdpad; + + S_StartSound(player->mo, sfxnum); } break; - case 7: // N/A (formerly bustable block sprite parameters) - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: + case 6: // Unused + case 7: // Unused + case 8: // Unused + case 9: // Unused + case 10: // Unused + case 11: // Unused + case 12: // Unused + case 13: // Unused + case 14: // Unused + case 15: // Unused break; } From 94e4d3ddbf9396d95d0a79a265cd8b920b14c2cc Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 5 Jun 2016 01:26:02 +0100 Subject: [PATCH 19/42] Good eye, MI. --- src/p_floor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_floor.c b/src/p_floor.c index 48d62f6f2..9c6580970 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2899,7 +2899,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) spacing = sides[lines[tagline].sidenum[0]].textureoffset; if (sides[lines[tagline].sidenum[0]].rowoffset) { - if (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS == -1) + if (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS != -1) lifetime = (sides[lines[tagline].sidenum[0]].rowoffset>>FRACBITS); else lifetime = 0; From 76a3c1687c9dbbd614b132324c54e269750baf3c Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 5 Jun 2016 02:20:26 +0100 Subject: [PATCH 20/42] Noticed an assymetry in the Zoom Tube code. I assume the forward-going zoom tube's cancelling of gliding and climbing solved some bug, so I'm mirroring it for the backwards version. --- src/p_spec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_spec.c b/src/p_spec.c index 1536b3c46..118e319ed 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4027,6 +4027,8 @@ DoneSection2: player->speed = speed; player->pflags |= PF_SPINNING; player->pflags &= ~PF_JUMPED; + player->pflags &= ~PF_GLIDING; + player->climbing = 0; if (player->mo->state-states != S_PLAY_SPIN) { From 2ffc06c0bc9eb3f5d3604d15bf076678fd3b69cd Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 6 Jun 2016 00:00:31 +0100 Subject: [PATCH 21/42] Fan particle generators now suck less! For the object... * Tag via its angle field * Number of objects to spawn per tic around it via its z field, if zero then just spawn at center * Is flipped if given MTF_OBJECTFLIP. Now there's a linedef type 15! * Tag is tag of object(s!) * Object type set via concatenation of frontside textures, MT_PARTICLE is default * The length of the linedef is the radius the particle is spawned out (zeroed if z field is 0) * Frontside x offset is speed upwards * Frontside y offset is number of degrees to turn each tic (zeroed if z field is 0) * Frontside floor and ceiling heights are the heights in which the particle is bound through some fun mathematics and/or BDSM Of course, not every story has a happy ending. * A_ParticleSpawn no longer accepts objects via its var1 because of how specialised it's gotten. Considering it can be set via abuse of actor->cvmem, I don't consider this an issue. Maybe you might disagree. --- src/p_enemy.c | 48 +++++++++++++++++-------------- src/p_mobj.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/p_setup.c | 1 + 3 files changed, 106 insertions(+), 22 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 4e11dc494..fc46f697a 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3359,41 +3359,45 @@ void A_ScoreRise(mobj_t *actor) // Function: A_ParticleSpawn // -// Description: Spawns a particle at a specified interval +// Description: Hyper-specialised function for spawning a particle for MT_PARTICLEGEN. // -// var1 = type (if 0, defaults to MT_PARTICLE) +// var1 = unused // var2 = unused // void A_ParticleSpawn(mobj_t *actor) { - INT32 locvar1 = var1; - fixed_t speed; - mobjtype_t type; + INT32 i = 0; mobj_t *spawn; #ifdef HAVE_BLUA if (LUA_CallAction("A_ParticleSpawn", actor)) return; #endif - if (!actor->spawnpoint) - { - P_RemoveMobj(actor); + if (!actor->health) return; + + if ((actor->lastlook) && (actor->cvmem)) + { + for (i = 0; i < actor->lastlook; i++) + { + spawn = P_SpawnMobj(actor->x + FixedMul(actor->friction, FINECOSINE(actor->angle>>ANGLETOFINESHIFT)), + actor->y + FixedMul(actor->friction, FINESINE(actor->angle>>ANGLETOFINESHIFT)), + actor->z, + (mobjtype_t)actor->cvmem); + P_SetScale(spawn, actor->scale); + spawn->momz = actor->movefactor; + spawn->destscale = spawn->scale/100; + spawn->scalespeed = spawn->scale/actor->health; + spawn->tics = (tic_t)actor->health; + spawn->flags2 |= (actor->flags2 & MF2_OBJECTFLIP); + spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones + if (spawn->frame & FF_ANIMATE) + spawn->frame += P_RandomKey(spawn->state->var1); + + actor->angle += actor->movedir; + } + actor->angle += (angle_t)actor->movecount; } - - if (locvar1) - type = (mobjtype_t)locvar1; - else - type = MT_PARTICLE; - - speed = FixedMul((actor->spawnpoint->angle >> 12)<scale); - - spawn = P_SpawnMobj(actor->x, actor->y, actor->z, type); - P_SetScale(spawn, actor->scale); - spawn->momz = speed; - spawn->destscale = FixedDiv(spawn->scale<scalespeed = FixedDiv(((actor->spawnpoint->angle >> 8) & 63) << FRACBITS, 100<tics = actor->spawnpoint->extrainfo + 1; } // Function: A_BunnyHop diff --git a/src/p_mobj.c b/src/p_mobj.c index 3e87130b0..df136edd6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9303,6 +9303,85 @@ ML_NOCLIMB : Direction not controllable } break; } + case MT_PARTICLEGEN: + { + fixed_t radius, speed, bottomheight, topheight; + INT32 type, numdivisions, time, anglespeed; + angle_t angledivision; + size_t line; + const size_t mthingi = (size_t)(mthing - mapthings); + + for (line = 0; line < numlines; line++) + { + if (lines[line].special == 15 && lines[line].tag == mthing->angle) + break; + } + + if (line == numlines) + { + CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%s) needs tagged to a #15 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle); + return; + } + + if (sides[lines[line].sidenum[0]].toptexture) + type = sides[lines[line].sidenum[0]].toptexture; // Set as object type in p_setup.c... + else + type = (INT32)MT_PARTICLE; + + speed = abs(sides[lines[line].sidenum[0]].textureoffset); + bottomheight = lines[line].frontsector->floorheight; + topheight = lines[line].frontsector->ceilingheight - mobjinfo[(mobjtype_t)type].height; + + numdivisions = (mthing->options >> ZSHIFT); + + if (numdivisions) + { + radius = R_PointToDist2(lines[line].v1->x, lines[line].v1->y, lines[line].v2->x, lines[line].v2->y); + anglespeed = (sides[lines[line].sidenum[0]].rowoffset >> FRACBITS) % 360; + angledivision = 360/numdivisions; + } + else + { + numdivisions = 1; // Simple trick to make A_ParticleSpawn simpler. + radius = 0; + anglespeed = 0; + angledivision = 0; + } + + if ((speed) && (topheight > bottomheight)) + time = (INT32)(FixedDiv((topheight - bottomheight), speed) >> FRACBITS); + else + time = 1; // There's no reasonable way to set it, so just show the object for one tic and move on. + + if (mthing->options & MTF_OBJECTFLIP) + { + mobj->z = topheight; + speed *= -1; + } + else + mobj->z = bottomheight; + + CONS_Debug(DBG_GAMELOGIC, "Particle Generator (mapthing #%s):\n" + "Radius is %d\n" + "Speed is %d\n" + "Anglespeed is %d\n" + "Numdivisions is %d\n" + "Angledivision is %d\n" + "Time is %d\n" + "Type is %d\n", + sizeu1(mthingi), radius, speed, anglespeed, numdivisions, angledivision, time, type); + + mobj->angle = 0; + mobj->movefactor = speed; + mobj->lastlook = numdivisions; + mobj->movedir = angledivision*ANG1; + mobj->movecount = anglespeed*ANG1; + mobj->health = time; + mobj->friction = radius; + mobj->cvmem = type; + + break; + } case MT_ROCKSPAWNER: mobj->threshold = mthing->angle; mobj->movecount = mthing->extrainfo; diff --git a/src/p_setup.c b/src/p_setup.c index cfcc7d405..50df019ef 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1479,6 +1479,7 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum) } case 14: // Bustable block parameters + case 15: // Fan particle spawner parameters case 425: // Calls P_SetMobjState on calling mobj case 434: // Custom Power case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors From 4b385eb7ebf1a404688e96e979f4546464ad03bd Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 6 Jun 2016 00:36:47 +0100 Subject: [PATCH 22/42] Forgot to take scale into account consistently. --- src/p_enemy.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index fc46f697a..75a6b4e15 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3380,12 +3380,13 @@ void A_ParticleSpawn(mobj_t *actor) { for (i = 0; i < actor->lastlook; i++) { - spawn = P_SpawnMobj(actor->x + FixedMul(actor->friction, FINECOSINE(actor->angle>>ANGLETOFINESHIFT)), - actor->y + FixedMul(actor->friction, FINESINE(actor->angle>>ANGLETOFINESHIFT)), + spawn = P_SpawnMobj( + actor->x + FixedMul(FixedMul(actor->friction, actor->scale), FINECOSINE(actor->angle>>ANGLETOFINESHIFT)), + actor->y + FixedMul(FixedMul(actor->friction, actor->scale), FINESINE(actor->angle>>ANGLETOFINESHIFT)), actor->z, (mobjtype_t)actor->cvmem); P_SetScale(spawn, actor->scale); - spawn->momz = actor->movefactor; + spawn->momz = FixedMul(actor->movefactor, spawn->scale); spawn->destscale = spawn->scale/100; spawn->scalespeed = spawn->scale/actor->health; spawn->tics = (tic_t)actor->health; From 316cb9c24f55b6041846958511049261742b36c0 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 6 Jun 2016 02:17:48 +0100 Subject: [PATCH 23/42] cvmem -> threshold, on MI's reccomendation (I NEVER SLEEP) --- src/p_enemy.c | 4 ++-- src/p_mobj.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 75a6b4e15..ed05b43d9 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3376,7 +3376,7 @@ void A_ParticleSpawn(mobj_t *actor) if (!actor->health) return; - if ((actor->lastlook) && (actor->cvmem)) + if ((actor->lastlook) && (actor->threshold)) { for (i = 0; i < actor->lastlook; i++) { @@ -3384,7 +3384,7 @@ void A_ParticleSpawn(mobj_t *actor) actor->x + FixedMul(FixedMul(actor->friction, actor->scale), FINECOSINE(actor->angle>>ANGLETOFINESHIFT)), actor->y + FixedMul(FixedMul(actor->friction, actor->scale), FINESINE(actor->angle>>ANGLETOFINESHIFT)), actor->z, - (mobjtype_t)actor->cvmem); + (mobjtype_t)actor->threshold); P_SetScale(spawn, actor->scale); spawn->momz = FixedMul(actor->movefactor, spawn->scale); spawn->destscale = spawn->scale/100; diff --git a/src/p_mobj.c b/src/p_mobj.c index df136edd6..6e7e0ad20 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9378,7 +9378,7 @@ ML_NOCLIMB : Direction not controllable mobj->movecount = anglespeed*ANG1; mobj->health = time; mobj->friction = radius; - mobj->cvmem = type; + mobj->threshold = type; break; } From 356dd0323447abb61aa2d1d7c506deb2ee25ae5a Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 6 Jun 2016 18:30:58 +0100 Subject: [PATCH 24/42] Mario block improvements. (I JUST CAN'T STOP) * Only change texture when stationary or moving down, for additional fidelity to source material. This has zero overhead, and actually might REDUCE lag in some circumstances... my nitpickiness wins again. * Apply ML_EFFECT1 to it to make it invisible and intangible (removing (FF_SOLID|FF_RENDERALL|FF_CUTLEVEL) from it) from every side except the bottom. Becomes visible and tangible when it's hit once. Might fuck over players in mp, but really our Mario blocks are so high in the air (and we'd need to update Pipe Towers to take advantage anyways) that they're super unlikely to get a kill this way * Checks for the Brick Block have been switched over to the presence of FF_SHATTERBOTTOM instead of checking for the source linedef's flags every time. --- src/p_floor.c | 33 ++++++++++++++++---------- src/p_mobj.c | 19 +++++++++------ src/p_spec.c | 64 +++++++++++++++++++++++---------------------------- src/p_spec.h | 2 +- 4 files changed, 63 insertions(+), 55 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 9c6580970..0e7f52376 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1132,7 +1132,10 @@ void T_MarioBlock(levelspecthink_t *block) ); if (block->sector->ceilingheight >= block->ceilingwasheight + 32*FRACUNIT) // Go back down now.. + { block->direction = -block->direction; + block->sector->floorspeed = 0; + } else if (block->sector->ceilingheight <= block->ceilingwasheight) { block->sector->ceilingheight = block->ceilingwasheight; @@ -1140,8 +1143,6 @@ void T_MarioBlock(levelspecthink_t *block) P_RemoveThinker(&block->thinker); block->sector->floordata = NULL; block->sector->ceilingdata = NULL; - block->sector->floorspeed = 0; - block->sector->ceilspeed = 0; } for (i = -1; (i = P_FindSectorFromTag((INT16)block->vars[0], i)) >= 0 ;) @@ -1797,6 +1798,8 @@ static mobj_t *SearchMarioNode(msecnode_t *node) void T_MarioBlockChecker(levelspecthink_t *block) { + if (block->sector->floorspeed) // Don't update the textures when the block's being bumped upwards. + return; line_t *masterline = block->sourceline; if (SearchMarioNode(block->sector->touching_thinglist)) sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture; @@ -3122,8 +3125,10 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating, return 1; } -INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mobj_t *puncher) +INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) { + sector_t *roversec = rover->master->frontsector; + fixed_t topheight = *rover->topheight; levelspecthink_t *block; mobj_t *thing; fixed_t oldx = 0, oldy = 0, oldz = 0; @@ -3131,11 +3136,14 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob I_Assert(puncher != NULL); I_Assert(puncher->player != NULL); - if (sec->floordata || sec->ceilingdata) + if (roversec->floordata || roversec->ceilingdata) return 0; + if (!(rover->flags & FF_SOLID)) + rover->flags |= (FF_SOLID|FF_RENDERALL|FF_CUTLEVEL); + // Find an item to pop out! - thing = SearchMarioNode(sec->touching_thinglist); + thing = SearchMarioNode(roversec->touching_thinglist); // Found something! if (thing) @@ -3145,13 +3153,14 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob block = Z_Calloc(sizeof (*block), PU_LEVSPEC, NULL); P_AddThinker(&block->thinker); - sec->floordata = block; - sec->ceilingdata = block; + roversec->floordata = block; + roversec->ceilingdata = block; block->thinker.function.acp1 = (actionf_p1)T_MarioBlock; // Set up the fields - block->sector = sec; - block->vars[0] = roversector->tag; // actionsector + roversec->floorspeed = 1; // Flag to prevent side changing. + block->sector = roversec; + block->vars[0] = sector->tag; // actionsector block->vars[1] = 4*FRACUNIT; // speed block->vars[2] = 1; // Up // direction block->vars[3] = block->sector->floorheight; // floorwasheight @@ -3167,8 +3176,8 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob } P_UnsetThingPosition(thing); - thing->x = roversector->soundorg.x; - thing->y = roversector->soundorg.y; + thing->x = sector->soundorg.x; + thing->y = sector->soundorg.y; thing->z = topheight; thing->momz = FixedMul(6*FRACUNIT, thing->scale); P_SetThingPosition(thing); @@ -3185,7 +3194,7 @@ INT32 EV_MarioBlock(sector_t *sec, sector_t *roversector, fixed_t topheight, mob { if (thing->type == MT_EMMY && thing->spawnpoint && (thing->spawnpoint->options & MTF_OBJECTSPECIAL)) { - mobj_t *tokenobj = P_SpawnMobj(roversector->soundorg.x, roversector->soundorg.y, topheight, MT_TOKEN); + mobj_t *tokenobj = P_SpawnMobj(sector->soundorg.x, sector->soundorg.y, topheight, MT_TOKEN); P_SetTarget(&thing->tracer, tokenobj); P_SetTarget(&tokenobj->target, thing); P_SetMobjState(tokenobj, mobjinfo[MT_TOKEN].seestate); diff --git a/src/p_mobj.c b/src/p_mobj.c index 6e7e0ad20..f1d164930 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2154,14 +2154,16 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL); bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL); - if (mo->player && (P_CheckSolidLava(mo, rover) || P_CanRunOnWater(mo->player, rover))) // only the player should be affected + if (mo->player && (P_CheckSolidLava(mo, rover) || P_CanRunOnWater(mo->player, rover))) // only the player should stand on lava or run on water ; else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only continue; else if (rover->flags & FF_QUICKSAND) // quicksand ; - else if (!((rover->flags & FF_BLOCKPLAYER && mo->player) // solid to players? - || (rover->flags & FF_BLOCKOTHERS && !mo->player))) // solid to others? + else if (!( // if it's not either of the following... + (rover->flags & (FF_BLOCKPLAYER|FF_MARIO) && mo->player) // ...solid to players? (mario blocks are always solid from beneath to players) + || (rover->flags & FF_BLOCKOTHERS && !mo->player) // ...solid to others? + )) // ...don't take it into account. continue; if (rover->flags & FF_QUICKSAND) { @@ -2186,13 +2188,16 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp delta1 = mo->z - (bottomheight + ((topheight - bottomheight)/2)); delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2)); + if (topheight > mo->floorz && abs(delta1) < abs(delta2) - && !(rover->flags & FF_REVERSEPLATFORM)) + && !(rover->flags & FF_REVERSEPLATFORM) + && (rover->flags & FF_SOLID)) // Non-FF_SOLID Mario blocks are only solid from bottom { mo->floorz = topheight; } if (bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2) - && !(rover->flags & FF_PLATFORM)) + && !(rover->flags & FF_PLATFORM) + && ((mo->momz > 0) || ((rover->flags & FF_SOLID) && !(rover->flags & FF_REVERSEPLATFORM)))) // Only clip for FOFs that are intangible from the top if you're coming from below { mo->ceilingz = bottomheight; } @@ -3070,10 +3075,10 @@ nightsdone: && *rover->bottomheight == mo->ceilingz) // The player's head hit the bottom! { // DO THE MARIO! - if (rover->master->flags & ML_NOCLIMB) // Brick block! + if (rover->flags & FF_SHATTERBOTTOM) // Brick block! EV_CrumbleChain(node->m_sector, rover); else // Question block! - EV_MarioBlock(rover->master->frontsector, node->m_sector, *rover->topheight, mo); + EV_MarioBlock(rover, node->m_sector, mo); } } } // Ugly ugly billions of braces! Argh! diff --git a/src/p_spec.c b/src/p_spec.c index 493a692e2..7d77a66ed 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5793,11 +5793,8 @@ void P_SpawnSpecials(INT32 fromnetsave) // Draw the 'insides' of the block too if (lines[i].flags & ML_NOCLIMB) { - ffloorflags |= FF_CUTLEVEL; - ffloorflags |= FF_BOTHPLANES; - ffloorflags |= FF_ALLSIDES; - ffloorflags &= ~FF_EXTRA; - ffloorflags &= ~FF_CUTEXTRA; + ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES; + ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA); } P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); @@ -5904,11 +5901,8 @@ void P_SpawnSpecials(INT32 fromnetsave) // Draw the 'insides' of the block too if (lines[i].flags & ML_EFFECT2) { - ffloorflags |= FF_CUTLEVEL; - ffloorflags |= FF_BOTHPLANES; - ffloorflags |= FF_ALLSIDES; - ffloorflags &= ~FF_EXTRA; - ffloorflags &= ~FF_CUTEXTRA; + ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES; + ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA); } P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); @@ -5922,11 +5916,8 @@ void P_SpawnSpecials(INT32 fromnetsave) // Draw the 'insides' of the block too if (lines[i].flags & ML_EFFECT2) { - ffloorflags |= FF_CUTLEVEL; - ffloorflags |= FF_BOTHPLANES; - ffloorflags |= FF_ALLSIDES; - ffloorflags &= ~FF_EXTRA; - ffloorflags &= ~FF_CUTEXTRA; + ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES; + ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA); } P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); @@ -5950,11 +5941,8 @@ void P_SpawnSpecials(INT32 fromnetsave) // Draw the 'insides' of the block too if (lines[i].flags & ML_EFFECT2) { - ffloorflags |= FF_CUTLEVEL; - ffloorflags |= FF_BOTHPLANES; - ffloorflags |= FF_ALLSIDES; - ffloorflags &= ~FF_EXTRA; - ffloorflags &= ~FF_CUTEXTRA; + ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES; + ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA); } P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); @@ -5968,11 +5956,8 @@ void P_SpawnSpecials(INT32 fromnetsave) // Draw the 'insides' of the block too if (lines[i].flags & ML_EFFECT2) { - ffloorflags |= FF_CUTLEVEL; - ffloorflags |= FF_BOTHPLANES; - ffloorflags |= FF_ALLSIDES; - ffloorflags &= ~FF_EXTRA; - ffloorflags &= ~FF_CUTEXTRA; + ffloorflags |= FF_CUTLEVEL|FF_BOTHPLANES|FF_ALLSIDES; + ffloorflags &= ~(FF_EXTRA|FF_CUTEXTRA); } P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); @@ -6150,7 +6135,13 @@ void P_SpawnSpecials(INT32 fromnetsave) break; case 250: // Mario Block - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_MARIO, secthinkers); + ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL|FF_MARIO; + if (lines[i].flags & ML_NOCLIMB) + ffloorflags |= FF_SHATTERBOTTOM; + if (lines[i].flags & ML_EFFECT1) + ffloorflags &= ~(FF_SOLID|FF_RENDERALL|FF_CUTLEVEL); + + P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); break; case 251: // A THWOMP! @@ -6164,10 +6155,11 @@ void P_SpawnSpecials(INT32 fromnetsave) break; case 252: // Shatter block (breaks when touched) + ffloorflags = FF_EXISTS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER; if (lines[i].flags & ML_NOCLIMB) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP|FF_SHATTER|FF_SHATTERBOTTOM, secthinkers); - else - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_RENDERALL|FF_BUSTUP|FF_SHATTER, secthinkers); + ffloorflags |= FF_SOLID|FF_SHATTERBOTTOM; + + P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); break; case 253: // Translucent shatter block (see 76) @@ -6175,10 +6167,11 @@ void P_SpawnSpecials(INT32 fromnetsave) break; case 254: // Bustable block + ffloorflags = FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP; if (lines[i].flags & ML_NOCLIMB) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP|FF_ONLYKNUX, secthinkers); - else - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_BUSTUP, secthinkers); + ffloorflags |= FF_ONLYKNUX; + + P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); break; case 255: // Spin bust block (breaks when jumped or spun downwards onto) @@ -6190,10 +6183,11 @@ void P_SpawnSpecials(INT32 fromnetsave) break; case 257: // Quicksand + ffloorflags = FF_EXISTS|FF_QUICKSAND|FF_RENDERALL|FF_ALLSIDES|FF_CUTSPRITES; if (lines[i].flags & ML_EFFECT5) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_QUICKSAND|FF_RENDERALL|FF_ALLSIDES|FF_CUTSPRITES|FF_RIPPLE, secthinkers); - else - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_QUICKSAND|FF_RENDERALL|FF_ALLSIDES|FF_CUTSPRITES, secthinkers); + ffloorflags |= FF_RIPPLE; + + P_AddFakeFloorsByLine(i, ffloorflags, secthinkers); break; case 258: // Laser block diff --git a/src/p_spec.h b/src/p_spec.h index b90764f61..b38500288 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -323,7 +323,7 @@ INT32 EV_StartCrumble(sector_t *sector, ffloor_t *rover, INT32 EV_DoContinuousFall(sector_t *sec, sector_t *pbacksector, fixed_t spd, boolean backwards); -INT32 EV_MarioBlock(sector_t *sector, sector_t *roversector, fixed_t topheight, mobj_t *puncher); +INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher); void T_MoveFloor(floormove_t *movefloor); From 8e2212bb48fe91b7899c1e3c70b0f9c1937ef07b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 6 Jun 2016 19:02:08 +0100 Subject: [PATCH 25/42] One more Mario block change. If FOF linedef has backside: * If there's items in it set the FOF's floor and ceiling flats to that of the backside sector's ceiling * Otherwise, set them to that of the backside sector's floor. Otherwise, the flats do not change. This allows for SMW style blocks which are much darker when empty then full on all sides. --- src/p_floor.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/p_floor.c b/src/p_floor.c index 0e7f52376..4ddba60bc 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1802,9 +1802,21 @@ void T_MarioBlockChecker(levelspecthink_t *block) return; line_t *masterline = block->sourceline; if (SearchMarioNode(block->sector->touching_thinglist)) - sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture; + { + sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture; // Update textures + if (masterline->sidenum[1]) + { + sides[masterline->sidenum[0]].sector->ceilingpic = sides[masterline->sidenum[0]].sector->floorpic = sides[masterline->sidenum[1]].sector->ceilingpic; // Update flats to be backside's ceiling if there's a back sector, otherwise leave them alone + } + } else + { sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].toptexture; + if (masterline->sidenum[1]) + { + sides[masterline->sidenum[0]].sector->ceilingpic = sides[masterline->sidenum[0]].sector->floorpic = sides[masterline->sidenum[1]].sector->floorpic; // Update flats to be backside's floor if there's a back sector, otherwise leave them alone + } + } } // This is the Thwomp's 'brain'. It looks around for players nearby, and if From 7f3f46860b9c948b5f30043b12dcdd4063c8c834 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 6 Jun 2016 20:57:50 +0100 Subject: [PATCH 26/42] Forward-port of the fix to the backwards port. --- src/p_mobj.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index f1d164930..b86185ee4 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2191,13 +2191,14 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp if (topheight > mo->floorz && abs(delta1) < abs(delta2) && !(rover->flags & FF_REVERSEPLATFORM) - && (rover->flags & FF_SOLID)) // Non-FF_SOLID Mario blocks are only solid from bottom + && (rover->flags & FF_SOLID) // Non-FF_SOLID Mario blocks are only solid from bottom + && ((P_MobjFlip(mo)*mo->momz < 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference) { mo->floorz = topheight; } if (bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2) && !(rover->flags & FF_PLATFORM) - && ((mo->momz > 0) || ((rover->flags & FF_SOLID) && !(rover->flags & FF_REVERSEPLATFORM)))) // Only clip for FOFs that are intangible from the top if you're coming from below + && ((P_MobjFlip(mo)*mo->momz > 0) || ((rover->flags & FF_SOLID) && !(rover->flags & FF_REVERSEPLATFORM)))) // Only clip for FOFs that are intangible from the top if you're coming from below { mo->ceilingz = bottomheight; } From ba2fe378fbd27333430a15faef7a2ad0d0ce277f Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 6 Jun 2016 21:03:24 +0100 Subject: [PATCH 27/42] woops #2 --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index b86185ee4..70b96f4bc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2192,7 +2192,7 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp if (topheight > mo->floorz && abs(delta1) < abs(delta2) && !(rover->flags & FF_REVERSEPLATFORM) && (rover->flags & FF_SOLID) // Non-FF_SOLID Mario blocks are only solid from bottom - && ((P_MobjFlip(mo)*mo->momz < 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference) + && ((P_MobjFlip(mo)*mo->momz > 0) || (!(rover->flags & FF_PLATFORM)))) // In reverse gravity, only clip for FOFs that are intangible from their bottom (the "top" you're falling through) if you're coming from above ("below" in your frame of reference) { mo->floorz = topheight; } From 26f34d10381b883a1d2fefb145c51b4eeaa446f4 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sat, 9 Jul 2016 17:36:24 +0100 Subject: [PATCH 28/42] Compiling fixes. --- src/p_floor.c | 2 +- src/p_spec.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index 4ddba60bc..62e89be6f 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1798,9 +1798,9 @@ static mobj_t *SearchMarioNode(msecnode_t *node) void T_MarioBlockChecker(levelspecthink_t *block) { + line_t *masterline = block->sourceline; if (block->sector->floorspeed) // Don't update the textures when the block's being bumped upwards. return; - line_t *masterline = block->sourceline; if (SearchMarioNode(block->sector->touching_thinglist)) { sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture; // Update textures diff --git a/src/p_spec.c b/src/p_spec.c index 7d77a66ed..c6972c5eb 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3676,6 +3676,7 @@ DoneSection2: { angle_t lineangle; fixed_t linespeed; + fixed_t sfxnum; lineangle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y); linespeed = sides[lines[i].sidenum[0]].textureoffset; @@ -3724,7 +3725,7 @@ DoneSection2: player->powers[pw_flashing] = TICRATE/3; - fixed_t sfxnum = sides[lines[i].sidenum[0]].toptexture; + sfxnum = sides[lines[i].sidenum[0]].toptexture; if (!sfxnum) sfxnum = sfx_spdpad; From aa93f8a25c84404044712fc8b5deca7d1e31e554 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 10 Aug 2016 00:05:46 +0100 Subject: [PATCH 29/42] Refactored the movefactor changes that made the player go Looney Tunes style on ice. --- src/p_mobj.c | 2 +- src/p_saveg.c | 2 ++ src/p_spec.c | 20 ++++++++++++++------ src/p_spec.h | 1 + src/p_user.c | 7 +------ 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 70b96f4bc..28f24b921 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7808,7 +7808,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->friction = ORIG_FRICTION; - mobj->movefactor = ORIG_FRICTION; + mobj->movefactor = FRACUNIT; // All mobjs are created at 100% scale. mobj->scale = FRACUNIT; diff --git a/src/p_saveg.c b/src/p_saveg.c index c99e15cfb..48f283bd3 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1434,6 +1434,7 @@ static inline void SaveFrictionThinker(const thinker_t *th, const UINT8 type) const friction_t *ht = (const void *)th; WRITEUINT8(save_p, type); WRITEINT32(save_p, ht->friction); + WRITEINT32(save_p, ht->movefactor); WRITEINT32(save_p, ht->affectee); WRITEINT32(save_p, ht->referrer); WRITEUINT8(save_p, ht->roverfriction); @@ -2368,6 +2369,7 @@ static inline void LoadFrictionThinker(actionf_p1 thinker) friction_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); ht->thinker.function.acp1 = thinker; ht->friction = READINT32(save_p); + ht->movefactor = READINT32(save_p); ht->affectee = READINT32(save_p); ht->referrer = READINT32(save_p); ht->roverfriction = READUINT8(save_p); diff --git a/src/p_spec.c b/src/p_spec.c index c6972c5eb..09228b7d8 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -109,7 +109,7 @@ static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline); //static void P_AddBridgeThinker(line_t *sourceline, sector_t *sec); static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinkerlist_t *secthinkers); static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec); -static void Add_Friction(INT32 friction, INT32 affectee, INT32 referrer); +static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer); static void P_AddSpikeThinker(sector_t *sec, INT32 referrer); @@ -4932,7 +4932,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f f = (friction_t *)th; if (f->affectee == (INT32)sec2num) - Add_Friction(f->friction, (INT32)(sec-sectors), f->affectee); + Add_Friction(f->friction, f->movefactor, (INT32)(sec-sectors), f->affectee); } // Should this FOF have wind/current/pusher? else if(th->function.acp1 == (actionf_p1)T_Pusher) @@ -6978,12 +6978,13 @@ void T_Disappear(disappear_t *d) * \param roverfriction FOF or not * \sa T_Friction, P_SpawnFriction */ -static void Add_Friction(INT32 friction, INT32 affectee, INT32 referrer) +static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer) { friction_t *f = Z_Calloc(sizeof *f, PU_LEVSPEC, NULL); f->thinker.function.acp1 = (actionf_p1)T_Friction; f->friction = friction; + f->movefactor = movefactor; f->affectee = affectee; if (referrer != -1) @@ -7044,7 +7045,7 @@ void T_Friction(friction_t *f) { thing->friction = f->friction; if (thing->player) - thing->movefactor = f->friction; + thing->movefactor = f->movefactor; } } else if (P_GetSpecialBottomZ(thing, sec, sec) == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction? @@ -7052,7 +7053,7 @@ void T_Friction(friction_t *f) { thing->friction = f->friction; if (thing->player) - thing->movefactor = f->friction; + thing->movefactor = f->movefactor; } } node = node->m_snext; @@ -7070,6 +7071,7 @@ static void P_SpawnFriction(void) register INT32 s; fixed_t strength; // frontside texture offset controls magnitude fixed_t friction; // friction value to be applied during movement + INT32 movefactor; // applied to each player move to simulate inertia for (i = 0; i < numlines; i++, l++) if (l->special == 540) @@ -7088,8 +7090,14 @@ static void P_SpawnFriction(void) if (friction < 0) friction = 0; + movefactor = FixedDiv(ORIG_FRICTION, friction); + if (movefactor < FRACUNIT) + movefactor = 8*movefactor - 7*FRACUNIT; + else + movefactor = FRACUNIT; + for (s = -1; (s = P_FindSectorFromLineTag(l, s)) >= 0 ;) - Add_Friction(friction, s, -1); + Add_Friction(friction, movefactor, s, -1); } } diff --git a/src/p_spec.h b/src/p_spec.h index b38500288..c7e7af0b3 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -386,6 +386,7 @@ typedef struct { thinker_t thinker; ///< Thinker structure for friction. INT32 friction; ///< Friction value, 0xe800 = normal. + INT32 movefactor; ///< Inertia factor when adding to momentum, FRACUNIT = normal. INT32 affectee; ///< Number of affected sector. INT32 referrer; ///< If roverfriction == true, then this will contain the sector # of the control sector where the effect was applied. UINT8 roverfriction; ///< flag for whether friction originated from a FOF or not diff --git a/src/p_user.c b/src/p_user.c index 6aebbe642..c61f7d06f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -6369,11 +6369,6 @@ static void P_MovePlayer(player_t *player) runspd = FixedMul(player->runspeed, player->mo->scale); // Let's have some movement speed fun on low-friction surfaces, JUST for players... (high friction surfaces shouldn't have any adjustment, since the acceleration in this game is super high and that ends up cheesing high-friction surfaces.) - player->mo->movefactor = FixedDiv(ORIG_FRICTION, player->mo->movefactor); - if (player->mo->movefactor < FRACUNIT) - player->mo->movefactor = 8*player->mo->movefactor - 7*FRACUNIT; - else - player->mo->movefactor = FRACUNIT; runspd = FixedMul(runspd, player->mo->movefactor); // Control relinquishing stuff! @@ -6547,7 +6542,7 @@ static void P_MovePlayer(player_t *player) if (!player->mo->momx && !player->mo->momy && !player->mo->momz && player->panim == PA_WALK) P_SetPlayerMobjState(player->mo, S_PLAY_STND); - player->mo->movefactor = ORIG_FRICTION; // We're not going to do any more with this, so let's change it back for the next frame. + player->mo->movefactor = FRACUNIT; // We're not going to do any more with this, so let's change it back for the next frame. ////////////////// //GAMEPLAY STUFF// From 7b5fbad6a7c6795338e5d5f4c32b164a6b96f3e6 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Wed, 10 Aug 2016 00:31:16 +0100 Subject: [PATCH 30/42] Changes to match the new default value and to make player acceleration perfectly match what it was previously. --- src/p_saveg.c | 4 ++-- src/p_user.c | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index 964e8b774..55dc9fbc6 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1087,7 +1087,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff |= MD_TRACER; if (mobj->friction != ORIG_FRICTION) diff |= MD_FRICTION; - if (mobj->movefactor != ORIG_FRICTION_FACTOR) + if (mobj->movefactor != FRACUNIT) diff |= MD_MOVEFACTOR; if (mobj->fuse) diff |= MD_FUSE; @@ -2073,7 +2073,7 @@ static void LoadMobjThinker(actionf_p1 thinker) if (diff & MD_MOVEFACTOR) mobj->movefactor = READFIXED(save_p); else - mobj->movefactor = ORIG_FRICTION_FACTOR; + mobj->movefactor = FRACUNIT; if (diff & MD_FUSE) mobj->fuse = READINT32(save_p); if (diff & MD_WATERTOP) diff --git a/src/p_user.c b/src/p_user.c index 12da63e5f..ac95bf572 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4634,8 +4634,8 @@ static void P_3dMovement(player_t *player) acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration; } - // Friction-scaled acceleration... - acceleration = FixedMul(acceleration<mo->movefactor)>>FRACBITS; + if (player->mo->movefactor != FRACUNIT) // Friction-scaled acceleration... + acceleration = FixedMul(acceleration<mo->movefactor)>>FRACBITS; // Forward movement if (player->climbing) @@ -6291,8 +6291,7 @@ static void P_SkidStuff(player_t *player) // If your push angle is more than this close to a full 180 degrees, trigger a skid. if (dang > ANGLE_157h) { - //player->skidtime = TICRATE/2; - player->skidtime = (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; + player->skidtime = (player->mo->movefactor == FRACUNIT) ? TICRATE/2 : (FixedDiv(35<<(FRACBITS-1), FixedSqrt(player->mo->movefactor)))>>FRACBITS; S_StartSound(player->mo, sfx_skid); if (player->panim != PA_WALK) P_SetPlayerMobjState(player->mo, S_PLAY_WALK); From bf7ed0b9e99a843e7333e3efe5371316cf9434ae Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 29 Sep 2016 12:36:20 +0100 Subject: [PATCH 31/42] I call this... the GFZ3 Unfuckening. * GFZ3 Eggmobile's laser won't change its angle when you move left and right anymore. * Changed because its ability to move quickly was extremely punishing for new players (see ProJared's youtube video on the matter). * http://gfycat.com/PassionateUnknownAgama (the twitching on the third laser has been fixed since this was recorded) * GFZ3 Eggmobile will, when too far away from the ground and moving upwards, slow itself down vertically. * This was punishing and annoying for both old and new players alike. * http://gfycat.com/ShabbyAncientEarthworm (old values - the typical settling height is slightly lower now) --- src/p_enemy.c | 16 +++++++++++----- src/p_mobj.c | 11 ++++++++++- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 73ec2a79d..dda12ae7d 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2092,12 +2092,13 @@ void A_Boss1Laser(mobj_t *actor) if (!(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)) { point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET); + point->angle = actor->angle; point->fuse = actor->tics+1; P_SetTarget(&point->target, actor->target); P_SetTarget(&actor->target, point); } } - else if (actor->target && !(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)) + else if (actor->target && actor->target->type != MT_EGGMOBILE_TARGET && !(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)) actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y); if (actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH) @@ -2148,11 +2149,16 @@ void A_Boss1Laser(mobj_t *actor) // var1: // 0 - accelerative focus with friction // 1 - steady focus with fixed movement speed -// var2 = unused +// anything else - don't move +// var2: +// 0 - don't trace target, just move forwards +// & 1 - change horizontal angle +// & 2 - change vertical angle // void A_FocusTarget(mobj_t *actor) { INT32 locvar1 = var1; + INT32 locvar2 = var2; #ifdef HAVE_BLUA if (LUA_CallAction("A_FocusTarget", actor)) return; @@ -2161,9 +2167,9 @@ void A_FocusTarget(mobj_t *actor) if (actor->target) { fixed_t speed = FixedMul(actor->info->speed, actor->scale); - fixed_t dist = R_PointToDist2(actor->x, actor->y, actor->target->x, actor->target->y); - angle_t vangle = R_PointToAngle2(actor->z , 0, actor->target->z + (actor->target->height>>1), dist); - angle_t hangle = R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y); + fixed_t dist = (locvar2 ? R_PointToDist2(actor->x, actor->y, actor->target->x, actor->target->y) : speed+1); + angle_t hangle = ((locvar2 & 1) ? R_PointToAngle2(actor->x, actor->y, actor->target->x, actor->target->y) : actor->angle); + angle_t vangle = ((locvar2 & 2) ? R_PointToAngle2(actor->z , 0, actor->target->z + (actor->target->height>>1), dist) : ANGLE_90); switch(locvar1) { case 0: diff --git a/src/p_mobj.c b/src/p_mobj.c index db80851f3..e1c45dd72 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4436,7 +4436,16 @@ static void P_Boss1Thinker(mobj_t *mobj) return; } - if (mobj->state != &states[mobj->info->spawnstate] && mobj->health > 0 && mobj->flags & MF_FLOAT && !(mobj->flags2 & MF2_SKULLFLY)) + if (mobj->flags2 & MF2_SKULLFLY) + { + if (P_MobjFlip(mobj)*mobj->momz > 0 + && ((mobj->eflags & MFE_VERTICALFLIP + && (mobj->z+mobj->height) < (mobj->ceilingz-(2*mobj->height))) + || (!(mobj->eflags & MFE_VERTICALFLIP) + && mobj->z > (mobj->floorz+(2*mobj->height))))) + mobj->momz = FixedMul(mobj->momz, 60000); + } + else if (mobj->state != &states[mobj->info->spawnstate] && mobj->health > 0 && mobj->flags & MF_FLOAT) mobj->momz = FixedMul(mobj->momz,7*FRACUNIT/8); if (mobj->state == &states[mobj->info->meleestate] From 7e8f7a59d1d4c6903a162f0907c066c51d6ef787 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 29 Sep 2016 12:42:26 +0100 Subject: [PATCH 32/42] This code never ran anyways, so. --- src/p_enemy.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index dda12ae7d..967ad15e7 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2098,8 +2098,9 @@ void A_Boss1Laser(mobj_t *actor) P_SetTarget(&actor->target, point); } } - else if (actor->target && actor->target->type != MT_EGGMOBILE_TARGET && !(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)) - actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y); + /* -- the following was relevant when the MT_EGGMOBILE_TARGET was allowed to move left and right from its path + else if (actor->target && !(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)) + actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y);*/ if (actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH) angle = FixedAngle(FixedDiv(actor->tics*160*FRACUNIT, actor->state->tics*FRACUNIT) + 10*FRACUNIT); From c786dbda78f28b634442dceb86d4022c5e598866 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 29 Sep 2016 13:06:07 +0100 Subject: [PATCH 33/42] Improved the way GFZ3 Eggman slows down in the air when MF2_SKULLFLYing. --- src/p_mobj.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index e1c45dd72..b249e6741 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4438,12 +4438,11 @@ static void P_Boss1Thinker(mobj_t *mobj) if (mobj->flags2 & MF2_SKULLFLY) { - if (P_MobjFlip(mobj)*mobj->momz > 0 - && ((mobj->eflags & MFE_VERTICALFLIP - && (mobj->z+mobj->height) < (mobj->ceilingz-(2*mobj->height))) - || (!(mobj->eflags & MFE_VERTICALFLIP) - && mobj->z > (mobj->floorz+(2*mobj->height))))) - mobj->momz = FixedMul(mobj->momz, 60000); + fixed_t dist = (mobj->eflags & MFE_VERTICALFLIP) + ? ((mobj->ceilingz-(2*mobj->height)) - (mobj->z+mobj->height)) + : (mobj->z - (mobj->floorz+(2*mobj->height))); + if (dist > 0 && P_MobjFlip(mobj)*mobj->momz > 0) + mobj->momz = FixedMul(mobj->momz, FRACUNIT - (dist>>12)); } else if (mobj->state != &states[mobj->info->spawnstate] && mobj->health > 0 && mobj->flags & MF_FLOAT) mobj->momz = FixedMul(mobj->momz,7*FRACUNIT/8); From 5a048df3d53e3507129005dd6ff6538c70d7bc64 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 29 Sep 2016 13:07:24 +0100 Subject: [PATCH 34/42] Messed up the indentation royally. --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index b249e6741..f564a1525 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4439,8 +4439,8 @@ static void P_Boss1Thinker(mobj_t *mobj) if (mobj->flags2 & MF2_SKULLFLY) { fixed_t dist = (mobj->eflags & MFE_VERTICALFLIP) - ? ((mobj->ceilingz-(2*mobj->height)) - (mobj->z+mobj->height)) - : (mobj->z - (mobj->floorz+(2*mobj->height))); + ? ((mobj->ceilingz-(2*mobj->height)) - (mobj->z+mobj->height)) + : (mobj->z - (mobj->floorz+(2*mobj->height))); if (dist > 0 && P_MobjFlip(mobj)*mobj->momz > 0) mobj->momz = FixedMul(mobj->momz, FRACUNIT - (dist>>12)); } From bf01e9e5c3772e99b002290ea12e28f2cb2519c0 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 29 Sep 2016 14:23:58 +0100 Subject: [PATCH 35/42] Bustable material updated to: * Take advantage of FF_MIDDLESTARTCHANCE. * Be bound to the space of a slope. --- src/info.c | 32 ++++++++++++++++---------------- src/p_floor.c | 25 ++++++++++++++++--------- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/info.c b/src/info.c index 9d65c8721..ed5de0125 100644 --- a/src/info.c +++ b/src/info.c @@ -2484,22 +2484,22 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, 1, {A_RockSpawn}, 0, 0, S_ROCKSPAWN}, // S_ROCKSPAWN - {SPR_ROIA, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEA}, // S_ROCKCRUMBLEA - {SPR_ROIB, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEB}, // S_ROCKCRUMBLEB - {SPR_ROIC, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEC}, // S_ROCKCRUMBLEC - {SPR_ROID, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLED}, // S_ROCKCRUMBLED - {SPR_ROIE, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEE}, // S_ROCKCRUMBLEE - {SPR_ROIF, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEF}, // S_ROCKCRUMBLEF - {SPR_ROIG, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEG}, // S_ROCKCRUMBLEG - {SPR_ROIH, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEH}, // S_ROCKCRUMBLEH - {SPR_ROII, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEI}, // S_ROCKCRUMBLEI - {SPR_ROIJ, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEJ}, // S_ROCKCRUMBLEJ - {SPR_ROIK, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEK}, // S_ROCKCRUMBLEK - {SPR_ROIL, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEL}, // S_ROCKCRUMBLEL - {SPR_ROIM, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEM}, // S_ROCKCRUMBLEM - {SPR_ROIN, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEN}, // S_ROCKCRUMBLEN - {SPR_ROIO, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEO}, // S_ROCKCRUMBLEO - {SPR_ROIP, FF_ANIMATE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEP}, // S_ROCKCRUMBLEP + {SPR_ROIA, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEA}, // S_ROCKCRUMBLEA + {SPR_ROIB, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEB}, // S_ROCKCRUMBLEB + {SPR_ROIC, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEC}, // S_ROCKCRUMBLEC + {SPR_ROID, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLED}, // S_ROCKCRUMBLED + {SPR_ROIE, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEE}, // S_ROCKCRUMBLEE + {SPR_ROIF, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEF}, // S_ROCKCRUMBLEF + {SPR_ROIG, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEG}, // S_ROCKCRUMBLEG + {SPR_ROIH, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEH}, // S_ROCKCRUMBLEH + {SPR_ROII, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEI}, // S_ROCKCRUMBLEI + {SPR_ROIJ, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEJ}, // S_ROCKCRUMBLEJ + {SPR_ROIK, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEK}, // S_ROCKCRUMBLEK + {SPR_ROIL, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEL}, // S_ROCKCRUMBLEL + {SPR_ROIM, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEM}, // S_ROCKCRUMBLEM + {SPR_ROIN, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEN}, // S_ROCKCRUMBLEN + {SPR_ROIO, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEO}, // S_ROCKCRUMBLEO + {SPR_ROIP, FF_ANIMATE|FF_MIDDLESTARTCHANCE, -1, {NULL}, 4, 2, S_ROCKCRUMBLEP}, // S_ROCKCRUMBLEP {SPR_SRBA, 0, 5, {A_Look}, 0, 0, S_SRB1_CRAWLA1}, // S_SRB1_CRAWLA1 {SPR_SRBA, 0, 3, {A_Chase}, 0, 0, S_SRB1_CRAWLA3}, // S_SRB1_CRAWLA2 diff --git a/src/p_floor.c b/src/p_floor.c index 5a1b9e78d..5ee08beea 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -15,6 +15,7 @@ #include "doomstat.h" #include "m_random.h" #include "p_local.h" +#include "p_slopes.h" #include "r_state.h" #include "s_sound.h" #include "z_zone.h" @@ -2893,7 +2894,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) size_t topmostvertex = 0, bottommostvertex = 0; fixed_t leftx, rightx; fixed_t topy, bottomy; - fixed_t topz; + fixed_t topz, bottomz; fixed_t widthfactor, heightfactor; fixed_t a, b, c; mobjtype_t type = MT_ROCKCRUMBLE1; @@ -2950,10 +2951,15 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) rightx = sec->lines[rightmostvertex]->v1->x; topy = sec->lines[topmostvertex]->v1->y-(spacing>>1); bottomy = sec->lines[bottommostvertex]->v1->y; - topz = *rover->topheight-(spacing>>1); - widthfactor = (rightx + topy - leftx - bottomy)>>3; - heightfactor = (topz - *rover->bottomheight)>>2; + topz = *rover->topheight-(spacing>>1); + bottomz = *rover->bottomheight; + + if (flags & ML_EFFECT1) + { + widthfactor = (rightx + topy - leftx - bottomy)>>3; + heightfactor = (topz - *rover->bottomheight)>>2; + } for (a = leftx; a < rightx; a += spacing) { @@ -2962,13 +2968,14 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) if (R_PointInSubsector(a, b)->sector == sec) { mobj_t *spawned = NULL; - for (c = topz; c > *rover->bottomheight; c -= spacing) + if (*rover->t_slope) + topz = P_GetZAt(*rover->t_slope, a, b) - (spacing>>1); + if (*rover->b_slope) + bottomz = P_GetZAt(*rover->b_slope, a, b); + + for (c = topz; c > bottomz; c -= spacing) { spawned = P_SpawnMobj(a, b, c, type); - - if (spawned->frame & FF_ANIMATE) - spawned->frame += P_RandomKey(spawned->state->var1); - spawned->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones if (flags & ML_EFFECT1) From 041347bb6a3df5a8ee5a4c21953ad0eb0767572b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Fri, 30 Sep 2016 01:26:23 +0100 Subject: [PATCH 36/42] eslopeless compiling fix --- src/p_floor.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_floor.c b/src/p_floor.c index 5ee08beea..921d11b6c 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -15,7 +15,9 @@ #include "doomstat.h" #include "m_random.h" #include "p_local.h" +#ifdef ESLOPE #include "p_slopes.h" +#endif #include "r_state.h" #include "s_sound.h" #include "z_zone.h" @@ -2968,10 +2970,12 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) if (R_PointInSubsector(a, b)->sector == sec) { mobj_t *spawned = NULL; +#ifdef ESLOPE if (*rover->t_slope) topz = P_GetZAt(*rover->t_slope, a, b) - (spacing>>1); if (*rover->b_slope) bottomz = P_GetZAt(*rover->b_slope, a, b); +#endif for (c = topz; c > bottomz; c -= spacing) { From 05f58df7094ead4e6597fab0caad0e1bf6af04bf Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 22 Nov 2016 16:21:30 +0000 Subject: [PATCH 37/42] Some changes and corrections. * Cleaner A_ParticleSpawn code. * Removed several hacks with Mario blocks, and corrected a mistaken assumption with when the FOF's thinker is being applied. * Made the flashing of T_LaserFlash even less obnoxious. --- src/p_enemy.c | 45 ++++++++++++++++++++++++--------------------- src/p_floor.c | 9 ++++----- src/p_spec.c | 8 ++++---- 3 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 9bc487baa..b688cbf03 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3477,29 +3477,32 @@ void A_ParticleSpawn(mobj_t *actor) if (!actor->health) return; - if ((actor->lastlook) && (actor->threshold)) - { - for (i = 0; i < actor->lastlook; i++) - { - spawn = P_SpawnMobj( - actor->x + FixedMul(FixedMul(actor->friction, actor->scale), FINECOSINE(actor->angle>>ANGLETOFINESHIFT)), - actor->y + FixedMul(FixedMul(actor->friction, actor->scale), FINESINE(actor->angle>>ANGLETOFINESHIFT)), - actor->z, - (mobjtype_t)actor->threshold); - P_SetScale(spawn, actor->scale); - spawn->momz = FixedMul(actor->movefactor, spawn->scale); - spawn->destscale = spawn->scale/100; - spawn->scalespeed = spawn->scale/actor->health; - spawn->tics = (tic_t)actor->health; - spawn->flags2 |= (actor->flags2 & MF2_OBJECTFLIP); - spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones - if (spawn->frame & FF_ANIMATE) - spawn->frame += P_RandomKey(spawn->state->var1); + if (!actor->lastlook) + return; - actor->angle += actor->movedir; - } - actor->angle += (angle_t)actor->movecount; + if (!actor->threshold) + return; + + for (i = 0; i < actor->lastlook; i++) + { + spawn = P_SpawnMobj( + actor->x + FixedMul(FixedMul(actor->friction, actor->scale), FINECOSINE(actor->angle>>ANGLETOFINESHIFT)), + actor->y + FixedMul(FixedMul(actor->friction, actor->scale), FINESINE(actor->angle>>ANGLETOFINESHIFT)), + actor->z, + (mobjtype_t)actor->threshold); + P_SetScale(spawn, actor->scale); + spawn->momz = FixedMul(actor->movefactor, spawn->scale); + spawn->destscale = spawn->scale/100; + spawn->scalespeed = spawn->scale/actor->health; + spawn->tics = (tic_t)actor->health; + spawn->flags2 |= (actor->flags2 & MF2_OBJECTFLIP); + spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones + if (spawn->frame & FF_ANIMATE) + spawn->frame += P_RandomKey(spawn->state->var1); + + actor->angle += actor->movedir; } + actor->angle += (angle_t)actor->movecount; } // Function: A_BunnyHop diff --git a/src/p_floor.c b/src/p_floor.c index 921d11b6c..c3e506fcd 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1135,10 +1135,7 @@ void T_MarioBlock(levelspecthink_t *block) ); if (block->sector->ceilingheight >= block->ceilingwasheight + 32*FRACUNIT) // Go back down now.. - { block->direction = -block->direction; - block->sector->floorspeed = 0; - } else if (block->sector->ceilingheight <= block->ceilingwasheight) { block->sector->ceilingheight = block->ceilingwasheight; @@ -1146,6 +1143,9 @@ void T_MarioBlock(levelspecthink_t *block) P_RemoveThinker(&block->thinker); block->sector->floordata = NULL; block->sector->ceilingdata = NULL; + block->sector->floorspeed = 0; + block->sector->ceilspeed = 0; + block->direction = 0; } for (i = -1; (i = P_FindSectorFromTag((INT16)block->vars[0], i)) >= 0 ;) @@ -1802,7 +1802,7 @@ static mobj_t *SearchMarioNode(msecnode_t *node) void T_MarioBlockChecker(levelspecthink_t *block) { line_t *masterline = block->sourceline; - if (block->sector->floorspeed) // Don't update the textures when the block's being bumped upwards. + if (block->vars[2] == 1) // Don't update the textures when the block's being bumped upwards. return; if (SearchMarioNode(block->sector->touching_thinglist)) { @@ -3181,7 +3181,6 @@ INT32 EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher) block->thinker.function.acp1 = (actionf_p1)T_MarioBlock; // Set up the fields - roversec->floorspeed = 1; // Flag to prevent side changing. block->sector = roversec; block->vars[0] = sector->tag; // actionsector block->vars[1] = 4*FRACUNIT; // speed diff --git a/src/p_spec.c b/src/p_spec.c index 760bf2363..a8561997b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4989,7 +4989,7 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f if ((flags & FF_MARIO)) { - if (!(master->flags & ML_NOCLIMB)) // Don't change the textures of a brick block, just a question block + if (!(flags & FF_SHATTERBOTTOM)) // Don't change the textures of a brick block, just a question block P_AddBlockThinker(sec2, master); CheckForMarioBlocks = true; } @@ -5348,12 +5348,12 @@ void T_LaserFlash(laserthink_t *flash) if (!ffloor || !(ffloor->flags & FF_EXISTS)) return; - if (leveltime & 1) + if (leveltime & 2) //ffloor->flags |= FF_RENDERALL; - ffloor->alpha = 0xC0; + ffloor->alpha = 0xB0; else //ffloor->flags &= ~FF_RENDERALL; - ffloor->alpha = 0x60; + ffloor->alpha = 0x90; sourcesec = ffloor->master->frontsector; // Less to type! From a9c68a78e9f61a06fe130c6d00b958c355635888 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Thu, 24 Nov 2016 15:23:13 +0000 Subject: [PATCH 38/42] Slope correction. --- src/p_floor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_floor.c b/src/p_floor.c index c3e506fcd..e8c3a6053 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2985,7 +2985,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover) if (flags & ML_EFFECT1) { P_InstaThrust(spawned, R_PointToAngle2(sec->soundorg.x, sec->soundorg.y, a, b), FixedDiv(P_AproxDistance(a - sec->soundorg.x, b - sec->soundorg.y), widthfactor)); - P_SetObjectMomZ(spawned, FixedDiv((c - *rover->bottomheight), heightfactor), false); + P_SetObjectMomZ(spawned, FixedDiv((c - bottomz), heightfactor), false); } spawned->fuse = lifetime; From f8961d396fc144b6b65b9ff063c25691e24ab4b9 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Tue, 13 Dec 2016 22:42:47 +0000 Subject: [PATCH 39/42] Initial commit of what I've done so far, DOES NOT COMPILE --- src/p_spec.c | 14 ++++++++++++++ src/p_spec.h | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/p_spec.c b/src/p_spec.c index 6e0ac7486..5afa38dd3 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -108,6 +108,7 @@ static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinker static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec); static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer); static void P_AddSpikeThinker(sector_t *sec, INT32 referrer); +static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee) //SoM: 3/7/2000: New sturcture without limits. @@ -5762,6 +5763,19 @@ void P_SpawnSpecials(INT32 fromnetsave) P_AddBridgeThinker(&lines[i], §ors[s]);*/ break; + case 66: // Displace floor by front sector + for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + P_AddPlaneDisplaceThinker(pd_floor, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s); + break; + case 67: // Displace ceiling by front sector + for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + P_AddPlaneDisplaceThinker(pd_ceiling, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s); + break; + case 68: // Displace both floor AND ceiling by front sector + for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + P_AddPlaneDisplaceThinker(pd_both, P_AproxDistance(lines[i].dx, lines[i].dy)>>8, sides[lines[i].sidenum[0]].sector-sectors, s); + break; + case 100: // FOF (solid, opaque, shadows) P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERALL|FF_CUTLEVEL, secthinkers); break; diff --git a/src/p_spec.h b/src/p_spec.h index a8f9ac492..6e173eec5 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -448,6 +448,26 @@ void T_Disappear(disappear_t *d); void T_Pusher(pusher_t *p); mobj_t *P_GetPushThing(UINT32 s); +// Plane displacement +typedef struct +{ + thinker_t thinker; ///< Thinker structure for plane displacement effect. + INT32 affectee; ///< Number of affected sector. + INT32 control; ///< Control sector used to control plane positions. + fixed_t last_height; ///< Last known height of control sector. + fixed_t speed; ///< Plane movement speed. + /** Types of plane displacement effects. + */ + enum + { + pd_floor, ///< Displace floor. + pd_ceiling, ///< Displace ceiling. + pd_both, ///< Displace both floor AND ceiling. + } type; +} planedisplace_t; + +void T_PlaneDisplace(planedisplace_t *pd); + void P_CalcHeight(player_t *player); sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo); From 5358359ddb830d100f8c4eac32abf52df102becc Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 5 Jan 2017 20:29:48 +0000 Subject: [PATCH 40/42] Added the thinker creation function and the thinker itself, we now have functional plane displacement thinkers! --- src/p_floor.c | 23 +++++++++++++++++++++++ src/p_spec.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/p_floor.c b/src/p_floor.c index 8f51698cc..000da302f 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2520,6 +2520,29 @@ void T_CameraScanner(elevator_t *elevator) } } +void T_PlaneDisplace(planedisplace_t *pd) +{ + sector_t *control, *target; + INT32 direction; + fixed_t diff; + + control = §ors[pd->control]; + target = §ors[pd->affectee]; + + if (control->floorheight == pd->last_height) + return; // no change, no movement + + direction = (control->floorheight > pd->last_height) ? 1 : -1; + diff = FixedMul(control->floorheight-pd->last_height, pd->speed); + + if (pd->type == pd_floor || pd->type == pd_both) + T_MovePlane(target, INT32_MAX/2, target->floorheight+diff, 0, 0, direction); // move floor + if (pd->type == pd_ceiling || pd->type == pd_both) + T_MovePlane(target, INT32_MAX/2, target->ceilingheight+diff, 0, 1, direction); // move ceiling + + pd->last_height = control->floorheight; +} + // // EV_DoFloor // diff --git a/src/p_spec.c b/src/p_spec.c index 5afa38dd3..703d49f9a 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -108,7 +108,7 @@ static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinker static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec); static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer); static void P_AddSpikeThinker(sector_t *sec, INT32 referrer); -static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee) +static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee); //SoM: 3/7/2000: New sturcture without limits. @@ -5055,6 +5055,33 @@ static inline void P_AddBridgeThinker(line_t *sourceline, sector_t *sec) } */ +/** + * Adds a plane displacement thinker. + * Whenever the "control" sector moves, + * the "affectee" sector's floor or ceiling plane moves too! + * + * \param speed Rate of movement relative to control sector + * \param control Control sector. + * \param affectee Target sector. + * \sa P_SpawnSpecials, T_PlaneDisplace + * \author Monster Iestyn + */ +static void P_AddPlaneDisplaceThinker(INT32 type, fixed_t speed, INT32 control, INT32 affectee) +{ + planedisplace_t *displace; + + // create and initialize new displacement thinker + displace = Z_Calloc(sizeof (*displace), PU_LEVSPEC, NULL); + P_AddThinker(&displace->thinker); + + displace->thinker.function.acp1 = (actionf_p1)T_PlaneDisplace; + displace->affectee = affectee; + displace->control = control; + displace->last_height = sectors[control].floorheight; + displace->speed = speed; + displace->type = type; +} + /** Adds a Mario block thinker, which changes the block's texture between blank * and ? depending on whether it has contents. * Needed in case objects respawn inside. From 020234cc5f473e6f99b33e97a6f23210cf529376 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 16 Jan 2017 17:33:07 +0000 Subject: [PATCH 41/42] Fixed crash bug. It's weird that linedefs' backsides aren't NULL but are instead 0xFFFF when invalid, so instead I used something which DOES take null pointers as a parameter. --- src/p_floor.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_floor.c b/src/p_floor.c index f1678c934..6498fbda8 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1810,17 +1810,17 @@ void T_MarioBlockChecker(levelspecthink_t *block) if (SearchMarioNode(block->sector->touching_thinglist)) { sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].bottomtexture; // Update textures - if (masterline->sidenum[1]) + if (masterline->backsector) { - sides[masterline->sidenum[0]].sector->ceilingpic = sides[masterline->sidenum[0]].sector->floorpic = sides[masterline->sidenum[1]].sector->ceilingpic; // Update flats to be backside's ceiling if there's a back sector, otherwise leave them alone + block->sector->ceilingpic = block->sector->floorpic = masterline->backsector->ceilingpic; // Update flats to be backside's ceiling } } else { sides[masterline->sidenum[0]].midtexture = sides[masterline->sidenum[0]].toptexture; - if (masterline->sidenum[1]) + if (masterline->backsector) { - sides[masterline->sidenum[0]].sector->ceilingpic = sides[masterline->sidenum[0]].sector->floorpic = sides[masterline->sidenum[1]].sector->floorpic; // Update flats to be backside's floor if there's a back sector, otherwise leave them alone + block->sector->ceilingpic = block->sector->floorpic = masterline->backsector->floorpic; // Update flats to be backside's floor } } } From c9b623390f1f6ee9bc33a2b47349db3c6b4db00a Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 20 Jan 2017 20:17:40 +0000 Subject: [PATCH 42/42] Add code for saving/loading planedisplace_t thinkers to/from $$$.sav --- src/p_saveg.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/p_saveg.c b/src/p_saveg.c index bdeb6ff97..450f8c904 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -974,6 +974,7 @@ typedef enum tc_noenemies, tc_eachtime, tc_disappear, + tc_planedisplace, #ifdef POLYOBJECTS tc_polyrotate, // haleyjd 03/26/06: polyobjects tc_polymove, @@ -1537,6 +1538,21 @@ static void SaveDisappearThinker(const thinker_t *th, const UINT8 type) WRITEINT32(save_p, ht->exists); } +// +// SavePlaneDisplaceThinker +// +// Saves a planedisplace_t thinker +// +static void SavePlaneDisplaceThinker(const thinker_t *th, const UINT8 type) +{ + const planedisplace_t *ht = (const void *)th; + WRITEUINT8(save_p, type); + WRITEINT32(save_p, ht->affectee); + WRITEINT32(save_p, ht->control); + WRITEFIXED(save_p, ht->last_height); + WRITEFIXED(save_p, ht->speed); + WRITEUINT8(save_p, ht->type); +} #ifdef POLYOBJECTS // @@ -1818,6 +1834,12 @@ static void P_NetArchiveThinkers(void) SaveDisappearThinker(th, tc_disappear); continue; } + + else if (th->function.acp1 == (actionf_p1)T_PlaneDisplace) + { + SavePlaneDisplaceThinker(th, tc_planedisplace); + continue; + } #ifdef POLYOBJECTS else if (th->function.acp1 == (actionf_p1)T_PolyObjRotate) { @@ -2486,6 +2508,23 @@ static inline void LoadDisappearThinker(actionf_p1 thinker) P_AddThinker(&ht->thinker); } +// +// LoadPlaneDisplaceThinker +// +// Loads a planedisplace_t thinker +// +static inline void LoadPlaneDisplaceThinker(actionf_p1 thinker) +{ + planedisplace_t *ht = Z_Malloc(sizeof (*ht), PU_LEVSPEC, NULL); + ht->thinker.function.acp1 = thinker; + ht->affectee = READINT32(save_p); + ht->control = READINT32(save_p); + ht->last_height = READFIXED(save_p); + ht->speed = READFIXED(save_p); + ht->type = READUINT8(save_p); + P_AddThinker(&ht->thinker); +} + #ifdef POLYOBJECTS // @@ -2769,6 +2808,10 @@ static void P_NetUnArchiveThinkers(void) case tc_disappear: LoadDisappearThinker((actionf_p1)T_Disappear); break; + + case tc_planedisplace: + LoadPlaneDisplaceThinker((actionf_p1)T_PlaneDisplace); + break; #ifdef POLYOBJECTS case tc_polyrotate: LoadPolyrotatetThinker((actionf_p1)T_PolyObjRotate);