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