mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-09 01:01:05 +00:00
TArrays to TObjPtr
- Made the 2 TArrays into a class called DActorModelData. - Removed the skinindex and now just uses one index - Replaced a bunch of nullptr for modelDef checking with NAME_None - Added some garbage cleanup to A_ChangeModel itself, as well as removing memory of modelData that is no longer needed - Attempted serialize code, putting up for review
This commit is contained in:
parent
c304a8f974
commit
e827e9b086
6 changed files with 84 additions and 27 deletions
|
@ -673,6 +673,18 @@ enum EViewPosFlags // [MC] Flags for SetViewPos.
|
|||
VPSF_ABSOLUTEPOS = 1 << 2, // Use absolute position.
|
||||
};
|
||||
|
||||
class DActorModelData : public DObject
|
||||
{
|
||||
DECLARE_CLASS(DActorModelData, DObject);
|
||||
public:
|
||||
bool hasModel;
|
||||
TArray<int> modelIDs;
|
||||
TArray<FTextureID> skinIDs;
|
||||
|
||||
DActorModelData() = default;
|
||||
virtual void Serialize(FSerializer& arc) override;
|
||||
};
|
||||
|
||||
class DViewPosition : public DObject
|
||||
{
|
||||
DECLARE_CLASS(DViewPosition, DObject);
|
||||
|
@ -1068,9 +1080,8 @@ public:
|
|||
DVector3 WorldOffset;
|
||||
double Speed;
|
||||
double FloatSpeed;
|
||||
FName modelDef;
|
||||
TArray<int> models;
|
||||
TArray <FTextureID> skins;
|
||||
FName modelDef;
|
||||
TObjPtr<DActorModelData*> modelData;
|
||||
|
||||
// interaction info
|
||||
FBlockNode *BlockNode; // links in blocks (if needed)
|
||||
|
|
|
@ -5037,12 +5037,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_ChangeModel)
|
|||
{
|
||||
PARAM_ACTION_PROLOGUE(AActor);
|
||||
PARAM_NAME(modeldef)
|
||||
PARAM_INT(index)
|
||||
PARAM_STRING_VAL(modelpath)
|
||||
PARAM_NAME(model)
|
||||
PARAM_INT(modelindex)
|
||||
PARAM_STRING_VAL(skinpath)
|
||||
PARAM_NAME(skin)
|
||||
PARAM_INT(skinindex)
|
||||
PARAM_INT(flags)
|
||||
|
||||
if (self == nullptr)
|
||||
|
@ -5053,15 +5052,42 @@ DEFINE_ACTION_FUNCTION(AActor, A_ChangeModel)
|
|||
if (modelpath[(int)modelpath.Len() - 1] != '/') modelpath += '/';
|
||||
if (skinpath[(int)skinpath.Len() - 1] != '/') skinpath += '/';
|
||||
|
||||
mobj->hasmodel = modeldef == nullptr && !mobj->hasmodel ? 1 : 0;
|
||||
mobj->modelDef = modeldef;
|
||||
if (mobj->modelData == nullptr)
|
||||
{
|
||||
auto ptr = Create<DActorModelData>();
|
||||
ptr->hasModel = modeldef != NAME_None && !mobj->hasmodel ? 0 : 1;
|
||||
ptr->modelIDs = *new TArray<int>();
|
||||
ptr->skinIDs = *new TArray<FTextureID>();
|
||||
mobj->modelData = ptr;
|
||||
mobj->hasmodel = mobj->modelData->hasModel;
|
||||
GC::WriteBarrier(mobj, ptr);
|
||||
}
|
||||
|
||||
mobj->models.Delete(modelindex);
|
||||
mobj->skins.Delete(skinindex);
|
||||
if(model != nullptr) mobj->models.Insert(modelindex, FindModel(modelpath.GetChars(), model.GetChars()));
|
||||
else mobj->models.Insert(modelindex, -1);
|
||||
if(skin != nullptr) mobj->skins.Insert(skinindex, LoadSkin(skinpath.GetChars(), skin.GetChars()));
|
||||
else mobj->skins.Insert(skinindex, FNullTextureID());
|
||||
mobj->modelDef = modeldef;
|
||||
mobj->modelData->modelIDs.Delete(index);
|
||||
mobj->modelData->skinIDs.Delete(index);
|
||||
mobj->modelData->modelIDs.Insert(index, model != NAME_None ? FindModel(modelpath.GetChars(), model.GetChars()) : -1);
|
||||
mobj->modelData->skinIDs.Insert(index, skin != NAME_None ? LoadSkin(skinpath.GetChars(), skin.GetChars()) : FNullTextureID());
|
||||
|
||||
//[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.
|
||||
int i = 0;
|
||||
int maxModels = mobj->modelData->modelIDs.Size();
|
||||
int maxSkins = mobj->modelData->modelIDs.Size();
|
||||
for (i = 0; i < maxModels; i++)
|
||||
{
|
||||
if (mobj->modelData->modelIDs[mobj->modelData->modelIDs.Size()-1] == -1)
|
||||
mobj->modelData->modelIDs.Delete(mobj->modelData->modelIDs.Size()-1);
|
||||
}
|
||||
for (i = 0; i < maxSkins; i++)
|
||||
{
|
||||
if (mobj->modelData->skinIDs[mobj->modelData->skinIDs.Size()-1] == FNullTextureID())
|
||||
mobj->modelData->skinIDs.Delete(mobj->modelData->skinIDs.Size()-1);
|
||||
}
|
||||
if (mobj->modelData->modelIDs.Size() == 0 && mobj->modelData->skinIDs.Size() == 0 && modeldef == NAME_None)
|
||||
{
|
||||
mobj->hasmodel = mobj->modelData->hasModel;
|
||||
mobj->modelData = nullptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -158,6 +158,7 @@ CVAR (Int, cl_bloodtype, 0, CVAR_ARCHIVE);
|
|||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_CLASS(DActorModelData, false, false);
|
||||
IMPLEMENT_CLASS(AActor, false, true)
|
||||
|
||||
IMPLEMENT_POINTERS_START(AActor)
|
||||
|
@ -374,7 +375,9 @@ void AActor::Serialize(FSerializer &arc)
|
|||
("viewpos", ViewPos)
|
||||
A("lightlevel", LightLevel)
|
||||
A("userlights", UserLights)
|
||||
A("WorldOffset", WorldOffset);
|
||||
A("WorldOffset", WorldOffset)
|
||||
A("modelData", modelData)
|
||||
A("modelDef", modelDef);
|
||||
|
||||
SerializeTerrain(arc, "floorterrain", floorterrain, &def->floorterrain);
|
||||
SerializeArgs(arc, "args", args, def->args, special);
|
||||
|
@ -1353,6 +1356,20 @@ bool AActor::Massacre ()
|
|||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// Serialize DActorModelData
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void DActorModelData::Serialize(FSerializer& arc)
|
||||
{
|
||||
Super::Serialize(arc);
|
||||
arc ("modelIDs", modelIDs)
|
||||
("skinIDs", skinIDs)
|
||||
("hasModel", hasModel);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_ExplodeMissile
|
||||
|
|
|
@ -176,14 +176,14 @@ void RenderModel(FModelRenderer *renderer, float x, float y, float z, FSpriteMod
|
|||
float orientation = scaleFactorX * scaleFactorY * scaleFactorZ;
|
||||
|
||||
renderer->BeginDrawModel(actor->RenderStyle, smf, objectToWorldMatrix, orientation < 0);
|
||||
RenderFrameModels(renderer, actor->Level, smf, actor->state, actor->tics, actor->modelDef != nullptr ? PClass::FindActor(actor->modelDef) : actor->GetClass(), translation, actor);
|
||||
RenderFrameModels(renderer, actor->Level, smf, actor->state, actor->tics, actor->modelDef != NAME_None ? PClass::FindActor(actor->modelDef) : actor->GetClass(), translation, actor);
|
||||
renderer->EndDrawModel(actor->RenderStyle, smf);
|
||||
}
|
||||
|
||||
void RenderHUDModel(FModelRenderer *renderer, DPSprite *psp, float ofsX, float ofsY)
|
||||
{
|
||||
AActor * playermo = players[consoleplayer].camera;
|
||||
FSpriteModelFrame *smf = psp->Caller != nullptr ? FindModelFrame(psp->Caller->modelDef != nullptr ? PClass::FindActor(psp->Caller->modelDef) : psp->Caller->GetClass(), psp->GetSprite(), psp->GetFrame(), false) : nullptr;
|
||||
FSpriteModelFrame *smf = psp->Caller != nullptr ? FindModelFrame(psp->Caller->modelDef != NAME_None ? PClass::FindActor(psp->Caller->modelDef) : psp->Caller->GetClass(), psp->GetSprite(), psp->GetFrame(), false) : nullptr;
|
||||
|
||||
// [BB] No model found for this sprite, so we can't render anything.
|
||||
if (smf == nullptr)
|
||||
|
@ -224,7 +224,7 @@ void RenderHUDModel(FModelRenderer *renderer, DPSprite *psp, float ofsX, float o
|
|||
renderer->BeginDrawHUDModel(playermo->RenderStyle, objectToWorldMatrix, orientation < 0);
|
||||
uint32_t trans = psp->GetTranslation() != 0 ? psp->GetTranslation() : 0;
|
||||
if ((psp->Flags & PSPF_PLAYERTRANSLATED)) trans = psp->Owner->mo->Translation;
|
||||
RenderFrameModels(renderer, playermo->Level, smf, psp->GetState(), psp->GetTics(), psp->Caller->modelDef != nullptr ? PClass::FindActor(psp->Caller->modelDef) : psp->Caller->GetClass(), trans, psp->Caller);
|
||||
RenderFrameModels(renderer, playermo->Level, smf, psp->GetState(), psp->GetTics(), psp->Caller->modelDef != NAME_None ? PClass::FindActor(psp->Caller->modelDef) : psp->Caller->GetClass(), trans, psp->Caller);
|
||||
renderer->EndDrawHUDModel(playermo->RenderStyle);
|
||||
}
|
||||
|
||||
|
@ -281,19 +281,22 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
|
|||
TArray<FTextureID> tempSkinIDs = smf->skinIDs;
|
||||
for (int i = 0; i < smf->modelsAmount; i++)
|
||||
{
|
||||
if (i < actor->models.Size())
|
||||
if (actor->modelData != nullptr)
|
||||
{
|
||||
if (actor->models[i] >= 0)
|
||||
tempModelIDs[i] = actor->models[i];
|
||||
if (i < (int)actor->modelData->modelIDs.Size())
|
||||
{
|
||||
if(actor->modelData->modelIDs[i] >= 0)
|
||||
tempModelIDs[i] = actor->modelData->modelIDs[i];
|
||||
}
|
||||
if (i < (int)actor->modelData->skinIDs.Size())
|
||||
{
|
||||
if (actor->modelData->skinIDs[i].isValid())
|
||||
tempSkinIDs[i] = actor->modelData->skinIDs[i];
|
||||
}
|
||||
}
|
||||
if (tempModelIDs[i] != -1)
|
||||
{
|
||||
FModel * mdl = Models[tempModelIDs[i]];
|
||||
if (i < actor->skins.Size())
|
||||
{
|
||||
if (actor->skins[i].isValid())
|
||||
tempSkinIDs[i] = actor->skins[i];
|
||||
}
|
||||
auto tex = tempSkinIDs[i].isValid() ? TexMan.GetGameTexture(tempSkinIDs[i], true) : nullptr;
|
||||
mdl->BuildVertexBuffer(renderer);
|
||||
|
||||
|
|
|
@ -834,7 +834,7 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t
|
|||
z += fz;
|
||||
}
|
||||
|
||||
modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing->modelDef != nullptr ? PClass::FindActor(thing->modelDef) : thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED));
|
||||
modelframe = isPicnumOverride ? nullptr : FindModelFrame(thing->modelDef != NAME_None ? PClass::FindActor(thing->modelDef) : thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED));
|
||||
|
||||
// don't bother drawing sprite shadows if this is a model (it will never look right)
|
||||
if (modelframe && isSpriteShadow)
|
||||
|
|
|
@ -1132,7 +1132,7 @@ class Actor : Thinker native
|
|||
native void A_SetBlend(color color1, double alpha, int tics, color color2 = 0, double alpha2 = 0.);
|
||||
deprecated("2.3", "Use 'b<FlagName> = [true/false]' instead") native void A_ChangeFlag(string flagname, bool value);
|
||||
native void A_ChangeCountFlags(int kill = FLAG_NO_CHANGE, int item = FLAG_NO_CHANGE, int secret = FLAG_NO_CHANGE);
|
||||
action native void A_ChangeModel(name modeldef, string modelpath = "", name model = "", int modelindex = 0, string skinpath = "", name skin = "", int skinindex = 0, int flags = 0);
|
||||
action native void A_ChangeModel(name modeldef, int index = 0, string modelpath = "", name model = "", string skinpath = "", name skin = "", int flags = 0);
|
||||
|
||||
void A_SetFriendly (bool set)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue