Merge branch 'master' of https://github.com/ZDoom/gzdoom into gzd-master-experimental

This commit is contained in:
nashmuhandes 2024-11-15 00:42:38 +08:00
commit 1770bbc0d0
25 changed files with 243 additions and 151 deletions

View file

@ -252,7 +252,8 @@ FSerializer &Serialize(FSerializer &arc, const char *key, struct ModelOverride &
FSerializer &Serialize(FSerializer &arc, const char *key, struct AnimModelOverride &mo, struct AnimModelOverride *def);
FSerializer &Serialize(FSerializer &arc, const char *key, ModelAnim &ao, ModelAnim *def);
FSerializer &Serialize(FSerializer &arc, const char *key, ModelAnimFrame &ao, ModelAnimFrame *def);
FSerializer& Serialize(FSerializer& arc, const char* key, FTranslationID& value, FTranslationID* defval);
FSerializer &Serialize(FSerializer& arc, const char* key, FTranslationID& value, FTranslationID* defval);
FSerializer &Serialize(FSerializer& arc, const char* key, struct FStandaloneAnimation& value, struct FStandaloneAnimation* defval);
void SerializeFunctionPointer(FSerializer &arc, const char *key, FunctionPointerValue *&p);

View file

@ -46,6 +46,8 @@
#include "symbols.h"
#include "types.h"
#include "p_visualthinker.h"
// MACROS ------------------------------------------------------------------
// TYPES -------------------------------------------------------------------
@ -421,7 +423,7 @@ PClass *PClass::FindClass (FName zaname)
//
//==========================================================================
DObject *PClass::CreateNew()
DObject *PClass::CreateNew(int *statnum)
{
uint8_t *mem = (uint8_t *)M_Malloc (Size);
assert (mem != nullptr);
@ -444,6 +446,12 @@ DObject *PClass::CreateNew()
((DObject *)mem)->SetClass (const_cast<PClass *>(this));
InitializeSpecials(mem, Defaults, &PClass::SpecialInits);
if(statnum && ((DObject *)mem)->IsKindOf(RUNTIME_CLASS(DVisualThinker)))
{
*statnum = STAT_VISUALTHINKER;
}
return (DObject *)mem;
}

View file

@ -90,7 +90,7 @@ public:
PClass();
~PClass();
void InsertIntoHash(bool native);
DObject *CreateNew();
DObject *CreateNew(int *statnum = nullptr);
PClass *CreateDerivedClass(FName name, unsigned int size, bool *newlycreated = nullptr, int fileno = 0);
void InitializeActorInfo();

View file

@ -425,11 +425,9 @@ public:
DThinker *CreateThinker(PClass *cls, int statnum = STAT_DEFAULT)
{
DThinker *thinker = static_cast<DThinker*>(cls->CreateNew());
DThinker *thinker = static_cast<DThinker*>(cls->CreateNew(&statnum));
assert(thinker->IsKindOf(RUNTIME_CLASS(DThinker)));
thinker->ObjectFlags |= OF_JustSpawned;
if (thinker->IsKindOf(RUNTIME_CLASS(DVisualThinker))) // [MC] This absolutely must happen for this class!
statnum = STAT_VISUALTHINKER;
Thinkers.Link(thinker, statnum);
thinker->Level = this;
return thinker;

View file

@ -405,10 +405,14 @@ void FDynamicLight::UpdateLocation()
Pos = target->Vec3Offset(m_off.X * c + m_off.Y * s, m_off.X * s - m_off.Y * c, m_off.Z + target->GetBobOffset());
Sector = target->subsector->sector; // Get the render sector. target->Sector is the sector according to play logic.
// Some z-coordinate fudging to prevent the light from getting too close to the floor or ceiling planes. With proper attenuation this would render them invisible.
// A distance of 5 is needed so that the light's effect doesn't become too small.
if (Z() < target->floorz + 5.) Pos.Z = target->floorz + 5.;
else if (Z() > target->ceilingz - 5.) Pos.Z = target->ceilingz - 5.;
if (!(target->flags5 & MF5_NOINTERACTION))
{
// Some z-coordinate fudging to prevent the light from getting too close to the floor or ceiling planes. With proper attenuation this would render them invisible.
// A distance of 5 is needed so that the light's effect doesn't become too small.
// [SP] don't do this if +NOINTERACTION is set, since the object can fly right through floors and ceilings with that flag
if (Z() < target->floorz + 5.) Pos.Z = target->floorz + 5.;
else if (Z() > target->ceilingz - 5.) Pos.Z = target->ceilingz - 5.;
}
// The radius being used here is always the maximum possible with the
// current settings. This avoids constant relinking of flickering lights

View file

@ -46,6 +46,8 @@
#include "g_cvars.h"
#include "d_main.h"
#include "p_visualthinker.h"
static int ThinkCount;
static cycle_t ThinkCycles;
extern cycle_t BotSupportCycles;

View file

@ -50,6 +50,7 @@
#include "actorinlines.h"
#include "g_game.h"
#include "serializer_doom.h"
#include "p_visualthinker.h"
#include "hwrenderer/scene/hw_drawstructs.h"
@ -364,9 +365,9 @@ void P_SpawnParticle(FLevelLocals *Level, const DVector3 &pos, const DVector3 &v
particle->sizestep = sizestep;
particle->texture = texture;
particle->style = style;
particle->Roll = startroll;
particle->RollVel = rollvel;
particle->RollAcc = rollacc;
particle->Roll = (float)startroll;
particle->RollVel = (float)rollvel;
particle->RollAcc = (float)rollacc;
particle->flags = flags;
if(flags & SPF_LOCAL_ANIM)
{
@ -1005,7 +1006,6 @@ void DVisualThinker::Construct()
PT.subsector = nullptr;
cursector = nullptr;
PT.color = 0xffffff;
spr = new HWSprite();
AnimatedTexture.SetNull();
}
@ -1017,11 +1017,6 @@ DVisualThinker::DVisualThinker()
void DVisualThinker::OnDestroy()
{
PT.alpha = 0.0; // stops all rendering.
if(spr)
{
delete spr;
spr = nullptr;
}
Super::OnDestroy();
}
@ -1050,6 +1045,33 @@ static DVisualThinker* SpawnVisualThinker(FLevelLocals* Level, PClass* type)
return DVisualThinker::NewVisualThinker(Level, type);
}
void DVisualThinker::UpdateSector(subsector_t * newSubsector)
{
assert(newSubsector);
if(PT.subsector != newSubsector)
{
PT.subsector = newSubsector;
cursector = newSubsector->sector;
}
}
void DVisualThinker::UpdateSector()
{
UpdateSector(Level->PointInRenderSubsector(PT.Pos));
}
static void UpdateSector(DVisualThinker * self)
{
self->UpdateSector();
}
DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, UpdateSector, UpdateSector)
{
PARAM_SELF_PROLOGUE(DVisualThinker);
self->UpdateSector();
return 0;
}
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, SpawnVisualThinker, SpawnVisualThinker)
{
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
@ -1068,6 +1090,19 @@ void DVisualThinker::UpdateSpriteInfo()
}
}
static void UpdateSpriteInfo(DVisualThinker * self)
{
self->UpdateSpriteInfo();
}
DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, UpdateSpriteInfo, UpdateSpriteInfo)
{
PARAM_SELF_PROLOGUE(DVisualThinker);
self->UpdateSpriteInfo();
return 0;
}
// This runs just like Actor's, make sure to call Super.Tick() in ZScript.
void DVisualThinker::Tick()
{
@ -1097,27 +1132,27 @@ void DVisualThinker::Tick()
PT.Pos.Y = newxy.Y;
PT.Pos.Z += PT.Vel.Z;
PT.subsector = Level->PointInRenderSubsector(PT.Pos);
cursector = PT.subsector->sector;
subsector_t * ss = Level->PointInRenderSubsector(PT.Pos);
// Handle crossing a sector portal.
if (!cursector->PortalBlocksMovement(sector_t::ceiling))
if (!ss->sector->PortalBlocksMovement(sector_t::ceiling))
{
if (PT.Pos.Z > cursector->GetPortalPlaneZ(sector_t::ceiling))
if (PT.Pos.Z > ss->sector->GetPortalPlaneZ(sector_t::ceiling))
{
PT.Pos += cursector->GetPortalDisplacement(sector_t::ceiling);
PT.subsector = Level->PointInRenderSubsector(PT.Pos);
cursector = PT.subsector->sector;
PT.Pos += ss->sector->GetPortalDisplacement(sector_t::ceiling);
ss = Level->PointInRenderSubsector(PT.Pos);
}
}
else if (!cursector->PortalBlocksMovement(sector_t::floor))
else if (!ss->sector->PortalBlocksMovement(sector_t::floor))
{
if (PT.Pos.Z < cursector->GetPortalPlaneZ(sector_t::floor))
if (PT.Pos.Z < ss->sector->GetPortalPlaneZ(sector_t::floor))
{
PT.Pos += cursector->GetPortalDisplacement(sector_t::floor);
PT.subsector = Level->PointInRenderSubsector(PT.Pos);
cursector = PT.subsector->sector;
PT.Pos += ss->sector->GetPortalDisplacement(sector_t::floor);
ss = Level->PointInRenderSubsector(PT.Pos);
}
}
UpdateSector(ss);
UpdateSpriteInfo();
}
@ -1125,7 +1160,7 @@ int DVisualThinker::GetLightLevel(sector_t* rendersector) const
{
int lightlevel = rendersector->GetSpriteLight();
if (bAddLightLevel)
if (flags & VTF_AddLightLevel)
{
lightlevel += LightLevel;
}
@ -1138,7 +1173,7 @@ int DVisualThinker::GetLightLevel(sector_t* rendersector) const
FVector3 DVisualThinker::InterpolatedPosition(double ticFrac) const
{
if (bDontInterpolate) return FVector3(PT.Pos);
if (flags & VTF_DontInterpolate) return FVector3(PT.Pos);
DVector3 proc = Prev + (ticFrac * (PT.Pos - Prev));
return FVector3(proc);
@ -1147,7 +1182,7 @@ FVector3 DVisualThinker::InterpolatedPosition(double ticFrac) const
float DVisualThinker::InterpolatedRoll(double ticFrac) const
{
if (bDontInterpolate) return PT.Roll;
if (flags & VTF_DontInterpolate) return PT.Roll;
return float(PrevRoll + (PT.Roll - PrevRoll) * ticFrac);
}
@ -1227,17 +1262,29 @@ int DVisualThinker::GetRenderStyle()
float DVisualThinker::GetOffset(bool y) const // Needed for the renderer.
{
if (y)
return (float)(bFlipOffsetY ? Offset.Y : -Offset.Y);
return (float)((flags & VTF_FlipOffsetY) ? Offset.Y : -Offset.Y);
else
return (float)(bFlipOffsetX ? Offset.X : -Offset.X);
return (float)((flags & VTF_FlipOffsetX) ? Offset.X : -Offset.X);
}
FSerializer& Serialize(FSerializer& arc, const char* key, FStandaloneAnimation& value, FStandaloneAnimation* defval)
{
arc.BeginObject(key);
arc("SwitchTic", value.SwitchTic);
arc("AnimIndex", value.AnimIndex);
arc("CurFrame", value.CurFrame);
arc("Ok", value.ok);
arc("AnimType", value.AnimType);
arc.EndObject();
return arc;
}
void DVisualThinker::Serialize(FSerializer& arc)
{
Super::Serialize(arc);
arc
("pos", PT.Pos)
arc ("pos", PT.Pos)
("vel", PT.Vel)
("prev", Prev)
("scale", Scale)
@ -1250,15 +1297,15 @@ void DVisualThinker::Serialize(FSerializer& arc)
("translation", Translation)
("cursector", cursector)
("scolor", PT.color)
("flipx", bXFlip)
("flipy", bYFlip)
("dontinterpolate", bDontInterpolate)
("addlightlevel", bAddLightLevel)
("flipoffsetx", bFlipOffsetX)
("flipoffsetY", bFlipOffsetY)
("lightlevel", LightLevel)
("flags", PT.flags);
("animData", PT.animData)
("flags", PT.flags)
("visualThinkerFlags", flags);
if(arc.isReading())
{
UpdateSector();
}
}
IMPLEMENT_CLASS(DVisualThinker, false, false);
@ -1269,6 +1316,7 @@ DEFINE_FIELD_NAMED(DVisualThinker, PT.Roll, Roll);
DEFINE_FIELD_NAMED(DVisualThinker, PT.alpha, Alpha);
DEFINE_FIELD_NAMED(DVisualThinker, PT.texture, Texture);
DEFINE_FIELD_NAMED(DVisualThinker, PT.flags, Flags);
DEFINE_FIELD_NAMED(DVisualThinker, flags, VisualThinkerFlags);
DEFINE_FIELD(DVisualThinker, Prev);
DEFINE_FIELD(DVisualThinker, Scale);
@ -1277,9 +1325,3 @@ DEFINE_FIELD(DVisualThinker, PrevRoll);
DEFINE_FIELD(DVisualThinker, Translation);
DEFINE_FIELD(DVisualThinker, LightLevel);
DEFINE_FIELD(DVisualThinker, cursector);
DEFINE_FIELD(DVisualThinker, bXFlip);
DEFINE_FIELD(DVisualThinker, bYFlip);
DEFINE_FIELD(DVisualThinker, bDontInterpolate);
DEFINE_FIELD(DVisualThinker, bAddLightLevel);
DEFINE_FIELD(DVisualThinker, bFlipOffsetX);
DEFINE_FIELD(DVisualThinker, bFlipOffsetY);

View file

@ -147,56 +147,4 @@ struct SPortalHit
void P_DrawRailTrail(AActor *source, TArray<SPortalHit> &portalhits, int color1, int color2, double maxdiff = 0, int flags = 0, PClassActor *spawnclass = NULL, DAngle angle = nullAngle, int duration = TICRATE, double sparsity = 1.0, double drift = 1.0, int SpiralOffset = 270, DAngle pitch = nullAngle);
void P_DrawSplash (FLevelLocals *Level, int count, const DVector3 &pos, DAngle angle, int kind);
void P_DrawSplash2 (FLevelLocals *Level, int count, const DVector3 &pos, DAngle angle, int updown, int kind);
void P_DisconnectEffect (AActor *actor);
//===========================================================================
//
// VisualThinkers
// by Major Cooke
// Credit to phantombeta, RicardoLuis0 & RaveYard for aid
//
//===========================================================================
class HWSprite;
struct FTranslationID;
class DVisualThinker : public DThinker
{
DECLARE_CLASS(DVisualThinker, DThinker);
public:
DVector3 Prev;
DVector2 Scale,
Offset;
float PrevRoll;
int16_t LightLevel;
FTranslationID Translation;
FTextureID AnimatedTexture;
sector_t *cursector;
bool bFlipOffsetX,
bFlipOffsetY,
bXFlip,
bYFlip, // flip the sprite on the x/y axis.
bDontInterpolate, // disable all interpolation
bAddLightLevel; // adds sector light level to 'LightLevel'
// internal only variables
particle_t PT;
HWSprite *spr; //in an effort to cache the result.
DVisualThinker();
void Construct();
void OnDestroy() override;
static DVisualThinker* NewVisualThinker(FLevelLocals* Level, PClass* type);
void SetTranslation(FName trname);
int GetRenderStyle();
bool isFrozen();
int GetLightLevel(sector_t *rendersector) const;
FVector3 InterpolatedPosition(double ticFrac) const;
float InterpolatedRoll(double ticFrac) const;
void Tick() override;
void UpdateSpriteInfo();
void Serialize(FSerializer& arc) override;
float GetOffset(bool y) const;
};
void P_DisconnectEffect (AActor *actor);

View file

@ -0,0 +1,62 @@
#pragma once
#include "palettecontainer.h"
#include "hwrenderer/scene/hw_drawstructs.h"
//===========================================================================
//
// VisualThinkers
// by Major Cooke
// Credit to phantombeta, RicardoLuis0 & RaveYard for aid
//
//===========================================================================
enum EVisualThinkerFlags
{
VTF_FlipOffsetX = 1 << 0,
VTF_FlipOffsetY = 1 << 1,
VTF_FlipX = 1 << 2,
VTF_FlipY = 1 << 3, // flip the sprite on the x/y axis.
VTF_DontInterpolate = 1 << 4, // disable all interpolation
VTF_AddLightLevel = 1 << 5, // adds sector light level to 'LightLevel'
};
class DVisualThinker : public DThinker
{
DECLARE_CLASS(DVisualThinker, DThinker);
void UpdateSector(subsector_t * newSubsector);
public:
DVector3 Prev;
DVector2 Scale,
Offset;
float PrevRoll;
int16_t LightLevel;
FTranslationID Translation;
FTextureID AnimatedTexture;
sector_t *cursector;
int flags;
// internal only variables
particle_t PT;
DVisualThinker();
void Construct();
void OnDestroy() override;
static DVisualThinker* NewVisualThinker(FLevelLocals* Level, PClass* type);
void SetTranslation(FName trname);
int GetRenderStyle();
bool isFrozen();
int GetLightLevel(sector_t *rendersector) const;
FVector3 InterpolatedPosition(double ticFrac) const;
float InterpolatedRoll(double ticFrac) const;
void Tick() override;
void UpdateSpriteInfo();
void UpdateSector();
void Serialize(FSerializer& arc) override;
float GetOffset(bool y) const;
};

View file

@ -45,6 +45,8 @@
#include "hw_walldispatcher.h"
#include "hw_flatdispatcher.h"
#include "p_visualthinker.h"
#ifdef ARCH_IA32
#include <immintrin.h>
#endif // ARCH_IA32
@ -670,10 +672,9 @@ void HWDrawInfo::RenderParticles(subsector_t *sub, sector_t *front, FRenderState
int clipres = mClipPortal->ClipPoint(sp->PT.Pos.XY());
if (clipres == PClip_InFront) continue;
}
assert(sp->spr);
sp->spr->ProcessParticle(this, state, &sp->PT, front, sp);
HWSprite sprite;
sprite.ProcessParticle(this, state, &sp->PT, front, sp);
}
for (int i = Level->ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Level->Particles[i].snext)
{

View file

@ -59,6 +59,8 @@
#include "hw_drawcontext.h"
#include "quaternion.h"
#include "p_visualthinker.h"
extern TArray<spritedef_t> sprites;
extern TArray<spriteframe_t> SpriteFrames;
extern uint32_t r_renderercaps;
@ -1657,7 +1659,7 @@ void HWSprite::AdjustVisualThinker(HWDrawInfo* di, DVisualThinker* spr, sector_t
? TexAnim.UpdateStandaloneAnimation(spr->PT.animData, di->Level->maptime + timefrac)
: spr->PT.texture, !custom_anim);
if (spr->bDontInterpolate)
if (spr->flags & VTF_DontInterpolate)
timefrac = 0.;
FVector3 interp = spr->InterpolatedPosition(timefrac);
@ -1687,13 +1689,12 @@ void HWSprite::AdjustVisualThinker(HWDrawInfo* di, DVisualThinker* spr, sector_t
double mult = 1.0 / sqrt(ps); // shrink slightly
r.Scale(mult * ps, mult);
}
if (spr->bXFlip)
if (spr->flags & VTF_FlipX)
{
std::swap(ul,ur);
r.left = -r.width - r.left; // mirror the sprite's x-offset
}
if (spr->bYFlip) std::swap(vt,vb);
if (spr->flags & VTF_FlipY) std::swap(vt,vb);
float viewvecX = vp.ViewVector.X;
float viewvecY = vp.ViewVector.Y;

View file

@ -161,17 +161,14 @@ bool ZCCDoomCompiler::CompileProperties(PClass *type, TArray<ZCC_Property *> &Pr
bool ZCCDoomCompiler::CompileFlagDefs(PClass *type, TArray<ZCC_FlagDef *> &Properties, FName prefix)
{
if (!type->IsDescendantOf(RUNTIME_CLASS(AActor)))
{
Error(Properties[0], "Flags can only be defined for actors");
return false;
}
//[RL0] allow property-less flagdefs for non-actors
bool isActor = type->IsDescendantOf(RUNTIME_CLASS(AActor));
for (auto p : Properties)
{
PField *field;
FName referenced = FName(p->RefName);
if (FName(p->NodeName) == FName("prefix") && fileSystem.GetFileContainer(Lump) == 0)
if (isActor && FName(p->NodeName) == FName("prefix") && fileSystem.GetFileContainer(Lump) == 0)
{
// only for internal definitions: Allow setting a prefix. This is only for compatiblity with the old DECORATE property parser, but not for general use.
prefix = referenced;
@ -191,24 +188,28 @@ bool ZCCDoomCompiler::CompileFlagDefs(PClass *type, TArray<ZCC_FlagDef *> &Prope
}
}
else field = nullptr;
FString qualifiedname;
// Store the full qualified name and prepend some 'garbage' to the name so that no conflicts with other symbol types can happen.
// All these will be removed from the symbol table after the compiler finishes to free up the allocated space.
FName name = FName(p->NodeName);
for (int i = 0; i < 2; i++)
{
if (i == 0) qualifiedname.Format("@flagdef@%s", name.GetChars());
else
{
if (prefix == NAME_None) continue;
qualifiedname.Format("@flagdef@%s.%s", prefix.GetChars(), name.GetChars());
}
if (!type->VMType->Symbols.AddSymbol(Create<PPropFlag>(qualifiedname, field, p->BitValue, i == 0 && prefix != NAME_None)))
if(isActor)
{
FString qualifiedname;
// Store the full qualified name and prepend some 'garbage' to the name so that no conflicts with other symbol types can happen.
// All these will be removed from the symbol table after the compiler finishes to free up the allocated space.
for (int i = 0; i < 2; i++)
{
Error(p, "Unable to add flag definition %s to class %s", FName(p->NodeName).GetChars(), type->TypeName.GetChars());
if (i == 0) qualifiedname.Format("@flagdef@%s", name.GetChars());
else
{
if (prefix == NAME_None) continue;
qualifiedname.Format("@flagdef@%s.%s", prefix.GetChars(), name.GetChars());
}
if (!type->VMType->Symbols.AddSymbol(Create<PPropFlag>(qualifiedname, field, p->BitValue, i == 0 && prefix != NAME_None)))
{
Error(p, "Unable to add flag definition %s to class %s", FName(p->NodeName).GetChars(), type->TypeName.GetChars());
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 B

View file

@ -1410,6 +1410,8 @@ enum ELevelFlags
LEVEL3_AVOIDMELEE = 0x00020000, // global flag needed for proper MBF support.
LEVEL3_NOJUMPDOWN = 0x00040000, // only for MBF21. Inverse of MBF's dog_jumping flag.
LEVEL3_LIGHTCREATED = 0x00080000, // a light had been created in the last frame
LEVEL3_NOFOGOFWAR = 0x00100000, // disables effect of r_radarclipper CVAR on this map
LEVEL3_SECRET = 0x00200000, // level is a secret level
VKDLEVELFLAG_NOUSERSAVE = 0x00000001,
VKDLEVELFLAG_NOAUTOMAP = 0x00000002,
@ -1519,3 +1521,13 @@ enum EModelFlags
MDL_CORRECTPIXELSTRETCH = 1<<13, // ensure model does not distort with pixel stretch when pitch/roll is applied
MDL_FORCECULLBACKFACES = 1<<14,
};
enum EVisualThinkerFlags
{
VTF_FlipOffsetX = 1 << 0,
VTF_FlipOffsetY = 1 << 1,
VTF_FlipX = 1 << 2,
VTF_FlipY = 1 << 3, // flip the sprite on the x/y axis.
VTF_DontInterpolate = 1 << 4, // disable all interpolation
VTF_AddLightLevel = 1 << 5, // adds sector light level to 'LightLevel'
};

View file

@ -15,27 +15,29 @@ enum ESoundFlags
// modifier flags
CHAN_LISTENERZ = 8,
CHAN_MAYBE_LOCAL = 16,
CHAN_UI = 32,
CHAN_NOPAUSE = 64,
CHAN_UI = 32, // Do not record sound in savegames.
CHAN_NOPAUSE = 64, // Do not pause this sound in menus.
CHAN_LOOP = 256,
CHAN_PICKUP = (CHAN_ITEM|CHAN_MAYBE_LOCAL), // Do not use this with A_StartSound! It would not do what is expected.
CHAN_NOSTOP = 4096,
CHAN_OVERLAP = 8192,
CHAN_NOSTOP = 4096, // only for A_PlaySound. Does not start if channel is playing something.
CHAN_OVERLAP = 8192, // [MK] Does not stop any sounds in the channel and instead plays over them.
// Same as above, with an F appended to allow better distinction of channel and channel flags.
CHANF_DEFAULT = 0, // just to make the code look better and avoid literal 0's.
CHANF_DEFAULT = 0, // just to make the code look better and avoid literal 0's.
CHANF_LISTENERZ = 8,
CHANF_MAYBE_LOCAL = 16,
CHANF_UI = 32,
CHANF_NOPAUSE = 64,
CHANF_UI = 32, // Do not record sound in savegames.
CHANF_NOPAUSE = 64, // Do not pause this sound in menus.
CHANF_LOOP = 256,
CHANF_NOSTOP = 4096,
CHANF_OVERLAP = 8192,
CHANF_LOCAL = 16384,
CHANF_NOSTOP = 4096, // only for A_PlaySound. Does not start if channel is playing something.
CHANF_OVERLAP = 8192, // [MK] Does not stop any sounds in the channel and instead plays over them.
CHANF_LOCAL = 16384, // only plays locally for the calling actor
CHANF_TRANSIENT = 32768, // Do not record in savegames - used for sounds that get restarted outside the sound system (e.g. ambients in SW and Blood)
CHANF_FORCE = 65536, // Start, even if sound is paused.
CHANF_SINGULAR = 0x20000, // Only start if no sound of this name is already playing.
CHANF_LOOPING = CHANF_LOOP | CHANF_NOSTOP, // convenience value for replicating the old 'looping' boolean.
};
// sound attenuation values

View file

@ -10,14 +10,18 @@ Class VisualThinker : Thinker native
Alpha;
native TextureID Texture;
native TranslationID Translation;
native uint16 Flags;
native int16 LightLevel;
native bool bFlipOffsetX,
bFlipOffsetY,
bXFlip,
bYFlip,
bDontInterpolate,
bAddLightLevel;
native uint16 Flags;
native int VisualThinkerFlags;
FlagDef FlipOffsetX : VisualThinkerFlags, 0;
FlagDef FlipOffsetY : VisualThinkerFlags, 1;
FlagDef XFlip : VisualThinkerFlags, 2;
FlagDef YFlip : VisualThinkerFlags, 3;
FlagDef DontInterpolate : VisualThinkerFlags, 4;
FlagDef AddLightLevel : VisualThinkerFlags, 5;
native Color scolor;
native Sector CurSector; // can be null!
@ -26,8 +30,11 @@ Class VisualThinker : Thinker native
native void SetRenderStyle(int mode); // see ERenderStyle
native bool IsFrozen();
native protected void UpdateSector(); // needs to be called if the thinker is set to a non-ticking statnum and the position is modified (or if Tick is overriden and doesn't call Super.Tick())
native protected void UpdateSpriteInfo(); // needs to be called every time the texture is updated if the thinker uses SPF_LOCAL_ANIM and is set to a non-ticking statnum (or if Tick is overriden and doesn't call Super.Tick())
static VisualThinker Spawn(Class<VisualThinker> type, TextureID tex, Vector3 pos, Vector3 vel, double alpha = 1.0, int flags = 0,
double roll = 0.0, Vector2 scale = (1,1), Vector2 offset = (0,0), int style = STYLE_Normal, TranslationID trans = 0)
double roll = 0.0, Vector2 scale = (1,1), Vector2 offset = (0,0), int style = STYLE_Normal, TranslationID trans = 0, int VisualThinkerFlags = 0)
{
if (!Level) return null;
@ -44,6 +51,9 @@ Class VisualThinker : Thinker native
p.SetRenderStyle(style);
p.Translation = trans;
p.Flags = flags;
p.VisualThinkerFlags = VisualThinkerFlags;
p.UpdateSector();
p.UpdateSpriteInfo();
}
return p;
}