From 697ef02871d10c8cd01be7f445eb6f46681fd73f Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Fri, 28 Mar 2014 00:17:32 +1300 Subject: [PATCH 1/5] Added StencilColor to Set/GetActorProperty --- src/p_acs.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 1ed89f783d..0a29f48e89 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3529,7 +3529,8 @@ enum APROP_ReactionTime = 37, APROP_MeleeRange = 38, APROP_ViewHeight = 39, - APROP_AttackZOffset = 40 + APROP_AttackZOffset = 40, + APROP_StencilColor = 41 }; // These are needed for ACS's APROP_RenderStyle @@ -3755,6 +3756,10 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value) static_cast(actor)->AttackZOffset = value; break; + case APROP_StencilColor: + actor->SetShade(value); + break; + default: // do nothing. break; @@ -3852,6 +3857,7 @@ int DLevelScript::GetActorProperty (int tid, int property, const SDWORD *stack, case APROP_ActiveSound: return GlobalACSStrings.AddString(actor->ActiveSound, stack, stackdepth); case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies(), stack, stackdepth); case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag(), stack, stackdepth); + case APROP_StencilColor:return actor->fillcolor; default: return 0; } From d7a2435703f56ce36c00892f31c3a582bb947b7d Mon Sep 17 00:00:00 2001 From: crimsondusk Date: Thu, 27 Mar 2014 16:34:32 +0200 Subject: [PATCH 2/5] - the ACS functions GetSectorFloorZ and GetSectorCeilingZ now interpret tag=0 as 'any sector' and return the z height of whatever sector is at those coordinates. --- src/p_acs.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 1ed89f783d..10aa79becb 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -7874,14 +7874,22 @@ scriptwait: case PCD_GETSECTORCEILINGZ: // Arguments are (tag, x, y). If you don't use slopes, then (x, y) don't // really matter and can be left as (0, 0) if you like. + // [Dusk] If tag = 0, then this returns the z height at whatever sector + // is in x, y. { - int secnum = P_FindSectorFromTag (STACK(3), -1); + int tag = STACK(3); + int secnum; + fixed_t x = STACK(2) << FRACBITS; + fixed_t y = STACK(1) << FRACBITS; fixed_t z = 0; + if (tag != 0) + secnum = P_FindSectorFromTag (tag, -1); + else + secnum = P_PointInSector (x, y) - sectors; + if (secnum >= 0) { - fixed_t x = STACK(2) << FRACBITS; - fixed_t y = STACK(1) << FRACBITS; if (pcd == PCD_GETSECTORFLOORZ) { z = sectors[secnum].floorplane.ZatPoint (x, y); From edcc2576673d09f353441abd4db096251877d0bd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 31 Mar 2014 16:39:34 +0200 Subject: [PATCH 3/5] fixed: APROP_StencilColor was not implemented for CheckActorProperty. --- src/p_acs.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 0a29f48e89..5f6af94080 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3904,6 +3904,7 @@ int DLevelScript::CheckActorProperty (int tid, int property, int value) case APROP_MeleeRange: case APROP_ViewHeight: case APROP_AttackZOffset: + case APROP_StencilColor: return (GetActorProperty(tid, property, NULL, 0) == value); // Boolean values need to compare to a binary version of value From be33d2894ac59be3d8424f145113cb8248645b2f Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Tue, 1 Apr 2014 23:05:08 +1300 Subject: [PATCH 4/5] Fixed prediction thinglist order restoration Prediction didn't take sector_thinglist and thinglist order into account. This notably broke the order in which things were damaged. --- src/p_user.cpp | 115 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 107 insertions(+), 8 deletions(-) diff --git a/src/p_user.cpp b/src/p_user.cpp index 90d0dd6cfc..f792cf1d1c 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -65,6 +65,8 @@ CVAR (Bool, cl_noprediction, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) static player_t PredictionPlayerBackup; static BYTE PredictionActorBackup[sizeof(AActor)]; static TArray PredictionTouchingSectorsBackup; +static TArray PredictionSectorListBackup; +static TArray PredictionSector_sprev_Backup; // [GRB] Custom player classes TArray PlayerClasses; @@ -2661,15 +2663,41 @@ void P_PredictPlayer (player_t *player) player->cheats |= CF_PREDICTING; // The ordering of the touching_sectorlist needs to remain unchanged + // Also store a copy of all previous sector_thinglist nodes msecnode_t *mnode = act->touching_sectorlist; + msecnode_t *snode; + PredictionSector_sprev_Backup.Clear(); PredictionTouchingSectorsBackup.Clear (); while (mnode != NULL) { PredictionTouchingSectorsBackup.Push (mnode->m_sector); + + for (snode = mnode->m_sector->touching_thinglist; snode; snode = snode->m_snext) + { + if (snode->m_thing == act) + { + PredictionSector_sprev_Backup.Push(snode->m_sprev); + break; + } + } + mnode = mnode->m_tnext; } + // Keep an ordered list off all actors in the linked sector. + PredictionSectorListBackup.Clear(); + if (!(act->flags & MF_NOSECTOR)) + { + AActor *link = act->Sector->thinglist; + + while (link != NULL) + { + PredictionSectorListBackup.Push(link); + link = link->snext; + } + } + // Blockmap ordering also needs to stay the same, so unlink the block nodes // without releasing them. (They will be used again in P_UnpredictPlayer). FBlockNode *block = act->BlockNode; @@ -2701,6 +2729,7 @@ void P_UnPredictPlayer () if (player->cheats & CF_PREDICTING) { + unsigned int i; AActor *act = player->mo; AActor *savedcamera = player->camera; @@ -2710,23 +2739,93 @@ void P_UnPredictPlayer () // could cause it to change during prediction. player->camera = savedcamera; - act->UnlinkFromWorld (); - memcpy (&act->x, PredictionActorBackup, sizeof(AActor)-((BYTE *)&act->x-(BYTE *)act)); + act->UnlinkFromWorld(); + memcpy(&act->x, PredictionActorBackup, sizeof(AActor)-((BYTE *)&act->x - (BYTE *)act)); // Make the sector_list match the player's touching_sectorlist before it got predicted. - P_DelSeclist (sector_list); + P_DelSeclist(sector_list); sector_list = NULL; - for (unsigned int i = PredictionTouchingSectorsBackup.Size (); i-- > 0; ) + for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;) { - sector_list = P_AddSecnode (PredictionTouchingSectorsBackup[i], act, sector_list); + sector_list = P_AddSecnode(PredictionTouchingSectorsBackup[i], act, sector_list); } // The blockmap ordering needs to remain unchanged, too. Right now, act has the right // pointers, so temporarily set its MF_NOBLOCKMAP flag so that LinkToWorld() does not // mess with them. - act->flags |= MF_NOBLOCKMAP; - act->LinkToWorld (); - act->flags &= ~MF_NOBLOCKMAP; + { + DWORD keepflags = act->flags; + act->flags |= MF_NOBLOCKMAP; + act->LinkToWorld(); + act->flags = keepflags; + } + + // Restore sector links. + if (!(act->flags & MF_NOSECTOR)) + { + sector_t *sec = act->Sector; + AActor *me, *next; + AActor **link;// , **prev; + + // The thinglist is just a pointer chain. We are restoring the exact same things, so we can NULL the head safely + sec->thinglist = NULL; + + // [ED850] It doesn't look like I need this method. I'll keep it just incase something crops up, however. + /*for (i = PredictionSectorListBackup.Size(); i-- > 0;) + { + me = PredictionSectorListBackup[i]; + prev = me->sprev; + next = me->snext; + + if (prev != NULL) // prev will be NULL if this actor gets deleted due to cleaning up from a broken savegame + { + if ((*prev = next)) // unlink from sector list + next->sprev = prev; + me->snext = NULL; + me->sprev = (AActor **)(size_t)0xBeefCafe; // Woo! Bug-catching value! + } + }*/ + + for (i = PredictionSectorListBackup.Size(); i-- > 0;) + { + me = PredictionSectorListBackup[i]; + link = &sec->thinglist; + next = *link; + if ((me->snext = next)) + next->sprev = &me->snext; + me->sprev = link; + *link = me; + } + + // Restore sector thinglist order + for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;) + { + msecnode_t *snode; + + for (snode = PredictionTouchingSectorsBackup[i]->touching_thinglist; snode; snode = snode->m_snext) + { + // If we were already the head, none of this is needed + if (snode->m_thing == act && PredictionSector_sprev_Backup[i]) + { + if (snode->m_sprev) + snode->m_sprev->m_snext = snode->m_snext; + else + snode->m_sector->touching_thinglist = snode->m_snext; + if (snode->m_snext) + snode->m_snext->m_sprev = snode->m_sprev; + + snode->m_sprev = PredictionSector_sprev_Backup[i]; + + // At the moment, we don't exist in the list anymore, but we do know what our previous node is, so we set its current m_snext->m_sprev to us. + if (snode->m_sprev->m_snext) + snode->m_sprev->m_snext->m_sprev = snode; + snode->m_snext = snode->m_sprev->m_snext; + snode->m_sprev->m_snext = snode; + break; + } + } + } + } // Now fix the pointers in the blocknode chain FBlockNode *block = act->BlockNode; From 546ae759fdf3abb27f01f0b70ff550e703d917b0 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Wed, 2 Apr 2014 21:12:10 +1300 Subject: [PATCH 5/5] Cleanup old prediction fix development code --- src/p_user.cpp | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/p_user.cpp b/src/p_user.cpp index f792cf1d1c..ea7b315d80 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2770,22 +2770,6 @@ void P_UnPredictPlayer () // The thinglist is just a pointer chain. We are restoring the exact same things, so we can NULL the head safely sec->thinglist = NULL; - // [ED850] It doesn't look like I need this method. I'll keep it just incase something crops up, however. - /*for (i = PredictionSectorListBackup.Size(); i-- > 0;) - { - me = PredictionSectorListBackup[i]; - prev = me->sprev; - next = me->snext; - - if (prev != NULL) // prev will be NULL if this actor gets deleted due to cleaning up from a broken savegame - { - if ((*prev = next)) // unlink from sector list - next->sprev = prev; - me->snext = NULL; - me->sprev = (AActor **)(size_t)0xBeefCafe; // Woo! Bug-catching value! - } - }*/ - for (i = PredictionSectorListBackup.Size(); i-- > 0;) { me = PredictionSectorListBackup[i]; @@ -2797,15 +2781,18 @@ void P_UnPredictPlayer () *link = me; } + msecnode_t *snode; + // Restore sector thinglist order for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;) { - msecnode_t *snode; + // If we were already the head node, then nothing needs to change + if (PredictionSector_sprev_Backup[i] == NULL) + continue; for (snode = PredictionTouchingSectorsBackup[i]->touching_thinglist; snode; snode = snode->m_snext) { - // If we were already the head, none of this is needed - if (snode->m_thing == act && PredictionSector_sprev_Backup[i]) + if (snode->m_thing == act) { if (snode->m_sprev) snode->m_sprev->m_snext = snode->m_snext;