This commit is contained in:
Christoph Oelckers 2014-04-02 23:51:24 +02:00
commit 072db7920d
2 changed files with 113 additions and 12 deletions

View file

@ -3529,7 +3529,8 @@ enum
APROP_ReactionTime = 37, APROP_ReactionTime = 37,
APROP_MeleeRange = 38, APROP_MeleeRange = 38,
APROP_ViewHeight = 39, APROP_ViewHeight = 39,
APROP_AttackZOffset = 40 APROP_AttackZOffset = 40,
APROP_StencilColor = 41
}; };
// These are needed for ACS's APROP_RenderStyle // These are needed for ACS's APROP_RenderStyle
@ -3755,6 +3756,10 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
static_cast<APlayerPawn *>(actor)->AttackZOffset = value; static_cast<APlayerPawn *>(actor)->AttackZOffset = value;
break; break;
case APROP_StencilColor:
actor->SetShade(value);
break;
default: default:
// do nothing. // do nothing.
break; 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_ActiveSound: return GlobalACSStrings.AddString(actor->ActiveSound, stack, stackdepth);
case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies(), stack, stackdepth); case APROP_Species: return GlobalACSStrings.AddString(actor->GetSpecies(), stack, stackdepth);
case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag(), stack, stackdepth); case APROP_NameTag: return GlobalACSStrings.AddString(actor->GetTag(), stack, stackdepth);
case APROP_StencilColor:return actor->fillcolor;
default: return 0; default: return 0;
} }
@ -3898,6 +3904,7 @@ int DLevelScript::CheckActorProperty (int tid, int property, int value)
case APROP_MeleeRange: case APROP_MeleeRange:
case APROP_ViewHeight: case APROP_ViewHeight:
case APROP_AttackZOffset: case APROP_AttackZOffset:
case APROP_StencilColor:
return (GetActorProperty(tid, property, NULL, 0) == value); return (GetActorProperty(tid, property, NULL, 0) == value);
// Boolean values need to compare to a binary version of value // Boolean values need to compare to a binary version of value
@ -7874,14 +7881,22 @@ scriptwait:
case PCD_GETSECTORCEILINGZ: case PCD_GETSECTORCEILINGZ:
// Arguments are (tag, x, y). If you don't use slopes, then (x, y) don't // 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. // 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; fixed_t z = 0;
if (tag != 0)
secnum = P_FindSectorFromTag (tag, -1);
else
secnum = P_PointInSector (x, y) - sectors;
if (secnum >= 0) if (secnum >= 0)
{ {
fixed_t x = STACK(2) << FRACBITS;
fixed_t y = STACK(1) << FRACBITS;
if (pcd == PCD_GETSECTORFLOORZ) if (pcd == PCD_GETSECTORFLOORZ)
{ {
z = sectors[secnum].floorplane.ZatPoint (x, y); z = sectors[secnum].floorplane.ZatPoint (x, y);

View file

@ -65,6 +65,8 @@ CVAR (Bool, cl_noprediction, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
static player_t PredictionPlayerBackup; static player_t PredictionPlayerBackup;
static BYTE PredictionActorBackup[sizeof(AActor)]; static BYTE PredictionActorBackup[sizeof(AActor)];
static TArray<sector_t *> PredictionTouchingSectorsBackup; static TArray<sector_t *> PredictionTouchingSectorsBackup;
static TArray<AActor *> PredictionSectorListBackup;
static TArray<msecnode_t *> PredictionSector_sprev_Backup;
// [GRB] Custom player classes // [GRB] Custom player classes
TArray<FPlayerClass> PlayerClasses; TArray<FPlayerClass> PlayerClasses;
@ -2661,15 +2663,41 @@ void P_PredictPlayer (player_t *player)
player->cheats |= CF_PREDICTING; player->cheats |= CF_PREDICTING;
// The ordering of the touching_sectorlist needs to remain unchanged // 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 *mnode = act->touching_sectorlist;
msecnode_t *snode;
PredictionSector_sprev_Backup.Clear();
PredictionTouchingSectorsBackup.Clear (); PredictionTouchingSectorsBackup.Clear ();
while (mnode != NULL) while (mnode != NULL)
{ {
PredictionTouchingSectorsBackup.Push (mnode->m_sector); 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; 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 // Blockmap ordering also needs to stay the same, so unlink the block nodes
// without releasing them. (They will be used again in P_UnpredictPlayer). // without releasing them. (They will be used again in P_UnpredictPlayer).
FBlockNode *block = act->BlockNode; FBlockNode *block = act->BlockNode;
@ -2701,6 +2729,7 @@ void P_UnPredictPlayer ()
if (player->cheats & CF_PREDICTING) if (player->cheats & CF_PREDICTING)
{ {
unsigned int i;
AActor *act = player->mo; AActor *act = player->mo;
AActor *savedcamera = player->camera; AActor *savedcamera = player->camera;
@ -2710,23 +2739,80 @@ void P_UnPredictPlayer ()
// could cause it to change during prediction. // could cause it to change during prediction.
player->camera = savedcamera; player->camera = savedcamera;
act->UnlinkFromWorld (); act->UnlinkFromWorld();
memcpy (&act->x, PredictionActorBackup, sizeof(AActor)-((BYTE *)&act->x-(BYTE *)act)); 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. // 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; 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 // 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 // pointers, so temporarily set its MF_NOBLOCKMAP flag so that LinkToWorld() does not
// mess with them. // mess with them.
act->flags |= MF_NOBLOCKMAP; {
act->LinkToWorld (); DWORD keepflags = act->flags;
act->flags &= ~MF_NOBLOCKMAP; 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;
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;
}
msecnode_t *snode;
// Restore sector thinglist order
for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;)
{
// 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 (snode->m_thing == act)
{
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 // Now fix the pointers in the blocknode chain
FBlockNode *block = act->BlockNode; FBlockNode *block = act->BlockNode;