- fixed handling of actor defaults.

Order of application with map sprites was not correct.
This also simplifies how the defaults are stored - the separate data is gone, they now use the regular defaults.
This commit is contained in:
Christoph Oelckers 2022-11-19 10:58:35 +01:00
parent 5ae7011e41
commit 9cf6f5dabc
8 changed files with 81 additions and 68 deletions

View file

@ -116,7 +116,7 @@ void PClassActor::StaticInit()
if (cls->IsDescendantOf(RUNTIME_CLASS(DCoreActor)))
{
AllActorClasses.Push(static_cast<PClassActor*>(cls));
static_cast<PClassActor*>(cls)->ActorInfo()->ResolveTextures(cls->TypeName.GetChars());
static_cast<PClassActor*>(cls)->ActorInfo()->ResolveTextures(cls->TypeName.GetChars(), GetDefaultByType(cls));
}
}
}
@ -242,7 +242,7 @@ PClassActor *PClassActor::GetReplacee()
//
//==========================================================================
void FActorInfo::ResolveTextures(const char* clsname)
void FActorInfo::ResolveTextures(const char* clsname, DCoreActor* defaults)
{
SpriteSet.Resize(SpriteSetNames.Size());
for (unsigned i = 0; i < SpriteSet.Size(); i++)
@ -250,10 +250,11 @@ void FActorInfo::ResolveTextures(const char* clsname)
SpriteSet[i] = TileFiles.tileForName(SpriteSetNames[i]);
if (SpriteSet[i] == -1) Printf("Unknown texture '%s' in sprite set for class %s\n", SpriteSetNames[i].GetChars(), clsname);
}
if (SpriteSet.Size() > 0) defaults->spr.picnum = SpriteSet[0]; // Unless picnum is specified it will be set to the first image of the sprite set.
if (PicName.IsNotEmpty())
{
defsprite.picnum = TileFiles.tileForName(PicName);
if (defsprite.picnum == -1) Printf("Unknown texture '%s' in pic for class %s\n", PicName.GetChars(), clsname);
defaults->spr.picnum = TileFiles.tileForName(PicName);
if (defaults->spr.picnum == -1) Printf("Unknown texture '%s' in pic for class %s\n", PicName.GetChars(), clsname);
}
SpriteSetNames.Reset();
PicName = "";

View file

@ -32,6 +32,7 @@ enum EDefaultFlags
DEFF_XOFFSET = 0x20000,
DEFF_YOFFSET = 0x40000,
DEFF_OWNER = 0x80000,
DEFF_INTANG = 0x100000
};
struct FActorInfo
@ -44,7 +45,6 @@ struct FActorInfo
int DefaultFlags = 0;
int DefaultCstat = 0;
int Health = 0; // not used yet - this will stand in if no CON defines a health value for Duke.
spritetype defsprite{}; // Due to how the map format works we cannot define defaults for the sprite itself. These must be applied later.
// these are temporary. Due to how Build games handle their tiles, we cannot look up the textures when scripts are being parsed.
FString PicName;
@ -57,12 +57,11 @@ struct FActorInfo
TypeNum = other.TypeNum;
DefaultFlags = other.DefaultFlags;
DefaultCstat = other.DefaultCstat;
defsprite = other.defsprite;
PicName = other.PicName;
SpriteSetNames = other.SpriteSetNames;
}
void ResolveTextures(const char* clsname);
void ResolveTextures(const char* clsname, DCoreActor *defaults);
};
// No objects of this type will be created ever - its only use is to static_cast

View file

