in doom_py/src/vizdoom/src/d_dehacked.cpp [2617:2944]
static bool LoadDehSupp ()
{
try
{
// Make sure we only get the DEHSUPP lump from zdoom.pk3
// User modifications are not supported!
int lump = Wads.CheckNumForName("DEHSUPP");
if (lump == -1)
{
return false;
}
if (Wads.GetLumpFile(lump) > 0)
{
Printf("Warning: DEHSUPP no longer supported. DEHACKED patch disabled.\n");
return false;
}
bool gotnames = false;
int i;
if (++DehUseCount > 1)
{
return true;
}
if (EnglishStrings == NULL)
{
EnglishStrings = new FStringTable;
EnglishStrings->LoadStrings (true);
}
if (UnchangedSpriteNames == NULL)
{
UnchangedSpriteNames = new char[sprites.Size()*4];
NumUnchangedSprites = sprites.Size();
for (i = 0; i < NumUnchangedSprites; ++i)
{
memcpy (UnchangedSpriteNames+i*4, &sprites[i].name, 4);
}
}
FScanner sc;
sc.OpenLumpNum(lump);
sc.SetCMode(true);
while (sc.GetString())
{
if (sc.Compare("ActionList"))
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
sc.MustGetString();
if (sc.Compare("NULL"))
{
Actions.Push(NULL);
}
else
{
// all relevant code pointers are either defined in AInventory
// or AActor so this will find all of them.
FString name = "A_";
name << sc.String;
PSymbol *sym = RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(name, true);
if (sym == NULL || sym->SymbolType != SYM_ActionFunction)
{
sc.ScriptError("Unknown code pointer '%s'", sc.String);
}
else
{
FString &args = static_cast<PSymbolActionFunction*>(sym)->Arguments;
if (args.Len()!=0 && (args[0]<'a' || args[0]>'z'))
{
sc.ScriptError("Incompatible code pointer '%s'", sc.String);
}
}
Actions.Push(sym);
}
if (sc.CheckString("}")) break;
sc.MustGetStringName(",");
}
}
else if (sc.Compare("OrgHeights"))
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
sc.MustGetNumber();
OrgHeights.Push(sc.Number);
if (sc.CheckString("}")) break;
sc.MustGetStringName(",");
}
}
else if (sc.Compare("CodePConv"))
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
sc.MustGetNumber();
CodePConv.Push(sc.Number);
if (sc.CheckString("}")) break;
sc.MustGetStringName(",");
}
}
else if (sc.Compare("OrgSprNames"))
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
sc.MustGetString();
DEHSprName s;
// initialize with zeroes
memset(&s, 0, sizeof(s));
if (strlen(sc.String) ==4)
{
s.c[0] = sc.String[0];
s.c[1] = sc.String[1];
s.c[2] = sc.String[2];
s.c[3] = sc.String[3];
s.c[4] = 0;
}
else
{
sc.ScriptError("Invalid sprite name '%s' (must be 4 characters)", sc.String);
}
OrgSprNames.Push(s);
if (sc.CheckString("}")) break;
sc.MustGetStringName(",");
}
}
else if (sc.Compare("StateMap"))
{
bool addit = StateMap.Size() == 0;
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
StateMapper s;
sc.MustGetString();
const PClass *type = PClass::FindClass (sc.String);
if (type == NULL)
{
sc.ScriptError ("Can't find type %s", sc.String);
}
else if (type->ActorInfo == NULL)
{
sc.ScriptError ("%s has no ActorInfo", sc.String);
}
sc.MustGetStringName(",");
sc.MustGetString();
s.State = type->ActorInfo->FindState(sc.String);
if (s.State == NULL)
{
sc.ScriptError("Invalid state '%s' in '%s'", sc.String, type->TypeName.GetChars());
}
sc.MustGetStringName(",");
sc.MustGetNumber();
if (s.State == NULL || s.State + sc.Number > type->ActorInfo->OwnedStates + type->ActorInfo->NumOwnedStates)
{
sc.ScriptError("Invalid state range in '%s'", type->TypeName.GetChars());
}
AActor *def = GetDefaultByType(type);
s.StateSpan = sc.Number;
s.Owner = type;
s.OwnerIsPickup = def != NULL && (def->flags & MF_SPECIAL) != 0;
if (addit) StateMap.Push(s);
if (sc.CheckString("}")) break;
sc.MustGetStringName(",");
}
}
else if (sc.Compare("SoundMap"))
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
sc.MustGetString();
SoundMap.Push(S_FindSound(sc.String));
if (sc.CheckString("}")) break;
sc.MustGetStringName(",");
}
}
else if (sc.Compare("InfoNames"))
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
sc.MustGetString();
const PClass *cls = PClass::FindClass(sc.String);
if (cls == NULL)
{
sc.ScriptError("Unknown actor type '%s'", sc.String);
}
InfoNames.Push(cls);
if (sc.CheckString("}")) break;
sc.MustGetStringName(",");
}
}
else if (sc.Compare("ThingBits"))
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
BitName bit;
sc.MustGetNumber();
if (sc.Number < 0 || sc.Number > 31)
{
sc.ScriptError("Invalid bit value %d", sc.Number);
}
bit.Bit = sc.Number;
sc.MustGetStringName(",");
sc.MustGetNumber();
if (sc.Number < 0 || sc.Number > 2)
{
sc.ScriptError("Invalid flag word %d", sc.Number);
}
bit.WhichFlags = sc.Number;
sc.MustGetStringName(",");
sc.MustGetString();
strncpy(bit.Name, sc.String, 19);
bit.Name[19]=0;
BitNames.Push(bit);
if (sc.CheckString("}")) break;
sc.MustGetStringName(",");
}
}
else if (sc.Compare("RenderStyles"))
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
StyleName style;
sc.MustGetNumber();
style.Num = sc.Number;
sc.MustGetStringName(",");
sc.MustGetString();
strncpy(style.Name, sc.String, 19);
style.Name[19]=0;
StyleNames.Push(style);
if (sc.CheckString("}")) break;
sc.MustGetStringName(",");
}
}
else if (sc.Compare("AmmoNames"))
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
sc.MustGetString();
if (sc.Compare("NULL"))
{
AmmoNames.Push(NULL);
}
else
{
const PClass *cls = PClass::FindClass(sc.String);
if (cls == NULL || cls->ParentClass != RUNTIME_CLASS(AAmmo))
{
sc.ScriptError("Unknown ammo type '%s'", sc.String);
}
AmmoNames.Push(cls);
}
if (sc.CheckString("}")) break;
sc.MustGetStringName(",");
}
}
else if (sc.Compare("WeaponNames"))
{
WeaponNames.Clear(); // This won't be cleared by UnloadDEHSupp so we need to do it here explicitly
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
sc.MustGetString();
const PClass *cls = PClass::FindClass(sc.String);
if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(AWeapon)))
{
sc.ScriptError("Unknown weapon type '%s'", sc.String);
}
WeaponNames.Push(cls);
if (sc.CheckString("}")) break;
sc.MustGetStringName(",");
}
}
else if (sc.Compare("Aliases"))
{
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
CodePointerAlias temp;
sc.MustGetString();
strncpy(temp.alias, sc.String, 19);
temp.alias[19]=0;
sc.MustGetStringName(",");
sc.MustGetString();
strncpy(temp.name, sc.String, 19);
temp.name[19]=0;
sc.MustGetStringName(",");
sc.MustGetNumber();
temp.params = sc.Number;
MBFCodePointers.Push(temp);
if (sc.CheckString("}")) break;
sc.MustGetStringName(",");
}
}
else
{
sc.ScriptError("Unknown section '%s'", sc.String);
}
sc.MustGetStringName(";");
}
return true;
}
catch(CRecoverableError &err)
{
// Don't abort if DEHSUPP loading fails.
// Just print the message and continue.
Printf("%s\n", err.GetMessage());
return false;
}
}