mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-23 12:32:34 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
012f10400c
20 changed files with 200 additions and 92 deletions
|
@ -73,13 +73,14 @@ class PClassPlayerPawn : public PClassActor
|
|||
{
|
||||
DECLARE_CLASS(PClassPlayerPawn, PClassActor);
|
||||
protected:
|
||||
virtual void Derive(PClass *newclass);
|
||||
public:
|
||||
PClassPlayerPawn();
|
||||
virtual void DeriveData(PClass *newclass);
|
||||
void EnumColorSets(TArray<int> *out);
|
||||
FPlayerColorSet *GetColorSet(int setnum) { return ColorSets.CheckKey(setnum); }
|
||||
void SetPainFlash(FName type, PalEntry color);
|
||||
bool GetPainFlash(FName type, PalEntry *color) const;
|
||||
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
|
||||
|
||||
FString DisplayName; // Display name (used in menus, etc.)
|
||||
FString SoundClass; // Sound class
|
||||
|
|
|
@ -98,6 +98,7 @@ enum
|
|||
CLASSREG_PClassPlayerPawn,
|
||||
CLASSREG_PClassType,
|
||||
CLASSREG_PClassClass,
|
||||
CLASSREG_PClassWeaponPiece
|
||||
};
|
||||
|
||||
struct ClassReg
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "autosegs.h"
|
||||
#include "v_text.h"
|
||||
#include "a_pickups.h"
|
||||
#include "a_weaponpiece.h"
|
||||
#include "d_player.h"
|
||||
#include "fragglescript/t_fs.h"
|
||||
|
||||
|
@ -2163,6 +2164,7 @@ PClass *ClassReg::RegisterClass()
|
|||
&PClassPlayerPawn::RegistrationInfo,
|
||||
&PClassType::RegistrationInfo,
|
||||
&PClassClass::RegistrationInfo,
|
||||
&PClassWeaponPiece::RegistrationInfo,
|
||||
};
|
||||
|
||||
// Skip classes that have already been registered
|
||||
|
@ -2318,42 +2320,50 @@ PClass *PClass::CreateDerivedClass(FName name, unsigned int size)
|
|||
assert (size >= Size);
|
||||
PClass *type;
|
||||
bool notnew;
|
||||
size_t bucket;
|
||||
|
||||
const PClass *existclass = FindClass(name);
|
||||
PClass *existclass = static_cast<PClass *>(TypeTable.FindType(RUNTIME_CLASS(PClass), /*FIXME:Outer*/0, name, &bucket));
|
||||
|
||||
// This is a placeholder so fill it in
|
||||
if (existclass != NULL && (existclass->Size == TClass_Fatal || existclass->Size == TClass_Nonfatal))
|
||||
if (existclass != NULL && (existclass->Size == TentativeClass))
|
||||
{
|
||||
type = const_cast<PClass*>(existclass);
|
||||
if (!IsDescendantOf(type->ParentClass))
|
||||
{
|
||||
if (existclass->Size == TClass_Fatal)
|
||||
{
|
||||
I_Error("%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf(TEXTCOLOR_RED "%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars());
|
||||
}
|
||||
I_Error("%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars());
|
||||
}
|
||||
DPrintf("Defining placeholder class %s\n", name.GetChars());
|
||||
notnew = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new type object of the same type as us. (We may be a derived class of PClass.)
|
||||
type = static_cast<PClass *>(GetClass()->CreateNew());
|
||||
notnew = false;
|
||||
}
|
||||
|
||||
// Create a new type object of the same type as us. (We may be a derived class of PClass.)
|
||||
type = static_cast<PClass *>(GetClass()->CreateNew());
|
||||
|
||||
type->TypeName = name;
|
||||
type->Size = size;
|
||||
type->bRuntimeClass = true;
|
||||
Derive(type);
|
||||
DeriveData(type);
|
||||
if (!notnew)
|
||||
{
|
||||
type->InsertIntoHash();
|
||||
}
|
||||
else
|
||||
{
|
||||
PClassActor::AllActorClasses.Pop(); // remove the newly added class from the list
|
||||
// todo: replace all affected fields
|
||||
for (unsigned i = 0; i < PClassActor::AllActorClasses.Size(); i++)
|
||||
{
|
||||
PClassActor::AllActorClasses[i]->ReplaceClassRef(existclass, type);
|
||||
if (PClassActor::AllActorClasses[i] == existclass)
|
||||
PClassActor::AllActorClasses[i] = static_cast<PClassActor*>(type);
|
||||
}
|
||||
TypeTable.ReplaceType(type, existclass, bucket);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -2403,11 +2413,11 @@ PClass *PClass::FindClassTentative(FName name, bool fatal)
|
|||
return static_cast<PClass *>(found);
|
||||
}
|
||||
PClass *type = static_cast<PClass *>(GetClass()->CreateNew());
|
||||
DPrintf("Creating placeholder class %s : %s\n", name.GetChars(), TypeName.GetChars());
|
||||
Printf("Creating placeholder class %s : %s\n", name.GetChars(), TypeName.GetChars());
|
||||
|
||||
type->TypeName = name;
|
||||
type->ParentClass = this;
|
||||
type->Size = fatal? TClass_Fatal : TClass_Nonfatal;
|
||||
type->Size = TentativeClass;
|
||||
type->bRuntimeClass = true;
|
||||
TypeTable.AddType(type, RUNTIME_CLASS(PClass), (intptr_t)type->Outer, name, bucket);
|
||||
return type;
|
||||
|
|
|
@ -601,8 +601,7 @@ public:
|
|||
|
||||
enum
|
||||
{
|
||||
TClass_Fatal = UINT_MAX,
|
||||
TClass_Nonfatal = UINT_MAX - 1
|
||||
TentativeClass = UINT_MAX,
|
||||
};
|
||||
|
||||
class PClassClass;
|
||||
|
@ -611,13 +610,14 @@ class PClass : public PStruct
|
|||
DECLARE_CLASS(PClass, PStruct);
|
||||
HAS_OBJECT_POINTERS;
|
||||
protected:
|
||||
virtual void Derive(PClass *newclass);
|
||||
// We unravel _WITH_META here just as we did for PType.
|
||||
enum { MetaClassNum = CLASSREG_PClassClass };
|
||||
virtual void Derive(PClass *newclass);
|
||||
public:
|
||||
typedef PClassClass MetaClass;
|
||||
MetaClass *GetClass() const;
|
||||
|
||||
virtual void DeriveData(PClass *newclass) {}
|
||||
static void StaticInit();
|
||||
static void StaticShutdown();
|
||||
static void StaticBootstrap();
|
||||
|
@ -678,9 +678,9 @@ class PClassType : public PClass
|
|||
{
|
||||
DECLARE_CLASS(PClassType, PClass);
|
||||
protected:
|
||||
virtual void Derive(PClass *newclass);
|
||||
public:
|
||||
PClassType();
|
||||
virtual void Derive(PClass *newclass);
|
||||
|
||||
PClass *TypeTableType; // The type to use for hashing into the type table
|
||||
};
|
||||
|
|
|
@ -30,15 +30,37 @@ PClassInventory::PClassInventory()
|
|||
AltHUDIcon.SetNull();
|
||||
}
|
||||
|
||||
void PClassInventory::Derive(PClass *newclass)
|
||||
void PClassInventory::DeriveData(PClass *newclass)
|
||||
{
|
||||
assert(newclass->IsKindOf(RUNTIME_CLASS(PClassInventory)));
|
||||
Super::Derive(newclass);
|
||||
Super::DeriveData(newclass);
|
||||
PClassInventory *newc = static_cast<PClassInventory *>(newclass);
|
||||
|
||||
newc->PickupMessage = PickupMessage;
|
||||
newc->GiveQuest = GiveQuest;
|
||||
newc->AltHUDIcon = AltHUDIcon;
|
||||
newc->ForbiddenToPlayerClass = ForbiddenToPlayerClass;
|
||||
newc->RestrictedToPlayerClass = RestrictedToPlayerClass;
|
||||
}
|
||||
|
||||
void PClassInventory::ReplaceClassRef(PClass *oldclass, PClass *newclass)
|
||||
{
|
||||
Super::ReplaceClassRef(oldclass, newclass);
|
||||
AInventory *def = (AInventory*)Defaults;
|
||||
if (def != NULL)
|
||||
{
|
||||
if (def->PickupFlash == oldclass) def->PickupFlash = static_cast<PClassActor *>(newclass);
|
||||
for (unsigned i = 0; i < ForbiddenToPlayerClass.Size(); i++)
|
||||
{
|
||||
if (ForbiddenToPlayerClass[i] == oldclass)
|
||||
ForbiddenToPlayerClass[i] = static_cast<PClassPlayerPawn*>(newclass);
|
||||
}
|
||||
for (unsigned i = 0; i < RestrictedToPlayerClass.Size(); i++)
|
||||
{
|
||||
if (RestrictedToPlayerClass[i] == oldclass)
|
||||
RestrictedToPlayerClass[i] = static_cast<PClassPlayerPawn*>(newclass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IMPLEMENT_CLASS(PClassAmmo)
|
||||
|
@ -48,10 +70,10 @@ PClassAmmo::PClassAmmo()
|
|||
DropAmount = 0;
|
||||
}
|
||||
|
||||
void PClassAmmo::Derive(PClass *newclass)
|
||||
void PClassAmmo::DeriveData(PClass *newclass)
|
||||
{
|
||||
assert(newclass->IsKindOf(RUNTIME_CLASS(PClassAmmo)));
|
||||
Super::Derive(newclass);
|
||||
Super::DeriveData(newclass);
|
||||
PClassAmmo *newc = static_cast<PClassAmmo *>(newclass);
|
||||
|
||||
newc->DropAmount = DropAmount;
|
||||
|
@ -1524,7 +1546,7 @@ bool AInventory::CanPickup (AActor *toucher)
|
|||
if (!toucher)
|
||||
return false;
|
||||
|
||||
PClassActor *ai = GetClass();
|
||||
PClassInventory *ai = GetClass();
|
||||
// Is the item restricted to certain player classes?
|
||||
if (ai->RestrictedToPlayerClass.Size() != 0)
|
||||
{
|
||||
|
@ -1672,10 +1694,10 @@ PClassHealth::PClassHealth()
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void PClassHealth::Derive(PClass *newclass)
|
||||
void PClassHealth::DeriveData(PClass *newclass)
|
||||
{
|
||||
assert(newclass->IsKindOf(RUNTIME_CLASS(PClassHealth)));
|
||||
Super::Derive(newclass);
|
||||
Super::DeriveData(newclass);
|
||||
PClassHealth *newc = static_cast<PClassHealth *>(newclass);
|
||||
|
||||
newc->LowHealth = LowHealth;
|
||||
|
|
|
@ -135,14 +135,16 @@ enum
|
|||
class PClassInventory : public PClassActor
|
||||
{
|
||||
DECLARE_CLASS(PClassInventory, PClassActor)
|
||||
protected:
|
||||
virtual void Derive(PClass *newclass);
|
||||
public:
|
||||
PClassInventory();
|
||||
virtual void DeriveData(PClass *newclass);
|
||||
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
|
||||
|
||||
FString PickupMessage;
|
||||
int GiveQuest; // Optionally give one of the quest items.
|
||||
FTextureID AltHUDIcon;
|
||||
TArray<PClassPlayerPawn *> RestrictedToPlayerClass;
|
||||
TArray<PClassPlayerPawn *> ForbiddenToPlayerClass;
|
||||
};
|
||||
|
||||
class AInventory : public AActor
|
||||
|
@ -241,7 +243,7 @@ class PClassAmmo : public PClassInventory
|
|||
{
|
||||
DECLARE_CLASS(PClassAmmo, PClassInventory)
|
||||
protected:
|
||||
virtual void Derive(PClass *newclass);
|
||||
virtual void DeriveData(PClass *newclass);
|
||||
public:
|
||||
PClassAmmo();
|
||||
|
||||
|
@ -266,9 +268,10 @@ class PClassWeapon : public PClassInventory
|
|||
{
|
||||
DECLARE_CLASS(PClassWeapon, PClassInventory);
|
||||
protected:
|
||||
virtual void Derive(PClass *newclass);
|
||||
virtual void DeriveData(PClass *newclass);
|
||||
public:
|
||||
PClassWeapon();
|
||||
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
|
||||
|
||||
int SlotNumber;
|
||||
fixed_t SlotPriority;
|
||||
|
@ -401,9 +404,9 @@ class PClassHealth : public PClassInventory
|
|||
{
|
||||
DECLARE_CLASS(PClassHealth, PClassInventory)
|
||||
protected:
|
||||
virtual void Derive(PClass *newclass);
|
||||
public:
|
||||
PClassHealth();
|
||||
virtual void DeriveData(PClass *newclass);
|
||||
|
||||
FString LowHealthMessage;
|
||||
int LowHealth;
|
||||
|
@ -518,8 +521,8 @@ class PClassPuzzleItem : public PClassInventory
|
|||
{
|
||||
DECLARE_CLASS(PClassPuzzleItem, PClassInventory);
|
||||
protected:
|
||||
virtual void Derive(PClass *newclass);
|
||||
public:
|
||||
virtual void DeriveData(PClass *newclass);
|
||||
FString PuzzFailMessage;
|
||||
};
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
|
||||
IMPLEMENT_CLASS(PClassPuzzleItem)
|
||||
|
||||
void PClassPuzzleItem::Derive(PClass *newclass)
|
||||
void PClassPuzzleItem::DeriveData(PClass *newclass)
|
||||
{
|
||||
Super::Derive(newclass);
|
||||
Super::DeriveData(newclass);
|
||||
assert(newclass->IsKindOf(RUNTIME_CLASS(PClassPuzzleItem)));
|
||||
static_cast<PClassPuzzleItem *>(newclass)->PuzzFailMessage = PuzzFailMessage;
|
||||
}
|
||||
|
|
|
@ -3,8 +3,20 @@
|
|||
#include "doomstat.h"
|
||||
#include "farchive.h"
|
||||
|
||||
IMPLEMENT_CLASS(PClassWeaponPiece)
|
||||
IMPLEMENT_CLASS (AWeaponHolder)
|
||||
|
||||
void PClassWeaponPiece::ReplaceClassRef(PClass *oldclass, PClass *newclass)
|
||||
{
|
||||
Super::ReplaceClassRef(oldclass, newclass);
|
||||
AWeaponPiece *def = (AWeaponPiece*)Defaults;
|
||||
if (def != NULL)
|
||||
{
|
||||
if (def->WeaponClass == oldclass) def->WeaponClass = static_cast<PClassWeapon *>(newclass);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AWeaponHolder::Serialize (FArchive &arc)
|
||||
{
|
||||
Super::Serialize(arc);
|
||||
|
|
|
@ -1,7 +1,16 @@
|
|||
|
||||
// Ammo: Something a weapon needs to operate
|
||||
class PClassWeaponPiece : public PClassInventory
|
||||
{
|
||||
DECLARE_CLASS(PClassWeaponPiece, PClassInventory)
|
||||
protected:
|
||||
public:
|
||||
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
|
||||
};
|
||||
|
||||
class AWeaponPiece : public AInventory
|
||||
{
|
||||
DECLARE_CLASS (AWeaponPiece, AInventory)
|
||||
DECLARE_CLASS_WITH_META(AWeaponPiece, AInventory, PClassWeaponPiece)
|
||||
HAS_OBJECT_POINTERS
|
||||
protected:
|
||||
bool PrivateShouldStay ();
|
||||
|
|
|
@ -44,16 +44,29 @@ PClassWeapon::PClassWeapon()
|
|||
SlotPriority = FIXED_MAX;
|
||||
}
|
||||
|
||||
void PClassWeapon::Derive(PClass *newclass)
|
||||
void PClassWeapon::DeriveData(PClass *newclass)
|
||||
{
|
||||
assert(newclass->IsKindOf(RUNTIME_CLASS(PClassWeapon)));
|
||||
Super::Derive(newclass);
|
||||
Super::DeriveData(newclass);
|
||||
PClassWeapon *newc = static_cast<PClassWeapon *>(newclass);
|
||||
|
||||
newc->SlotNumber = SlotNumber;
|
||||
newc->SlotPriority = SlotPriority;
|
||||
}
|
||||
|
||||
|
||||
void PClassWeapon::ReplaceClassRef(PClass *oldclass, PClass *newclass)
|
||||
{
|
||||
Super::ReplaceClassRef(oldclass, newclass);
|
||||
AWeapon *def = (AWeapon*)Defaults;
|
||||
if (def != NULL)
|
||||
{
|
||||
if (def->AmmoType1 == oldclass) def->AmmoType1 = static_cast<PClassAmmo *>(newclass);
|
||||
if (def->AmmoType2 == oldclass) def->AmmoType2 = static_cast<PClassAmmo *>(newclass);
|
||||
if (def->SisterWeaponType == oldclass) def->SisterWeaponType = static_cast<PClassWeapon *>(newclass);
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AWeapon :: Serialize
|
||||
|
|
45
src/info.cpp
45
src/info.cpp
|
@ -201,16 +201,11 @@ PClassActor::PClassActor()
|
|||
FastSpeed = FIXED_MIN;
|
||||
RDFactor = FRACUNIT;
|
||||
CameraHeight = FIXED_MIN;
|
||||
BloodType = NAME_Blood;
|
||||
BloodType2 = NAME_BloodSplatter;
|
||||
BloodType3 = NAME_AxeBlood;
|
||||
|
||||
DropItems = NULL;
|
||||
|
||||
DontHurtShooter = false;
|
||||
ExplosionDamage = 128;
|
||||
ExplosionRadius = -1;
|
||||
MissileHeight = 32*FRACUNIT;
|
||||
MeleeDamage = 0;
|
||||
|
||||
// Record this in the master list.
|
||||
|
@ -250,10 +245,9 @@ PClassActor::~PClassActor()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void PClassActor::Derive(PClass *newclass)
|
||||
void PClassActor::DeriveData(PClass *newclass)
|
||||
{
|
||||
assert(newclass->IsKindOf(RUNTIME_CLASS(PClassActor)));
|
||||
Super::Derive(newclass);
|
||||
PClassActor *newa = static_cast<PClassActor *>(newclass);
|
||||
|
||||
newa->Obituary = Obituary;
|
||||
|
@ -281,6 +275,22 @@ void PClassActor::Derive(PClass *newclass)
|
|||
newa->MeleeSound = MeleeSound;
|
||||
newa->MissileName = MissileName;
|
||||
newa->MissileHeight = MissileHeight;
|
||||
|
||||
newa->VisibleToPlayerClass = VisibleToPlayerClass;
|
||||
|
||||
if (DamageFactors != NULL)
|
||||
{
|
||||
// copy damage factors from parent
|
||||
newa->DamageFactors = new DmgFactors;
|
||||
*newa->DamageFactors = *DamageFactors;
|
||||
}
|
||||
if (PainChances != NULL)
|
||||
{
|
||||
// copy pain chances from parent
|
||||
newa->PainChances = new PainChanceList;
|
||||
*newa->PainChances = *PainChances;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -522,6 +532,27 @@ void PClassActor::SetPainChance(FName type, int chance)
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClassActor :: ReplaceClassRef
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PClassActor::ReplaceClassRef(PClass *oldclass, PClass *newclass)
|
||||
{
|
||||
for (unsigned i = 0; i < VisibleToPlayerClass.Size(); i++)
|
||||
{
|
||||
if (VisibleToPlayerClass[i] == oldclass)
|
||||
VisibleToPlayerClass[i] = static_cast<PClassPlayerPawn*>(newclass);
|
||||
}
|
||||
AActor *def = (AActor*)Defaults;
|
||||
if (def != NULL)
|
||||
{
|
||||
if (def->TeleFogSourceType == oldclass) def->TeleFogSourceType = static_cast<PClassActor *>(newclass);
|
||||
if (def->TeleFogDestType == oldclass) def->TeleFogDestType = static_cast<PClassActor *>(newclass);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DmgFactors :: CheckFactor
|
||||
|
|
|
@ -192,14 +192,15 @@ class PClassActor : public PClass
|
|||
DECLARE_CLASS(PClassActor, PClass);
|
||||
HAS_OBJECT_POINTERS;
|
||||
protected:
|
||||
virtual void Derive(PClass *newclass);
|
||||
public:
|
||||
static void StaticInit ();
|
||||
static void StaticSetActorNums ();
|
||||
virtual void DeriveData(PClass *newclass);
|
||||
|
||||
PClassActor();
|
||||
~PClassActor();
|
||||
|
||||
virtual void ReplaceClassRef(PClass *oldclass, PClass *newclass);
|
||||
void BuildDefaults();
|
||||
void ApplyDefaults(BYTE *defaults);
|
||||
void RegisterIDs();
|
||||
|
@ -236,8 +237,6 @@ public:
|
|||
PainChanceList *PainChances;
|
||||
|
||||
TArray<PClassPlayerPawn *> VisibleToPlayerClass;
|
||||
TArray<PClassPlayerPawn *> RestrictedToPlayerClass;
|
||||
TArray<PClassPlayerPawn *> ForbiddenToPlayerClass;
|
||||
|
||||
FString Obituary; // Player was killed by this actor
|
||||
FString HitObituary; // Player was killed by this actor in melee
|
||||
|
|
|
@ -515,10 +515,10 @@ PClassPlayerPawn::PClassPlayerPawn()
|
|||
ColorRangeEnd = 0;
|
||||
}
|
||||
|
||||
void PClassPlayerPawn::Derive(PClass *newclass)
|
||||
void PClassPlayerPawn::DeriveData(PClass *newclass)
|
||||
{
|
||||
assert(newclass->IsKindOf(RUNTIME_CLASS(PClassPlayerPawn)));
|
||||
Super::Derive(newclass);
|
||||
Super::DeriveData(newclass);
|
||||
PClassPlayerPawn *newp = static_cast<PClassPlayerPawn *>(newclass);
|
||||
size_t i;
|
||||
|
||||
|
@ -581,6 +581,16 @@ bool PClassPlayerPawn::GetPainFlash(FName type, PalEntry *color) const
|
|||
return false;
|
||||
}
|
||||
|
||||
void PClassPlayerPawn::ReplaceClassRef(PClass *oldclass, PClass *newclass)
|
||||
{
|
||||
Super::ReplaceClassRef(oldclass, newclass);
|
||||
APlayerPawn *def = (APlayerPawn*)Defaults;
|
||||
if (def != NULL)
|
||||
{
|
||||
if (def->FlechetteType == oldclass) def->FlechetteType = static_cast<PClassInventory *>(newclass);
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// player_t :: SendPitchLimits
|
||||
|
|
|
@ -137,6 +137,7 @@ PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName par
|
|||
goto create;
|
||||
}
|
||||
ti->InitializeNativeDefaults();
|
||||
ti->ParentClass->DeriveData(ti);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -144,23 +145,6 @@ PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName par
|
|||
ti = static_cast<PClassActor *>(parent->CreateDerivedClass (typeName, parent->Size));
|
||||
}
|
||||
|
||||
// Copy class lists from parent
|
||||
ti->ForbiddenToPlayerClass = parent->ForbiddenToPlayerClass;
|
||||
ti->RestrictedToPlayerClass = parent->RestrictedToPlayerClass;
|
||||
ti->VisibleToPlayerClass = parent->VisibleToPlayerClass;
|
||||
|
||||
if (parent->DamageFactors != NULL)
|
||||
{
|
||||
// copy damage factors from parent
|
||||
ti->DamageFactors = new DmgFactors;
|
||||
*ti->DamageFactors = *parent->DamageFactors;
|
||||
}
|
||||
if (parent->PainChances != NULL)
|
||||
{
|
||||
// copy pain chances from parent
|
||||
ti->PainChances = new PainChanceList;
|
||||
*ti->PainChances = *parent->PainChances;
|
||||
}
|
||||
ti->Replacee = ti->Replacement = NULL;
|
||||
ti->DoomEdNum = -1;
|
||||
return ti;
|
||||
|
@ -340,15 +324,10 @@ static void FinishThingdef()
|
|||
{
|
||||
PClassActor *ti = PClassActor::AllActorClasses[i];
|
||||
|
||||
if (ti->Size == TClass_Fatal || ti->Size == TClass_Nonfatal)
|
||||
if (ti->Size == TentativeClass)
|
||||
{
|
||||
Printf(TEXTCOLOR_RED "Class %s referenced but not defined\n", ti->TypeName.GetChars());
|
||||
if (ti->Size == TClass_Fatal) errorcount++;
|
||||
else
|
||||
{
|
||||
// In order to prevent a crash, this class needs to be completed, even though it defines nothing.
|
||||
ti->ParentClass->CreateDerivedClass(ti->TypeName, ti->ParentClass->Size);
|
||||
}
|
||||
errorcount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,12 +72,15 @@ static FxExpression *ParseExpressionB (FScanner &sc, PClassActor *cls);
|
|||
static FxExpression *ParseExpressionA (FScanner &sc, PClassActor *cls);
|
||||
static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls);
|
||||
|
||||
FxExpression *ParseExpression (FScanner &sc, PClassActor *cls)
|
||||
FxExpression *ParseExpression (FScanner &sc, PClassActor *cls, bool mustresolve)
|
||||
{
|
||||
FxExpression *data = ParseExpressionM (sc, cls);
|
||||
|
||||
FCompileContext ctx(cls);
|
||||
data = data->Resolve(ctx);
|
||||
if (mustresolve)
|
||||
{
|
||||
FCompileContext ctx(cls);
|
||||
data = data->Resolve(ctx);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -984,7 +984,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
FxExpression *ParseExpression (FScanner &sc, PClassActor *cls);
|
||||
FxExpression *ParseExpression (FScanner &sc, PClassActor *cls, bool mustresolve = false);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "thingdef_exp.h"
|
||||
#include "m_fixed.h"
|
||||
#include "vmbuilder.h"
|
||||
#include "v_text.h"
|
||||
|
||||
ExpEmit::ExpEmit(VMFunctionBuilder *build, int type)
|
||||
: RegNum(build->Registers[type].Get(1)), RegType(type), Konst(false), Fixed(false)
|
||||
|
@ -3546,15 +3547,25 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx)
|
|||
|
||||
if (clsname != NAME_None)
|
||||
{
|
||||
// for backwards compatibility with old times it cannot be made a fatal error, if the class is not defined. :(
|
||||
cls = desttype->FindClassTentative(clsname, false);
|
||||
if (!cls->IsDescendantOf(desttype))
|
||||
cls = PClass::FindClass(clsname);
|
||||
if (cls == NULL)
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR,"class '%s' is not compatible with '%s'", clsname.GetChars(), desttype->TypeName.GetChars());
|
||||
delete this;
|
||||
return NULL;
|
||||
/* lax */
|
||||
// Since this happens in released WADs it must pass without a terminal error... :(
|
||||
ScriptPosition.Message(MSG_WARNING,
|
||||
"Unknown class name '%s'",
|
||||
clsname.GetChars(), desttype->TypeName.GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!cls->IsDescendantOf(desttype))
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "class '%s' is not compatible with '%s'", clsname.GetChars(), desttype->TypeName.GetChars());
|
||||
delete this;
|
||||
return NULL;
|
||||
}
|
||||
ScriptPosition.Message(MSG_DEBUG, "resolving '%s' as class name", clsname.GetChars());
|
||||
}
|
||||
ScriptPosition.Message(MSG_DEBUG,"resolving '%s' as class name", clsname.GetChars());
|
||||
}
|
||||
FxExpression *x = new FxConstant(cls, ScriptPosition);
|
||||
delete this;
|
||||
|
|
|
@ -79,7 +79,7 @@ FxExpression *ParseParameter(FScanner &sc, PClassActor *cls, PType *type, bool c
|
|||
}
|
||||
else if (type == TypeSInt32 || type == TypeFloat64)
|
||||
{
|
||||
x = ParseExpression (sc, cls);
|
||||
x = ParseExpression (sc, cls, constant);
|
||||
if (constant && !x->isConstant())
|
||||
{
|
||||
sc.ScriptMessage("Default parameter must be constant.");
|
||||
|
@ -190,7 +190,7 @@ static void ParseConstant (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
|
|||
sc.MustGetToken(TK_Identifier);
|
||||
FName symname = sc.String;
|
||||
sc.MustGetToken('=');
|
||||
FxExpression *expr = ParseExpression (sc, cls);
|
||||
FxExpression *expr = ParseExpression (sc, cls, true);
|
||||
sc.MustGetToken(';');
|
||||
|
||||
if (!expr->isConstant())
|
||||
|
@ -248,7 +248,7 @@ static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
|
|||
FName symname = sc.String;
|
||||
if (sc.CheckToken('='))
|
||||
{
|
||||
FxExpression *expr = ParseExpression (sc, cls);
|
||||
FxExpression *expr = ParseExpression (sc, cls, true);
|
||||
if (!expr->isConstant())
|
||||
{
|
||||
sc.ScriptMessage("'%s' must be constant", symname.GetChars());
|
||||
|
@ -536,7 +536,7 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cl
|
|||
|
||||
if (sc.CheckToken('['))
|
||||
{
|
||||
FxExpression *expr = ParseExpression(sc, cls);
|
||||
FxExpression *expr = ParseExpression(sc, cls, true);
|
||||
if (!expr->isConstant())
|
||||
{
|
||||
sc.ScriptMessage("Array size must be a constant");
|
||||
|
|
|
@ -1534,12 +1534,12 @@ DEFINE_PROPERTY(riplevelmax, I, Actor)
|
|||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(restrictedto, Ssssssssssssssssssss, Inventory)
|
||||
{
|
||||
info->RestrictedToPlayerClass.Clear();
|
||||
static_cast<PClassInventory*>(info)->RestrictedToPlayerClass.Clear();
|
||||
for(int i = 0;i < PROP_PARM_COUNT;++i)
|
||||
{
|
||||
PROP_STRING_PARM(n, i);
|
||||
if (*n != 0)
|
||||
info->RestrictedToPlayerClass.Push(FindClassTentativePlayerPawn(n));
|
||||
static_cast<PClassInventory*>(info)->RestrictedToPlayerClass.Push(FindClassTentativePlayerPawn(n));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1548,12 +1548,12 @@ DEFINE_CLASS_PROPERTY(restrictedto, Ssssssssssssssssssss, Inventory)
|
|||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(forbiddento, Ssssssssssssssssssss, Inventory)
|
||||
{
|
||||
info->ForbiddenToPlayerClass.Clear();
|
||||
static_cast<PClassInventory*>(info)->ForbiddenToPlayerClass.Clear();
|
||||
for(int i = 0;i < PROP_PARM_COUNT;++i)
|
||||
{
|
||||
PROP_STRING_PARM(n, i);
|
||||
if (*n != 0)
|
||||
info->ForbiddenToPlayerClass.Push(FindClassTentativePlayerPawn(n));
|
||||
static_cast<PClassInventory*>(info)->ForbiddenToPlayerClass.Push(FindClassTentativePlayerPawn(n));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,10 @@ ACTOR Actor native //: Thinker
|
|||
RipLevelMin 0
|
||||
RipLevelMax 0
|
||||
DefThreshold 100
|
||||
BloodType "Blood", "BloodSplatter", "AxeBlood"
|
||||
ExplosionDamage 128
|
||||
MissileHeight 32
|
||||
|
||||
|
||||
// Functions
|
||||
native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);
|
||||
|
|
Loading…
Reference in a new issue