Merge branch 'master' of https://github.com/ZDoom/gzdoom into gzd-master-experimental
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
62
src/playsim/p_visualthinker.h
Normal 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;
|
||||
};
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
BIN
wadsrc/static/graphics/AMMNUM0.png
Normal file
|
After Width: | Height: | Size: 89 B |
BIN
wadsrc/static/graphics/AMMNUM1.png
Normal file
|
After Width: | Height: | Size: 88 B |
BIN
wadsrc/static/graphics/AMMNUM2.png
Normal file
|
After Width: | Height: | Size: 86 B |
BIN
wadsrc/static/graphics/AMMNUM3.png
Normal file
|
After Width: | Height: | Size: 84 B |
BIN
wadsrc/static/graphics/AMMNUM4.png
Normal file
|
After Width: | Height: | Size: 89 B |
BIN
wadsrc/static/graphics/AMMNUM5.png
Normal file
|
After Width: | Height: | Size: 87 B |
BIN
wadsrc/static/graphics/AMMNUM6.png
Normal file
|
After Width: | Height: | Size: 89 B |
BIN
wadsrc/static/graphics/AMMNUM7.png
Normal file
|
After Width: | Height: | Size: 87 B |
BIN
wadsrc/static/graphics/AMMNUM8.png
Normal file
|
After Width: | Height: | Size: 86 B |
BIN
wadsrc/static/graphics/AMMNUM9.png
Normal file
|
After Width: | Height: | Size: 89 B |
|
|
@ -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'
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||