This commit is contained in:
Christoph Oelckers 2016-05-13 10:09:24 +02:00
commit 03b31796cc
13 changed files with 143 additions and 31 deletions

View file

@ -322,6 +322,8 @@ void Net_ClearBuffers ()
memset (netcmds, 0, sizeof(netcmds));
memset (nettics, 0, sizeof(nettics));
memset (nodeingame, 0, sizeof(nodeingame));
memset (nodeforplayer, 0, sizeof(nodeforplayer));
memset (playerfornode, 0, sizeof(playerfornode));
memset (remoteresend, 0, sizeof(remoteresend));
memset (resendto, 0, sizeof(resendto));
memset (resendcount, 0, sizeof(resendcount));

View file

@ -59,13 +59,6 @@ void ASkyViewpoint::BeginPlay ()
void ASkyViewpoint::Destroy ()
{
// remove all sector references to ourselves.
for (int i = 0; i < numsectors; i++)
{
if (sectors[i].GetPortal(sector_t::floor)->mSkybox == this)
sectors[i].ClearPortal(sector_t::floor);
if (sectors[i].GetPortal(sector_t::ceiling)->mSkybox == this)
sectors[i].ClearPortal(sector_t::ceiling);
}
for (auto &s : sectorPortals)
{
if (s.mSkybox == this) s.mSkybox = 0;

View file

@ -367,11 +367,11 @@ int FMugShot::UpdateState(player_t *player, StateFlags stateflags)
DAngle diffang = deltaangle(player->mo->Angles.Yaw, badguyangle);
if (diffang > 45.)
{ // turn face right
damage_angle = 0;
damage_angle = 2;
}
else if (diffang < -45.)
{ // turn face left
damage_angle = 2;
damage_angle = 0;
}
}
}

View file

@ -942,7 +942,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
bool forcedPain = false;
int fakeDamage = 0;
int holdDamage = 0;
int rawdamage = damage;
const int rawdamage = damage;
if (damage < 0) damage = 0;
@ -1267,7 +1267,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
else
return -1;
}
// Armor for players.
if (!(flags & DMG_NO_ARMOR) && player->mo->Inventory != NULL)
{
int newdam = damage;
@ -1280,15 +1280,21 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage,
// if we are telefragging don't let the damage value go below that magic value. Some further checks would fail otherwise.
damage = newdam;
}
if (damage <= 0)
{
// [MC] Godmode doesn't need checking here, it's already being handled above.
if ((target->flags5 & MF5_NOPAIN) || (inflictor && (inflictor->flags5 & MF5_PAINLESS)))
return damage;
// If MF6_FORCEPAIN is set, make the player enter the pain state.
if (!(target->flags5 & MF5_NOPAIN) && inflictor != NULL &&
(inflictor->flags6 & MF6_FORCEPAIN) && !(inflictor->flags5 & MF5_PAINLESS)
&& (!(player->mo->flags2 & MF2_INVULNERABLE)) && (!(player->cheats & CF_GODMODE)) && (!(player->cheats & CF_GODMODE2)))
{
if ((inflictor && (inflictor->flags6 & MF6_FORCEPAIN)))
goto dopain;
else if (((player->mo->flags7 & MF7_ALLOWPAIN) && (rawdamage > 0)) ||
(inflictor && (inflictor->flags7 & MF7_CAUSEPAIN)))
{
invulpain = true;
goto fakepain;
}
return damage;
}

View file

@ -343,6 +343,7 @@ enum
RADF_NOIMPACTDAMAGE = 2,
RADF_SOURCEISSPOT = 4,
RADF_NODAMAGE = 8,
RADF_THRUSTZ = 16,
};
void P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance,
FName damageType, int flags, int fulldamagedistance=0);

View file

