- Fixed: Polyobjects are serialized before players, which means that a call

to PO_MovePolyobj() from P_SerializePolyobjs() for a crushing polyobject
  that touches a player actor will not have a valid actor->player->mo chain
  for P_DamageMobj and crash if it happens to touch the player. Since the
  polyobject was presumably in a good spot when the game was saved, we can
  just skip this step entirely and let it take care of itself the next time
  it moves (by which time, the players will be valid).
- Fixed: When transitioning from fullscreen to windowed mode with D3DFB, the
  window kept the WS_EX_TOPMOST style.
- Slight correctness fix: When in fullscreen, the window should have WS_POPUP
  style.
- Added a NULL target check to P_SpawnMissileXYZ(), A_DemonAttack1(),
  A_DemonAttack2_1(), and A_DemonAttack2_2().


SVN r384 (trunk)
This commit is contained in:
Randy Heit 2006-11-21 05:43:34 +00:00
parent 93b18c3bfa
commit 48bb782b19
8 changed files with 77 additions and 41 deletions

View file

@ -1,3 +1,18 @@
November 20, 2006
- Fixed: Polyobjects are serialized before players, which means that a call
to PO_MovePolyobj() from P_SerializePolyobjs() for a crushing polyobject
that touches a player actor will not have a valid actor->player->mo chain
for P_DamageMobj and crash if it happens to touch the player. Since the
polyobject was presumably in a good spot when the game was saved, we can
just skip this step entirely and let it take care of itself the next time
it moves (by which time, the players will be valid).
- Fixed: When transitioning from fullscreen to windowed mode with D3DFB, the
window kept the WS_EX_TOPMOST style.
- Slight correctness fix: When in fullscreen, the window should have WS_POPUP
style.
- Added a NULL target check to P_SpawnMissileXYZ(), A_DemonAttack1(),
A_DemonAttack2_1(), and A_DemonAttack2_2().
November 18, 2006
- Fixed: DFrameBuffer and related classes did not use DECLARE_CLASS macros,
so there was no guarantee that they would allocate the proper amount of

View file

@ -548,7 +548,7 @@ END_DEFAULTS
void A_DemonAttack1 (AActor *actor)
{
if (actor->CheckMeleeRange ())
if (actor->target != NULL && actor->CheckMeleeRange ())
{
int damage = pr_atk.HitDice (2);
P_DamageMobj (actor->target, actor, actor, damage, NAME_Melee);
@ -565,15 +565,18 @@ void A_DemonAttack1 (AActor *actor)
void A_DemonAttack2_1 (AActor *actor)
{
AActor *mo;
// Improve the aiming of this code!
actor->z += 30*FRACUNIT;
mo = P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(ADemon1FX1));
actor->z -= 30*FRACUNIT;
if (mo)
if (actor->target != NULL)
{
S_Sound (actor, CHAN_BODY, "DemonMissileFire", 1, ATTN_NORM);
AActor *mo;
// Improve the aiming of this code!
actor->z += 30*FRACUNIT;
mo = P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(ADemon1FX1));
actor->z -= 30*FRACUNIT;
if (mo)
{
S_Sound (actor, CHAN_BODY, "DemonMissileFire", 1, ATTN_NORM);
}
}
}
@ -585,15 +588,18 @@ void A_DemonAttack2_1 (AActor *actor)
void A_DemonAttack2_2 (AActor *actor)
{
AActor *mo;
// Improve the aiming of this code!
actor->z += 30*FRACUNIT;
mo = P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(ADemon2FX1));
actor->z -= 30*FRACUNIT;
if (mo)
if (actor->target != NULL)
{
S_Sound (actor, CHAN_BODY, "DemonMissileFire", 1, ATTN_NORM);
AActor *mo;
// Improve the aiming of this code!
actor->z += 30*FRACUNIT;
mo = P_SpawnMissile (actor, actor->target, RUNTIME_CLASS(ADemon2FX1));
actor->z -= 30*FRACUNIT;
if (mo)
{
S_Sound (actor, CHAN_BODY, "DemonMissileFire", 1, ATTN_NORM);
}
}
}

View file

@ -484,7 +484,7 @@ extern int po_NumPolyobjs;
extern polyspawns_t *polyspawns; // [RH] list of polyobject things to spawn
bool PO_MovePolyobj (int num, int x, int y);
bool PO_MovePolyobj (int num, int x, int y, bool force=false);
bool PO_RotatePolyobj (int num, angle_t angle);
void PO_Init ();
bool PO_Busy (int polyobj);

View file

