A_ChangeModeldef

-Added A_ChangeModelDef
A_ChangeModel(modeldef, modelpath, model, modelindex, skinpath, skin, skinid, flags)

This can change the modeldef, model and skins of an actor.

Currently, modelindex and skinindex accept indices from 0-15.

An actor MUST have a modeldef in order to use this function, either defined from modeldef, or given one through the modeldef parameter. You can pass "" to use the same modeldef. Likewise, passing "" for model or skin will just revert to the default model.

Available flags:
CMDL_WEAPONTOPLAYER - If used on a weapon, this instead change's the model on the player instead.

One issue I am aware of right now is that clearing a model by "" sort of works but is buggy. For now you can just manually set the model back using the names explicitly. However, I am stumped and I think getting more eyes on it would help.
This commit is contained in:
Shiny Metagross 2022-06-27 20:23:28 -07:00 committed by Christoph Oelckers
commit 5abadd3aab
6 changed files with 60 additions and 7 deletions

View file

@ -55,7 +55,7 @@ EXTERN_CVAR (Bool, r_drawvoxels)
extern TDeletingArray<FVoxel *> Voxels;
extern TDeletingArray<FVoxelDef *> VoxelDefs;
void RenderFrameModels(FModelRenderer* renderer, FLevelLocals* Level, const FSpriteModelFrame* smf, const FState* curState, const int curTics, const PClass* ti, int translation);
void RenderFrameModels(FModelRenderer* renderer, FLevelLocals* Level, const FSpriteModelFrame* smf, const FState* curState, const int curTics, const PClass* ti, int translation, AActor* actor);
void RenderModel(FModelRenderer *renderer, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor, double ticFrac)
@ -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->GetClass(), translation);
RenderFrameModels(renderer, actor->Level, smf, actor->state, actor->tics, actor->modelDef != nullptr ? 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->GetClass(), psp->GetSprite(), psp->GetFrame(), false) : nullptr;
FSpriteModelFrame *smf = psp->Caller != nullptr ? FindModelFrame(psp->Caller->modelDef != nullptr ? 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,11 +224,11 @@ 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->GetClass(), trans);
RenderFrameModels(renderer, playermo->Level, smf, psp->GetState(), psp->GetTics(), psp->Caller->modelDef != nullptr ? PClass::FindActor(psp->Caller->modelDef) : psp->Caller->GetClass(), trans, psp->Caller);
renderer->EndDrawHUDModel(playermo->RenderStyle);
}
void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, int translation)
void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, int translation, AActor* actor)
{
// [BB] Frame interpolation: Find the FSpriteModelFrame smfNext which follows after smf in the animation
// and the scalar value inter ( element of [0,1) ), both necessary to determine the interpolated frame.
@ -278,10 +278,12 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
for (int i = 0; i < smf->modelsAmount; i++)
{
if (actor->models[i] != -1)
smf->modelIDs[i] = actor->models[i];
if (smf->modelIDs[i] != -1)
{
FModel * mdl = Models[smf->modelIDs[i]];
auto tex = smf->skinIDs[i].isValid() ? TexMan.GetGameTexture(smf->skinIDs[i], true) : nullptr;
auto tex = actor->skins[i].isValid() ? TexMan.GetGameTexture(actor->skins[i], true) : smf->skinIDs[i].isValid() ? TexMan.GetGameTexture(smf->skinIDs[i], true) : nullptr;
mdl->BuildVertexBuffer(renderer);
mdl->PushSpriteMDLFrame(smf, i);