use std:variant for nextDude to get some type safety

This commit is contained in:
Christoph Oelckers 2023-10-16 19:04:11 +02:00
parent 00112c472d
commit 54878bf125
5 changed files with 40 additions and 37 deletions

View file

@ -140,6 +140,7 @@ void actInit(TArray<DBloodActor*>& actors);
void actWallBounceVector(DBloodActor* actor, walltype* pWall, double factor);
DVector4 actFloorBounceVector(DBloodActor* actor, double oldz, sectortype* pSector, double factor);
void actRadiusDamage(DBloodActor* source, const DVector3& pos, sectortype* pSector, int nDist, int a7, int a8, DAMAGE_TYPE a9, int a10, int a11);
DBloodActor* actDropObject(DBloodActor* pSprite, PClass* nType);
DBloodActor *actDropObject(DBloodActor *pSprite, int nType);
bool actHealDude(DBloodActor* pXDude, int a2, int a3);
void actKillDude(DBloodActor* a1, DBloodActor* pSprite, DAMAGE_TYPE a3, int a4);

View file

@ -1264,10 +1264,10 @@ void thinkMorph(DBloodActor* pSpr)
pSpr->xspr.locked = 0;
pSpr->xspr.scale = 0;
if (pDude->NextDude)
if (auto ppNext = std::get_if<DBloodActor*>(&pDude->nextDude))
{
auto pNext = *ppNext;
// classic morphing to already inserted sprite by TX ID
DBloodActor* pNext = pDude->NextDude;
pSpr->xspr.key = pSpr->xspr.dropMsg = 0;
@ -1325,21 +1325,19 @@ void thinkMorph(DBloodActor* pSpr)
}
else
{
int nNextDudeType = pDude->NextDudeType;
// v2 morphing
if (nNextDudeType > 0)
{
// morph to another custom dude
pSpr->xspr.data1 = nNextDudeType - 1;
}
else if (nNextDudeType < 0)
if (auto ppClass = std::get_if<PClass*>(&pDude->nextDude))
{
// morph to some vanilla dude
pSpr->ChangeType(-nNextDudeType - 1);
pSpr->ChangeType(*ppClass);
pSpr->clipdist = getDudeInfo(pSpr)->clipdist * CLIPDIST_SCALE;
pSpr->xspr.data1 = 0;
}
// v2 morphing
else if (auto pExt = std::get_if<int>(&pDude->nextDude))
{
// morph to another custom dude
pSpr->xspr.data1 = *pExt;
}
pSpr->spr.inittype = pSpr->GetType();
pSpr->xspr.health = nnExtDudeStartHealth(pSpr, 0);

View file

@ -12,7 +12,7 @@ struct SPRITEHIT
Collision hit, ceilhit, florhit;
};
class DBloodActor;
class DCustomDude;
class DBloodActor : public DCoreActor
{

View file

@ -989,7 +989,7 @@ void DCustomDude::Kill(DBloodActor* pFrom, int nDmgType, int nDmg)
if (IsDying())
return;
if (NextDude || NextDudeType != 0)
if (!std::get_if<bool>(&nextDude))
{
// clamp hp so is not count as dead
pSpr->xspr.health = ClipLow(pSpr->xspr.health, 16);
@ -1146,7 +1146,7 @@ void DCustomDude::DropItems(void)
if (dropItem.Pick(pSpr, itemList))
{
for(auto& cls : itemList)
for(auto cls : itemList)
{
pDrop = actDropObject(pSpr, cls);
if (pDrop && IsUnderwater()) // add a physics for drop items
@ -1220,7 +1220,7 @@ void DCustomDude::LeechKill(bool delSpr)
void DCustomDude::UpdateSlaves()
{
int t = 0; int32_t* pDb;
int t = 0;
if (pSlaves.Size() == 0)
return;
@ -1404,9 +1404,10 @@ int CUSTOMDUDE_SETUP::DescriptCheck(void)
}
pValue = DescriptGetValue(pGroup->text, pParam->text);
if (pValue && rngok(strlen(pValue), 0, 5))
if (pValue && rngok((int)strlen(pValue), 0, 5))
{
major[0] = pValue[0]; major[1] = '\0';
major[0] = pValue[0];
major[1] = '\0';
if (isdigit(major[0]))
nRetn = atoi(major);
}
@ -1462,7 +1463,6 @@ void CUSTOMDUDE_SETUP::SetupLeech()
DCustomDude* CUSTOMDUDE_SETUP::GetFirstDude(int nID)
{
int i;
DCustomDude* pRetn;
BloodStatIterator it(kStatDude);
while (auto pSpr2 = it.Next())
@ -1564,8 +1564,7 @@ void CUSTOMDUDE_SETUP::DoSetup(DBloodActor* pSpr)
pDude->pWeapon = &pDude->weapons[0];
pDude->posture = kCdudePostureL;
pDude->NextDude = nullptr;
pDude->NextDudeType = 0;
pDude->nextDude = false;
// default stuff
pDude->_seeDist = pDude->pInfo->SeeDist();
@ -2025,7 +2024,7 @@ void CUSTOMDUDE_SETUP::SoundFill(void)
void CUSTOMDUDE_SETUP::FindLargestPic(void)
{
int i, j, nPic, nHeigh = 0;
int i, j, nHeigh = 0;
AISTATE* pState; Seq* pSeq;
for (i = 0; i < kCdudeStateMax; i++)
@ -2036,10 +2035,12 @@ void CUSTOMDUDE_SETUP::FindLargestPic(void)
for (j = 0; j < pSeq->nFrames; j++)
{
nPic = seqGetTile(&pSeq->frames[j]);
if (tilesiz[nPic].y > nHeigh)
auto nPic = seqGetTexture(&pSeq->frames[j]);
auto pPic = TexMan.GetGameTexture(nPic);
int h = (int)pPic->GetDisplayHeight();
if (h > nHeigh)
{
nHeigh = tilesiz[nPic].y;
nHeigh = h;
pDude->largestPic = nPic;
}
}
@ -2169,7 +2170,7 @@ void CUSTOMDUDEV2_SETUP::SetupGeneral(void)
/* ----------------------------------*/
pDude->mass = 75;
pDude->medium = kParMediumAny;
pDude->nextDude = -1;
pDude->nextDude = false;
pParam = gParamGeneral;
while (pParam->id != kParamMax)
@ -2219,12 +2220,12 @@ void CUSTOMDUDEV2_SETUP::SetupGeneral(void)
switch (pMorph->id)
{
case kValCdud:
pDude->nextDude = CheckRange(pMorph->text, nVal, 0, 9999) + kMaxSprites;
pDude->nextDude = CheckRange(pMorph->text, nVal, 0, 9999);
break;
case kValVdud:
range[0] = kDudeCultistTommy - kDudeBase;
range[1] = kDudeVanillaMax - kDudeBase;
pDude->nextDude = -(kDudeBase + CheckRange(pMorph->text, nVal, range[0], range[1])) - 1;
pDude->nextDude = GetSpawnType(kDudeBase + CheckRange(pMorph->text, nVal, range[0], range[1]));
break;
default:
continue;
@ -4154,7 +4155,7 @@ void CUSTOMDUDEV1_SETUP::SetupIncarnation(void)
}
}
pDude->nextDude = -1; // then search
pDude->nextDude = false; // then search
BloodStatIterator it(kStatInactive);
while (auto pSpr2 = it.Next())
{
@ -4163,7 +4164,7 @@ void CUSTOMDUDEV1_SETUP::SetupIncarnation(void)
XSPRITE* pXSpr2 = &xsprite[pSpr2->extra];
if (pXSpr2->rxID == pSpr->xspr.txID)
{
pDude->nextDude = pSpr2->index;
pDude->nextDude = pSpr2;
if (nnExtRandom(0, 6) == 3) // random stop
break;
}
@ -4465,11 +4466,14 @@ IMPLEMENT_CLASS(DCustomDude, false, true)
IMPLEMENT_POINTERS_START(DCustomDude)
IMPLEMENT_POINTER(pSpr)
IMPLEMENT_POINTER(pLeech)
IMPLEMENT_POINTER(NextDude)
IMPLEMENT_POINTERS_END
size_t DCustomDude::PropagateMark()
{
if (auto ppDude = std::get_if<DBloodActor*>(&nextDude))
{
GC::Mark(ppDude);
}
for (auto& slave : pSlaves) GC::Mark(slave);
return pSlaves.Size() + Super::PropagateMark();
}

View file

@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifdef NOONE_EXTENSIONS
#pragma once
#include <variant>
#include "nnexts.h"
#include "sound.h"
#include "view.h"
@ -1226,8 +1227,7 @@ class DCustomDude : public DObject
double _hearDist ; // dudeInfo duplicate for sleeping
DAngle periphery ; // dudeInfo duplicate for sleeping
unsigned int fallHeight ; // in pixels
TObjPtr<DBloodActor*> NextDude;
int NextDudeType; // 0: none, <0: vdude, >0: cdude, NextDude: existing
std::variant<bool, int, PClass*, DBloodActor*> nextDude;
//signed int nextDude ;
//----------------------------------------------------------------------------------------------------
@ -1397,7 +1397,7 @@ class CUSTOMDUDEV2_SETUP : public CUSTOMDUDE_SETUP
bool ParseOnEventDmg(const char* str, int* pOut, int nLen);
bool ParseDropItem(const char* str, uint8_t out[2]);
bool ParseSkill(const char* str);
int ParseKeywords(const char* str, PARAM* pDb);
int ParseKeywords(const char* str, const PARAM* pDb);
int ParseIDs(const char* str, int nValType, TArray<PClass*>& pOut, int nMax = 0);
int ParseIDs(const char* str, int nValType, int* pOut, int nMax);
int ParseEffectIDs(const char* str, const char* paramName, unsigned short* pOut, int nLen = 0);
@ -1409,7 +1409,7 @@ class CUSTOMDUDEV2_SETUP : public CUSTOMDUDE_SETUP
int CheckValue(const char* str, int nValType, int nMin, int nMax);
int CheckValue(const char* str, int nValType, int nMin, int nMax, int nDefault);
int CheckRange(const char* str, int nVal, int nMin, int nMax);
int CheckParam(const char* str, PARAM* pDb);
int CheckParam(const char* str, const PARAM* pDb);
/*-------------------------------------------------*/
void SetupGeneral(void);
void SetupVelocity(void);