@ -348,16 +348,33 @@ DCoreActor* InsertActor(PClass* type, sectortype* sector, int stat, bool tail)
assert(type->IsDescendantOf(RUNTIME_CLASS(DCoreActor)));
auto actor = static_cast<DCoreActor*>(type->CreateNew());
auto defaults = GetDefaultByType(type);
auto actorinfo = static_cast<PClassActor*>(actor->GetClass())->ActorInfo();
if (actorinfo)
if (actorinfo && actorinfo->DefaultFlags & DEFF_STATNUM) stat = defaults->spr.statnum;
GC::WriteBarrier(actor);
InsertActorStat(actor, stat, tail);
InsertActorSect(actor, sector, tail);
Numsprites++;
actor->time = leveltimer++;
return actor;
}
void DCoreActor::initFromSprite(spritetype* mspr)
{
actor->spr.cstat = (actor->spr.cstat & ~ESpriteFlags::FromInt(actorinfo->DefaultCstat)) | (actorinfo->defsprite.cstat & ESpriteFlags::FromInt(actorinfo->DefaultCstat));
auto actorinfo = static_cast<PClassActor*>(GetClass())->ActorInfo();
#define setter(flag, var) if (actorinfo->DefaultFlags & flag) actor->spr.var = actorinfo->defsprite.var;
spr.cstat = (mspr->cstat & ~ESpriteFlags::FromInt(actorinfo->DefaultCstat)) | (spr.cstat & ESpriteFlags::FromInt(actorinfo->DefaultCstat));
spr.pos = mspr->pos;
spr.sectp = mspr->sectp;
// only copy those values which have not been defaulted by the class definition.
#define setter(flag, var) if (!(actorinfo->DefaultFlags & flag)) spr.var = mspr->var;
if (actorinfo->DefaultFlags & DEFF_STATNUM) stat = actorinfo->defsprite.statnum;
setter(DEFF_PICNUM, picnum);
setter(DEFF_ANG, angle);
setter(DEFF_INTANG, intangle);
setter(DEFF_XVEL, xint);
setter(DEFF_YVEL, yint);
setter(DEFF_ZVEL, inittype);
@ -376,15 +393,10 @@ DCoreActor* InsertActor(PClass* type, sectortype* sector, int stat, bool tail)
setter(DEFF_OWNER, intowner);
#undef setter
}
GC::WriteBarrier(actor);
InsertActorStat(actor, stat, tail);
InsertActorSect(actor, sector, tail);
Numsprites++;
actor->time = leveltimer++;
return actor;
clipdist = spr.clipdist * 0.25;
if (mspr->statnum != 0 && !(actorinfo->DefaultFlags & DEFF_STATNUM))
ChangeActorStat(this, mspr->statnum);
}
//==========================================================================

View file