@ -2535,11 +2535,7 @@ bool P_CheckMove(AActor *thing, const DVector2 &pos, int flags)
}
else if ((flags & PCM_DROPOFF) && !(thing->flags & (MF_FLOAT|MF_DROPOFF)))
{
const DVector3 oldpos = thing->Pos();
thing->SetOrigin(pos.X, pos.Y, newz, true);
bool hcheck = (newz - thing->dropoffz > thing->MaxDropOffHeight);
thing->SetOrigin(oldpos, true);
if (hcheck)
if (newz - tm.dropoffz > thing->MaxDropOffHeight)
{
return false;
}
@ -4844,7 +4840,7 @@ void P_AimCamera(AActor *t1, DVector3 &campos, DAngle &camangle, sector_t *&Came
}
else
{
campos = trace.HitPos;
campos = trace.HitPos - trace.HitVector * 1/256.;
}
CameraSector = trace.Sector;
unlinked = trace.unlinked;
@ -5325,7 +5321,7 @@ void P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bo
vz *= 0.8;
}
thing->Thrust(bombspot->AngleTo(thing), thrust);
if (!(flags & RADF_NODAMAGE))
if (!(flags & RADF_NODAMAGE) || (flags & RADF_THRUSTZ))
thing->Vel.Z += vz; // this really doesn't work well
}
}

View file

@ -231,6 +231,10 @@ FArchive &operator<< (FArchive &arc, FSectorPortal &port)
<< port.mDestination
<< port.mDisplacement
<< port.mPlaneZ;
if (arc.IsLoading())
{
port.mSkybox = nullptr;
}
return arc;
}

View file

@ -191,7 +191,6 @@ struct FLinePortal
double mSinRot;
double mCosRot;
portnode_t *render_thinglist;
void *mRenderData;
};
extern TArray<FLinePortal> linePortals;
@ -229,7 +228,6 @@ struct FSectorPortal
DVector2 mDisplacement;
double mPlaneZ;
TObjPtr<AActor> mSkybox;
void *mRenderData;
bool MergeAllowed() const
{

View file

@ -2352,6 +2352,7 @@ void R_CheckDrawSegs ()
ptrdiff_t R_NewOpening (ptrdiff_t len)
{
ptrdiff_t res = lastopening;
len = (len + 1) & ~1; // only return DWORD aligned addresses because some code stores fixed_t's and floats in openings...
lastopening += len;
if ((size_t)lastopening > maxopenings)
{
@ -2512,6 +2513,7 @@ void R_StoreWallRange (int start, int stop)
if(sidedef->GetTexture(side_t::mid).isValid())
ds_p->bFakeBoundary |= 4; // it is also mid texture
// note: This should never have used the openings array to store its data!
ds_p->maskedtexturecol = R_NewOpening ((stop - start) * 2);
ds_p->swall = R_NewOpening ((stop - start) * 2);

View file

@ -1188,7 +1188,7 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(BYTE *sfxdata, int le
int sum = 0;
for(size_t c = 0;c < chancount;c++)
sum += sfxdata[i*chancount + c];
sfxdata[i] = sum / chancount;
sfxdata[i] = short(sum / chancount);
}
}
else if(type == SampleType_UInt8)
@ -1199,10 +1199,10 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(BYTE *sfxdata, int le
int sum = 0;
for(size_t c = 0;c < chancount;c++)
sum += sfxdata[i*chancount + c] - 128;
sfxdata[i] = (sum / chancount) + 128;
sfxdata[i] = BYTE((sum / chancount) + 128);
}
}
data.Resize(data.Size()/chancount);
data.Resize(unsigned(data.Size()/chancount));
}
ALenum err;

View file

