- handle intermediate special values in thinkers. They also need to take care of the related damage variables and flags.

This commit is contained in:
Christoph Oelckers 2016-01-06 13:30:28 +01:00
parent bd8513c063
commit eb6c855a95
7 changed files with 109 additions and 25 deletions

View file

@ -143,7 +143,7 @@ void DCeiling::Tick ()
// movers with texture change, change the texture then get removed
case genCeilingChgT:
case genCeilingChg0:
m_Sector->xspecial = m_NewSpecial;
m_Sector->SetSpecial(&m_NewSpecial);
// fall through
case genCeilingChg:
m_Sector->SetTexture(sector_t::ceiling, m_Texture);
@ -176,7 +176,7 @@ void DCeiling::Tick ()
// then remove the active ceiling
case genCeilingChgT:
case genCeilingChg0:
m_Sector->xspecial = m_NewSpecial;
m_Sector->SetSpecial(&m_NewSpecial);
// fall through
case genCeilingChg:
m_Sector->SetTexture(sector_t::ceiling, m_Texture);
@ -436,11 +436,11 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line,
switch (change & 3)
{
case 1: // type is zeroed
ceiling->m_NewSpecial = 0;
ceiling->m_NewSpecial.Clear();
ceiling->m_Type = genCeilingChg0;
break;
case 2: // type is copied
ceiling->m_NewSpecial = sec->xspecial;
sec->GetSpecial(&ceiling->m_NewSpecial);
ceiling->m_Type = genCeilingChgT;
break;
case 3: // type is left alone
@ -455,11 +455,11 @@ DCeiling *DCeiling::Create(sector_t *sec, DCeiling::ECeiling type, line_t *line,
switch (change & 3)
{
case 1: // type is zeroed
ceiling->m_NewSpecial = 0;
ceiling->m_NewSpecial.Clear();
ceiling->m_Type = genCeilingChg0;
break;
case 2: // type is copied
ceiling->m_NewSpecial = line->frontsector->xspecial;
line->frontsector->GetSpecial(&ceiling->m_NewSpecial);
ceiling->m_Type = genCeilingChgT;
break;
case 3: // type is left alone

View file

@ -161,7 +161,7 @@ void DFloor::Tick ()
case donutRaise:
case genFloorChgT:
case genFloorChg0:
m_Sector->xspecial = m_Sector->xspecial | m_NewSpecial;
m_Sector->GetSpecial(&m_NewSpecial);
//fall thru
case genFloorChg:
m_Sector->SetTexture(sector_t::floor, m_Texture);
@ -177,7 +177,7 @@ void DFloor::Tick ()
case floorLowerAndChange:
case genFloorChgT:
case genFloorChg0:
m_Sector->xspecial = m_Sector->xspecial | m_NewSpecial;
m_Sector->GetSpecial(&m_NewSpecial);
//fall thru
case genFloorChg:
m_Sector->SetTexture(sector_t::floor, m_Texture);
@ -235,14 +235,14 @@ void DFloor::SetFloorChangeType (sector_t *sec, int change)
switch (change & 3)
{
case 1:
m_NewSpecial = 0;
m_NewSpecial.Clear();
m_Type = DFloor::genFloorChg0;
break;
case 2:
m_Type = DFloor::genFloorChg;
break;
case 3:
m_NewSpecial = sec->xspecial;
sec->GetSpecial(&m_NewSpecial);
m_Type = DFloor::genFloorChgT;
break;
}
@ -440,11 +440,11 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
{
FTextureID oldpic = sec->GetTexture(sector_t::floor);
sec->SetTexture(sector_t::floor, line->frontsector->GetTexture(sector_t::floor));
sec->xspecial = line->frontsector->xspecial;
sec->TransferSpecial(line->frontsector);
}
else
{
sec->xspecial = 0;
sec->ClearSpecial();
}
break;
@ -455,8 +455,7 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
floor->m_Texture = sec->GetTexture(sector_t::floor);
// jff 1/24/98 make sure floor->m_NewSpecial gets initialized
// in case no surrounding sector is at floordestheight
// --> should not affect compatibility <--
floor->m_NewSpecial = sec->xspecial;
sec->GetSpecial(&floor->m_NewSpecial);
//jff 5/23/98 use model subroutine to unify fixes and handling
sector_t *modelsec;
@ -464,7 +463,7 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
if (modelsec != NULL)
{
floor->m_Texture = modelsec->GetTexture(sector_t::floor);
floor->m_NewSpecial = modelsec->xspecial;
modelsec->GetSpecial(&floor->m_NewSpecial);
}
break;
@ -794,7 +793,7 @@ bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed)
floor->m_Sector = s2;
floor->m_Speed = slimespeed;
floor->m_Texture = s3->GetTexture(sector_t::floor);
floor->m_NewSpecial = 0;
floor->m_NewSpecial.Clear();
height = s3->FindHighestFloorPoint (&spot);
floor->m_FloorDestDist = s2->floorplane.PointToDist (spot, height);
floor->StartFloorSound ();
@ -1093,7 +1092,7 @@ bool EV_DoChange (line_t *line, EChange changetype, int tag)
if (line)
{ // [RH] if no line, no change
sec->SetTexture(sector_t::floor, line->frontsector->GetTexture(sector_t::floor));
sec->xspecial = line->frontsector->xspecial;
sec->TransferSpecial(line->frontsector);
}
break;
case numChangeOnly:
@ -1101,7 +1100,7 @@ bool EV_DoChange (line_t *line, EChange changetype, int tag)
if (secm)
{ // if no model, no change
sec->SetTexture(sector_t::floor, secm->GetTexture(sector_t::floor));
sec->xspecial = secm->xspecial;
sec->TransferSpecial(secm);
}
break;
default:

View file

@ -4424,7 +4424,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
( gameaction != ga_worlddone ) &&
( p->mo != NULL ) &&
( !(p->mo->Sector->Flags & SECF_NORESPAWN) ) &&
( p->mo->Sector->damageamount < TELEFRAG_DAMAGE ))
( p->mo->Sector->damageamount < TELEFRAG_DAMAGE )) // this really should be a bit smarter...
{
spawn_x = p->mo->x;
spawn_y = p->mo->y;

View file

@ -282,8 +282,7 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height,
{
if (line)
sec->SetTexture(sector_t::floor, line->sidedef[0]->sector->GetTexture(sector_t::floor));
if (change == 1)
sec->xspecial = 0; // Stop damage and other stuff, if any
if (change == 1) sec->ClearSpecial();
}
switch (type)
@ -295,7 +294,7 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height,
plat->m_Low = sec->floorplane.d;
plat->m_Status = DPlat::up;
plat->PlayPlatSound ("Floor");
sec->xspecial = 0; // NO MORE DAMAGE, IF APPLICABLE
sec->ClearSpecial();
break;
case DPlat::platUpByValue:

View file

@ -843,6 +843,60 @@ sector_t *sector_t::GetHeightSec() const
}
void sector_t::GetSpecial(secspecial_t *spec)
{
spec->special = special;
spec->damageamount = damageamount;
spec->damagetype = damagetype;
spec->damageinterval = damageinterval;
spec->leakydamage = leakydamage;
spec->Flags = Flags & SECF_SPECIALFLAGS;
}
void sector_t::SetSpecial(const secspecial_t *spec)
{
special = spec->special;
damageamount = spec->damageamount;
damagetype = spec->damagetype;
damageinterval = spec->damageinterval;
leakydamage = spec->leakydamage;
Flags = (Flags & ~SECF_SPECIALFLAGS) | (spec->Flags & SECF_SPECIALFLAGS);
}
void sector_t::TransferSpecial(sector_t *model)
{
special = model->special;
damageamount = model->damageamount;
damagetype = model->damagetype;
damageinterval = model->damageinterval;
leakydamage = model->leakydamage;
Flags = (Flags&~SECF_SPECIALFLAGS) | (model->Flags & SECF_SPECIALFLAGS);
}
FArchive &operator<< (FArchive &arc, secspecial_t &p)
{
if (SaveVersion < 4529)
{
short special;
arc << special;
sector_t sec;
P_InitSectorSpecial(&sec, special, true);
sec.GetSpecial(&p);
}
else
{
arc << p.special
<< p.damageamount
<< p.damagetype
<< p.damageinterval
<< p.leakydamage
<< p.Flags;
}
return arc;
}
bool secplane_t::CopyPlaneIfValid (secplane_t *dest, const secplane_t *opp) const
{
bool copy = false;

View file

@ -674,7 +674,7 @@ protected:
// [RH] Need these for BOOM-ish transferring ceilings
FTextureID m_Texture;
int m_NewSpecial;
secspecial_t m_NewSpecial;
// ID
int m_Tag;
@ -761,7 +761,7 @@ protected:
int m_Crush;
bool m_Hexencrush;
int m_Direction;
int m_NewSpecial;
secspecial_t m_NewSpecial;
FTextureID m_Texture;
fixed_t m_FloorDestDist;
fixed_t m_Speed;

View file

@ -367,7 +367,8 @@ enum
SECF_SECRET = 1 << 31, // a secret sector
SECF_DAMAGEFLAGS = SECF_ENDGODMODE|SECF_ENDLEVEL|SECF_DMGTERRAINFX|SECF_HAZARD,
SECF_NOMODIFY = SECF_SECRET|SECF_WASSECRET // not modifiable by Sector_ChangeFlags
SECF_NOMODIFY = SECF_SECRET|SECF_WASSECRET, // not modifiable by Sector_ChangeFlags
SECF_SPECIALFLAGS = SECF_DAMAGEFLAGS|SECF_FRICTION|SECF_PUSH, // these flags originate from 'special and must be transferrable by floor thinkers
};
enum
@ -440,6 +441,23 @@ struct FTransform
fixed_t base_angle, base_yoffs;
};
struct secspecial_t
{
FNameNoInit damagetype; // [RH] Means-of-death for applied damage
int damageamount; // [RH] Damage to do while standing on floor
short special;
short damageinterval; // Interval for damage application
short leakydamage; // chance of leaking through radiation suit
int Flags;
void Clear()
{
memset(this, 0, sizeof(*this));
}
};
FArchive &operator<< (FArchive &arc, secspecial_t &p);
struct sector_t
{
// Member functions
@ -670,6 +688,20 @@ struct sector_t
Flags &= ~SECF_SECRET;
}
void ClearSpecial()
{
// clears all variables that originate from 'special'. Used for sector type transferring thinkers
special = 0;
damageamount = 0;
damageinterval = 0;
damagetype = NAME_None;
leakydamage = 0;
Flags &= ~SECF_SPECIALFLAGS;
}
void TransferSpecial(sector_t *model);
void GetSpecial(secspecial_t *spec);
void SetSpecial(const secspecial_t *spec);
bool PlaneMoving(int pos);