mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 14:01:45 +00:00
- dsdhacked: Allow dynamic creation of new actors
This commit is contained in:
parent
b44741b8aa
commit
24d57b58c5
1 changed files with 38 additions and 29 deletions
|
@ -97,6 +97,7 @@ static TArray<int> OrgHeights;
|
|||
// disappear, but that doesn't explain why frame patches specify an exact
|
||||
// state rather than a code pointer.)
|
||||
static TArray<int> CodePConv;
|
||||
static bool dsdhacked = false;
|
||||
|
||||
// Sprite names in the order Doom originally had them.
|
||||
struct DEHSprName
|
||||
|
@ -122,6 +123,28 @@ static TArray<FSoundID> SoundMap;
|
|||
// Names of different actor types, in original Doom 2 order
|
||||
static TArray<PClassActor *> InfoNames;
|
||||
|
||||
static PClassActor* FindInfoName(int index, bool mustexist = false)
|
||||
{
|
||||
if (index < 0) return nullptr;
|
||||
if (index < (int)InfoNames.Size()) return InfoNames[index];
|
||||
|
||||
if (dsdhacked)
|
||||
{
|
||||
FStringf name("~Dsdhacked~%d", index);
|
||||
auto cls = PClass::FindActor(name);
|
||||
if (cls)
|
||||
{
|
||||
GetDefaultByType(cls)->flags8 |= MF8_RETARGETAFTERSLAM; // This flag is not a ZDoom default, but it must be a Dehacked default.
|
||||
return cls;
|
||||
}
|
||||
if (!mustexist)
|
||||
{
|
||||
return static_cast<PClassActor*>(RUNTIME_CLASS(AActor)->CreateDerivedClass(name.GetChars(), (unsigned)sizeof(AActor)));
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// bit flags for PatchThing (a .bex extension):
|
||||
struct BitName
|
||||
{
|
||||
|
@ -163,10 +186,8 @@ struct MBFParamState
|
|||
|
||||
PClassActor* GetTypeArg(int i)
|
||||
{
|
||||
PClassActor* type = nullptr;
|
||||
int num = (int)args[i];
|
||||
if (num > 0 && num < int(InfoNames.Size())) type = InfoNames[num-1]; // Dehacked is 1-based.
|
||||
return type;
|
||||
return FindInfoName(num-1, true);
|
||||
}
|
||||
|
||||
FState* GetStateArg(int i)
|
||||
|
@ -341,7 +362,7 @@ FString PatchName;
|
|||
static int PatchSize;
|
||||
static char *Line1, *Line2;
|
||||
static int dversion, pversion;
|
||||
static bool including, includenotext, dsdhacked = false;
|
||||
static bool including, includenotext;
|
||||
static int LumpFileNum;
|
||||
|
||||
static const char *unknown_str = "Unknown key %s encountered in %s %d.\n";
|
||||
|
@ -373,8 +394,8 @@ static int PatchPars (int);
|
|||
static int PatchCodePtrs (int);
|
||||
static int PatchMusic (int);
|
||||
static int DoInclude (int);
|
||||
static int PatchSpriteNames (int);
|
||||
static int PatchSoundNames(int) {} // todo
|
||||
static int PatchSpriteNames(int) { return 0; } // todo
|
||||
static int PatchSoundNames(int) { return 0; } // todo
|
||||
static bool DoDehPatch();
|
||||
|
||||
static const struct {
|
||||
|
@ -710,11 +731,12 @@ static void CreateMushroomFunc(FunctionCallEmitter &emitters, int value1, int va
|
|||
// misc1 = type (arg +0), misc2 = Z-pos (arg +2)
|
||||
static void CreateSpawnFunc(FunctionCallEmitter &emitters, int value1, int value2, MBFParamState* state)
|
||||
{ // A_SpawnItem
|
||||
if (InfoNames[value1-1] == nullptr)
|
||||
auto p = FindInfoName(value1 - 1, true);
|
||||
if (p == nullptr)
|
||||
{
|
||||
I_Error("No class found for dehackednum %d!\n", value1+1);
|
||||
}
|
||||
emitters.AddParameterPointerConst(InfoNames[value1-1]); // itemtype
|
||||
emitters.AddParameterPointerConst(p); // itemtype
|
||||
emitters.AddParameterFloatConst(0); // distance
|
||||
emitters.AddParameterFloatConst(value2); // height
|
||||
emitters.AddParameterIntConst(0); // useammo
|
||||
|
@ -1124,30 +1146,17 @@ static int PatchThing (int thingy)
|
|||
type = NULL;
|
||||
info = (AActor *)&dummy;
|
||||
ednum = &dummyed;
|
||||
if (thingy > (int)InfoNames.Size() || thingy <= 0)
|
||||
auto thingytype = FindInfoName(thingy-1);
|
||||
if (thingytype == nullptr)
|
||||
{
|
||||
Printf ("Thing %d out of range.\n", thingy);
|
||||
Printf ("Thing %d out of range or invalid.\n", thingy);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPrintf (DMSG_SPAMMY, "Thing %d\n", thingy);
|
||||
if (thingy > 0)
|
||||
{
|
||||
type = InfoNames[thingy - 1];
|
||||
if (type == NULL)
|
||||
{
|
||||
info = (AActor *)&dummy;
|
||||
ednum = &dummyed;
|
||||
// An error for the name has already been printed while loading DEHSUPP.
|
||||
Printf ("Could not find thing %d\n", thingy);
|
||||
}
|
||||
else
|
||||
{
|
||||
info = GetDefaultByType (type);
|
||||
ednum = &type->ActorInfo()->DoomEdNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oldflags = info->flags;
|
||||
|
||||
|
@ -1280,13 +1289,13 @@ static int PatchThing (int thingy)
|
|||
}
|
||||
else if (linelen == 12 && stricmp(Line1, "dropped item") == 0)
|
||||
{
|
||||
val--; // This is 1-based and 0 means 'no drop'.
|
||||
if ((unsigned)val < InfoNames.Size())
|
||||
auto drop = FindInfoName(val - 1);
|
||||
if (drop)
|
||||
{
|
||||
FDropItem* di = (FDropItem*)ClassDataAllocator.Alloc(sizeof(FDropItem));
|
||||
|
||||
di->Next = nullptr;
|
||||
di->Name = InfoNames[val]->TypeName.GetChars();
|
||||
di->Name = drop->TypeName;
|
||||
di->Probability = 255;
|
||||
di->Amount = -1;
|
||||
info->GetInfo()->DropItems = di;
|
||||
|
|
Loading…
Reference in a new issue