@ -386,6 +386,103 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetGibHealth)
return 0;
}
//==========================================================================
//
// GetZAt
//
// NON-ACTION function to get the floor or ceiling z at (x, y) with
// relativity being an option.
//==========================================================================
enum GZFlags
{
GZF_ABSOLUTEPOS = 1, // Use the absolute position instead of an offsetted one.
GZF_ABSOLUTEANG = 1 << 1, // Don't add the actor's angle to the parameter.
GZF_CEILING = 1 << 2, // Check the ceiling instead of the floor.
GZF_3DRESTRICT = 1 << 3, // Ignore midtextures and 3D floors above the pointer's z.
GZF_NOPORTALS = 1 << 4, // Don't pass through any portals.
GZF_NO3DFLOOR = 1 << 5, // Pass all 3D floors.
};
DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetZAt)
{
if (numret > 0)
{
assert(ret != NULL);
PARAM_SELF_PROLOGUE(AActor);
PARAM_FLOAT_OPT(px) { px = 0.; }
PARAM_FLOAT_OPT(py) { py = 0.; }
PARAM_ANGLE_OPT(angle) { angle = 0.; }
PARAM_INT_OPT(flags) { flags = 0; }
PARAM_INT_OPT(pick_pointer) { pick_pointer = AAPTR_DEFAULT; }
AActor *mobj = COPY_AAPTR(self, pick_pointer);
if (mobj == nullptr)
{
ret->SetFloat(0);
}
else
{
// [MC] At any time, the NextLowest/Highest functions could be changed to include
// more FFC flags to check. Don't risk it by just passing flags straight to it.
DVector2 pos = { px, py };
double z = 0.;
int pflags = (flags & GZF_3DRESTRICT) ? FFCF_3DRESTRICT : 0;
if (flags & GZF_NOPORTALS) pflags |= FFCF_NOPORTALS;
if (!(flags & GZF_ABSOLUTEPOS))
{
if (!(flags & GZF_ABSOLUTEANG))
{
angle += mobj->Angles.Yaw;
}
double s = angle.Sin();
double c = angle.Cos();
pos = mobj->Vec2Offset(pos.X * c + pos.Y * s, pos.X * s - pos.Y * c);
}
sector_t *sec = P_PointInSector(pos);
if (sec)
{
if (flags & GZF_CEILING)
{
if ((flags & GZF_NO3DFLOOR) && (flags & GZF_NOPORTALS))
{
z = sec->ceilingplane.ZatPoint(pos);
}
else if (flags & GZF_NO3DFLOOR)
{
z = sec->HighestCeilingAt(pos);
}
else
{ // [MC] Handle strict 3D floors and portal toggling via the flags passed to it.
z = sec->NextHighestCeilingAt(pos.X, pos.Y, mobj->Z(), mobj->Top(), pflags);
}
}
else
{
if ((flags & GZF_NO3DFLOOR) && (flags & GZF_NOPORTALS))
{
z = sec->floorplane.ZatPoint(pos);
}
else if (flags & GZF_NO3DFLOOR)
{
z = sec->LowestFloorAt(pos);
}
else
{
z = sec->NextLowestFloorAt(pos.X, pos.Y, mobj->Z(), pflags, mobj->MaxStepHeight);
}
}
}
ret->SetFloat(z);
return 1;
}
}
return 0;
}
//===========================================================================
//
// __decorate_internal_state__
@ -1143,9 +1240,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Explode)
enum
{
RTF_AFFECTSOURCE = 1,
RTF_NOIMPACTDAMAGE = 2,
RTF_NOTMISSILE = 4,
RTF_AFFECTSOURCE = 1,
RTF_NOIMPACTDAMAGE = 2,
RTF_NOTMISSILE = 4,
};
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusThrust)

View file

@ -43,6 +43,7 @@ ACTOR Actor native //: Thinker
native int CountInv(class<Inventory> itemtype, int ptr_select = AAPTR_DEFAULT);
native float GetDistance(bool checkz, int ptr = AAPTR_DEFAULT);
native float GetAngle(bool relative, int ptr = AAPTR_DEFAULT);
native float GetZAt(float px = 0, float py = 0, float angle = 0, int flags = 0, int pick_pointer = AAPTR_DEFAULT);
native int GetSpawnHealth();
native int GetGibHealth();

View file

@ -178,6 +178,7 @@ const int XF_NOTMISSILE = 4;
const int RTF_AFFECTSOURCE = 1;
const int RTF_NOIMPACTDAMAGE = 2;
const int RTF_NOTMISSILE = 4;
const int RTF_THRUSTZ = 16;
// Flags for A_Blast
const int BF_USEAMMO = 1;
@ -549,3 +550,14 @@ enum
FMDF_INTERPOLATE = 1 << 1,
FMDF_NOANGLE = 1 << 2,
};
// Flags for GetZAt
enum
{
GZF_ABSOLUTEPOS = 1, // Use the absolute position instead of an offsetted one.
GZF_ABSOLUTEANG = 1 << 1, // Don't add the actor's angle to the parameter.
GZF_CEILING = 1 << 2, // Check the ceiling instead of the floor.
GZF_3DRESTRICT = 1 << 3, // Ignore midtextures and 3D floors above the pointer's z.
GZF_NOPORTALS = 1 << 4, // Don't pass through any portals.
GZF_NO3DFLOOR = 1 << 5, // Pass all 3D floors.
};