More fixes

- Let's fill the holes of serialized data so it can properly be removed instead of leaving undefined behavior behind.
- Added CMDL_HIDEMODEL flag. This makes a model index invisible.
This commit is contained in:
Shiny Metagross 2022-07-01 11:49:13 -07:00 committed by Christoph Oelckers
parent 11f342795b
commit ec3d81a34f
3 changed files with 17 additions and 17 deletions

View file

@ -5030,7 +5030,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetMugshotState)
enum ChangeModelFlags
{
CMDL_WEAPONTOPLAYER = 1
CMDL_WEAPONTOPLAYER = 1,
CMDL_HIDEMODEL = 1 << 1,
};
DEFINE_ACTION_FUNCTION(AActor, A_ChangeModel)
@ -5067,17 +5068,21 @@ DEFINE_ACTION_FUNCTION(AActor, A_ChangeModel)
int maxModels = mobj->modelData->modelIDs.Size();
int maxSkins = mobj->modelData->skinIDs.Size();
int queryModel = model != NAME_None ? FindModel(modelpath.GetChars(), model.GetChars()) : -1;
int queryModel = !(flags & CMDL_HIDEMODEL) ? model != NAME_None ? FindModel(modelpath.GetChars(), model.GetChars()) : -1 : -2;
mobj->modelData->modelDef = modeldef;
if(maxModels > index) mobj->modelData->modelIDs.Pop(mobj->modelData->modelIDs[index]);
if(maxSkins > index) mobj->modelData->skinIDs.Pop(mobj->modelData->skinIDs[index]);
//[SM] - We need to fill up any holes this new index will make so that it doesn't leave behind any undefined behavior
while ((int)mobj->modelData->modelIDs.Size() < index) mobj->modelData->modelIDs.Push(-1);
while ((int)mobj->modelData->skinIDs.Size() < index) mobj->modelData->skinIDs.Push(FNullTextureID());
mobj->modelData->modelIDs.Insert(index, queryModel);
mobj->modelData->skinIDs.Insert(index, skin != NAME_None ? LoadSkin(skinpath.GetChars(), skin.GetChars()) : FNullTextureID());
//[SM] - We need to serialize file paths and model names so that they are pushed on loading save files. Likewise, let's not include models that were already parsed when initialized.
if (model != NAME_None)
if (queryModel >= 0)
{
FString fullName;
fullName.Format("%s%s", modelpath.GetChars(), model.GetChars());
@ -5089,20 +5094,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_ChangeModel)
}
//[SM] - if an indice of modelIDs or skinIDs comes up blank and it's the last one, just delete it. For using very large amounts of indices, common sense says to just not run this repeatedly.
for (int i = 0; i < maxModels; i++)
{
if (mobj->modelData->modelIDs.Last() == -1) mobj->modelData->modelIDs.Pop(mobj->modelData->modelIDs.Last());
else break;
}
for (int i = 0; i < maxSkins; i++)
{
if (mobj->modelData->skinIDs.Last() == FNullTextureID()) mobj->modelData->skinIDs.Pop(mobj->modelData->skinIDs.Last());
else break;
}
while (mobj->modelData->modelIDs.Size() > 0 && mobj->modelData->modelIDs.Last() == -1)
mobj->modelData->modelIDs.Pop(mobj->modelData->modelIDs.Last());
while (mobj->modelData->skinIDs.Size() > 0 && mobj->modelData->skinIDs.Last() == FNullTextureID())
mobj->modelData->skinIDs.Pop(mobj->modelData->skinIDs.Last());
if (mobj->modelData->modelIDs.Size() == 0 && mobj->modelData->skinIDs.Size() == 0 && modeldef == NAME_None)
{
mobj->hasmodel = mobj->modelData->hasModel;
mobj->modelData;
mobj->modelData->modelIDs.Reset();
mobj->modelData->skinIDs.Reset();
mobj->modelData->Destroy();

View file

@ -285,7 +285,7 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
{
if (i < (int)actor->modelData->modelIDs.Size())
{
if(actor->modelData->modelIDs[i] >= 0)
if(actor->modelData->modelIDs[i] != -1)
tempModelIDs[i] = actor->modelData->modelIDs[i];
}
if (i < (int)actor->modelData->skinIDs.Size())
@ -294,7 +294,7 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
tempSkinIDs[i] = actor->modelData->skinIDs[i];
}
}
if (tempModelIDs[i] != -1)
if (tempModelIDs[i] >= 0)
{
FModel * mdl = Models[tempModelIDs[i]];
auto tex = tempSkinIDs[i].isValid() ? TexMan.GetGameTexture(tempSkinIDs[i], true) : nullptr;

View file

@ -368,7 +368,8 @@ enum ERadiusGiveFlags
// Change model flags
enum ChangeModelFlags
{
CMDL_WEAPONTOPLAYER = 1
CMDL_WEAPONTOPLAYER = 1,
CMDL_HIDEMODEL = 1 << 1,
};
// Activation flags