This commit is contained in:
Christoph Oelckers 2016-03-08 15:40:47 +01:00
commit 024efc9e61
8 changed files with 88 additions and 58 deletions

View file

@ -1167,7 +1167,7 @@ private:
bool FixMapthingPos();
public:
void LinkToWorld (bool spawningmapthing=false, FPortalGroupArray *groups = NULL, sector_t *sector = NULL);
void LinkToWorld (bool spawningmapthing=false, sector_t *sector = NULL);
void UnlinkFromWorld ();
void AdjustFloorClip ();
virtual void SetOrigin (fixed_t x, fixed_t y, fixed_t z, bool moving = false);

View file

@ -2505,9 +2505,9 @@ static bool DoDehPatch()
{
if (PatchFile[25] < '3')
{
Printf (PRINT_BOLD, "\"%s\" is an old and unsupported DeHackEd patch\n", PatchName);
delete[] PatchName;
delete[] PatchFile;
Printf (PRINT_BOLD, "\"%s\" is an old and unsupported DeHackEd patch\n", PatchFile);
return false;
}
// fix for broken WolfenDoom patches which contain \0 characters in some places.

View file

@ -381,13 +381,15 @@ int FIWadManager::CheckIWAD (const char *doomwaddir, WadStuff *wads)
//
//==========================================================================
static bool havepicked = false;
int FIWadManager::IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, const char *zdoom_wad)
{
TArray<WadStuff> wads;
TArray<size_t> foundwads;
const char *iwadparm = Args->CheckValue ("-iwad");
size_t numwads;
int pickwad;
size_t numwads;
size_t i;
bool iwadparmfound = false;
FString custwad;
@ -536,26 +538,29 @@ int FIWadManager::IdentifyVersion (TArray<FString> &wadfiles, const char *iwad,
{
for (i = 0; i < numwads; ++i)
{
FString basename = ExtractFileBase (wads[i].Path);
if (stricmp (basename, defaultiwad) == 0)
FString basename = ExtractFileBase(wads[i].Path);
if (stricmp(basename, defaultiwad) == 0)
{
defiwad = (int)i;
break;
}
}
}
pickwad = I_PickIWad (&wads[0], (int)numwads, queryiwad, defiwad);
if (pickwad >= 0)
if (!havepicked) // just use the first IWAD if the restart doesn't have a -iwad parameter. We cannot open the picker in fullscreen mode.
{
// The newly selected IWAD becomes the new default
FString basename = ExtractFileBase (wads[pickwad].Path);
defaultiwad = basename;
pickwad = I_PickIWad(&wads[0], (int)numwads, queryiwad, defiwad);
if (pickwad >= 0)
{
// The newly selected IWAD becomes the new default
FString basename = ExtractFileBase(wads[pickwad].Path);
defaultiwad = basename;
}
if (pickwad < 0)
exit(0);
havepicked = true;
}
}
if (pickwad < 0)
exit (0);
// zdoom.pk3 must always be the first file loaded and the IWAD second.
wadfiles.Clear();
D_AddFile (wadfiles, zdoom_wad);

View file

@ -5250,7 +5250,7 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo
double bombdistancefloat = 1.f / (double)(bombdistance - fulldamagedistance);
double bombdamagefloat = (double)bombdamage;
FPortalGroupArray grouplist;
FPortalGroupArray grouplist(FPortalGroupArray::PGA_Full3d);
FMultiBlockThingsIterator it(grouplist, bombspot->X(), bombspot->Y(), bombspot->Z() - bombdistfix, bombspot->height + bombdistfix*2, bombdistfix);
FMultiBlockThingsIterator::CheckResult cres;

View file

@ -435,7 +435,7 @@ bool AActor::FixMapthingPos()
//
//==========================================================================
void AActor::LinkToWorld (bool spawningmapthing, FPortalGroupArray *groups, sector_t *sector)
void AActor::LinkToWorld(bool spawningmapthing, sector_t *sector)
{
if (spawningmapthing && (flags4 & MF4_FIXMAPTHINGPOS) && sector == NULL)
{
@ -457,7 +457,7 @@ void AActor::LinkToWorld (bool spawningmapthing, FPortalGroupArray *groups, sect
Sector = sector;
subsector = R_PointInSubsector(X(), Y()); // this is from the rendering nodes, not the gameplay nodes!
if ( !(flags & MF_NOSECTOR) )
if (!(flags & MF_NOSECTOR))
{
// invisible things don't go into the sector links
// killough 8/11/98: simpler scheme using pointer-to-pointer prev
@ -482,51 +482,60 @@ void AActor::LinkToWorld (bool spawningmapthing, FPortalGroupArray *groups, sect
// When a node is deleted, its sector links (the links starting
// at sector_t->touching_thinglist) are broken. When a node is
// added, new sector links are created.
P_CreateSecNodeList (this, X(), Y());
P_CreateSecNodeList(this, X(), Y());
touching_sectorlist = sector_list; // Attach to thing
sector_list = NULL; // clear for next time
}
}
// link into blockmap (inert things don't need to be in the blockmap)
if ( !(flags & MF_NOBLOCKMAP) )
if (!(flags & MF_NOBLOCKMAP))
{
int x1 = GetSafeBlockX(X() - radius - bmaporgx);
int x2 = GetSafeBlockX(X() + radius - bmaporgx);
int y1 = GetSafeBlockY(Y() - radius - bmaporgy);
int y2 = GetSafeBlockY(Y() + radius - bmaporgy);
FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals);
if (x1 >= bmapwidth || x2 < 0 || y1 >= bmapheight || y2 < 0)
{ // thing is off the map
BlockNode = NULL;
}
else
{ // [RH] Link into every block this actor touches, not just the center one
FBlockNode **alink = &this->BlockNode;
x1 = MAX (0, x1);
y1 = MAX (0, y1);
x2 = MIN (bmapwidth - 1, x2);
y2 = MIN (bmapheight - 1, y2);
for (int y = y1; y <= y2; ++y)
{
for (int x = x1; x <= x2; ++x)
P_CollectConnectedGroups(Sector->PortalGroup, Pos(), Top(), radius, check);
for (int i = -1; i < (int)check.Size(); i++)
{
fixedvec3 pos = i==-1? Pos() : PosRelative(check[i]);
int x1 = GetSafeBlockX(pos.x - radius - bmaporgx);
int x2 = GetSafeBlockX(pos.x + radius - bmaporgx);
int y1 = GetSafeBlockY(pos.y - radius - bmaporgy);
int y2 = GetSafeBlockY(pos.y + radius - bmaporgy);
if (x1 >= bmapwidth || x2 < 0 || y1 >= bmapheight || y2 < 0)
{ // thing is off the map
BlockNode = NULL;
}
else
{ // [RH] Link into every block this actor touches, not just the center one
FBlockNode **alink = &this->BlockNode;
x1 = MAX(0, x1);
y1 = MAX(0, y1);
x2 = MIN(bmapwidth - 1, x2);
y2 = MIN(bmapheight - 1, y2);
for (int y = y1; y <= y2; ++y)
{
FBlockNode **link = &blocklinks[y*bmapwidth + x];
FBlockNode *node = FBlockNode::Create (this, x, y, this->Sector->PortalGroup);
// Link in to block
if ((node->NextActor = *link) != NULL)
for (int x = x1; x <= x2; ++x)
{
(*link)->PrevActor = &node->NextActor;
}
node->PrevActor = link;
*link = node;
FBlockNode **link = &blocklinks[y*bmapwidth + x];
FBlockNode *node = FBlockNode::Create(this, x, y, this->Sector->PortalGroup);
// Link in to actor
node->PrevBlock = alink;
node->NextBlock = NULL;
(*alink) = node;
alink = &node->NextBlock;
// Link in to block
if ((node->NextActor = *link) != NULL)
{
(*link)->PrevActor = &node->NextActor;
}
node->PrevActor = link;
*link = node;
// Link in to actor
node->PrevBlock = alink;
node->NextBlock = NULL;
(*alink) = node;
alink = &node->NextBlock;
}
}
}
}

View file

@ -456,7 +456,7 @@ void AActor::Serialize (FArchive &arc)
if (arc.IsLoading ())
{
touching_sectorlist = NULL;
LinkToWorld (false, NULL, Sector);
LinkToWorld (false, Sector);
AddToHash ();
SetShade (fillcolor);
if (player)

View file

@ -1107,7 +1107,25 @@ void P_CreateLinkedPortals()
}
}
}
//BuildBlockmap();
if (linkedPortals.Size() > 0)
{
// We need to relink all actors that may touch a linked line portal
TThinkerIterator<AActor> it;
AActor *actor;
while ((actor = it.Next()))
{
if (!(actor->flags & MF_NOBLOCKMAP))
{
FPortalGroupArray check(FPortalGroupArray::PGA_NoSectorPortals);
P_CollectConnectedGroups(actor->Sector->PortalGroup, actor->Pos(), actor->Top(), actor->radius, check);
if (check.Size() > 0)
{
actor->UnlinkFromWorld();
actor->LinkToWorld();
}
}
}
}
}
@ -1208,7 +1226,7 @@ bool P_CollectConnectedGroups(int startgroup, const fixedvec3 &position, fixed_t
wsec = P_PointInSector(dx, dy); // get lower sector at the exact spot we want to check and repeat
retval = true;
}
if (out.method == FPortalGroupArray::PGA_Full3d)
if (out.method == FPortalGroupArray::PGA_Full3d && PortalBlockmap.hasLinkedSectorPortals)
{
groupsToCheck.Clear();
groupsToCheck.Push(startgroup);

View file

@ -5024,9 +5024,7 @@ void A_Weave(AActor *self, int xyspeed, int zspeed, fixed_t xydist, fixed_t zdis
{
self->UnlinkFromWorld ();
self->flags |= MF_NOBLOCKMAP;
// the following 4 lines are for future-proofing this for both interpolation overhaul and line portals.
// For portals we need to calculate the destination including the portal offset
// and for interpolation we need to set the performed movement explicitly, because SetXY cannot do that.
// We need to do portal offsetting here explicitly, because SetXY cannot do that.
newX -= self->X();
newY -= self->Y();
self->SetXY(self->Vec2Offset(newX, newY));