@ -62,11 +62,7 @@ public:
size_t PropagateMark() override;
double GetOffsetAndHeight(double& height);
void initFromSprite(spritetype* pspr)
{
spr = *pspr;
clipdist = pspr->clipdist * 0.25;
}
void initFromSprite(spritetype* pspr);
bool exists() const
{

View file

@ -323,27 +323,37 @@ DEFINE_PROPERTY(pic, S, CoreActor)
DEFINE_PROPERTY(statnum, I, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.statnum = i;
defaults->spr.statnum = i;
bag.Info->ActorInfo()->DefaultFlags |= DEFF_STATNUM;
}
//==========================================================================
//
//==========================================================================
DEFINE_PROPERTY(angle, I, CoreActor)
DEFINE_PROPERTY(angle, F, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.angle = DAngle::fromDeg(i);
defaults->spr.angle = DAngle::fromDeg(i);
bag.Info->ActorInfo()->DefaultFlags |= DEFF_ANG;
}
//==========================================================================
//
//==========================================================================
DEFINE_PROPERTY(intangle, I, CoreActor)
{
PROP_INT_PARM(i, 0);
defaults->spr.intangle = i;
bag.Info->ActorInfo()->DefaultFlags |= DEFF_INTANG;
}
//==========================================================================
//
//==========================================================================
DEFINE_PROPERTY(xvel, I, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.xint = i;
defaults->spr.xint = i;
bag.Info->ActorInfo()->DefaultFlags |= DEFF_XVEL;
}
@ -353,7 +363,7 @@ DEFINE_PROPERTY(xvel, I, CoreActor)
DEFINE_PROPERTY(yvel, I, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.yint = i;
defaults->spr.yint = i;
bag.Info->ActorInfo()->DefaultFlags |= DEFF_YVEL;
}
@ -363,7 +373,7 @@ DEFINE_PROPERTY(yvel, I, CoreActor)
DEFINE_PROPERTY(zvel, I, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.inittype = i;
defaults->spr.inittype = i;
bag.Info->ActorInfo()->DefaultFlags |= DEFF_ZVEL;
}
@ -373,7 +383,7 @@ DEFINE_PROPERTY(zvel, I, CoreActor)
DEFINE_PROPERTY(lotag, I, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.lotag = i;
defaults->spr.lotag = i;
bag.Info->ActorInfo()->DefaultFlags |= DEFF_LOTAG;
}
@ -383,7 +393,7 @@ DEFINE_PROPERTY(lotag, I, CoreActor)
DEFINE_PROPERTY(hitag, I, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.lotag = i;
defaults->spr.lotag = i;
bag.Info->ActorInfo()->DefaultFlags |= DEFF_HITAG;
}
@ -393,7 +403,7 @@ DEFINE_PROPERTY(hitag, I, CoreActor)
DEFINE_PROPERTY(extra, I, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.lotag = i;
defaults->spr.lotag = i;
bag.Info->ActorInfo()->DefaultFlags |= DEFF_EXTRA;
}
@ -403,7 +413,7 @@ DEFINE_PROPERTY(extra, I, CoreActor)
DEFINE_PROPERTY(detail, I, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.detail = i;
defaults->spr.detail = i;
bag.Info->ActorInfo()->DefaultFlags |= DEFF_DETAIL;
}
@ -413,7 +423,7 @@ DEFINE_PROPERTY(detail, I, CoreActor)
DEFINE_PROPERTY(shade, I, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.shade = i;
defaults->spr.shade = i;
bag.Info->ActorInfo()->DefaultFlags |= DEFF_SHADE;
}
@ -423,7 +433,7 @@ DEFINE_PROPERTY(shade, I, CoreActor)
DEFINE_PROPERTY(pal, I, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.pal = i;
defaults->spr.pal = i;
bag.Info->ActorInfo()->DefaultFlags |= DEFF_PAL;
}
@ -433,7 +443,7 @@ DEFINE_PROPERTY(pal, I, CoreActor)
DEFINE_PROPERTY(clipdist, I, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.clipdist = i;
defaults->spr.clipdist = i;
bag.Info->ActorInfo()->DefaultFlags |= DEFF_CLIPDIST;
}
@ -443,7 +453,7 @@ DEFINE_PROPERTY(clipdist, I, CoreActor)
DEFINE_PROPERTY(scalex, F, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.scale.X = (i);
defaults->spr.scale.X = (i);
bag.Info->ActorInfo()->DefaultFlags |= DEFF_XREPEAT;
}
@ -453,7 +463,7 @@ DEFINE_PROPERTY(scalex, F, CoreActor)
DEFINE_PROPERTY(scaley, F, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.scale.Y = (i);
defaults->spr.scale.Y = (i);
bag.Info->ActorInfo()->DefaultFlags |= DEFF_YREPEAT;
}
@ -463,7 +473,7 @@ DEFINE_PROPERTY(scaley, F, CoreActor)
DEFINE_PROPERTY(xoffset, I, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.xoffset = i;
defaults->spr.xoffset = i;
bag.Info->ActorInfo()->DefaultFlags |= DEFF_XOFFSET;
}
@ -473,7 +483,7 @@ DEFINE_PROPERTY(xoffset, I, CoreActor)
DEFINE_PROPERTY(yoffset, I, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.yoffset = i;
defaults->spr.yoffset = i;
bag.Info->ActorInfo()->DefaultFlags |= DEFF_YOFFSET;
}
@ -483,7 +493,7 @@ DEFINE_PROPERTY(yoffset, I, CoreActor)
DEFINE_PROPERTY(owner, I, CoreActor)
{
PROP_INT_PARM(i, 0);
bag.Info->ActorInfo()->defsprite.intowner = i;
defaults->spr.intowner = i;
bag.Info->ActorInfo()->DefaultFlags |= DEFF_OWNER;
}
@ -492,6 +502,7 @@ DEFINE_PROPERTY(owner, I, CoreActor)
//==========================================================================
DEFINE_PROPERTY(spriteset, Sssssssssssssssssssssssssssssss, CoreActor)
{
bag.Info->ActorInfo()->DefaultFlags |= DEFF_PICNUM; // this also overrides the map's picnum
info->ActorInfo()->SpriteSetNames.Clear();
for (int i = 0; i < PROP_PARM_COUNT; ++i)
{

View file

@ -1202,7 +1202,10 @@ void operatemasterswitches(int low)
while (auto act2 = it.Next())
{
if (ismasterswitch(act2) && act2->spr.lotag == low && act2->spr.yint == 0)
{
act2->spr.yint = 1;
Printf("triggering %d\n", act2->time);
}
}
}

View file

@ -45,8 +45,6 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
{
if (act->GetClass() != RUNTIME_CLASS(DDukeActor))
{
auto sset = act->spriteset();
if (sset.Size() > 0) act->spr.picnum = sset[0];
CallInitialize(act);
return act;
}
@ -700,12 +698,7 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
case SIDEBOLT1 + 1:
case SIDEBOLT1 + 2:
case SIDEBOLT1 + 3:
act->temp_pos.X = act->spr.scale.X;
act->temp_pos.Y = act->spr.scale.Y;
[[fallthrough]];
case MASTERSWITCH:
if (act->spr.picnum == MASTERSWITCH)
act->spr.cstat |= CSTAT_SPRITE_INVISIBLE;
act->temp_pos.XY() = act->spr.scale;
act->spr.yint = 0;
ChangeActorStat(act, STAT_STANDABLE);
break;

View file

@ -39,8 +39,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray<DDukeActor*>*
{
if (act->GetClass() != RUNTIME_CLASS(DDukeActor))
{
auto sset = act->spriteset();
if (sset.Size() > 0) act->spr.picnum = sset[0];
CallInitialize(act);
return act;
}