mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-19 07:01:09 +00:00
- handle cases where CON tries to spawn unknown actors.
It must fall back to spawning an inert sprite in these cases, not just fail.
This commit is contained in:
parent
34160a4354
commit
8a331e226f
5 changed files with 38 additions and 19 deletions
|
@ -42,6 +42,8 @@ int getlabelvalue(const char* text);
|
|||
|
||||
static int ccmd_spawn(CCmdFuncPtr parm)
|
||||
{
|
||||
FTextureID texid = FNullTextureID();
|
||||
int picno = -1;
|
||||
int x = 0, y = 0, z = 0;
|
||||
ESpriteFlags cstat = 0;
|
||||
PClassActor* cls = nullptr;
|
||||
|
@ -74,14 +76,19 @@ static int ccmd_spawn(CCmdFuncPtr parm)
|
|||
[[fallthrough]];
|
||||
case 1: // tile number
|
||||
if (isdigit((uint8_t)parm->parms[0][0])) {
|
||||
cls = GetSpawnType((unsigned short)atol(parm->parms[0]));
|
||||
picno = (unsigned short)atol(parm->parms[0]);
|
||||
cls = GetSpawnType(picno);
|
||||
}
|
||||
else
|
||||
{
|
||||
cls = PClass::FindActor(parm->parms[0]);
|
||||
if (!cls)
|
||||
{
|
||||
int picno = tileForName(parm->parms[0]);
|
||||
texid = TexMan.CheckForTexture(parm->parms[0], ETextureType::Any, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_ReturnAll);
|
||||
if (texid.isValid())
|
||||
{
|
||||
picno = legacyTileNum(texid);
|
||||
}
|
||||
if (picno < 0)
|
||||
{
|
||||
picno = getlabelvalue(parm->parms[0]);
|
||||
|
@ -90,7 +97,7 @@ static int ccmd_spawn(CCmdFuncPtr parm)
|
|||
}
|
||||
}
|
||||
|
||||
if (cls == nullptr)
|
||||
if (cls == nullptr && !texid.isValid())
|
||||
{
|
||||
Printf("spawn: Invalid actor type '%s'\n", parm->parms[0]);
|
||||
return CCMD_OK;
|
||||
|
@ -100,7 +107,9 @@ static int ccmd_spawn(CCmdFuncPtr parm)
|
|||
return CCMD_SHOWHELP;
|
||||
}
|
||||
|
||||
auto spawned = spawn(ps[myconnectindex].GetActor(), cls);
|
||||
DDukeActor* spawned;
|
||||
if (!cls) spawned = spawnsprite(ps[myconnectindex].GetActor(), picno);
|
||||
else spawned = spawn(ps[myconnectindex].GetActor(), cls);
|
||||
if (spawned)
|
||||
{
|
||||
if (set & 1) spawned->spr.pal = (uint8_t)pal;
|
||||
|
|
|
@ -20,6 +20,7 @@ inline int player_struct::GetPlayerNum()
|
|||
}
|
||||
|
||||
DDukeActor* spawn(DDukeActor* spawner, PClassActor* pname);
|
||||
DDukeActor* spawnsprite(DDukeActor* origin, int typeId);
|
||||
|
||||
// return type is int for scripting - the value must still be true or false!
|
||||
inline int badguy(const DDukeActor* pSprite)
|
||||
|
|
|
@ -1894,7 +1894,7 @@ int ParseState::parse(void)
|
|||
case concmd_spawn:
|
||||
insptr++;
|
||||
if(g_ac->insector())
|
||||
spawn(g_ac, GetSpawnType(*insptr));
|
||||
spawnsprite(g_ac, *insptr);
|
||||
insptr++;
|
||||
break;
|
||||
case concmd_ifwasweapon:
|
||||
|
|
|
@ -82,7 +82,6 @@ DDukeActor* CreateActor(sectortype* whatsectp, const DVector3& pos, PClassActor*
|
|||
if (whatsectp == nullptr || !validSectorIndex(sectindex(whatsectp))) return nullptr;
|
||||
// spawning out of range sprites will also crash.
|
||||
if (clstype == nullptr) return nullptr;
|
||||
SpawnRec* info = nullptr;
|
||||
|
||||
if (s_stat < 0) s_stat = clstype ? GetDefaultByType(clstype)->spr.statnum : 0;
|
||||
|
||||
|
@ -90,7 +89,7 @@ DDukeActor* CreateActor(sectortype* whatsectp, const DVector3& pos, PClassActor*
|
|||
if (act == nullptr) return nullptr;
|
||||
SetupGameVarsForActor(act);
|
||||
|
||||
setFromSpawnRec(act, info);
|
||||
setFromSpawnRec(act, nullptr);
|
||||
act->spr.pos = pos;
|
||||
act->spr.shade = s_shd;
|
||||
if (!scale.isZero()) act->spr.scale = DVector2(scale.X, scale.Y);
|
||||
|
@ -258,6 +257,26 @@ DDukeActor* spawn(DDukeActor* actj, PClassActor * cls)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// This spawns an actor from a spawnclasses type ID.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
DDukeActor* spawnsprite(DDukeActor* origin, int typeId)
|
||||
{
|
||||
auto srec = spawnMap.CheckKey(typeId);
|
||||
if (srec && !srec->basetex.isValid()) return spawn(origin, srec->cls);
|
||||
|
||||
PClassActor* cls = srec ? srec->cls : (PClassActor*)RUNTIME_CLASS(DDukeActor);
|
||||
auto spawned = spawn(origin, cls);
|
||||
if (!spawned) return nullptr;
|
||||
setFromSpawnRec(spawned, srec);
|
||||
if (!srec) spawned->spr.setspritetexture(tileGetTextureID(typeId));
|
||||
return spawned;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
|
|
|
@ -491,21 +491,11 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, movesprite_ex, DukeActor_movesprite_ex
|
|||
ACTION_RETURN_INT(DukeActor_movesprite_ex(self, velx, vely, velz, clipmask, coll));
|
||||
}
|
||||
|
||||
DDukeActor* DukeActor_Spawnsprite(DDukeActor* origin, int typeId)
|
||||
{
|
||||
auto st = GetSpawnType(typeId);
|
||||
if (st)
|
||||
{
|
||||
return spawn(origin, st);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, spawnsprite, DukeActor_Spawnsprite)
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, spawnsprite, spawnsprite)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DDukeActor);
|
||||
PARAM_INT(type);
|
||||
ACTION_RETURN_POINTER(DukeActor_Spawnsprite(self, type));
|
||||
ACTION_RETURN_POINTER(spawnsprite(self, type));
|
||||
}
|
||||
|
||||
void DukeActor_Lotsofglass(DDukeActor* origin, int count, walltype* wal)
|
||||
|
|
Loading…
Reference in a new issue