mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-01-31 04:50:48 +00:00
Merge branch 'master' into timidity++
# Conflicts: # src/sound/musicformats/music_midistream.cpp
This commit is contained in:
commit
4c0f68bcd4
41 changed files with 430 additions and 132 deletions
|
@ -886,6 +886,12 @@ public:
|
||||||
|
|
||||||
|
|
||||||
// a full 3D version of the above
|
// 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)
|
double Distance3D(AActor *other, bool absolute = false)
|
||||||
{
|
{
|
||||||
DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
|
DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
|
||||||
|
|
|
@ -92,6 +92,7 @@ enum
|
||||||
CP_SETTHINGSKILLS,
|
CP_SETTHINGSKILLS,
|
||||||
CP_SETSECTORTEXTURE,
|
CP_SETSECTORTEXTURE,
|
||||||
CP_SETSECTORLIGHT,
|
CP_SETSECTORLIGHT,
|
||||||
|
CP_SETLINESECTORREF,
|
||||||
};
|
};
|
||||||
|
|
||||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||||
|
@ -283,6 +284,18 @@ void ParseCompatibility()
|
||||||
CompatParams.Push(sc.Number);
|
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"))
|
else if (sc.Compare("clearlinespecial"))
|
||||||
{
|
{
|
||||||
if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
|
if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
|
||||||
|
@ -719,6 +732,22 @@ void SetCompatibilityParams()
|
||||||
i += 3;
|
i += 3;
|
||||||
break;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2840,14 +2840,14 @@ static bool LoadDehSupp ()
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
PClassActor *actortype = static_cast<PClassActor *>(type);
|
PClassActor *actortype = static_cast<PClassActor *>(type);
|
||||||
s.State = actortype->FindState(sc.String);
|
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.ScriptError("Invalid state '%s' in '%s'", sc.String, type->TypeName.GetChars());
|
||||||
}
|
}
|
||||||
|
|
||||||
sc.MustGetStringName(",");
|
sc.MustGetStringName(",");
|
||||||
sc.MustGetNumber();
|
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());
|
sc.ScriptError("Invalid state range in '%s'", type->TypeName.GetChars());
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,15 +40,18 @@
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
|
#include "vm.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Int, con_scaletext)
|
EXTERN_CVAR(Int, con_scaletext)
|
||||||
|
|
||||||
IMPLEMENT_CLASS(DHUDMessage, false, true)
|
IMPLEMENT_CLASS(DHUDMessageBase, true, true)
|
||||||
|
IMPLEMENT_POINTERS_START(DHUDMessageBase)
|
||||||
IMPLEMENT_POINTERS_START(DHUDMessage)
|
IMPLEMENT_POINTER(Next)
|
||||||
IMPLEMENT_POINTER(Next)
|
|
||||||
IMPLEMENT_POINTERS_END
|
IMPLEMENT_POINTERS_END
|
||||||
|
|
||||||
|
|
||||||
|
IMPLEMENT_CLASS(DHUDMessage, false, false)
|
||||||
|
|
||||||
IMPLEMENT_CLASS(DHUDMessageFadeOut, false, false)
|
IMPLEMENT_CLASS(DHUDMessageFadeOut, false, false)
|
||||||
IMPLEMENT_CLASS(DHUDMessageFadeInOut, false, false)
|
IMPLEMENT_CLASS(DHUDMessageFadeInOut, false, false)
|
||||||
IMPLEMENT_CLASS(DHUDMessageTypeOnFadeOut, false, false)
|
IMPLEMENT_CLASS(DHUDMessageTypeOnFadeOut, false, false)
|
||||||
|
@ -57,6 +60,68 @@ IMPLEMENT_CLASS(DHUDMessageTypeOnFadeOut, false, false)
|
||||||
* Basic HUD message. Appears and disappears without any special effects *
|
* Basic HUD message. Appears and disappears without any special effects *
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
|
void DHUDMessageBase::Serialize(FSerializer &arc)
|
||||||
|
{
|
||||||
|
Super::Serialize(arc);
|
||||||
|
arc("next", Next)
|
||||||
|
("sbarid", SBarID);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(DHUDMessageBase, Tick)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(DHUDMessageBase);
|
||||||
|
ACTION_RETURN_BOOL(self->Tick());
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(DHUDMessageBase, ScreenSizeChanged)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(DHUDMessageBase);
|
||||||
|
self->ScreenSizeChanged();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(DHUDMessageBase, Draw)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(DHUDMessageBase);
|
||||||
|
PARAM_INT(bottom);
|
||||||
|
PARAM_INT(visibility);
|
||||||
|
self->Draw(bottom, visibility);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DHUDMessageBase::CallTick()
|
||||||
|
{
|
||||||
|
IFVIRTUAL(DHUDMessageBase, Tick)
|
||||||
|
{
|
||||||
|
VMValue params[] = { (DObject*)this };
|
||||||
|
int retval;
|
||||||
|
VMReturn ret; ret.IntAt(&retval);
|
||||||
|
VMCall(func, params, countof(params), &ret, 1);
|
||||||
|
return !!retval;
|
||||||
|
}
|
||||||
|
return Tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DHUDMessageBase::CallScreenSizeChanged()
|
||||||
|
{
|
||||||
|
IFVIRTUAL(DHUDMessageBase, ScreenSizeChanged)
|
||||||
|
{
|
||||||
|
VMValue params[] = { (DObject*)this };
|
||||||
|
VMCall(func, params, countof(params), nullptr, 0);
|
||||||
|
}
|
||||||
|
else ScreenSizeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DHUDMessageBase::CallDraw(int bottom, int visibility)
|
||||||
|
{
|
||||||
|
IFVIRTUAL(DHUDMessageBase, Draw)
|
||||||
|
{
|
||||||
|
VMValue params[] = { (DObject*)this, bottom, visibility };
|
||||||
|
VMCall(func, params, countof(params), nullptr, 0);
|
||||||
|
}
|
||||||
|
else Draw(bottom, visibility);
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// DHUDMessage Constructor
|
// DHUDMessage Constructor
|
||||||
|
@ -130,7 +195,6 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h
|
||||||
WrapWidth = 0;
|
WrapWidth = 0;
|
||||||
HandleAspect = true;
|
HandleAspect = true;
|
||||||
Top = y;
|
Top = y;
|
||||||
Next = NULL;
|
|
||||||
Lines = NULL;
|
Lines = NULL;
|
||||||
HoldTics = (int)(holdTime * TICRATE);
|
HoldTics = (int)(holdTime * TICRATE);
|
||||||
Tics = 0;
|
Tics = 0;
|
||||||
|
@ -184,10 +248,8 @@ void DHUDMessage::Serialize(FSerializer &arc)
|
||||||
("tics", Tics)
|
("tics", Tics)
|
||||||
("state", State)
|
("state", State)
|
||||||
.Enum("textcolor", TextColor)
|
.Enum("textcolor", TextColor)
|
||||||
("sbarid", SBarID)
|
|
||||||
("sourcetext", SourceText)
|
("sourcetext", SourceText)
|
||||||
("font", Font)
|
("font", Font)
|
||||||
("next", Next)
|
|
||||||
("hudwidth", HUDWidth)
|
("hudwidth", HUDWidth)
|
||||||
("hudheight", HUDHeight)
|
("hudheight", HUDHeight)
|
||||||
("nowrap", NoWrap)
|
("nowrap", NoWrap)
|
||||||
|
|
|
@ -59,10 +59,34 @@ bool ST_IsLatencyVisible();
|
||||||
|
|
||||||
// HUD Message base object --------------------------------------------------
|
// HUD Message base object --------------------------------------------------
|
||||||
|
|
||||||
class DHUDMessage : public DObject
|
// This is a mo-op base class to allow derived ZScript message types that can be managed by the status bar.
|
||||||
|
class DHUDMessageBase : public DObject
|
||||||
{
|
{
|
||||||
DECLARE_CLASS (DHUDMessage, DObject)
|
DECLARE_CLASS(DHUDMessageBase, DObject)
|
||||||
HAS_OBJECT_POINTERS
|
HAS_OBJECT_POINTERS
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void Serialize(FSerializer &arc);
|
||||||
|
virtual bool Tick() { return true; } // Returns true to indicate time for removal
|
||||||
|
virtual void ScreenSizeChanged() {}
|
||||||
|
virtual void Draw(int bottom, int visibility) {}
|
||||||
|
|
||||||
|
bool CallTick(); // Returns true to indicate time for removal
|
||||||
|
void CallScreenSizeChanged();
|
||||||
|
void CallDraw(int bottom, int visibility);
|
||||||
|
|
||||||
|
private:
|
||||||
|
TObjPtr<DHUDMessageBase*> Next = nullptr;
|
||||||
|
uint32_t SBarID = 0;
|
||||||
|
friend class DBaseStatusBar;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// HUD Message --------------------------------------------------
|
||||||
|
|
||||||
|
class DHUDMessage : public DHUDMessageBase
|
||||||
|
{
|
||||||
|
DECLARE_CLASS (DHUDMessage, DHUDMessageBase)
|
||||||
public:
|
public:
|
||||||
DHUDMessage (FFont *font, const char *text, float x, float y, int hudwidth, int hudheight,
|
DHUDMessage (FFont *font, const char *text, float x, float y, int hudwidth, int hudheight,
|
||||||
EColorRange textColor, float holdTime);
|
EColorRange textColor, float holdTime);
|
||||||
|
@ -70,12 +94,12 @@ public:
|
||||||
|
|
||||||
virtual void Serialize(FSerializer &arc);
|
virtual void Serialize(FSerializer &arc);
|
||||||
|
|
||||||
void Draw (int bottom, int visibility);
|
virtual void Draw (int bottom, int visibility) override;
|
||||||
virtual void ResetText (const char *text);
|
virtual void ResetText (const char *text);
|
||||||
virtual void DrawSetup ();
|
virtual void DrawSetup ();
|
||||||
virtual void DoDraw (int linenum, int x, int y, bool clean, int hudheight);
|
virtual void DoDraw (int linenum, int x, int y, bool clean, int hudheight);
|
||||||
virtual bool Tick (); // Returns true to indicate time for removal
|
virtual bool Tick () override;
|
||||||
virtual void ScreenSizeChanged ();
|
virtual void ScreenSizeChanged () override;
|
||||||
|
|
||||||
void SetVisibility(int vis)
|
void SetVisibility(int vis)
|
||||||
{
|
{
|
||||||
|
@ -130,11 +154,8 @@ protected:
|
||||||
DHUDMessage () : SourceText(NULL) {}
|
DHUDMessage () : SourceText(NULL) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TObjPtr<DHUDMessage*> Next;
|
|
||||||
uint32_t SBarID;
|
|
||||||
char *SourceText;
|
char *SourceText;
|
||||||
|
|
||||||
friend class DBaseStatusBar;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// HUD message visibility flags
|
// HUD message visibility flags
|
||||||
|
@ -360,9 +381,9 @@ public:
|
||||||
void SetSize(int reltop = 32, int hres = 320, int vres = 200, int hhres = -1, int hvres = -1);
|
void SetSize(int reltop = 32, int hres = 320, int vres = 200, int hhres = -1, int hvres = -1);
|
||||||
void OnDestroy() override;
|
void OnDestroy() override;
|
||||||
|
|
||||||
void AttachMessage (DHUDMessage *msg, uint32_t id=0, int layer=HUDMSGLayer_Default);
|
void AttachMessage (DHUDMessageBase *msg, uint32_t id=0, int layer=HUDMSGLayer_Default);
|
||||||
DHUDMessage *DetachMessage (DHUDMessage *msg);
|
DHUDMessageBase *DetachMessage (DHUDMessageBase *msg);
|
||||||
DHUDMessage *DetachMessage (uint32_t id);
|
DHUDMessageBase *DetachMessage (uint32_t id);
|
||||||
void DetachAllMessages ();
|
void DetachAllMessages ();
|
||||||
void ShowPlayerName ();
|
void ShowPlayerName ();
|
||||||
double GetDisplacement() { return Displacement; }
|
double GetDisplacement() { return Displacement; }
|
||||||
|
@ -455,7 +476,7 @@ private:
|
||||||
void DrawWaiting () const;
|
void DrawWaiting () const;
|
||||||
void SetDrawSize(int reltop, int hres, int vres);
|
void SetDrawSize(int reltop, int hres, int vres);
|
||||||
|
|
||||||
TObjPtr<DHUDMessage*> Messages[NUM_HUDMSGLAYERS];
|
TObjPtr<DHUDMessageBase*> Messages[NUM_HUDMSGLAYERS];
|
||||||
|
|
||||||
int BaseRelTop;
|
int BaseRelTop;
|
||||||
int BaseSBarHorizontalResolution;
|
int BaseSBarHorizontalResolution;
|
||||||
|
|
|
@ -410,10 +410,10 @@ void DBaseStatusBar::OnDestroy ()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < countof(Messages); ++i)
|
for (size_t i = 0; i < countof(Messages); ++i)
|
||||||
{
|
{
|
||||||
DHUDMessage *msg = Messages[i];
|
DHUDMessageBase *msg = Messages[i];
|
||||||
while (msg)
|
while (msg)
|
||||||
{
|
{
|
||||||
DHUDMessage *next = msg->Next;
|
DHUDMessageBase *next = msg->Next;
|
||||||
msg->Destroy();
|
msg->Destroy();
|
||||||
msg = next;
|
msg = next;
|
||||||
}
|
}
|
||||||
|
@ -594,14 +594,14 @@ void DBaseStatusBar::Tick ()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < countof(Messages); ++i)
|
for (size_t i = 0; i < countof(Messages); ++i)
|
||||||
{
|
{
|
||||||
DHUDMessage *msg = Messages[i];
|
DHUDMessageBase *msg = Messages[i];
|
||||||
DHUDMessage **prev = &Messages[i];
|
DHUDMessageBase **prev = &Messages[i];
|
||||||
|
|
||||||
while (msg)
|
while (msg)
|
||||||
{
|
{
|
||||||
DHUDMessage *next = msg->Next;
|
DHUDMessageBase *next = msg->Next;
|
||||||
|
|
||||||
if (msg->Tick ())
|
if (msg->CallTick ())
|
||||||
{
|
{
|
||||||
*prev = next;
|
*prev = next;
|
||||||
msg->Destroy();
|
msg->Destroy();
|
||||||
|
@ -662,10 +662,10 @@ void DBaseStatusBar::CallTick()
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void DBaseStatusBar::AttachMessage (DHUDMessage *msg, uint32_t id, int layer)
|
void DBaseStatusBar::AttachMessage (DHUDMessageBase *msg, uint32_t id, int layer)
|
||||||
{
|
{
|
||||||
DHUDMessage *old = NULL;
|
DHUDMessageBase *old = NULL;
|
||||||
DHUDMessage **prev;
|
DHUDMessageBase **prev;
|
||||||
DObject *container = this;
|
DObject *container = this;
|
||||||
|
|
||||||
old = (id == 0 || id == 0xFFFFFFFF) ? NULL : DetachMessage (id);
|
old = (id == 0 || id == 0xFFFFFFFF) ? NULL : DetachMessage (id);
|
||||||
|
@ -697,18 +697,28 @@ void DBaseStatusBar::AttachMessage (DHUDMessage *msg, uint32_t id, int layer)
|
||||||
GC::WriteBarrier(container, msg);
|
GC::WriteBarrier(container, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(DBaseStatusBar, AttachMessage)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||||
|
PARAM_OBJECT(msg, DHUDMessageBase);
|
||||||
|
PARAM_UINT(id);
|
||||||
|
PARAM_INT(layer);
|
||||||
|
self->AttachMessage(msg, id, layer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// PROC DetachMessage
|
// PROC DetachMessage
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
DHUDMessage *DBaseStatusBar::DetachMessage (DHUDMessage *msg)
|
DHUDMessageBase *DBaseStatusBar::DetachMessage (DHUDMessageBase *msg)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < countof(Messages); ++i)
|
for (size_t i = 0; i < countof(Messages); ++i)
|
||||||
{
|
{
|
||||||
DHUDMessage *probe = Messages[i];
|
DHUDMessageBase *probe = Messages[i];
|
||||||
DHUDMessage **prev = &Messages[i];
|
DHUDMessageBase **prev = &Messages[i];
|
||||||
|
|
||||||
while (probe && probe != msg)
|
while (probe && probe != msg)
|
||||||
{
|
{
|
||||||
|
@ -725,12 +735,20 @@ DHUDMessage *DBaseStatusBar::DetachMessage (DHUDMessage *msg)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DHUDMessage *DBaseStatusBar::DetachMessage (uint32_t id)
|
DEFINE_ACTION_FUNCTION(DBaseStatusBar, DetachMessage)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||||
|
PARAM_OBJECT(msg, DHUDMessageBase);
|
||||||
|
ACTION_RETURN_OBJECT(self->DetachMessage(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DHUDMessageBase *DBaseStatusBar::DetachMessage (uint32_t id)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < countof(Messages); ++i)
|
for (size_t i = 0; i < countof(Messages); ++i)
|
||||||
{
|
{
|
||||||
DHUDMessage *probe = Messages[i];
|
DHUDMessageBase *probe = Messages[i];
|
||||||
DHUDMessage **prev = &Messages[i];
|
DHUDMessageBase **prev = &Messages[i];
|
||||||
|
|
||||||
while (probe && probe->SBarID != id)
|
while (probe && probe->SBarID != id)
|
||||||
{
|
{
|
||||||
|
@ -747,6 +765,13 @@ DHUDMessage *DBaseStatusBar::DetachMessage (uint32_t id)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(DBaseStatusBar, DetachMessageID)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||||
|
PARAM_INT(id);
|
||||||
|
ACTION_RETURN_OBJECT(self->DetachMessage(id));
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// PROC DetachAllMessages
|
// PROC DetachAllMessages
|
||||||
|
@ -757,18 +782,26 @@ void DBaseStatusBar::DetachAllMessages ()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < countof(Messages); ++i)
|
for (size_t i = 0; i < countof(Messages); ++i)
|
||||||
{
|
{
|
||||||
DHUDMessage *probe = Messages[i];
|
DHUDMessageBase *probe = Messages[i];
|
||||||
|
|
||||||
Messages[i] = NULL;
|
Messages[i] = NULL;
|
||||||
while (probe != NULL)
|
while (probe != NULL)
|
||||||
{
|
{
|
||||||
DHUDMessage *next = probe->Next;
|
DHUDMessageBase *next = probe->Next;
|
||||||
probe->Destroy();
|
probe->Destroy();
|
||||||
probe = next;
|
probe = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(DBaseStatusBar, DetachAllMessages)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||||
|
self->DetachAllMessages();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// PROC ShowPlayerName
|
// PROC ShowPlayerName
|
||||||
|
@ -940,7 +973,7 @@ void DBaseStatusBar::FlashCrosshair ()
|
||||||
|
|
||||||
void DBaseStatusBar::DrawMessages (int layer, int bottom)
|
void DBaseStatusBar::DrawMessages (int layer, int bottom)
|
||||||
{
|
{
|
||||||
DHUDMessage *msg = Messages[layer];
|
DHUDMessageBase *msg = Messages[layer];
|
||||||
int visibility = 0;
|
int visibility = 0;
|
||||||
|
|
||||||
if (viewactive)
|
if (viewactive)
|
||||||
|
@ -953,8 +986,8 @@ void DBaseStatusBar::DrawMessages (int layer, int bottom)
|
||||||
}
|
}
|
||||||
while (msg)
|
while (msg)
|
||||||
{
|
{
|
||||||
DHUDMessage *next = msg->Next;
|
DHUDMessageBase *next = msg->Next;
|
||||||
msg->Draw (bottom, visibility);
|
msg->CallDraw (bottom, visibility);
|
||||||
msg = next;
|
msg = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1307,10 +1340,10 @@ void DBaseStatusBar::ScreenSizeChanged ()
|
||||||
|
|
||||||
for (size_t i = 0; i < countof(Messages); ++i)
|
for (size_t i = 0; i < countof(Messages); ++i)
|
||||||
{
|
{
|
||||||
DHUDMessage *message = Messages[i];
|
DHUDMessageBase *message = Messages[i];
|
||||||
while (message != NULL)
|
while (message != NULL)
|
||||||
{
|
{
|
||||||
message->ScreenSizeChanged ();
|
message->CallScreenSizeChanged ();
|
||||||
message = message->Next;
|
message = message->Next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,6 +149,7 @@ FGameConfigFile::FGameConfigFile ()
|
||||||
SetValueForKey ("Path", "$PROGDIR", true);
|
SetValueForKey ("Path", "$PROGDIR", true);
|
||||||
#else
|
#else
|
||||||
SetValueForKey ("Path", "$HOME/" GAME_DIR, true);
|
SetValueForKey ("Path", "$HOME/" GAME_DIR, true);
|
||||||
|
SetValueForKey ("Path", SHARE_DIR, true);
|
||||||
SetValueForKey ("Path", "/usr/local/share/doom", true);
|
SetValueForKey ("Path", "/usr/local/share/doom", true);
|
||||||
SetValueForKey ("Path", "/usr/local/share/games/doom", true);
|
SetValueForKey ("Path", "/usr/local/share/games/doom", true);
|
||||||
SetValueForKey ("Path", "/usr/share/doom", true);
|
SetValueForKey ("Path", "/usr/share/doom", true);
|
||||||
|
|
|
@ -209,9 +209,10 @@ static bool currentModelMatrixState;
|
||||||
|
|
||||||
void FRenderState::ApplyFixedFunction()
|
void FRenderState::ApplyFixedFunction()
|
||||||
{
|
{
|
||||||
if (mTextureMode != ffTextureMode)
|
int thistm = mTextureMode == TM_MODULATE && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode;
|
||||||
|
if (thistm != ffTextureMode)
|
||||||
{
|
{
|
||||||
ffTextureMode = mTextureMode;
|
ffTextureMode = thistm;
|
||||||
if (ffTextureMode == TM_CLAMPY) ffTextureMode = TM_MODULATE; // this cannot be replicated. Too bad if it creates visual artifacts
|
if (ffTextureMode == TM_CLAMPY) ffTextureMode = TM_MODULATE; // this cannot be replicated. Too bad if it creates visual artifacts
|
||||||
gl_SetTextureMode(ffTextureMode);
|
gl_SetTextureMode(ffTextureMode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -405,7 +405,6 @@ void F2DDrawer::Draw()
|
||||||
|
|
||||||
gl_SetRenderStyle(dt->mRenderStyle, !dt->mMasked, false);
|
gl_SetRenderStyle(dt->mRenderStyle, !dt->mMasked, false);
|
||||||
gl_RenderState.SetMaterial(dt->mTexture, CLAMP_XY_NOMIP, dt->mTranslation, -1, dt->mAlphaTexture);
|
gl_RenderState.SetMaterial(dt->mTexture, CLAMP_XY_NOMIP, dt->mTranslation, -1, dt->mAlphaTexture);
|
||||||
if (dt->mTexture->tex->bHasCanvas) gl_RenderState.SetTextureMode(TM_OPAQUE);
|
|
||||||
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
glScissor(dt->mScissor[0], dt->mScissor[1], dt->mScissor[2], dt->mScissor[3]);
|
glScissor(dt->mScissor[0], dt->mScissor[1], dt->mScissor[2], dt->mScissor[3]);
|
||||||
|
|
|
@ -164,7 +164,7 @@ bool FRenderState::ApplyShader()
|
||||||
activeShader->muFogEnabled.Set(fogset);
|
activeShader->muFogEnabled.Set(fogset);
|
||||||
activeShader->muPalLightLevels.Set(static_cast<int>(gl_bandedswlight) | (static_cast<int>(gl_fogmode) << 8));
|
activeShader->muPalLightLevels.Set(static_cast<int>(gl_bandedswlight) | (static_cast<int>(gl_fogmode) << 8));
|
||||||
activeShader->muGlobVis.Set(GLRenderer->mGlobVis / 32.0f);
|
activeShader->muGlobVis.Set(GLRenderer->mGlobVis / 32.0f);
|
||||||
activeShader->muTextureMode.Set(mTextureMode);
|
activeShader->muTextureMode.Set(mTextureMode == TM_MODULATE && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode);
|
||||||
activeShader->muCameraPos.Set(mCameraPos.vec);
|
activeShader->muCameraPos.Set(mCameraPos.vec);
|
||||||
activeShader->muLightParms.Set(mLightParms);
|
activeShader->muLightParms.Set(mLightParms);
|
||||||
activeShader->muFogColor.Set(mFogColor);
|
activeShader->muFogColor.Set(mFogColor);
|
||||||
|
|
|
@ -112,6 +112,7 @@ class FRenderState
|
||||||
|
|
||||||
int mEffectState;
|
int mEffectState;
|
||||||
int mColormapState;
|
int mColormapState;
|
||||||
|
int mTempTM = TM_MODULATE;
|
||||||
|
|
||||||
float stAlphaThreshold;
|
float stAlphaThreshold;
|
||||||
int stSrcBlend, stDstBlend;
|
int stSrcBlend, stDstBlend;
|
||||||
|
@ -150,6 +151,14 @@ public:
|
||||||
{
|
{
|
||||||
if (mat->tex->UseBasePalette() || gl.legacyMode) translation = TRANSLATION(TRANSLATION_Standard, 8);
|
if (mat->tex->UseBasePalette() || gl.legacyMode) translation = TRANSLATION(TRANSLATION_Standard, 8);
|
||||||
}
|
}
|
||||||
|
if (mat->tex->bHasCanvas)
|
||||||
|
{
|
||||||
|
mTempTM = TM_OPAQUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mTempTM = TM_MODULATE;
|
||||||
|
}
|
||||||
mEffectState = overrideshader >= 0? overrideshader : mat->mShaderIndex;
|
mEffectState = overrideshader >= 0? overrideshader : mat->mShaderIndex;
|
||||||
mShaderTimer = mat->tex->gl_info.shaderspeed;
|
mShaderTimer = mat->tex->gl_info.shaderspeed;
|
||||||
mat->Bind(clampmode, translation);
|
mat->Bind(clampmode, translation);
|
||||||
|
|
|
@ -358,42 +358,46 @@ void GLDrawList::SortWallIntoPlane(SortNode * head,SortNode * sort)
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
void GLDrawList::SortSpriteIntoPlane(SortNode * head,SortNode * sort)
|
void GLDrawList::SortSpriteIntoPlane(SortNode * head, SortNode * sort)
|
||||||
{
|
{
|
||||||
GLFlat * fh=&flats[drawitems[head->itemindex].index];
|
GLFlat * fh = &flats[drawitems[head->itemindex].index];
|
||||||
GLSprite * ss=&sprites[drawitems[sort->itemindex].index];
|
GLSprite * ss = &sprites[drawitems[sort->itemindex].index];
|
||||||
|
|
||||||
bool ceiling = fh->z > r_viewpoint.Pos.Z;
|
bool ceiling = fh->z > r_viewpoint.Pos.Z;
|
||||||
|
|
||||||
if ((ss->z1>fh->z && ss->z2<fh->z) || ss->modelframe)
|
auto hiz = ss->z1 > ss->z2 ? ss->z1 : ss->z2;
|
||||||
|
auto loz = ss->z1 < ss->z2 ? ss->z1 : ss->z2;
|
||||||
|
|
||||||
|
if ((hiz > fh->z && loz < fh->z) || ss->modelframe)
|
||||||
{
|
{
|
||||||
// We have to split this sprite
|
// We have to split this sprite
|
||||||
GLSprite s=*ss;
|
GLSprite s = *ss;
|
||||||
AddSprite(&s); // add a copy to avoid reallocation issues.
|
AddSprite(&s); // add a copy to avoid reallocation issues.
|
||||||
|
|
||||||
// Splitting is done in the shader with clip planes, if available
|
// Splitting is done in the shader with clip planes, if available.
|
||||||
|
// The fallback here only really works for non-y-billboarded sprites.
|
||||||
if (gl.flags & RFL_NO_CLIP_PLANES)
|
if (gl.flags & RFL_NO_CLIP_PLANES)
|
||||||
{
|
{
|
||||||
GLSprite * ss1;
|
GLSprite * ss1;
|
||||||
ss1=&sprites[sprites.Size()-1];
|
ss1 = &sprites[sprites.Size() - 1];
|
||||||
ss=&sprites[drawitems[sort->itemindex].index]; // may have been reallocated!
|
ss = &sprites[drawitems[sort->itemindex].index]; // may have been reallocated!
|
||||||
float newtexv=ss->vt + ((ss->vb-ss->vt)/(ss->z2-ss->z1))*(fh->z-ss->z1);
|
float newtexv = ss->vt + ((ss->vb - ss->vt) / (ss->z2 - ss->z1))*(fh->z - ss->z1);
|
||||||
|
|
||||||
if (!ceiling)
|
if (!ceiling)
|
||||||
{
|
{
|
||||||
ss->z1=ss1->z2=fh->z;
|
ss->z1 = ss1->z2 = fh->z;
|
||||||
ss->vt=ss1->vb=newtexv;
|
ss->vt = ss1->vb = newtexv;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ss1->z1=ss->z2=fh->z;
|
ss1->z1 = ss->z2 = fh->z;
|
||||||
ss1->vt=ss->vb=newtexv;
|
ss1->vt = ss->vb = newtexv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SortNode * sort2=SortNodes.GetNew();
|
SortNode * sort2 = SortNodes.GetNew();
|
||||||
memset(sort2,0,sizeof(SortNode));
|
memset(sort2, 0, sizeof(SortNode));
|
||||||
sort2->itemindex=drawitems.Size()-1;
|
sort2->itemindex = drawitems.Size() - 1;
|
||||||
|
|
||||||
head->AddToLeft(sort);
|
head->AddToLeft(sort);
|
||||||
head->AddToRight(sort2);
|
head->AddToRight(sort2);
|
||||||
|
@ -406,7 +410,6 @@ void GLDrawList::SortSpriteIntoPlane(SortNode * head,SortNode * sort)
|
||||||
{
|
{
|
||||||
head->AddToRight(sort);
|
head->AddToRight(sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1211,7 +1211,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
|
||||||
}
|
}
|
||||||
|
|
||||||
double timefrac = r_viewpoint.TicFrac;
|
double timefrac = r_viewpoint.TicFrac;
|
||||||
if (paused || bglobal.freeze)
|
if (paused || bglobal.freeze || (level.flags2 & LEVEL2_FROZEN))
|
||||||
timefrac = 0.;
|
timefrac = 0.;
|
||||||
float xvf = (particle->Vel.X) * timefrac;
|
float xvf = (particle->Vel.X) * timefrac;
|
||||||
float yvf = (particle->Vel.Y) * timefrac;
|
float yvf = (particle->Vel.Y) * timefrac;
|
||||||
|
|
|
@ -1060,8 +1060,8 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
|
||||||
// Draw the stuff
|
// Draw the stuff
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
if (realfront->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) split.PutWall(translucent);
|
if (front->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) split.PutWall(translucent);
|
||||||
else split.SplitWall(realfront, translucent);
|
else split.SplitWall(front, translucent);
|
||||||
|
|
||||||
t=1;
|
t=1;
|
||||||
}
|
}
|
||||||
|
@ -1074,8 +1074,8 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
|
||||||
// Draw the stuff without splitting
|
// Draw the stuff without splitting
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
if (realfront->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) PutWall(translucent);
|
if (front->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) PutWall(translucent);
|
||||||
else SplitWall(realfront, translucent);
|
else SplitWall(front, translucent);
|
||||||
}
|
}
|
||||||
alpha=1.0f;
|
alpha=1.0f;
|
||||||
}
|
}
|
||||||
|
@ -1437,7 +1437,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||||
sector_t * segback;
|
sector_t * segback;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if (seg->linedef->Index() == 1)
|
if (seg->linedef->Index() == 10)
|
||||||
{
|
{
|
||||||
int a = 0;
|
int a = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,6 +244,7 @@ struct FActorInfo
|
||||||
PClassActor *Replacee = nullptr;
|
PClassActor *Replacee = nullptr;
|
||||||
FState *OwnedStates = nullptr;
|
FState *OwnedStates = nullptr;
|
||||||
int NumOwnedStates = 0;
|
int NumOwnedStates = 0;
|
||||||
|
bool SkipSuperSet = false;
|
||||||
uint8_t GameFilter = GAME_Any;
|
uint8_t GameFilter = GAME_Any;
|
||||||
uint16_t SpawnID = 0;
|
uint16_t SpawnID = 0;
|
||||||
uint16_t ConversationID = 0;
|
uint16_t ConversationID = 0;
|
||||||
|
@ -287,7 +288,7 @@ struct FActorInfo
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is now merely a wrapper that adds actor-specific functionality to PClass.
|
// 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.
|
// PClass to it.
|
||||||
class PClassActor : public PClass
|
class PClassActor : public PClass
|
||||||
{
|
{
|
||||||
|
@ -343,7 +344,7 @@ public:
|
||||||
bool OwnsState(const FState *state)
|
bool OwnsState(const FState *state)
|
||||||
{
|
{
|
||||||
auto i = ActorInfo();
|
auto i = ActorInfo();
|
||||||
return state >= i->OwnedStates && state < i->OwnedStates + i->NumOwnedStates;
|
return i != nullptr && state >= i->OwnedStates && state < i->OwnedStates + i->NumOwnedStates;
|
||||||
}
|
}
|
||||||
|
|
||||||
PClassActor *GetReplacement(bool lookskill=true);
|
PClassActor *GetReplacement(bool lookskill=true);
|
||||||
|
|
|
@ -377,6 +377,8 @@ xx(MomZ)
|
||||||
xx(Threshold)
|
xx(Threshold)
|
||||||
xx(DefThreshold)
|
xx(DefThreshold)
|
||||||
xx(Abs)
|
xx(Abs)
|
||||||
|
xx(TeleportSpecial)
|
||||||
|
xx(Teleport)
|
||||||
xx(ACS_NamedExecuteWithResult)
|
xx(ACS_NamedExecuteWithResult)
|
||||||
xx(CallACS)
|
xx(CallACS)
|
||||||
xx(Sqrt)
|
xx(Sqrt)
|
||||||
|
|
|
@ -814,8 +814,8 @@ void FNodeBuilder::SplitSegs (uint32_t set, node_t &node, uint32_t splitseg, uin
|
||||||
frac = InterceptVector (node, *seg);
|
frac = InterceptVector (node, *seg);
|
||||||
newvert.x = Vertices[seg->v1].x;
|
newvert.x = Vertices[seg->v1].x;
|
||||||
newvert.y = Vertices[seg->v1].y;
|
newvert.y = Vertices[seg->v1].y;
|
||||||
newvert.x += fixed_t(frac * double(Vertices[seg->v2].x - newvert.x));
|
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.y += fixed_t(frac * (double(Vertices[seg->v2].y) - newvert.y));
|
||||||
vertnum = VertexMap->SelectVertexClose (newvert);
|
vertnum = VertexMap->SelectVertexClose (newvert);
|
||||||
|
|
||||||
if (vertnum != (unsigned int)seg->v1 && vertnum != (unsigned int)seg->v2)
|
if (vertnum != (unsigned int)seg->v1 && vertnum != (unsigned int)seg->v2)
|
||||||
|
|
|
@ -91,6 +91,8 @@ struct FSimpleVert
|
||||||
fixed_t x, y;
|
fixed_t x, y;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef int64_t fixed64_t;
|
||||||
|
|
||||||
class FNodeBuilder
|
class FNodeBuilder
|
||||||
{
|
{
|
||||||
struct FPrivSeg
|
struct FPrivSeg
|
||||||
|
@ -167,14 +169,14 @@ class FNodeBuilder
|
||||||
FNodeBuilder &MyBuilder;
|
FNodeBuilder &MyBuilder;
|
||||||
TArray<int> *VertexGrid;
|
TArray<int> *VertexGrid;
|
||||||
|
|
||||||
fixed_t MinX, MinY, MaxX, MaxY;
|
fixed64_t MinX, MinY, MaxX, MaxY;
|
||||||
int BlocksWide, BlocksTall;
|
int BlocksWide, BlocksTall;
|
||||||
|
|
||||||
enum { BLOCK_SHIFT = 8 + FRACBITS };
|
enum { BLOCK_SHIFT = 8 + FRACBITS };
|
||||||
enum { BLOCK_SIZE = 1 << BLOCK_SHIFT };
|
enum { BLOCK_SIZE = 1 << BLOCK_SHIFT };
|
||||||
|
|
||||||
int InsertVertex (FPrivVert &vert);
|
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 (x >= MinX);
|
||||||
assert (y >= MinY);
|
assert (y >= MinY);
|
||||||
|
|
|
@ -641,8 +641,8 @@ FNodeBuilder::FVertexMap::FVertexMap (FNodeBuilder &builder,
|
||||||
MinY = miny;
|
MinY = miny;
|
||||||
BlocksWide = int(((double(maxx) - minx + 1) + (BLOCK_SIZE - 1)) / BLOCK_SIZE);
|
BlocksWide = int(((double(maxx) - minx + 1) + (BLOCK_SIZE - 1)) / BLOCK_SIZE);
|
||||||
BlocksTall = int(((double(maxy) - miny + 1) + (BLOCK_SIZE - 1)) / BLOCK_SIZE);
|
BlocksTall = int(((double(maxy) - miny + 1) + (BLOCK_SIZE - 1)) / BLOCK_SIZE);
|
||||||
MaxX = MinX + BlocksWide * BLOCK_SIZE - 1;
|
MaxX = MinX + fixed64_t(BlocksWide) * BLOCK_SIZE - 1;
|
||||||
MaxY = MinY + BlocksTall * BLOCK_SIZE - 1;
|
MaxY = MinY + fixed64_t(BlocksTall) * BLOCK_SIZE - 1;
|
||||||
VertexGrid = new TArray<int>[BlocksWide * BlocksTall];
|
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
|
// If a vertex is near a block boundary, then it will be inserted on
|
||||||
// both sides of the boundary so that SelectVertexClose can find
|
// both sides of the boundary so that SelectVertexClose can find
|
||||||
// it by checking in only one block.
|
// it by checking in only one block.
|
||||||
fixed_t minx = MAX (MinX, vert.x - VERTEX_EPSILON);
|
fixed64_t minx = MAX (MinX, fixed64_t(vert.x) - VERTEX_EPSILON);
|
||||||
fixed_t maxx = MIN (MaxX, vert.x + VERTEX_EPSILON);
|
fixed64_t maxx = MIN (MaxX, fixed64_t(vert.x) + VERTEX_EPSILON);
|
||||||
fixed_t miny = MAX (MinY, vert.y - VERTEX_EPSILON);
|
fixed64_t miny = MAX (MinY, fixed64_t(vert.y) - VERTEX_EPSILON);
|
||||||
fixed_t maxy = MIN (MaxY, vert.y + VERTEX_EPSILON);
|
fixed64_t maxy = MIN (MaxY, fixed64_t(vert.y) + VERTEX_EPSILON);
|
||||||
|
|
||||||
int blk[4] =
|
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
|
// 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);
|
double portz = cres.line->frontsector->GetPortalPlaneZ(sector_t::ceiling);
|
||||||
if (tm.thing->Z() < portz && tm.thing->Z() + tm.thing->MaxStepHeight >= portz && tm.floorz < portz)
|
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;
|
FLineOpening open;
|
||||||
|
|
||||||
P_LineOpening(open, tm.thing, ld, ref, &cres.Position, cres.portalflags);
|
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;
|
sector_t *oppsec = cres.line->frontsector == tm.thing->Sector ? cres.line->backsector : cres.line->frontsector;
|
||||||
if (oppsec->PortalBlocksMovement(sector_t::ceiling))
|
if (oppsec->PortalBlocksMovement(sector_t::ceiling))
|
||||||
|
@ -2707,8 +2711,8 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
|
||||||
FLinkContext ctx;
|
FLinkContext ctx;
|
||||||
DVector3 oldpos = thing->Pos();
|
DVector3 oldpos = thing->Pos();
|
||||||
thing->UnlinkFromWorld(&ctx);
|
thing->UnlinkFromWorld(&ctx);
|
||||||
thing->SetXYZ(thing->PosRelative(thing->Sector->GetOppositePortalGroup(sector_t::ceiling)));
|
thing->SetXYZ(thing->PosRelative(tm.portalgroup));
|
||||||
thing->Prev = thing->Pos() - oldpos;
|
thing->Prev += thing->Pos() - oldpos;
|
||||||
thing->Sector = P_PointInSector(thing->Pos());
|
thing->Sector = P_PointInSector(thing->Pos());
|
||||||
thing->PrevPortalGroup = thing->Sector->PortalGroup;
|
thing->PrevPortalGroup = thing->Sector->PortalGroup;
|
||||||
thing->LinkToWorld(&ctx);
|
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);
|
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)
|
DEFINE_ACTION_FUNCTION(AActor, Distance2D)
|
||||||
{
|
{
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
|
|
|
@ -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)
|
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;
|
double timefrac = r_viewpoint.TicFrac;
|
||||||
if (paused || bglobal.freeze)
|
if (paused || bglobal.freeze || (level.flags2 & LEVEL2_FROZEN))
|
||||||
timefrac = 0.;
|
timefrac = 0.;
|
||||||
DVector3 pos = particle->Pos + (particle->Vel * timefrac);
|
DVector3 pos = particle->Pos + (particle->Vel * timefrac);
|
||||||
double psize = particle->size / 8.0;
|
double psize = particle->size / 8.0;
|
||||||
|
|
|
@ -125,9 +125,17 @@ void FModelRenderer::RenderModel(float x, float y, float z, FSpriteModelFrame *s
|
||||||
|
|
||||||
// Applying model transformations:
|
// Applying model transformations:
|
||||||
// 1) Applying actor angle, pitch and roll to the model
|
// 1) Applying actor angle, pitch and roll to the model
|
||||||
|
if (smf->flags & MDL_USEROTATIONCENTER)
|
||||||
|
{
|
||||||
|
objectToWorldMatrix.translate(smf->rotationCenterX, smf->rotationCenterZ, smf->rotationCenterY);
|
||||||
|
}
|
||||||
objectToWorldMatrix.rotate(-angle, 0, 1, 0);
|
objectToWorldMatrix.rotate(-angle, 0, 1, 0);
|
||||||
objectToWorldMatrix.rotate(pitch, 0, 0, 1);
|
objectToWorldMatrix.rotate(pitch, 0, 0, 1);
|
||||||
objectToWorldMatrix.rotate(-roll, 1, 0, 0);
|
objectToWorldMatrix.rotate(-roll, 1, 0, 0);
|
||||||
|
if (smf->flags & MDL_USEROTATIONCENTER)
|
||||||
|
{
|
||||||
|
objectToWorldMatrix.translate(-smf->rotationCenterX, -smf->rotationCenterZ, -smf->rotationCenterY);
|
||||||
|
}
|
||||||
|
|
||||||
// 2) Applying Doomsday like rotation of the weapon pickup models
|
// 2) Applying Doomsday like rotation of the weapon pickup models
|
||||||
// The rotation angle is based on the elapsed time.
|
// The rotation angle is based on the elapsed time.
|
||||||
|
@ -789,6 +797,13 @@ void gl_InitModels()
|
||||||
{
|
{
|
||||||
smf.flags |= MDL_DONTCULLBACKFACES;
|
smf.flags |= MDL_DONTCULLBACKFACES;
|
||||||
}
|
}
|
||||||
|
else if (sc.Compare("userotationcenter"))
|
||||||
|
{
|
||||||
|
smf.flags |= MDL_USEROTATIONCENTER;
|
||||||
|
smf.rotationCenterX = 0.;
|
||||||
|
smf.rotationCenterY = 0.;
|
||||||
|
smf.rotationCenterZ = 0.;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sc.ScriptMessage("Unrecognized string \"%s\"", sc.String);
|
sc.ScriptMessage("Unrecognized string \"%s\"", sc.String);
|
||||||
|
|
|
@ -447,6 +447,7 @@ enum
|
||||||
MDL_USEACTORROLL = 64,
|
MDL_USEACTORROLL = 64,
|
||||||
MDL_BADROTATION = 128,
|
MDL_BADROTATION = 128,
|
||||||
MDL_DONTCULLBACKFACES = 256,
|
MDL_DONTCULLBACKFACES = 256,
|
||||||
|
MDL_USEROTATIONCENTER = 512,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FSpriteModelFrame
|
struct FSpriteModelFrame
|
||||||
|
|
|
@ -677,7 +677,7 @@ void S_UnloadReverbDef ()
|
||||||
Environments = &Off;
|
Environments = &Off;
|
||||||
}
|
}
|
||||||
|
|
||||||
CUSTOM_CVAR(Bool, eaxedit_test, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
CUSTOM_CVAR(Bool, eaxedit_test, false, CVAR_NOINITCALL)
|
||||||
{
|
{
|
||||||
if (self)
|
if (self)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2304,6 +2304,7 @@ ExpEmit FxPreIncrDecr::Emit(VMFunctionBuilder *build)
|
||||||
}
|
}
|
||||||
|
|
||||||
pointer.Free(build);
|
pointer.Free(build);
|
||||||
|
value.Target = false; // This is for 'unrequesting' the address of a register variable. If not done here, passing a preincrement expression to a function will generate bad code.
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7406,7 +7407,16 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
|
||||||
|
|
||||||
if (arrayispointer)
|
if (arrayispointer)
|
||||||
{
|
{
|
||||||
arraytype = static_cast<PArray*>(Array->ValueType->toPointer()->PointedType);
|
auto ptr = Array->ValueType->toPointer();
|
||||||
|
if (ptr != nullptr)
|
||||||
|
{
|
||||||
|
arraytype = static_cast<PArray*>(ptr->PointedType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "Internal error when generating code for array access");
|
||||||
|
return ExpEmit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -7758,6 +7768,8 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
|
||||||
}
|
}
|
||||||
else
|
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);
|
special = P_FindLineSpecial(MethodName.GetChars(), &min, &max);
|
||||||
}
|
}
|
||||||
if (special != 0 && min >= 0)
|
if (special != 0 && min >= 0)
|
||||||
|
|
|
@ -540,7 +540,7 @@ DEFINE_PROPERTY(skip_super, 0, Actor)
|
||||||
if (info->Size != actorclass->Size)
|
if (info->Size != actorclass->Size)
|
||||||
{
|
{
|
||||||
bag.ScriptPosition.Message(MSG_OPTERROR,
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (bag.StateSet)
|
if (bag.StateSet)
|
||||||
|
@ -552,6 +552,7 @@ DEFINE_PROPERTY(skip_super, 0, Actor)
|
||||||
|
|
||||||
*defaults = *GetDefault<AActor>();
|
*defaults = *GetDefault<AActor>();
|
||||||
ResetBaggage (&bag, RUNTIME_CLASS(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
|
void PDynArray::WriteValue(FSerializer &ar, const char *key, const void *addr) const
|
||||||
{
|
{
|
||||||
FArray *aray = (FArray*)addr;
|
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))
|
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.
|
FString statename; // The state builder wants the label as one complete string, not separated into tokens.
|
||||||
FStateDefinitions statedef;
|
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;
|
int numframes = 0;
|
||||||
|
|
||||||
for (auto s : c->States)
|
for (auto s : c->States)
|
||||||
|
|
|
@ -190,32 +190,32 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch (devtype)
|
switch (devtype)
|
||||||
{
|
{
|
||||||
case MDEV_GUS:
|
case MDEV_GUS:
|
||||||
return new TimidityMIDIDevice(Args);
|
return new TimidityMIDIDevice(Args);
|
||||||
|
|
||||||
case MDEV_MMAPI:
|
case MDEV_MMAPI:
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
return CreateWinMIDIDevice(mididevice);
|
return CreateWinMIDIDevice(mididevice);
|
||||||
#endif
|
#endif
|
||||||
// Intentional fall-through for non-Windows systems.
|
// Intentional fall-through for non-Windows systems.
|
||||||
|
|
||||||
case MDEV_FLUIDSYNTH:
|
case MDEV_FLUIDSYNTH:
|
||||||
return new FluidSynthMIDIDevice(Args);
|
return new FluidSynthMIDIDevice(Args);
|
||||||
|
|
||||||
case MDEV_OPL:
|
case MDEV_OPL:
|
||||||
return new OPLMIDIDevice(Args);
|
return new OPLMIDIDevice(Args);
|
||||||
|
|
||||||
case MDEV_TIMIDITY:
|
case MDEV_TIMIDITY:
|
||||||
return CreateTimidityPPMIDIDevice(Args);
|
return CreateTimidityPPMIDIDevice(Args);
|
||||||
|
|
||||||
case MDEV_WILDMIDI:
|
case MDEV_WILDMIDI:
|
||||||
return new WildMIDIDevice(Args);
|
return new WildMIDIDevice(Args);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (CRecoverableError &err)
|
catch (CRecoverableError &err)
|
||||||
{
|
{
|
||||||
|
@ -721,6 +721,14 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, uint32_t max_time)
|
||||||
if (InitialPlayback)
|
if (InitialPlayback)
|
||||||
{
|
{
|
||||||
InitialPlayback = false;
|
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.
|
// Send the full master volume SysEx message.
|
||||||
events[0] = 0; // dwDeltaTime
|
events[0] = 0; // dwDeltaTime
|
||||||
events[1] = 0; // dwStreamID
|
events[1] = 0; // dwStreamID
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace swrenderer
|
||||||
sector_t* heightsec = NULL;
|
sector_t* heightsec = NULL;
|
||||||
|
|
||||||
double timefrac = r_viewpoint.TicFrac;
|
double timefrac = r_viewpoint.TicFrac;
|
||||||
if (paused || bglobal.freeze)
|
if (paused || bglobal.freeze || (level.flags2 & LEVEL2_FROZEN))
|
||||||
timefrac = 0.;
|
timefrac = 0.;
|
||||||
|
|
||||||
double ippx = particle->Pos.X + particle->Vel.X * timefrac;
|
double ippx = particle->Pos.X + particle->Vel.X * timefrac;
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <wctype.h>
|
||||||
|
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
|
|
||||||
|
@ -387,7 +388,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bo
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isspace(c))
|
if (iswspace(c))
|
||||||
{
|
{
|
||||||
if (!lastWasSpace)
|
if (!lastWasSpace)
|
||||||
{
|
{
|
||||||
|
@ -420,12 +421,12 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bo
|
||||||
start = space;
|
start = space;
|
||||||
space = NULL;
|
space = NULL;
|
||||||
|
|
||||||
while (*start && isspace (*start) && *start != '\n')
|
while (*start && iswspace (*start) && *start != '\n')
|
||||||
start++;
|
start++;
|
||||||
if (*start == '\n')
|
if (*start == '\n')
|
||||||
start++;
|
start++;
|
||||||
else
|
else
|
||||||
while (*start && isspace (*start))
|
while (*start && iswspace (*start))
|
||||||
start++;
|
start++;
|
||||||
string = start;
|
string = start;
|
||||||
}
|
}
|
||||||
|
@ -443,7 +444,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bo
|
||||||
while (s < string)
|
while (s < string)
|
||||||
{
|
{
|
||||||
// If there is any non-white space in the remainder of the string, add it.
|
// 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);
|
auto i = Lines.Reserve(1);
|
||||||
breakit (&Lines[i], font, start, string, linecolor);
|
breakit (&Lines[i], font, start, string, linecolor);
|
||||||
|
|
|
@ -868,3 +868,17 @@ CA3773ED313E8899311F3DD0CA195A68 // e3m6
|
||||||
{
|
{
|
||||||
shorttex
|
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 void SetDamage(int dmg);
|
||||||
native clearscope double Distance2D(Actor other) const;
|
native clearscope double Distance2D(Actor other) const;
|
||||||
native clearscope double Distance3D(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 SetOrigin(vector3 newpos, bool moving);
|
||||||
native void SetXYZ(vector3 newpos);
|
native void SetXYZ(vector3 newpos);
|
||||||
native Actor GetPointer(int aaptr);
|
native Actor GetPointer(int aaptr);
|
||||||
|
@ -1185,6 +1187,10 @@ class Actor : Thinker native
|
||||||
{
|
{
|
||||||
return ACS_ExecuteAlways(-int(script), mapnum, arg1, arg2, arg3);
|
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)
|
States(Actor, Overlay, Weapon, Item)
|
||||||
{
|
{
|
||||||
|
|
|
@ -70,8 +70,13 @@ extend class Actor
|
||||||
{
|
{
|
||||||
if (mo.health > 0 && mo != self)
|
if (mo.health > 0 && mo != self)
|
||||||
{
|
{
|
||||||
// other Keen not dead
|
// Added check for Dehacked and repurposed inventory items.
|
||||||
return;
|
let inv = Inventory(mo);
|
||||||
|
if (inv == null || inv.Owner == null)
|
||||||
|
{
|
||||||
|
// other Keen not dead
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Door_Open(doortag, 16);
|
Door_Open(doortag, 16);
|
||||||
|
|
|
@ -244,6 +244,11 @@ class Korax : Actor
|
||||||
|
|
||||||
void A_KoraxMissile()
|
void A_KoraxMissile()
|
||||||
{
|
{
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static const class<Actor> choices[] =
|
static const class<Actor> choices[] =
|
||||||
{
|
{
|
||||||
"WraithFX1", "Demon1FX1", "Demon2FX1", "FireDemonMissile", "CentaurFX", "SerpentFX"
|
"WraithFX1", "Demon1FX1", "Demon2FX1", "FireDemonMissile", "CentaurFX", "SerpentFX"
|
||||||
|
@ -282,6 +287,11 @@ class Korax : Actor
|
||||||
|
|
||||||
void KoraxFire (Class<Actor> type, int arm)
|
void KoraxFire (Class<Actor> type, int arm)
|
||||||
{
|
{
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static const int extension[] =
|
static const int extension[] =
|
||||||
{
|
{
|
||||||
KORAX_ARM_EXTENSION_SHORT,
|
KORAX_ARM_EXTENSION_SHORT,
|
||||||
|
|
|
@ -1931,22 +1931,6 @@ class PowerMorph : Powerup
|
||||||
|
|
||||||
int savedMorphTics = MorphedPlayer.morphTics;
|
int savedMorphTics = MorphedPlayer.morphTics;
|
||||||
MorphedPlayer.UndoPlayerMorph (MorphedPlayer, 0, !!(MorphedPlayer.MorphStyle & MRF_UNDOALWAYS));
|
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;
|
MorphedPlayer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ class FastProjectile : Actor
|
||||||
int count = 8;
|
int count = 8;
|
||||||
if (radius > 0)
|
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.
|
// we need to take smaller steps.
|
||||||
count += count;
|
count += count;
|
||||||
|
|
|
@ -101,6 +101,12 @@ class InventoryBarState ui
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class HUDMessageBase native ui
|
||||||
|
{
|
||||||
|
virtual native bool Tick();
|
||||||
|
virtual native void ScreenSizeChanged();
|
||||||
|
virtual native void Draw(int bottom, int visibility);
|
||||||
|
}
|
||||||
|
|
||||||
class BaseStatusBar native ui
|
class BaseStatusBar native ui
|
||||||
{
|
{
|
||||||
|
@ -291,6 +297,10 @@ class BaseStatusBar native ui
|
||||||
|
|
||||||
private HUDFont mSmallFont;
|
private HUDFont mSmallFont;
|
||||||
|
|
||||||
|
native void AttachMessage(HUDMessageBase msg);
|
||||||
|
native HUDMessageBase DetachMessage(HUDMessageBase msg);
|
||||||
|
native HUDMessageBase DetachMessageID(uint msgid);
|
||||||
|
native void DetachAllMessages();
|
||||||
|
|
||||||
native void SetSize(int height, int vwidth, int vheight, int hwidth = -1, int hheight = -1);
|
native void SetSize(int height, int vwidth, int vheight, int hwidth = -1, int hheight = -1);
|
||||||
native Vector2 GetHUDScale();
|
native Vector2 GetHUDScale();
|
||||||
|
|
|
@ -559,6 +559,21 @@ object SoulSphere
|
||||||
frame SOUL { light 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
|
// Invulnerability Sphere
|
||||||
pulselight INVULN
|
pulselight INVULN
|
||||||
{
|
{
|
||||||
|
|
|
@ -559,6 +559,21 @@ object SoulSphere
|
||||||
frame SOUL { light 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
|
// Invulnerability Sphere
|
||||||
pulselight INVULN
|
pulselight INVULN
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue