From ca43ea734563cd044f1bab40d34764fb281e8b69 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 20 Mar 2008 21:12:03 +0000 Subject: [PATCH] - Fixed: A_CustomMissile with aimmode 2 ignored spawnofs_xy. - Changed savegame versioning so that the written version is never lower than the minmum one reported as compatible. - Added mirrored movement modes for linked sectors. - Added Eternity-style initialization for linked sectors as a new subtype of Static_Init. - Added linked sectors. The control sector determines how they move but if any one of the linked sectors is blocked, movement for all linked sectors will be affected. This will allow lifts consisting out of more than one sector without the risk of breaking them if only one of the sectors is blocked. - Fixed: A_Mushroom created an actor on the stack. SVN r825 (trunk) --- docs/rh-log.txt | 14 + src/actionspecials.h | 1 + src/dsectoreffect.cpp | 6 + src/g_doom/a_fatso.cpp | 13 +- src/p_3dmidtex.h | 6 + src/p_linkedsectors.cpp | 398 +++++++++++++++++++++++++++ src/p_lnspec.cpp | 18 +- src/p_lnspec.h | 1 + src/p_saveg.cpp | 4 +- src/p_sectors.cpp | 17 +- src/p_setup.cpp | 4 + src/p_spec.cpp | 12 + src/r_defs.h | 17 +- src/r_main.cpp | 36 ++- src/r_main.h | 8 +- src/r_state.h | 7 + src/thingdef/thingdef_codeptr.cpp | 4 + src/version.h | 6 +- zdoom.vcproj | 430 +++++++++++++++--------------- 19 files changed, 756 insertions(+), 246 deletions(-) create mode 100644 src/p_linkedsectors.cpp diff --git a/docs/rh-log.txt b/docs/rh-log.txt index bc123c783..6b590a69d 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,17 @@ +March 20, 2008 (Changes by Graf Zahl) +- Fixed: A_CustomMissile with aimmode 2 ignored spawnofs_xy. +- Changed savegame versioning so that the written version is never lower + than the minmum one reported as compatible. +- Added mirrored movement modes for linked sectors. +- Added Eternity-style initialization for linked sectors as a new subtype + of Static_Init. +- Added linked sectors. The control sector determines how they move but if + any one of the linked sectors is blocked, movement for all linked sectors + will be affected. This will allow lifts consisting out of more than one + sector without the risk of breaking them if only one of the sectors is + blocked. +- Fixed: A_Mushroom created an actor on the stack. + March 19, 2008 - Fixed: lempar.c needs to specify the __cdecl calling convention for malloc and free under VC++. diff --git a/src/actionspecials.h b/src/actionspecials.h index efe7ad58e..3821b5e3b 100644 --- a/src/actionspecials.h +++ b/src/actionspecials.h @@ -48,6 +48,7 @@ DEFINE_SPECIAL(Ceiling_MoveToValue, 47, 3, 4) DEFINE_SPECIAL(Sector_Attach3dMidtex, 48, -1, -1) DEFINE_SPECIAL(GlassBreak, 49, 0, 1) DEFINE_SPECIAL(ExtraFloor_LightOnly, 50, -1, -1) +DEFINE_SPECIAL(Sector_SetLink, 51, 4, 4) DEFINE_SPECIAL(Plat_PerpetualRaise, 60, 3, 3) DEFINE_SPECIAL(Plat_Stop, 61, 1, 1) diff --git a/src/dsectoreffect.cpp b/src/dsectoreffect.cpp index e94050390..11a61c4f5 100644 --- a/src/dsectoreffect.cpp +++ b/src/dsectoreffect.cpp @@ -111,6 +111,12 @@ bool DMover::MoveAttached(int crush, fixed_t move, int floorOrCeiling, bool rese P_Scroll3dMidtex(m_Sector, crush, -move, !!floorOrCeiling); return false; } + if (!P_MoveLinkedSectors(m_Sector, crush, move, !!floorOrCeiling) && resetfailed) + { + P_MoveLinkedSectors(m_Sector, crush, -move, !!floorOrCeiling); + P_Scroll3dMidtex(m_Sector, crush, -move, !!floorOrCeiling); + return false; + } return true; } diff --git a/src/g_doom/a_fatso.cpp b/src/g_doom/a_fatso.cpp index d21e65d30..b5e686f46 100644 --- a/src/g_doom/a_fatso.cpp +++ b/src/g_doom/a_fatso.cpp @@ -134,15 +134,17 @@ void A_Mushroom (AActor *actor) A_Explode (actor); // First make normal explosion // Now launch mushroom cloud + AActor *target = Spawn("Mapspot", 0, 0, 0, NO_REPLACE); // We need something to aim at. + target->height = actor->height; for (i = -n; i <= n; i += 8) { for (j = -n; j <= n; j += 8) { - AActor target = *actor, *mo; - target.x += i << FRACBITS; // Aim in many directions from source - target.y += j << FRACBITS; - target.z += P_AproxDistance(i,j) << (FRACBITS+2); // Aim up fairly high - mo = P_SpawnMissile (actor, &target, spawntype); // Launch fireball + AActor *mo; + target->x = actor->x + (i << FRACBITS); // Aim in many directions from source + target->y = actor->y + (j << FRACBITS); + target->z = actor->z + (P_AproxDistance(i,j) << (FRACBITS+2)); // Aim up fairly high + mo = P_SpawnMissile (actor, target, spawntype); // Launch fireball if (mo != NULL) { mo->momx >>= 1; @@ -152,4 +154,5 @@ void A_Mushroom (AActor *actor) } } } + target->Destroy(); } diff --git a/src/p_3dmidtex.h b/src/p_3dmidtex.h index 215da2b3d..0b9497ec7 100644 --- a/src/p_3dmidtex.h +++ b/src/p_3dmidtex.h @@ -15,5 +15,11 @@ bool P_GetMidTexturePosition(const line_t *line, int sideno, fixed_t *ptextop, f bool P_Check3dMidSwitch(AActor *actor, line_t *line, int side); bool P_LineOpening_3dMidtex(AActor *thing, const line_t *linedef, fixed_t &opentop, fixed_t &openbottom); +bool P_MoveLinkedSectors(sector_t *sector, int crush, fixed_t move, bool ceiling); +void P_StartLinkedSectorInterpolations(sector_t *sector, bool ceiling); +void P_StopLinkedSectorInterpolations(sector_t *sector, bool ceiling); +bool P_AddSectorLinks(sector_t *control, int tag, INTBOOL ceiling, int movetype); +void P_AddSectorLinksByID(sector_t *control, int id, INTBOOL ceiling); + #endif diff --git a/src/p_linkedsectors.cpp b/src/p_linkedsectors.cpp new file mode 100644 index 000000000..b24ff3d15 --- /dev/null +++ b/src/p_linkedsectors.cpp @@ -0,0 +1,398 @@ +/* +** p_linkedsectors.cpp +** +** Linked sector movement +** +**--------------------------------------------------------------------------- +** Copyright 2008 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#include "templates.h" +#include "p_local.h" +#include "p_lnspec.h" + +enum +{ + // The different movement types. + LINK_NONE=0, + LINK_FLOOR=1, + LINK_CEILING=2, + LINK_BOTH=3, + LINK_FLOORMIRRORFLAG=4, + LINK_CEILINGMIRRORFLAG=8, + + LINK_FLOORMIRROR=5, + LINK_CEILINGMIRROR=10, + LINK_BOTHMIRROR=15, + + LINK_FLAGMASK = 15 + +}; + + +//============================================================================ +// +// Checks whether the other sector is linked to this one +// Used to ignore linked sectors in the FindNextLowest/Highest* +// functions +// +// NOTE: After looking at Eternity's code I discovered that this check +// is not done for the FindNext* function but instead only for +// FindLowestCeilingSurrounding where IMO it makes much less sense +// because the most frequent use of this feature is most likely lifts +// with a more detailed surface. Needs to be investigated! +// +//============================================================================ + +bool sector_t::IsLinked(sector_t *other, bool ceiling) const +{ + extsector_t::linked::plane &scrollplane = ceiling? e->Linked.Ceiling : e->Linked.Floor; + int flag = ceiling? LINK_CEILING : LINK_FLOOR; + + for(unsigned i = 0; i < scrollplane.Sectors.Size(); i++) + { + if (other == scrollplane.Sectors[i].Sector && scrollplane.Sectors[i].Type & flag) return true; + } + return false; +} + + +//============================================================================ +// +// Helper functions for P_MoveLinkedSectors +// +//============================================================================ + +static bool MoveCeiling(sector_t *sector, int crush, fixed_t move) +{ + sector->ceilingplane.ChangeHeight (move); + sector->ceilingtexz += move; + + if (P_ChangeSector(sector, crush, move, 1)) return false; + + // Don't let the ceiling go below the floor + if ((sector->ceilingplane.a | sector->ceilingplane.b | + sector->floorplane.a | sector->floorplane.b) == 0 && + sector->floortexz > sector->ceilingtexz) return false; + + return true; +} + +static bool MoveFloor(sector_t *sector, int crush, fixed_t move) +{ + sector->floorplane.ChangeHeight (move); + sector->floortexz += move; + + if (P_ChangeSector(sector, crush, move, 0)) return false; + + // Don't let the floor go above the ceiling + if ((sector->ceilingplane.a | sector->ceilingplane.b | + sector->floorplane.a | sector->floorplane.b) == 0 && + sector->floortexz > sector->ceilingtexz) return false; + + return true; +} + +//============================================================================ +// +// P_MoveLinkedSectors +// +// Moves all floors/ceilings linked to the control sector +// Important: All sectors must complete their movement +// even if a previous one already failed. +// +//============================================================================ + +bool P_MoveLinkedSectors(sector_t *sector, int crush, fixed_t move, bool ceiling) +{ + extsector_t::linked::plane &scrollplane = ceiling? sector->e->Linked.Ceiling : sector->e->Linked.Floor; + bool ok = true; + + for(unsigned i = 0; i < scrollplane.Sectors.Size(); i++) + { + switch(scrollplane.Sectors[i].Type) + { + case LINK_FLOOR: + ok &= MoveFloor(scrollplane.Sectors[i].Sector, crush, move); + break; + + case LINK_CEILING: + ok &= MoveCeiling(scrollplane.Sectors[i].Sector, crush, move); + break; + + case LINK_BOTH: + if (move < 0) + { + ok &= MoveFloor(scrollplane.Sectors[i].Sector, crush, move); + ok &= MoveCeiling(scrollplane.Sectors[i].Sector, crush, move); + } + else + { + ok &= MoveCeiling(scrollplane.Sectors[i].Sector, crush, move); + ok &= MoveFloor(scrollplane.Sectors[i].Sector, crush, move); + } + break; + + case LINK_FLOORMIRROR: + ok &= MoveFloor(scrollplane.Sectors[i].Sector, crush, -move); + break; + + case LINK_CEILINGMIRROR: + ok &= MoveCeiling(scrollplane.Sectors[i].Sector, crush, -move); + break; + + case LINK_BOTHMIRROR: + if (move > 0) + { + ok &= MoveFloor(scrollplane.Sectors[i].Sector, crush, -move); + ok &= MoveCeiling(scrollplane.Sectors[i].Sector, crush, -move); + } + else + { + ok &= MoveCeiling(scrollplane.Sectors[i].Sector, crush, -move); + ok &= MoveFloor(scrollplane.Sectors[i].Sector, crush, -move); + } + break; + + case LINK_FLOOR+LINK_CEILINGMIRROR: + ok &= MoveFloor(scrollplane.Sectors[i].Sector, crush, move); + ok &= MoveCeiling(scrollplane.Sectors[i].Sector, crush, -move); + break; + + case LINK_CEILING+LINK_FLOORMIRROR: + ok &= MoveFloor(scrollplane.Sectors[i].Sector, crush, -move); + ok &= MoveCeiling(scrollplane.Sectors[i].Sector, crush, move); + break; + + default: + // all other types are invalid and have to be elimintated in the attachment stage + break; + } + } + return ok; +} + +//============================================================================ +// +// P_StartLinkedSectorInterpolations +// +// Starts interpolators for every sector plane is being changed by moving +// this sector +// +//============================================================================ + +void P_StartLinkedSectorInterpolations(sector_t *sector, bool ceiling) +{ + extsector_t::linked::plane &scrollplane = ceiling? sector->e->Linked.Ceiling : sector->e->Linked.Floor; + + for(unsigned i = 0; i < scrollplane.Sectors.Size(); i++) + { + if (scrollplane.Sectors[i].Type & LINK_FLOOR) + { + setinterpolation(INTERP_SectorFloor, scrollplane.Sectors[i].Sector, false); + } + if (scrollplane.Sectors[i].Type & LINK_CEILING) + { + setinterpolation(INTERP_SectorCeiling, scrollplane.Sectors[i].Sector, false); + } + } +} + +//============================================================================ +// +// P_StopLinkedSectorInterpolations +// +// Stops interpolators for every sector plane is being changed by moving +// this sector +// +//============================================================================ + +void P_StopLinkedSectorInterpolations(sector_t *sector, bool ceiling) +{ + extsector_t::linked::plane &scrollplane = ceiling? sector->e->Linked.Ceiling : sector->e->Linked.Floor; + + for(unsigned i = 0; i < scrollplane.Sectors.Size(); i++) + { + if (scrollplane.Sectors[i].Type & LINK_FLOOR) + { + stopinterpolation(INTERP_SectorFloor, scrollplane.Sectors[i].Sector, false); + } + if (scrollplane.Sectors[i].Type & LINK_CEILING) + { + stopinterpolation(INTERP_SectorCeiling, scrollplane.Sectors[i].Sector, false); + } + } +} + + + +//============================================================================ +// +// AddSingleSector +// +// Adds a single sector to a scroll plane. Checks for invalid +// flag combinations if the sector is already added and removes it if necessary. +// +//============================================================================ + +static void AddSingleSector(extsector_t::linked::plane &scrollplane, sector_t *sector, int movetype) +{ + // First we have to check the list if the sector is already in it + // If so the move type may have to be adjusted or the link to be removed + + for(unsigned i = 0; i < scrollplane.Sectors.Size(); i++) + { + if (scrollplane.Sectors[i].Sector == sector) + { + int oldtype = scrollplane.Sectors[i].Type; + + if ((oldtype & (LINK_FLOOR|LINK_FLOORMIRROR)) && + (movetype & (LINK_FLOORMIRROR|LINK_FLOOR))) + { + // Invalid combination for floor. + movetype &= ~(LINK_FLOOR + LINK_FLOORMIRROR); + } + + if ((oldtype & (LINK_CEILING|LINK_CEILINGMIRROR)) && + (movetype == LINK_CEILINGMIRROR || movetype == LINK_CEILING)) + { + // Invalid combination for CEILING. + movetype &= ~(LINK_CEILING + LINK_CEILINGMIRROR); + } + + scrollplane.Sectors[i].Type |= movetype; + return; + } + } + + // The sector hasn't been attached yet so do it now + + FLinkedSector newlink = {sector, movetype}; + scrollplane.Sectors.Push(newlink); +} + +//============================================================================ +// +// RemoveTaggedSectors +// +// Remove all sectors with the given tag from the link list +// +//============================================================================ + +static void RemoveTaggedSectors(extsector_t::linked::plane &scrollplane, int tag) +{ + for(int i = scrollplane.Sectors.Size()-1; i>=0; i--) + { + if (scrollplane.Sectors[i].Sector->tag == tag) + { + scrollplane.Sectors.Delete(i); + } + } +} + + + +//============================================================================ +// +// P_AddSectorLink +// +// Links sector planes to a control sector based on the sector's tag +// +//============================================================================ + +bool P_AddSectorLinks(sector_t *control, int tag, INTBOOL ceiling, int movetype) +{ + int param = movetype; + + // can't be done if the control sector is moving. + if ((ceiling && control->ceilingdata) || (!ceiling && control->floordata)) return false; + + // Make sure we have only valid combinations + movetype &= LINK_FLAGMASK; + if ((movetype & LINK_FLOORMIRROR) == LINK_FLOORMIRRORFLAG) movetype &= ~LINK_FLOORMIRRORFLAG; + if ((movetype & LINK_CEILINGMIRROR) == LINK_CEILINGMIRRORFLAG) movetype &= ~LINK_CEILINGMIRRORFLAG; + + // Don't remove any sector if the parameter is invalid. + // Addition may still be performed based on the given value. + if (param != 0 && movetype == 0) return false; + + extsector_t::linked::plane &scrollplane = ceiling? control->e->Linked.Ceiling : control->e->Linked.Floor; + + if (movetype > 0) + { + for(int sec = -1; (sec = P_FindSectorFromTag(tag, sec)) >= 0; ) + { + // Don't attach to self! + if (control != §ors[sec]) + { + AddSingleSector(scrollplane, §ors[sec], movetype); + } + } + } + else + { + RemoveTaggedSectors(scrollplane, tag); + } + return true; +} + +//============================================================================ +// +// P_AddSectorLinksByID +// +// Links sector planes to a control sector based on a control linedef +// touching the sectors. This is the method Eternity uses and is here +// mostly so that the Eternity line types can be emulated +// +//============================================================================ + +void P_AddSectorLinksByID(sector_t *control, int id, INTBOOL ceiling) +{ + extsector_t::linked::plane &scrollplane = ceiling? control->e->Linked.Ceiling : control->e->Linked.Floor; + + for(int line = -1; (line = P_FindLineFromID(id, line)) >= 0; ) + { + line_t *ld = &lines[line]; + + if (ld->special == Static_Init && ld->args[1] == Init_SectorLink) + { + int movetype = ld->args[3]; + + // Make sure we have only valid combinations + movetype &= LINK_FLAGMASK; + if ((movetype & LINK_FLOORMIRROR) == LINK_FLOORMIRRORFLAG) movetype &= ~LINK_FLOORMIRRORFLAG; + if ((movetype & LINK_CEILINGMIRROR) == LINK_CEILINGMIRRORFLAG) movetype &= ~LINK_CEILINGMIRRORFLAG; + + if (movetype != 0 && ld->frontsector != NULL && ld->frontsector != control) + { + AddSingleSector(scrollplane, ld->frontsector, movetype); + } + } + } +} diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index e20dd4df8..cbef22134 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -53,6 +53,7 @@ #include "p_conversation.h" #include "a_strifeglobal.h" #include "r_translate.h" +#include "p_3dmidtex.h" #define FUNC(a) static int a (line_t *ln, AActor *it, bool backSide, \ int arg0, int arg1, int arg2, int arg3, int arg4) @@ -1873,6 +1874,21 @@ FUNC(LS_Sector_SetFriction) return true; } +FUNC(LS_Sector_SetLink) +// Sector_SetLink (controltag, linktag, floor/ceiling, movetype) +{ + if (arg0 != 0) // control tag == 0 is for static initialization and must not be handled here + { + int control = P_FindSectorFromTag(arg0, -1); + if (control != 0) + { + return P_AddSectorLinks(§ors[control], arg1, arg2, arg3); + } + } + return false; +} + + static void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy) { if ((dx | dy) == 0) @@ -2843,7 +2859,7 @@ lnSpecFunc LineSpecials[256] = LS_NOP, // Sector_Attach3dMidtex LS_GlassBreak, LS_NOP, // 50: ExtraFloor_LightOnly - LS_NOP, // 51 + LS_Sector_SetLink, LS_NOP, // 52 LS_NOP, // 53 LS_NOP, // 54 diff --git a/src/p_lnspec.h b/src/p_lnspec.h index 75f1a169b..e6d705618 100644 --- a/src/p_lnspec.h +++ b/src/p_lnspec.h @@ -47,6 +47,7 @@ typedef enum { Init_Gravity = 0, Init_Color = 1, Init_Damage = 2, + Init_SectorLink = 3, NUM_STATIC_INITS, Init_TransferSky = 255 } staticinit_t; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 90a05a33b..ac95be1f3 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -413,7 +413,9 @@ void extsector_t::Serialize(FArchive &arc) arc << Midtex.Floor.AttachedLines << Midtex.Floor.AttachedSectors << Midtex.Ceiling.AttachedLines - << Midtex.Ceiling.AttachedSectors; + << Midtex.Ceiling.AttachedSectors + << Linked.Floor.Sectors + << Linked.Ceiling.Sectors; } // diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 7f8f98b13..3d951957a 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -25,6 +25,7 @@ #include "p_spec.h" #include "c_cvars.h" + // [RH] // P_NextSpecialSector() // @@ -170,7 +171,7 @@ fixed_t sector_t::FindNextHighestFloor (vertex_t **v) const { ofloor = other->floorplane.ZatPoint (check->v1); floor = floorplane.ZatPoint (check->v1); - if (ofloor > floor && ofloor - floor < heightdiff) + if (ofloor > floor && ofloor - floor < heightdiff && !IsLinked(other, false)) { heightdiff = ofloor - floor; height = ofloor; @@ -178,7 +179,7 @@ fixed_t sector_t::FindNextHighestFloor (vertex_t **v) const } ofloor = other->floorplane.ZatPoint (check->v2); floor = floorplane.ZatPoint (check->v2); - if (ofloor > floor && ofloor - floor < heightdiff) + if (ofloor > floor && ofloor - floor < heightdiff && !IsLinked(other, false)) { heightdiff = ofloor - floor; height = ofloor; @@ -227,7 +228,7 @@ fixed_t sector_t::FindNextLowestFloor (vertex_t **v) const other = other; ofloor = other->floorplane.ZatPoint (check->v1); floor = floorplane.ZatPoint (check->v1); - if (ofloor < floor && floor - ofloor < heightdiff) + if (ofloor < floor && floor - ofloor < heightdiff && !IsLinked(other, false)) { heightdiff = floor - ofloor; height = ofloor; @@ -235,7 +236,7 @@ fixed_t sector_t::FindNextLowestFloor (vertex_t **v) const } ofloor = other->floorplane.ZatPoint (check->v2); floor = floorplane.ZatPoint (check->v2); - if (ofloor < floor && floor - ofloor < heightdiff) + if (ofloor < floor && floor - ofloor < heightdiff && !IsLinked(other, false)) { heightdiff = floor - ofloor; height = ofloor; @@ -282,7 +283,7 @@ fixed_t sector_t::FindNextLowestCeiling (vertex_t **v) const { oceil = other->ceilingplane.ZatPoint (check->v1); ceil = ceilingplane.ZatPoint (check->v1); - if (oceil < ceil && ceil - oceil < heightdiff) + if (oceil < ceil && ceil - oceil < heightdiff && !IsLinked(other, true)) { heightdiff = ceil - oceil; height = oceil; @@ -290,7 +291,7 @@ fixed_t sector_t::FindNextLowestCeiling (vertex_t **v) const } oceil = other->ceilingplane.ZatPoint (check->v2); ceil = ceilingplane.ZatPoint (check->v2); - if (oceil < ceil && ceil - oceil < heightdiff) + if (oceil < ceil && ceil - oceil < heightdiff && !IsLinked(other, true)) { heightdiff = ceil - oceil; height = oceil; @@ -336,7 +337,7 @@ fixed_t sector_t::FindNextHighestCeiling (vertex_t **v) const { oceil = other->ceilingplane.ZatPoint (check->v1); ceil = ceilingplane.ZatPoint (check->v1); - if (oceil > ceil && oceil - ceil < heightdiff) + if (oceil > ceil && oceil - ceil < heightdiff && !IsLinked(other, true)) { heightdiff = oceil - ceil; height = oceil; @@ -344,7 +345,7 @@ fixed_t sector_t::FindNextHighestCeiling (vertex_t **v) const } oceil = other->ceilingplane.ZatPoint (check->v2); ceil = ceilingplane.ZatPoint (check->v2); - if (oceil > ceil && oceil - ceil < heightdiff) + if (oceil > ceil && oceil - ceil < heightdiff && !IsLinked(other, true)) { heightdiff = oceil - ceil; height = oceil; diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 11c50d1c8..8c3d7a44d 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1792,6 +1792,10 @@ void P_AdjustLine (line_t *ld) case Polyobj_ExplicitLine: ld->id = ld->args[4]; break; + + case Static_Init: + if (ld->args[1] == Init_SectorLink) ld->id = ld->args[0]; + break; } } } diff --git a/src/p_spec.cpp b/src/p_spec.cpp index c083383f1..620b605f9 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1004,6 +1004,13 @@ void P_SpawnSpecials (void) P_Attach3dMidtexLinesToSector(lines[i].frontsector, lines[i].args[0], lines[i].args[1], !!lines[i].args[2]); break; + case Sector_SetLink: + if (lines[i].args[0] == 0) + { + P_AddSectorLinks(lines[i].frontsector, lines[i].args[1], lines[i].args[2], lines[i].args[3]); + } + break; + // [RH] ZDoom Static_Init settings case Static_Init: switch (lines[i].args[1]) @@ -1030,6 +1037,11 @@ void P_SpawnSpecials (void) } break; + case Init_SectorLink: + if (lines[i].args[3] == 0) + P_AddSectorLinksByID(lines[i].frontsector, lines[i].args[0], lines[i].args[2]); + break; + // killough 10/98: // // Support for sky textures being transferred from sidedefs. diff --git a/src/r_defs.h b/src/r_defs.h index 99a1f464a..596d058d7 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -270,6 +270,13 @@ struct FExtraLight struct line_s; struct sector_t; +struct FLinkedSector +{ + sector_t *Sector; + int Type; +}; + + struct extsector_t { // 3DMIDTEX information @@ -282,13 +289,14 @@ struct extsector_t } Floor, Ceiling; } Midtex; - // linked sectors - /* + // Linked sector information struct linked { - TArray Sectors; + struct plane + { + TArray Sectors; + } Floor, Ceiling; } Linked; - */ void Serialize(FArchive &arc); }; @@ -297,6 +305,7 @@ struct extsector_t struct sector_t { // Member functions + bool IsLinked(sector_t *other, bool ceiling) const; fixed_t FindLowestFloorSurrounding (vertex_t **v) const; fixed_t FindHighestFloorSurrounding (vertex_t **v) const; fixed_t FindNextHighestFloor (vertex_t **v) const; diff --git a/src/r_main.cpp b/src/r_main.cpp index 2413d863a..150304f5f 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -1998,7 +1998,7 @@ void updateinterpolations() //Stick at beginning of domovethings } } -void setinterpolation(EInterpType type, void *posptr) +void setinterpolation(EInterpType type, void *posptr, bool dolinks) { FActiveInterpolation **interp_p; FActiveInterpolation *interp = FActiveInterpolation::FindInterpolation (type, posptr, interp_p); @@ -2010,21 +2010,43 @@ void setinterpolation(EInterpType type, void *posptr) *interp_p = interp; interp->CopyInterpToOld (); - if (type == INTERP_SectorFloor) P_Start3dMidtexInterpolations((sector_t*)posptr, false); - else if (type == INTERP_SectorCeiling) P_Start3dMidtexInterpolations((sector_t*)posptr, true); + if (dolinks) + { + if (type == INTERP_SectorFloor) + { + P_Start3dMidtexInterpolations((sector_t*)posptr, false); + P_StartLinkedSectorInterpolations((sector_t*)posptr, false); + } + else if (type == INTERP_SectorCeiling) + { + P_Start3dMidtexInterpolations((sector_t*)posptr, true); + P_StartLinkedSectorInterpolations((sector_t*)posptr, true); + } + } } -void stopinterpolation(EInterpType type, void *posptr) +void stopinterpolation(EInterpType type, void *posptr, bool dolinks) { FActiveInterpolation **interp_p; FActiveInterpolation *interp = FActiveInterpolation::FindInterpolation (type, posptr, interp_p); if (interp != NULL) { - if (type == INTERP_SectorFloor) P_Start3dMidtexInterpolations((sector_t*)posptr, false); - else if (type == INTERP_SectorCeiling) P_Start3dMidtexInterpolations((sector_t*)posptr, true); - *interp_p = interp->Next; delete interp; + + if (dolinks) + { + if (type == INTERP_SectorFloor) + { + P_Stop3dMidtexInterpolations((sector_t*)posptr, false); + P_StopLinkedSectorInterpolations((sector_t*)posptr, false); + } + else if (type == INTERP_SectorCeiling) + { + P_Stop3dMidtexInterpolations((sector_t*)posptr, true); + P_StopLinkedSectorInterpolations((sector_t*)posptr, true); + } + } } } diff --git a/src/r_main.h b/src/r_main.h index fdb3b636f..c4e9b4a41 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -242,8 +242,8 @@ private: static FActiveInterpolation *FindInterpolation(EInterpType, void *interptr, FActiveInterpolation **&interp_p); friend void updateinterpolations(); - friend void setinterpolation(EInterpType, void *interptr); - friend void stopinterpolation(EInterpType, void *interptr); + friend void setinterpolation(EInterpType, void *interptr, bool dolinks); + friend void stopinterpolation(EInterpType, void *interptr, bool dolinks); friend void dointerpolations(fixed_t smoothratio); friend void restoreinterpolations(); friend void clearinterpolations(); @@ -253,8 +253,8 @@ private: }; void updateinterpolations(); -void setinterpolation(EInterpType, void *interptr); -void stopinterpolation(EInterpType, void *interptr); +void setinterpolation(EInterpType, void *interptr, bool dolinks = true); +void stopinterpolation(EInterpType, void *interptr, bool dolinks = true); void dointerpolations(fixed_t smoothratio); void restoreinterpolations(); void clearinterpolations(); diff --git a/src/r_state.h b/src/r_state.h index c8544650c..ebd2d4a72 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -102,6 +102,13 @@ inline FArchive &operator<< (FArchive &arc, side_t *&side) return arc.SerializePointer (sides, (BYTE **)&side, sizeof(*sides)); } +inline FArchive &operator<< (FArchive &arc, FLinkedSector &link) +{ + arc << link.Sector << link.Type; + return arc; +} + + // // POV data. // diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 9aa406e14..87f1bc568 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -752,7 +752,11 @@ void A_CustomMissile(AActor * self) break; case 2: + self->x+=x; + self->y+=y; missile = P_SpawnMissileAngleZ(self, self->z+SpawnHeight, ti, self->angle, 0); + self->x-=x; + self->y-=y; // It is not necessary to use the correct angle here. // The only important thing is that the horizontal momentum is correct. diff --git a/src/version.h b/src/version.h index 83a79acc5..191aed244 100644 --- a/src/version.h +++ b/src/version.h @@ -75,10 +75,10 @@ // SAVESIG should match SAVEVER. // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 817 +#define MINSAVEVER 825 -#if SVN_REVISION_NUMBER == 0 -// This can happen if svnrevision is not updated properly (e.g. compiling while offline) +#if SVN_REVISION_NUMBER < MINSAVEVER +// Never write a savegame with a version lower than what we need #define SAVEVER MINSAVEVER #define MAKESAVESIG(x) "ZDOOMSAVE" #x #define SAVESIG MAKESAVESIG(SAVEVER) diff --git a/zdoom.vcproj b/zdoom.vcproj index bbde9cbd7..627aaf0ed 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -1,7 +1,7 @@ + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + @@ -916,16 +920,6 @@ Outputs=""src/$(InputName).h"" /> - - - @@ -936,6 +930,16 @@ Outputs=""src/$(InputName).h"" /> + + + @@ -1526,16 +1530,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -1546,6 +1540,16 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -1570,16 +1574,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -1590,6 +1584,16 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -1614,16 +1618,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -1634,6 +1628,16 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -1658,16 +1662,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -1678,6 +1672,16 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -1702,16 +1706,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -1722,6 +1716,16 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + @@ -1882,14 +1886,6 @@ Outputs="$(IntDir)\$(InputName).obj" /> - - - @@ -1900,6 +1896,14 @@ Outputs="$(IntDir)\$(InputName).obj" /> + + + - - - @@ -2766,6 +2762,14 @@ AdditionalIncludeDirectories="src\win32;$(NoInherit)" /> + + + @@ -2920,7 +2924,7 @@ />