mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 22:11:43 +00:00
Merge remote-tracking branch 'gzdoom/master' into materials
This commit is contained in:
commit
6652df40c1
36 changed files with 227 additions and 58 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -54,3 +54,4 @@
|
|||
.vs
|
||||
/src/gl/unused
|
||||
/mapfiles_release/*.map
|
||||
.DS_Store
|
||||
|
|
|
@ -886,6 +886,12 @@ public:
|
|||
|
||||
|
||||
// a full 3D version of the above
|
||||
double Distance3DSquared(AActor *other, bool absolute = false)
|
||||
{
|
||||
DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
|
||||
return (Pos() - otherpos).LengthSquared();
|
||||
}
|
||||
|
||||
double Distance3D(AActor *other, bool absolute = false)
|
||||
{
|
||||
DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
|
||||
|
|
|
@ -92,6 +92,7 @@ enum
|
|||
CP_SETTHINGSKILLS,
|
||||
CP_SETSECTORTEXTURE,
|
||||
CP_SETSECTORLIGHT,
|
||||
CP_SETLINESECTORREF,
|
||||
};
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
@ -283,6 +284,18 @@ void ParseCompatibility()
|
|||
CompatParams.Push(sc.Number);
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("setlinesectorref"))
|
||||
{
|
||||
if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
|
||||
CompatParams.Push(CP_SETLINESECTORREF);
|
||||
sc.MustGetNumber();
|
||||
CompatParams.Push(sc.Number);
|
||||
sc.MustGetString();
|
||||
CompatParams.Push(sc.MustMatchString(LineSides));
|
||||
sc.MustGetNumber();
|
||||
CompatParams.Push(sc.Number);
|
||||
flags.CompatFlags[SLOT_BCOMPAT] |= BCOMPATF_REBUILDNODES;
|
||||
}
|
||||
else if (sc.Compare("clearlinespecial"))
|
||||
{
|
||||
if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
|
||||
|
@ -719,6 +732,22 @@ void SetCompatibilityParams()
|
|||
i += 3;
|
||||
break;
|
||||
}
|
||||
case CP_SETLINESECTORREF:
|
||||
{
|
||||
if ((unsigned)CompatParams[i + 1] < level.lines.Size())
|
||||
{
|
||||
line_t *line = &level.lines[CompatParams[i + 1]];
|
||||
assert(line != nullptr);
|
||||
side_t *side = line->sidedef[CompatParams[i + 2]];
|
||||
if (side != nullptr && (unsigned)CompatParams[i + 3] < level.sectors.Size())
|
||||
{
|
||||
side->sector = &level.sectors[CompatParams[i + 3]];
|
||||
}
|
||||
}
|
||||
i += 4;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1196,6 +1196,10 @@ static int PatchThing (int thingy)
|
|||
// triggering line effects and can teleport when the missile flag is removed.
|
||||
info->flags2 &= ~MF2_NOTELEPORT;
|
||||
}
|
||||
if (thingy == 1) // [SP] special handling for players - always be friendly!
|
||||
{
|
||||
value[0] |= MF_FRIENDLY;
|
||||
}
|
||||
info->flags = ActorFlags::FromInt (value[0]);
|
||||
}
|
||||
if (vchanged[1])
|
||||
|
@ -2836,14 +2840,14 @@ static bool LoadDehSupp ()
|
|||
sc.MustGetString();
|
||||
PClassActor *actortype = static_cast<PClassActor *>(type);
|
||||
s.State = actortype->FindState(sc.String);
|
||||
if (s.State == NULL)
|
||||
if (s.State == NULL && addit)
|
||||
{
|
||||
sc.ScriptError("Invalid state '%s' in '%s'", sc.String, type->TypeName.GetChars());
|
||||
}
|
||||
|
||||
sc.MustGetStringName(",");
|
||||
sc.MustGetNumber();
|
||||
if (s.State == NULL || sc.Number < 1 || !actortype->OwnsState(s.State + sc.Number - 1))
|
||||
if (addit && (s.State == NULL || sc.Number < 1 || !actortype->OwnsState(s.State + sc.Number - 1)))
|
||||
{
|
||||
sc.ScriptError("Invalid state range in '%s'", type->TypeName.GetChars());
|
||||
}
|
||||
|
|
|
@ -149,6 +149,7 @@ FGameConfigFile::FGameConfigFile ()
|
|||
SetValueForKey ("Path", "$PROGDIR", true);
|
||||
#else
|
||||
SetValueForKey ("Path", "$HOME/" GAME_DIR, true);
|
||||
SetValueForKey ("Path", SHARE_DIR, true);
|
||||
SetValueForKey ("Path", "/usr/local/share/doom", true);
|
||||
SetValueForKey ("Path", "/usr/local/share/games/doom", true);
|
||||
SetValueForKey ("Path", "/usr/share/doom", true);
|
||||
|
|
|
@ -1211,7 +1211,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
|
|||
}
|
||||
|
||||
double timefrac = r_viewpoint.TicFrac;
|
||||
if (paused || bglobal.freeze)
|
||||
if (paused || bglobal.freeze || (level.flags2 & LEVEL2_FROZEN))
|
||||
timefrac = 0.;
|
||||
float xvf = (particle->Vel.X) * timefrac;
|
||||
float yvf = (particle->Vel.Y) * timefrac;
|
||||
|
|
|
@ -1060,8 +1060,8 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
|
|||
// Draw the stuff
|
||||
//
|
||||
//
|
||||
if (realfront->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) split.PutWall(translucent);
|
||||
else split.SplitWall(realfront, translucent);
|
||||
if (front->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) split.PutWall(translucent);
|
||||
else split.SplitWall(front, translucent);
|
||||
|
||||
t=1;
|
||||
}
|
||||
|
@ -1074,8 +1074,8 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
|
|||
// Draw the stuff without splitting
|
||||
//
|
||||
//
|
||||
if (realfront->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) PutWall(translucent);
|
||||
else SplitWall(realfront, translucent);
|
||||
if (front->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) PutWall(translucent);
|
||||
else SplitWall(front, translucent);
|
||||
}
|
||||
alpha=1.0f;
|
||||
}
|
||||
|
@ -1437,7 +1437,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
sector_t * segback;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (seg->linedef->Index() == 1)
|
||||
if (seg->linedef->Index() == 10)
|
||||
{
|
||||
int a = 0;
|
||||
}
|
||||
|
|
|
@ -244,6 +244,7 @@ struct FActorInfo
|
|||
PClassActor *Replacee = nullptr;
|
||||
FState *OwnedStates = nullptr;
|
||||
int NumOwnedStates = 0;
|
||||
bool SkipSuperSet = false;
|
||||
uint8_t GameFilter = GAME_Any;
|
||||
uint16_t SpawnID = 0;
|
||||
uint16_t ConversationID = 0;
|
||||
|
@ -287,7 +288,7 @@ struct FActorInfo
|
|||
};
|
||||
|
||||
// This is now merely a wrapper that adds actor-specific functionality to PClass.
|
||||
// No objects of this type will be created ever - its only use is to static_casr
|
||||
// No objects of this type will be created ever - its only use is to static_cast
|
||||
// PClass to it.
|
||||
class PClassActor : public PClass
|
||||
{
|
||||
|
|
|
@ -377,6 +377,8 @@ xx(MomZ)
|
|||
xx(Threshold)
|
||||
xx(DefThreshold)
|
||||
xx(Abs)
|
||||
xx(TeleportSpecial)
|
||||
xx(Teleport)
|
||||
xx(ACS_NamedExecuteWithResult)
|
||||
xx(CallACS)
|
||||
xx(Sqrt)
|
||||
|
|
|
@ -814,8 +814,8 @@ void FNodeBuilder::SplitSegs (uint32_t set, node_t &node, uint32_t splitseg, uin
|
|||
frac = InterceptVector (node, *seg);
|
||||
newvert.x = Vertices[seg->v1].x;
|
||||
newvert.y = Vertices[seg->v1].y;
|
||||
newvert.x += fixed_t(frac * double(Vertices[seg->v2].x - newvert.x));
|
||||
newvert.y += fixed_t(frac * double(Vertices[seg->v2].y - newvert.y));
|
||||
newvert.x += fixed_t(frac * (double(Vertices[seg->v2].x) - newvert.x));
|
||||
newvert.y += fixed_t(frac * (double(Vertices[seg->v2].y) - newvert.y));
|
||||
vertnum = VertexMap->SelectVertexClose (newvert);
|
||||
|
||||
if (vertnum != (unsigned int)seg->v1 && vertnum != (unsigned int)seg->v2)
|
||||
|
|
|
@ -91,6 +91,8 @@ struct FSimpleVert
|
|||
fixed_t x, y;
|
||||
};
|
||||
|
||||
typedef int64_t fixed64_t;
|
||||
|
||||
class FNodeBuilder
|
||||
{
|
||||
struct FPrivSeg
|
||||
|
@ -167,14 +169,14 @@ class FNodeBuilder
|
|||
FNodeBuilder &MyBuilder;
|
||||
TArray<int> *VertexGrid;
|
||||
|
||||
fixed_t MinX, MinY, MaxX, MaxY;
|
||||
fixed64_t MinX, MinY, MaxX, MaxY;
|
||||
int BlocksWide, BlocksTall;
|
||||
|
||||
enum { BLOCK_SHIFT = 8 + FRACBITS };
|
||||
enum { BLOCK_SIZE = 1 << BLOCK_SHIFT };
|
||||
|
||||
int InsertVertex (FPrivVert &vert);
|
||||
inline int GetBlock (fixed_t x, fixed_t y)
|
||||
inline int GetBlock (fixed64_t x, fixed64_t y)
|
||||
{
|
||||
assert (x >= MinX);
|
||||
assert (y >= MinY);
|
||||
|
|
|
@ -641,8 +641,8 @@ FNodeBuilder::FVertexMap::FVertexMap (FNodeBuilder &builder,
|
|||
MinY = miny;
|
||||
BlocksWide = int(((double(maxx) - minx + 1) + (BLOCK_SIZE - 1)) / BLOCK_SIZE);
|
||||
BlocksTall = int(((double(maxy) - miny + 1) + (BLOCK_SIZE - 1)) / BLOCK_SIZE);
|
||||
MaxX = MinX + BlocksWide * BLOCK_SIZE - 1;
|
||||
MaxY = MinY + BlocksTall * BLOCK_SIZE - 1;
|
||||
MaxX = MinX + fixed64_t(BlocksWide) * BLOCK_SIZE - 1;
|
||||
MaxY = MinY + fixed64_t(BlocksTall) * BLOCK_SIZE - 1;
|
||||
VertexGrid = new TArray<int>[BlocksWide * BlocksTall];
|
||||
}
|
||||
|
||||
|
@ -703,10 +703,10 @@ int FNodeBuilder::FVertexMap::InsertVertex (FNodeBuilder::FPrivVert &vert)
|
|||
// If a vertex is near a block boundary, then it will be inserted on
|
||||
// both sides of the boundary so that SelectVertexClose can find
|
||||
// it by checking in only one block.
|
||||
fixed_t minx = MAX (MinX, vert.x - VERTEX_EPSILON);
|
||||
fixed_t maxx = MIN (MaxX, vert.x + VERTEX_EPSILON);
|
||||
fixed_t miny = MAX (MinY, vert.y - VERTEX_EPSILON);
|
||||
fixed_t maxy = MIN (MaxY, vert.y + VERTEX_EPSILON);
|
||||
fixed64_t minx = MAX (MinX, fixed64_t(vert.x) - VERTEX_EPSILON);
|
||||
fixed64_t maxx = MIN (MaxX, fixed64_t(vert.x) + VERTEX_EPSILON);
|
||||
fixed64_t miny = MAX (MinY, fixed64_t(vert.y) - VERTEX_EPSILON);
|
||||
fixed64_t maxy = MIN (MaxY, fixed64_t(vert.y) + VERTEX_EPSILON);
|
||||
|
||||
int blk[4] =
|
||||
{
|
||||
|
|
|
@ -898,7 +898,9 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
|
|||
}
|
||||
|
||||
// check if the actor can step through the ceiling portal. In this case one-sided lines in the current area should not block
|
||||
if (!cres.line->frontsector->PortalBlocksMovement(sector_t::ceiling))
|
||||
// Use the same rules for stepping through a portal as for non-portal case.
|
||||
bool ismissile = (tm.thing->flags & MF_MISSILE) && !(tm.thing->flags6 & MF6_STEPMISSILE) && !(tm.thing->flags3 & MF3_FLOORHUGGER);
|
||||
if (!ismissile && !cres.line->frontsector->PortalBlocksMovement(sector_t::ceiling))
|
||||
{
|
||||
double portz = cres.line->frontsector->GetPortalPlaneZ(sector_t::ceiling);
|
||||
if (tm.thing->Z() < portz && tm.thing->Z() + tm.thing->MaxStepHeight >= portz && tm.floorz < portz)
|
||||
|
@ -1008,7 +1010,9 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
|
|||
FLineOpening open;
|
||||
|
||||
P_LineOpening(open, tm.thing, ld, ref, &cres.Position, cres.portalflags);
|
||||
if (!tm.thing->Sector->PortalBlocksMovement(sector_t::ceiling))
|
||||
// Use the same rules for stepping through a portal as for non-portal case.
|
||||
bool ismissile = (tm.thing->flags & MF_MISSILE) && !(tm.thing->flags6 & MF6_STEPMISSILE) && !(tm.thing->flags3 & MF3_FLOORHUGGER);
|
||||
if (!ismissile && !tm.thing->Sector->PortalBlocksMovement(sector_t::ceiling))
|
||||
{
|
||||
sector_t *oppsec = cres.line->frontsector == tm.thing->Sector ? cres.line->backsector : cres.line->frontsector;
|
||||
if (oppsec->PortalBlocksMovement(sector_t::ceiling))
|
||||
|
@ -2707,8 +2711,8 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
|
|||
FLinkContext ctx;
|
||||
DVector3 oldpos = thing->Pos();
|
||||
thing->UnlinkFromWorld(&ctx);
|
||||
thing->SetXYZ(thing->PosRelative(thing->Sector->GetOppositePortalGroup(sector_t::ceiling)));
|
||||
thing->Prev = thing->Pos() - oldpos;
|
||||
thing->SetXYZ(thing->PosRelative(tm.portalgroup));
|
||||
thing->Prev += thing->Pos() - oldpos;
|
||||
thing->Sector = P_PointInSector(thing->Pos());
|
||||
thing->PrevPortalGroup = thing->Sector->PortalGroup;
|
||||
thing->LinkToWorld(&ctx);
|
||||
|
|
|
@ -8127,6 +8127,20 @@ DEFINE_ACTION_FUNCTION(AActor, absangle) // should this be global?
|
|||
ACTION_RETURN_FLOAT(absangle(DAngle(a1), DAngle(a2)).Degrees);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, Distance2DSquared)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_OBJECT_NOT_NULL(other, AActor);
|
||||
ACTION_RETURN_FLOAT(self->Distance2DSquared(other));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, Distance3DSquared)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_OBJECT_NOT_NULL(other, AActor);
|
||||
ACTION_RETURN_FLOAT(self->Distance3DSquared(other));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, Distance2D)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
|
|
|
@ -4138,15 +4138,18 @@ void P_SetupLevel (const char *lumpname, int position)
|
|||
|
||||
// [SP] move unfriendly players around
|
||||
// horribly hacky - yes, this needs rewritten.
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
if (level.deathmatchstarts.Size () > 0)
|
||||
{
|
||||
if (playeringame[i] && players[i].mo != NULL)
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (!(players[i].mo->flags & MF_FRIENDLY))
|
||||
if (playeringame[i] && players[i].mo != NULL)
|
||||
{
|
||||
AActor * oldSpawn = players[i].mo;
|
||||
G_DeathMatchSpawnPlayer (i);
|
||||
oldSpawn->Destroy();
|
||||
if (!(players[i].mo->flags & MF_FRIENDLY))
|
||||
{
|
||||
AActor * oldSpawn = players[i].mo;
|
||||
G_DeathMatchSpawnPlayer (i);
|
||||
oldSpawn->Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ EXTERN_CVAR(Int, gl_particles_style)
|
|||
void RenderPolyParticle::Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t stencilValue)
|
||||
{
|
||||
double timefrac = r_viewpoint.TicFrac;
|
||||
if (paused || bglobal.freeze)
|
||||
if (paused || bglobal.freeze || (level.flags2 & LEVEL2_FROZEN))
|
||||
timefrac = 0.;
|
||||
DVector3 pos = particle->Pos + (particle->Vel * timefrac);
|
||||
double psize = particle->size / 8.0;
|
||||
|
|
|
@ -677,7 +677,7 @@ void S_UnloadReverbDef ()
|
|||
Environments = &Off;
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, eaxedit_test, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
CUSTOM_CVAR(Bool, eaxedit_test, false, CVAR_NOINITCALL)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
|
|
|
@ -7758,6 +7758,8 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
|
|||
}
|
||||
else
|
||||
{
|
||||
// This alias is needed because Actor has a Teleport function.
|
||||
if (MethodName == NAME_TeleportSpecial) MethodName = NAME_Teleport;
|
||||
special = P_FindLineSpecial(MethodName.GetChars(), &min, &max);
|
||||
}
|
||||
if (special != 0 && min >= 0)
|
||||
|
|
|
@ -540,7 +540,7 @@ DEFINE_PROPERTY(skip_super, 0, Actor)
|
|||
if (info->Size != actorclass->Size)
|
||||
{
|
||||
bag.ScriptPosition.Message(MSG_OPTERROR,
|
||||
"'skip_super' is only allowed in subclasses of AActor with no additional fields and will be ignored in type %s.", info->TypeName.GetChars());
|
||||
"'skip_super' is only allowed in subclasses of Actor with no additional fields and will be ignored in type %s.", info->TypeName.GetChars());
|
||||
return;
|
||||
}
|
||||
if (bag.StateSet)
|
||||
|
@ -552,6 +552,7 @@ DEFINE_PROPERTY(skip_super, 0, Actor)
|
|||
|
||||
*defaults = *GetDefault<AActor>();
|
||||
ResetBaggage (&bag, RUNTIME_CLASS(AActor));
|
||||
static_cast<PClassActor*>(bag.Info)->ActorInfo()->SkipSuperSet = true; // ZScript processes the states later so this property must be flagged for later handling.
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -1968,7 +1968,10 @@ void PDynArray::SetPointerArray(void *base, unsigned offset, TArray<size_t> *spe
|
|||
void PDynArray::WriteValue(FSerializer &ar, const char *key, const void *addr) const
|
||||
{
|
||||
FArray *aray = (FArray*)addr;
|
||||
if (aray->Count > 0)
|
||||
// We may skip an empty array only if it gets stored under a named key.
|
||||
// If no name is given, i.e. it's part of an outer array's element list, even empty arrays must be stored,
|
||||
// because otherwise the array would lose its entry.
|
||||
if (aray->Count > 0 || key == nullptr)
|
||||
{
|
||||
if (ar.BeginArray(key))
|
||||
{
|
||||
|
|
|
@ -2872,7 +2872,18 @@ void ZCCCompiler::CompileStates()
|
|||
|
||||
FString statename; // The state builder wants the label as one complete string, not separated into tokens.
|
||||
FStateDefinitions statedef;
|
||||
statedef.MakeStateDefines(ValidateActor(c->ClassType()->ParentClass));
|
||||
|
||||
if (static_cast<PClassActor*>(c->ClassType())->ActorInfo()->SkipSuperSet)
|
||||
{
|
||||
// SKIP_SUPER'ed actors only get the base states from AActor.
|
||||
statedef.MakeStateDefines(RUNTIME_CLASS(AActor));
|
||||
}
|
||||
else
|
||||
{
|
||||
statedef.MakeStateDefines(ValidateActor(c->ClassType()->ParentClass));
|
||||
}
|
||||
|
||||
|
||||
int numframes = 0;
|
||||
|
||||
for (auto s : c->States)
|
||||
|
|
|
@ -267,6 +267,7 @@ static void ParseSingleFile(FScanner *pSC, const char *filename, int lump, void
|
|||
|
||||
while (sc.GetToken())
|
||||
{
|
||||
value.Largest = 0;
|
||||
value.SourceLoc = sc.GetMessageLine();
|
||||
switch (sc.TokenType)
|
||||
{
|
||||
|
|
|
@ -7,11 +7,31 @@
|
|||
|
||||
struct ZCCToken
|
||||
{
|
||||
template <typename... Ts>
|
||||
struct TLargest;
|
||||
|
||||
template <typename T>
|
||||
struct TLargest<T>
|
||||
{
|
||||
using Type = T;
|
||||
};
|
||||
|
||||
template <typename T, typename U, typename... Ts>
|
||||
struct TLargest<T, U, Ts...>
|
||||
{
|
||||
using Type = typename TLargest<
|
||||
typename std::conditional<
|
||||
(sizeof(T) > sizeof(U)), T, U
|
||||
>::type, Ts...
|
||||
>::Type;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
int Int;
|
||||
double Float;
|
||||
FString *String;
|
||||
TLargest<decltype(Int), decltype(Float), decltype(String)>::Type Largest;
|
||||
};
|
||||
int SourceLoc;
|
||||
|
||||
|
|
|
@ -692,6 +692,10 @@ bool TimidityPPMIDIDevice::FillStream(SoundStream *stream, void *buff, int len,
|
|||
}
|
||||
break;
|
||||
}
|
||||
else if (r == 0 && errno != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
got += r;
|
||||
} while(got < len);
|
||||
if(got < len)
|
||||
|
|
|
@ -745,6 +745,14 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, uint32_t max_time)
|
|||
if (InitialPlayback)
|
||||
{
|
||||
InitialPlayback = false;
|
||||
// Send the GS System Reset SysEx message.
|
||||
events[0] = 0; // dwDeltaTime
|
||||
events[1] = 0; // dwStreamID
|
||||
events[2] = (MEVENT_LONGMSG << 24) | 6; // dwEvent
|
||||
events[3] = MAKE_ID(0xf0, 0x7e, 0x7f, 0x09); // dwParms[0]
|
||||
events[4] = MAKE_ID(0x01, 0xf7, 0x00, 0x00); // dwParms[1]
|
||||
events += 5;
|
||||
|
||||
// Send the full master volume SysEx message.
|
||||
events[0] = 0; // dwDeltaTime
|
||||
events[1] = 0; // dwStreamID
|
||||
|
@ -752,6 +760,7 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, uint32_t max_time)
|
|||
events[3] = MAKE_ID(0xf0,0x7f,0x7f,0x04); // dwParms[0]
|
||||
events[4] = MAKE_ID(0x01,0x7f,0x7f,0xf7); // dwParms[1]
|
||||
events += 5;
|
||||
|
||||
DoInitialSetup();
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace swrenderer
|
|||
sector_t* heightsec = NULL;
|
||||
|
||||
double timefrac = r_viewpoint.TicFrac;
|
||||
if (paused || bglobal.freeze)
|
||||
if (paused || bglobal.freeze || (level.flags2 & LEVEL2_FROZEN))
|
||||
timefrac = 0.;
|
||||
|
||||
double ippx = particle->Pos.X + particle->Vel.X * timefrac;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#include "v_text.h"
|
||||
|
||||
|
@ -387,7 +388,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bo
|
|||
continue;
|
||||
}
|
||||
|
||||
if (isspace(c))
|
||||
if (iswspace(c))
|
||||
{
|
||||
if (!lastWasSpace)
|
||||
{
|
||||
|
@ -420,12 +421,12 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bo
|
|||
start = space;
|
||||
space = NULL;
|
||||
|
||||
while (*start && isspace (*start) && *start != '\n')
|
||||
while (*start && iswspace (*start) && *start != '\n')
|
||||
start++;
|
||||
if (*start == '\n')
|
||||
start++;
|
||||
else
|
||||
while (*start && isspace (*start))
|
||||
while (*start && iswspace (*start))
|
||||
start++;
|
||||
string = start;
|
||||
}
|
||||
|
@ -443,7 +444,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bo
|
|||
while (s < string)
|
||||
{
|
||||
// If there is any non-white space in the remainder of the string, add it.
|
||||
if (!isspace (*s++))
|
||||
if (!iswspace (*s++))
|
||||
{
|
||||
auto i = Lines.Reserve(1);
|
||||
breakit (&Lines[i], font, start, string, linecolor);
|
||||
|
|
|
@ -868,3 +868,17 @@ CA3773ED313E8899311F3DD0CA195A68 // e3m6
|
|||
{
|
||||
shorttex
|
||||
}
|
||||
|
||||
FCCA97FC851F6473EAA069F74247B317 // pg-raw.wad map31
|
||||
{
|
||||
setlinesectorref 331 front 74
|
||||
setlinesectorref 326 front 74
|
||||
setlinesectorref 497 front 74
|
||||
setlinesectorref 474 front 74
|
||||
setlinesectorref 471 front 74
|
||||
setlinesectorref 327 front 74
|
||||
setlinesectorref 328 front 74
|
||||
setlinesectorref 329 front 74
|
||||
setsectortag 74 4
|
||||
setlinespecial 357 Transfer_Heights 4 2 0 0 0
|
||||
}
|
||||
|
|
|
@ -580,6 +580,8 @@ class Actor : Thinker native
|
|||
native void SetDamage(int dmg);
|
||||
native clearscope double Distance2D(Actor other) const;
|
||||
native clearscope double Distance3D(Actor other) const;
|
||||
native clearscope double Distance2DSquared(Actor other) const;
|
||||
native clearscope double Distance3DSquared(Actor other) const;
|
||||
native void SetOrigin(vector3 newpos, bool moving);
|
||||
native void SetXYZ(vector3 newpos);
|
||||
native Actor GetPointer(int aaptr);
|
||||
|
@ -1185,6 +1187,10 @@ class Actor : Thinker native
|
|||
{
|
||||
return ACS_ExecuteAlways(-int(script), mapnum, arg1, arg2, arg3);
|
||||
}
|
||||
int ACS_ScriptCall(name script, int arg1=0, int arg2=0, int arg3=0, int arg4=0)
|
||||
{
|
||||
return ACS_ExecuteWithResult(-int(script), arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
States(Actor, Overlay, Weapon, Item)
|
||||
{
|
||||
|
|
|
@ -416,6 +416,7 @@ enum ESoundFlags
|
|||
CHAN_MAYBE_LOCAL = 16,
|
||||
CHAN_UI = 32,
|
||||
CHAN_NOPAUSE = 64,
|
||||
CHAN_LOOP = 256,
|
||||
CHAN_PICKUP = (CHAN_ITEM|CHAN_MAYBE_LOCAL),
|
||||
CHAN_NOSTOP = 4096
|
||||
|
||||
|
|
|
@ -70,8 +70,13 @@ extend class Actor
|
|||
{
|
||||
if (mo.health > 0 && mo != self)
|
||||
{
|
||||
// other Keen not dead
|
||||
return;
|
||||
// Added check for Dehacked and repurposed inventory items.
|
||||
let inv = Inventory(mo);
|
||||
if (inv == null || inv.Owner == null)
|
||||
{
|
||||
// other Keen not dead
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Door_Open(doortag, 16);
|
||||
|
|
|
@ -244,6 +244,11 @@ class Korax : Actor
|
|||
|
||||
void A_KoraxMissile()
|
||||
{
|
||||
if (!target)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static const class<Actor> choices[] =
|
||||
{
|
||||
"WraithFX1", "Demon1FX1", "Demon2FX1", "FireDemonMissile", "CentaurFX", "SerpentFX"
|
||||
|
@ -282,6 +287,11 @@ class Korax : Actor
|
|||
|
||||
void KoraxFire (Class<Actor> type, int arm)
|
||||
{
|
||||
if (!target)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static const int extension[] =
|
||||
{
|
||||
KORAX_ARM_EXTENSION_SHORT,
|
||||
|
|
|
@ -1931,22 +1931,6 @@ class PowerMorph : Powerup
|
|||
|
||||
int savedMorphTics = MorphedPlayer.morphTics;
|
||||
MorphedPlayer.UndoPlayerMorph (MorphedPlayer, 0, !!(MorphedPlayer.MorphStyle & MRF_UNDOALWAYS));
|
||||
|
||||
// Abort if unmorph failed; in that case,
|
||||
// set the usual retry timer and return.
|
||||
if (MorphedPlayer != null && MorphedPlayer.morphTics)
|
||||
{
|
||||
// Transfer retry timeout
|
||||
// to the powerup's timer.
|
||||
EffectTics = MorphedPlayer.morphTics;
|
||||
// Reload negative morph tics;
|
||||
// use actual value; it may
|
||||
// be in use for animation.
|
||||
MorphedPlayer.morphTics = savedMorphTics;
|
||||
// Try again some time later
|
||||
return;
|
||||
}
|
||||
// Unmorph suceeded
|
||||
MorphedPlayer = null;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ class FastProjectile : Actor
|
|||
int count = 8;
|
||||
if (radius > 0)
|
||||
{
|
||||
while ( abs(Vel.X) > radius * count || abs(Vel.Y) > radius * count)
|
||||
while ( abs(Vel.X) >= radius * count || abs(Vel.Y) >= radius * count || abs(Vel.Z) >= height * count)
|
||||
{
|
||||
// we need to take smaller steps.
|
||||
count += count;
|
||||
|
|
|
@ -559,6 +559,21 @@ object SoulSphere
|
|||
frame SOUL { light SOULSPHERE }
|
||||
}
|
||||
|
||||
pulselight MEGASPHERE
|
||||
{
|
||||
color 0.5 0.5 0.4
|
||||
size 60
|
||||
secondarySize 63
|
||||
interval 2.0
|
||||
offset 0 16 0
|
||||
attenuate 1
|
||||
}
|
||||
|
||||
object MegaSphere
|
||||
{
|
||||
frame MEGA { light MEGASPHERE }
|
||||
}
|
||||
|
||||
// Invulnerability Sphere
|
||||
pulselight INVULN
|
||||
{
|
||||
|
|
|
@ -559,6 +559,21 @@ object SoulSphere
|
|||
frame SOUL { light SOULSPHERE }
|
||||
}
|
||||
|
||||
pulselight MEGASPHERE
|
||||
{
|
||||
color 0.5 0.5 0.4
|
||||
size 60
|
||||
secondarySize 63
|
||||
interval 2.0
|
||||
offset 0 16 0
|
||||
attenuate 1
|
||||
}
|
||||
|
||||
object MegaSphere
|
||||
{
|
||||
frame MEGA { light MEGASPHERE }
|
||||
}
|
||||
|
||||
// Invulnerability Sphere
|
||||
pulselight INVULN
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue