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); void actWallBounceVector(DBloodActor* actor, walltype* pWall, double factor);
DVector4 actFloorBounceVector(DBloodActor* actor, double oldz, sectortype* pSector, 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); 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); DBloodActor *actDropObject(DBloodActor *pSprite, int nType);
bool actHealDude(DBloodActor* pXDude, int a2, int a3); bool actHealDude(DBloodActor* pXDude, int a2, int a3);
void actKillDude(DBloodActor* a1, DBloodActor* pSprite, DAMAGE_TYPE a3, int a4); 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.locked = 0;
pSpr->xspr.scale = 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 // classic morphing to already inserted sprite by TX ID
DBloodActor* pNext = pDude->NextDude;
pSpr->xspr.key = pSpr->xspr.dropMsg = 0; pSpr->xspr.key = pSpr->xspr.dropMsg = 0;
@ -1325,21 +1325,19 @@ void thinkMorph(DBloodActor* pSpr)
} }
else else
{ {
int nNextDudeType = pDude->NextDudeType; if (auto ppClass = std::get_if<PClass*>(&pDude->nextDude))
// v2 morphing
if (nNextDudeType > 0)
{
// morph to another custom dude
pSpr->xspr.data1 = nNextDudeType - 1;
}
else if (nNextDudeType < 0)
{ {
// morph to some vanilla dude // morph to some vanilla dude
pSpr->ChangeType(-nNextDudeType - 1); pSpr->ChangeType(*ppClass);
pSpr->clipdist = getDudeInfo(pSpr)->clipdist * CLIPDIST_SCALE; pSpr->clipdist = getDudeInfo(pSpr)->clipdist * CLIPDIST_SCALE;
pSpr->xspr.data1 = 0; 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->spr.inittype = pSpr->GetType();
pSpr->xspr.health = nnExtDudeStartHealth(pSpr, 0); pSpr->xspr.health = nnExtDudeStartHealth(pSpr, 0);

View file

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

View file

@ -989,7 +989,7 @@ void DCustomDude::Kill(DBloodActor* pFrom, int nDmgType, int nDmg)
if (IsDying()) if (IsDying())
return; return;
if (NextDude || NextDudeType != 0) if (!std::get_if<bool>(&nextDude))
{ {
// clamp hp so is not count as dead // clamp hp so is not count as dead
pSpr->xspr.health = ClipLow(pSpr->xspr.health, 16); pSpr->xspr.health = ClipLow(pSpr->xspr.health, 16);
@ -1146,7 +1146,7 @@ void DCustomDude::DropItems(void)
if (dropItem.Pick(pSpr, itemList)) if (dropItem.Pick(pSpr, itemList))
{ {
for(auto& cls : itemList) for(auto cls : itemList)
{ {
pDrop = actDropObject(pSpr, cls); pDrop = actDropObject(pSpr, cls);
if (pDrop && IsUnderwater()) // add a physics for drop items if (pDrop && IsUnderwater()) // add a physics for drop items
@ -1220,7 +1220,7 @@ void DCustomDude::LeechKill(bool delSpr)
void DCustomDude::UpdateSlaves() void DCustomDude::UpdateSlaves()
{ {
int t = 0; int32_t* pDb; int t = 0;
if (pSlaves.Size() == 0) if (pSlaves.Size() == 0)
return; return;
@ -1404,9 +1404,10 @@ int CUSTOMDUDE_SETUP::DescriptCheck(void)
} }
pValue = DescriptGetValue(pGroup->text, pParam->text); 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])) if (isdigit(major[0]))
nRetn = atoi(major); nRetn = atoi(major);
} }
@ -1462,7 +1463,6 @@ void CUSTOMDUDE_SETUP::SetupLeech()
DCustomDude* CUSTOMDUDE_SETUP::GetFirstDude(int nID) DCustomDude* CUSTOMDUDE_SETUP::GetFirstDude(int nID)
{ {
int i;
DCustomDude* pRetn; DCustomDude* pRetn;
BloodStatIterator it(kStatDude); BloodStatIterator it(kStatDude);
while (auto pSpr2 = it.Next()) while (auto pSpr2 = it.Next())
@ -1564,8 +1564,7 @@ void CUSTOMDUDE_SETUP::DoSetup(DBloodActor* pSpr)
pDude->pWeapon = &pDude->weapons[0]; pDude->pWeapon = &pDude->weapons[0];
pDude->posture = kCdudePostureL; pDude->posture = kCdudePostureL;
pDude->NextDude = nullptr; pDude->nextDude = false;
pDude->NextDudeType = 0;
// default stuff // default stuff
pDude->_seeDist = pDude->pInfo->SeeDist(); pDude->_seeDist = pDude->pInfo->SeeDist();
@ -2025,7 +2024,7 @@ void CUSTOMDUDE_SETUP::SoundFill(void)
void CUSTOMDUDE_SETUP::FindLargestPic(void) void CUSTOMDUDE_SETUP::FindLargestPic(void)
{ {
int i, j, nPic, nHeigh = 0; int i, j, nHeigh = 0;
AISTATE* pState; Seq* pSeq; AISTATE* pState; Seq* pSeq;
for (i = 0; i < kCdudeStateMax; i++) for (i = 0; i < kCdudeStateMax; i++)
@ -2036,10 +2035,12 @@ void CUSTOMDUDE_SETUP::FindLargestPic(void)
for (j = 0; j < pSeq->nFrames; j++) for (j = 0; j < pSeq->nFrames; j++)
{ {
nPic = seqGetTile(&pSeq->frames[j]); auto nPic = seqGetTexture(&pSeq->frames[j]);
if (tilesiz[nPic].y > nHeigh) auto pPic = TexMan.GetGameTexture(nPic);
int h = (int)pPic->GetDisplayHeight();
if (h > nHeigh)
{ {
nHeigh = tilesiz[nPic].y; nHeigh = h;
pDude->largestPic = nPic; pDude->largestPic = nPic;
} }
} }
@ -2169,7 +2170,7 @@ void CUSTOMDUDEV2_SETUP::SetupGeneral(void)
/* ----------------------------------*/ /* ----------------------------------*/
pDude->mass = 75; pDude->mass = 75;
pDude->medium = kParMediumAny; pDude->medium = kParMediumAny;
pDude->nextDude = -1; pDude->nextDude = false;
pParam = gParamGeneral; pParam = gParamGeneral;
while (pParam->id != kParamMax) while (pParam->id != kParamMax)
@ -2219,12 +2220,12 @@ void CUSTOMDUDEV2_SETUP::SetupGeneral(void)
switch (pMorph->id) switch (pMorph->id)
{ {
case kValCdud: case kValCdud:
pDude->nextDude = CheckRange(pMorph->text, nVal, 0, 9999) + kMaxSprites; pDude->nextDude = CheckRange(pMorph->text, nVal, 0, 9999);
break; break;
case kValVdud: case kValVdud:
range[0] = kDudeCultistTommy - kDudeBase; range[0] = kDudeCultistTommy - kDudeBase;
range[1] = kDudeVanillaMax - 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; break;
default: default:
continue; continue;
@ -4154,7 +4155,7 @@ void CUSTOMDUDEV1_SETUP::SetupIncarnation(void)
} }
} }
pDude->nextDude = -1; // then search pDude->nextDude = false; // then search
BloodStatIterator it(kStatInactive); BloodStatIterator it(kStatInactive);
while (auto pSpr2 = it.Next()) while (auto pSpr2 = it.Next())
{ {
@ -4163,7 +4164,7 @@ void CUSTOMDUDEV1_SETUP::SetupIncarnation(void)
XSPRITE* pXSpr2 = &xsprite[pSpr2->extra]; XSPRITE* pXSpr2 = &xsprite[pSpr2->extra];
if (pXSpr2->rxID == pSpr->xspr.txID) if (pXSpr2->rxID == pSpr->xspr.txID)
{ {
pDude->nextDude = pSpr2->index; pDude->nextDude = pSpr2;
if (nnExtRandom(0, 6) == 3) // random stop if (nnExtRandom(0, 6) == 3) // random stop
break; break;
} }
@ -4465,11 +4466,14 @@ IMPLEMENT_CLASS(DCustomDude, false, true)
IMPLEMENT_POINTERS_START(DCustomDude) IMPLEMENT_POINTERS_START(DCustomDude)
IMPLEMENT_POINTER(pSpr) IMPLEMENT_POINTER(pSpr)
IMPLEMENT_POINTER(pLeech) IMPLEMENT_POINTER(pLeech)
IMPLEMENT_POINTER(NextDude)
IMPLEMENT_POINTERS_END IMPLEMENT_POINTERS_END
size_t DCustomDude::PropagateMark() size_t DCustomDude::PropagateMark()
{ {
if (auto ppDude = std::get_if<DBloodActor*>(&nextDude))
{
GC::Mark(ppDude);
}
for (auto& slave : pSlaves) GC::Mark(slave); for (auto& slave : pSlaves) GC::Mark(slave);
return pSlaves.Size() + Super::PropagateMark(); 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 #ifdef NOONE_EXTENSIONS
#pragma once #pragma once
#include <variant>
#include "nnexts.h" #include "nnexts.h"
#include "sound.h" #include "sound.h"
#include "view.h" #include "view.h"
@ -1226,8 +1227,7 @@ class DCustomDude : public DObject
double _hearDist ; // dudeInfo duplicate for sleeping double _hearDist ; // dudeInfo duplicate for sleeping
DAngle periphery ; // dudeInfo duplicate for sleeping DAngle periphery ; // dudeInfo duplicate for sleeping
unsigned int fallHeight ; // in pixels unsigned int fallHeight ; // in pixels
TObjPtr<DBloodActor*> NextDude; std::variant<bool, int, PClass*, DBloodActor*> nextDude;
int NextDudeType; // 0: none, <0: vdude, >0: cdude, NextDude: existing
//signed int nextDude ; //signed int nextDude ;
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
@ -1397,7 +1397,7 @@ class CUSTOMDUDEV2_SETUP : public CUSTOMDUDE_SETUP
bool ParseOnEventDmg(const char* str, int* pOut, int nLen); bool ParseOnEventDmg(const char* str, int* pOut, int nLen);
bool ParseDropItem(const char* str, uint8_t out[2]); bool ParseDropItem(const char* str, uint8_t out[2]);
bool ParseSkill(const char* str); 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, TArray<PClass*>& pOut, int nMax = 0);
int ParseIDs(const char* str, int nValType, int* pOut, int nMax); 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); 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 CheckValue(const char* str, int nValType, int nMin, int nMax, int nDefault); 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 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 SetupGeneral(void);
void SetupVelocity(void); void SetupVelocity(void);