@ -4269,6 +4269,12 @@ AActor *P_SpawnMissileZ (AActor *source, fixed_t z, AActor *dest, const PClass *
AActor *P_SpawnMissileXYZ (fixed_t x, fixed_t y, fixed_t z,
AActor *source, AActor *dest, const PClass *type)
{
if (dest == NULL)
{
Printf ("P_SpawnMissilyXYZ: Tried to shoot %s from %s with no dest\n",
type->TypeName.GetChars(), source->GetClass()->TypeName.GetChars());
return NULL;
}
int defflags3 = GetDefaultByType (type)->flags3;
if (defflags3 & MF3_FLOORHUGGER)

View file

@ -497,7 +497,7 @@ void P_SerializePolyobjs (FArchive &arc)
deltaX -= po->startSpot[0];
deltaY -= po->startSpot[1];
deltaZ -= po->startSpot[2];
PO_MovePolyobj (po->tag, deltaX, deltaY);
PO_MovePolyobj (po->tag, deltaX, deltaY, true);
}
}
}

View file

@ -32,7 +32,6 @@
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
bool PO_MovePolyobj (int num, int x, int y);
bool PO_RotatePolyobj (int num, angle_t angle);
void PO_Init (void);
@ -757,12 +756,9 @@ static void UpdateSegBBox (seg_t *seg)
//
//==========================================================================
bool PO_MovePolyobj (int num, int x, int y)
bool PO_MovePolyobj (int num, int x, int y, bool force)
{
int count;
seg_t **segList;
polyobj_t *po;
bool blocked;
if (!(po = GetPolyobj (num)))
{
@ -772,21 +768,25 @@ bool PO_MovePolyobj (int num, int x, int y)
UnLinkPolyobj (po);
DoMovePolyobj (po, x, y);
segList = po->segs;
blocked = false;
for (count = po->numsegs; count; count--, segList++)
if (!force)
{
if (CheckMobjBlocking(*segList, po))
seg_t **segList = po->segs;
bool blocked = false;
for (int count = po->numsegs; count; count--, segList++)
{
blocked = true;
break;
if (CheckMobjBlocking(*segList, po))
{
blocked = true;
break;
}
}
if (blocked)
{
DoMovePolyobj (po, -x, -y);
LinkPolyobj(po);
return false;
}
}
if (blocked)
{
DoMovePolyobj (po, -x, -y);
LinkPolyobj(po);
return false;
}
po->startSpot[0] += x;
po->startSpot[1] += y;

View file

@ -295,9 +295,9 @@ bool D3DFB::CreateResources ()
{
if (!Windowed)
{
ShowWindow (Window, SW_SHOW);
// Remove the window border in fullscreen mode
SetWindowLongPtr (Window, GWL_STYLE, WS_POPUP|WS_VISIBLE|WS_SYSMENU);
ShowWindow (Window, SW_SHOW);
}
else
{
@ -309,10 +309,19 @@ bool D3DFB::CreateResources ()
VidResizing = true;
// Make sure the window has a border in windowed mode
SetWindowLongPtr (Window, GWL_STYLE, WS_VISIBLE|WS_OVERLAPPEDWINDOW);
if (!SetWindowPos (Window, NULL, 0, 0, sizew, sizeh,
SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER))
if (GetWindowLong (Window, GWL_EXSTYLE) & WS_EX_TOPMOST)
{
LOG1 ("SetWindowPos failed because %08lx\n", GetLastError());
// Direct3D 9 will apparently add WS_EX_TOPMOST to fullscreen windows,
// and removing it is a little tricky. Using SetWindowLongPtr to clear it
// will not do the trick, but sending the window behind everything will.
SetWindowPos (Window, HWND_BOTTOM, 0, 0, sizew, sizeh,
SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE);
SetWindowPos (Window, HWND_TOP, 0, 0, 0, 0, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE);
}
else
{
SetWindowPos (Window, NULL, 0, 0, sizew, sizeh,
SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER);
}
VidResizing = false;
ShowWindow (Window, SW_SHOWNORMAL);

View file

@ -232,7 +232,7 @@ bool DDrawFB::CreateResources ()
{
ShowWindow (Window, SW_SHOW);
// Remove the window border in fullscreen mode
SetWindowLongPtr (Window, GWL_STYLE, WS_VISIBLE|WS_SYSMENU);
SetWindowLongPtr (Window, GWL_STYLE, WS_POPUP|WS_VISIBLE|WS_SYSMENU);
TrueHeight = Height;
for (Win32Video::ModeInfo *mode = static_cast<Win32Video *>(Video)->m_Modes; mode != NULL; mode = mode->next)