Merge branch '4.14.2' into gz_merge
This commit is contained in:
commit
9aa44fa13b
83 changed files with 927 additions and 270 deletions
|
|
@ -170,6 +170,7 @@ CVAR(Bool, am_showmonsters, true, CVAR_ARCHIVE);
|
|||
CVAR(Bool, am_showitems, true, CVAR_ARCHIVE);
|
||||
CVAR(Bool, am_showtime, true, CVAR_ARCHIVE);
|
||||
CVAR(Bool, am_showtotaltime, false, CVAR_ARCHIVE);
|
||||
CVAR(Bool, am_showlevelname, true, CVAR_ARCHIVE);
|
||||
CVAR(Int, am_colorset, 0, CVAR_ARCHIVE);
|
||||
CVAR(Bool, am_customcolors, true, CVAR_ARCHIVE);
|
||||
CVAR(Int, am_map_secrets, 1, CVAR_ARCHIVE);
|
||||
|
|
|
|||
|
|
@ -594,6 +594,8 @@ class FBoolCVarRef
|
|||
{
|
||||
FBoolCVar* ref;
|
||||
public:
|
||||
int operator= (const FBoolCVarRef&) = delete;
|
||||
int operator= (FBoolCVarRef&&) = delete;
|
||||
|
||||
inline bool operator= (bool val) { *ref = val; return val; }
|
||||
inline operator bool () const { return **ref; }
|
||||
|
|
@ -607,7 +609,11 @@ class FIntCVarRef
|
|||
FIntCVar* ref;
|
||||
public:
|
||||
|
||||
int operator= (const FIntCVarRef&) = delete;
|
||||
int operator= (FIntCVarRef&&) = delete;
|
||||
|
||||
int operator= (int val) { *ref = val; return val; }
|
||||
|
||||
inline operator int () const { return **ref; }
|
||||
inline int operator *() const { return **ref; }
|
||||
inline FIntCVar* operator->() { return ref; }
|
||||
|
|
@ -618,6 +624,8 @@ class FFloatCVarRef
|
|||
{
|
||||
FFloatCVar* ref;
|
||||
public:
|
||||
int operator= (const FFloatCVarRef&) = delete;
|
||||
int operator= (FFloatCVarRef&&) = delete;
|
||||
|
||||
float operator= (float val) { *ref = val; return val; }
|
||||
inline operator float () const { return **ref; }
|
||||
|
|
@ -630,6 +638,8 @@ class FStringCVarRef
|
|||
{
|
||||
FStringCVar* ref;
|
||||
public:
|
||||
int operator= (const FStringCVarRef&) = delete;
|
||||
int operator= (FStringCVarRef&&) = delete;
|
||||
|
||||
const char* operator= (const char* val) { *ref = val; return val; }
|
||||
inline operator const char* () const { return **ref; }
|
||||
|
|
@ -642,6 +652,8 @@ class FColorCVarRef
|
|||
{
|
||||
FColorCVar* ref;
|
||||
public:
|
||||
int operator= (const FColorCVarRef&) = delete;
|
||||
int operator= (FColorCVarRef&&) = delete;
|
||||
|
||||
//uint32_t operator= (uint32_t val) { *ref = val; return val; }
|
||||
inline operator uint32_t () const { return **ref; }
|
||||
|
|
@ -654,6 +666,9 @@ class FFlagCVarRef
|
|||
{
|
||||
FFlagCVar* ref;
|
||||
public:
|
||||
int operator= (const FFlagCVarRef&) = delete;
|
||||
int operator= (FFlagCVarRef&&) = delete;
|
||||
|
||||
inline bool operator= (bool val) { *ref = val; return val; }
|
||||
inline bool operator= (const FFlagCVar& val) { *ref = val; return val; }
|
||||
inline operator int () const { return **ref; }
|
||||
|
|
@ -665,6 +680,9 @@ class FMaskCVarRef
|
|||
{
|
||||
FMaskCVar* ref;
|
||||
public:
|
||||
int operator= (const FMaskCVarRef&) = delete;
|
||||
int operator= (FMaskCVarRef&&) = delete;
|
||||
|
||||
//int operator= (int val) { *ref = val; return val; }
|
||||
inline operator int () const { return **ref; }
|
||||
inline int operator *() const { return **ref; }
|
||||
|
|
|
|||
|
|
@ -270,8 +270,10 @@ void ScreenJobDraw()
|
|||
ScaleOverrider ovr(twod);
|
||||
IFVIRTUALPTRNAME(cutscene.runner, NAME_ScreenJobRunner, RunFrame)
|
||||
{
|
||||
int ret = 0;
|
||||
VMValue parm[] = { cutscene.runner, smoothratio };
|
||||
VMCall(func, parm, 2, nullptr, 0);
|
||||
VMReturn rets[] = { &ret };
|
||||
VMCall(func, parm, 2, rets, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "zstring.h"
|
||||
|
||||
#ifdef __unix__
|
||||
#if defined(__unix__) || defined(__HAIKU__)
|
||||
FString GetUserFile (const char *path);
|
||||
#endif
|
||||
FString M_GetAppDataPath(bool create);
|
||||
|
|
|
|||
|
|
@ -85,6 +85,11 @@ public:
|
|||
ParseVersion = ver;
|
||||
}
|
||||
|
||||
bool CheckParseVersion(VersionInfo ver)
|
||||
{
|
||||
return ParseVersion >= ver;
|
||||
}
|
||||
|
||||
void SetCMode(bool cmode);
|
||||
void SetNoOctals(bool cmode) { NoOctals = cmode; }
|
||||
void SetNoFatalErrors(bool cmode) { NoFatalErrors = cmode; }
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ std2:
|
|||
/* Other keywords from UnrealScript */
|
||||
'abstract' { RET(TK_Abstract); }
|
||||
'foreach' { RET(ParseVersion >= MakeVersion(4, 10, 0)? TK_ForEach : TK_Identifier); }
|
||||
'unsafe' { RET(ParseVersion >= MakeVersion(4, 14, 2)? TK_Unsafe : TK_Identifier); }
|
||||
'true' { RET(TK_True); }
|
||||
'false' { RET(TK_False); }
|
||||
'none' { RET(TK_None); }
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ xx(TK_Color, "'color'")
|
|||
xx(TK_Goto, "'goto'")
|
||||
xx(TK_Abstract, "'abstract'")
|
||||
xx(TK_ForEach, "'foreach'")
|
||||
xx(TK_Unsafe, "'unsafe'")
|
||||
xx(TK_True, "'true'")
|
||||
xx(TK_False, "'false'")
|
||||
xx(TK_None, "'none'")
|
||||
|
|
|
|||
|
|
@ -12748,16 +12748,15 @@ ExpEmit FxFunctionPtrCast::Emit(VMFunctionBuilder *build)
|
|||
FxLocalVariableDeclaration::FxLocalVariableDeclaration(PType *type, FName name, FxExpression *initval, int varflags, const FScriptPosition &p)
|
||||
:FxExpression(EFX_LocalVariableDeclaration, p)
|
||||
{
|
||||
// Local FVector isn't different from Vector
|
||||
if (type == TypeFVector2) type = TypeVector2;
|
||||
else if (type == TypeFVector3) type = TypeVector3;
|
||||
else if (type == TypeFVector4) type = TypeVector4;
|
||||
else if (type == TypeFQuaternion) type = TypeQuaternion;
|
||||
if(type != type->GetLocalType())
|
||||
{
|
||||
ScriptPosition.Message(MSG_WARNING, "Type '%s' not allowed in local variables, changing to '%s'", type->DescriptiveName(), type->GetLocalType()->DescriptiveName());
|
||||
}
|
||||
|
||||
ValueType = type;
|
||||
ValueType = type->GetLocalType();
|
||||
VarFlags = varflags;
|
||||
Name = name;
|
||||
RegCount = type->RegCount;
|
||||
RegCount = ValueType->RegCount;
|
||||
Init = initval;
|
||||
clearExpr = nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -359,6 +359,7 @@ void PType::StaticInit()
|
|||
TypeVector2->RegType = REGT_FLOAT;
|
||||
TypeVector2->RegCount = 2;
|
||||
TypeVector2->isOrdered = true;
|
||||
TypeVector2->mDescriptiveName = "Vector2";
|
||||
|
||||
TypeVector3 = new PStruct(NAME_Vector3, nullptr);
|
||||
TypeVector3->AddField(NAME_X, TypeFloat64);
|
||||
|
|
@ -373,6 +374,7 @@ void PType::StaticInit()
|
|||
TypeVector3->RegType = REGT_FLOAT;
|
||||
TypeVector3->RegCount = 3;
|
||||
TypeVector3->isOrdered = true;
|
||||
TypeVector3->mDescriptiveName = "Vector3";
|
||||
|
||||
TypeVector4 = new PStruct(NAME_Vector4, nullptr);
|
||||
TypeVector4->AddField(NAME_X, TypeFloat64);
|
||||
|
|
@ -389,6 +391,7 @@ void PType::StaticInit()
|
|||
TypeVector4->RegType = REGT_FLOAT;
|
||||
TypeVector4->RegCount = 4;
|
||||
TypeVector4->isOrdered = true;
|
||||
TypeVector4->mDescriptiveName = "Vector4";
|
||||
|
||||
|
||||
TypeFVector2 = new PStruct(NAME_FVector2, nullptr);
|
||||
|
|
@ -401,6 +404,8 @@ void PType::StaticInit()
|
|||
TypeFVector2->RegType = REGT_FLOAT;
|
||||
TypeFVector2->RegCount = 2;
|
||||
TypeFVector2->isOrdered = true;
|
||||
TypeFVector2->mDescriptiveName = "FVector2";
|
||||
TypeFVector2->SetLocalType(TypeVector2);
|
||||
|
||||
TypeFVector3 = new PStruct(NAME_FVector3, nullptr);
|
||||
TypeFVector3->AddField(NAME_X, TypeFloat32);
|
||||
|
|
@ -415,6 +420,8 @@ void PType::StaticInit()
|
|||
TypeFVector3->RegType = REGT_FLOAT;
|
||||
TypeFVector3->RegCount = 3;
|
||||
TypeFVector3->isOrdered = true;
|
||||
TypeFVector3->mDescriptiveName = "FVector3";
|
||||
TypeFVector3->SetLocalType(TypeVector3);
|
||||
|
||||
TypeFVector4 = new PStruct(NAME_FVector4, nullptr);
|
||||
TypeFVector4->AddField(NAME_X, TypeFloat32);
|
||||
|
|
@ -431,6 +438,8 @@ void PType::StaticInit()
|
|||
TypeFVector4->RegType = REGT_FLOAT;
|
||||
TypeFVector4->RegCount = 4;
|
||||
TypeFVector4->isOrdered = true;
|
||||
TypeFVector4->mDescriptiveName = "FVector4";
|
||||
TypeFVector4->SetLocalType(TypeVector4);
|
||||
|
||||
|
||||
TypeQuaternion = new PStruct(NAME_Quat, nullptr);
|
||||
|
|
@ -447,6 +456,7 @@ void PType::StaticInit()
|
|||
TypeQuaternion->moveOp = OP_MOVEV4;
|
||||
TypeQuaternion->RegType = REGT_FLOAT;
|
||||
TypeQuaternion->RegCount = 4;
|
||||
TypeQuaternion->mDescriptiveName = "Quat";
|
||||
TypeQuaternion->isOrdered = true;
|
||||
|
||||
TypeFQuaternion = new PStruct(NAME_FQuat, nullptr);
|
||||
|
|
@ -464,6 +474,8 @@ void PType::StaticInit()
|
|||
TypeFQuaternion->RegType = REGT_FLOAT;
|
||||
TypeFQuaternion->RegCount = 4;
|
||||
TypeFQuaternion->isOrdered = true;
|
||||
TypeFQuaternion->mDescriptiveName = "FQuat";
|
||||
TypeFQuaternion->SetLocalType(TypeQuaternion);
|
||||
|
||||
|
||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(Create<PSymbolType>(NAME_sByte, TypeSInt8));
|
||||
|
|
|
|||
|
|
@ -109,6 +109,13 @@ public:
|
|||
EScopeFlags ScopeFlags = (EScopeFlags)0;
|
||||
bool SizeKnown = true;
|
||||
|
||||
bool VMInternalStruct = false;
|
||||
|
||||
PType * LocalType = nullptr;
|
||||
|
||||
PType * SetLocalType(PType * LocalType) { this->LocalType = LocalType; return this; }
|
||||
PType * GetLocalType() { return LocalType ? LocalType : this; }
|
||||
|
||||
PType(unsigned int size = 1, unsigned int align = 1);
|
||||
virtual ~PType();
|
||||
virtual bool isNumeric() { return false; }
|
||||
|
|
|
|||
|
|
@ -427,11 +427,12 @@ struct_def(X) ::= EXTEND STRUCT(T) IDENTIFIER(A) LBRACE opt_struct_body(B) RBRAC
|
|||
}
|
||||
|
||||
%type struct_flags{ClassFlagsBlock}
|
||||
struct_flags(X) ::= . { X.Flags = 0; X.Version = {0, 0}; }
|
||||
struct_flags(X) ::= struct_flags(A) UI. { X.Flags = A.Flags | ZCC_UIFlag; }
|
||||
struct_flags(X) ::= struct_flags(A) PLAY. { X.Flags = A.Flags | ZCC_Play; }
|
||||
struct_flags(X) ::= struct_flags(A) CLEARSCOPE. { X.Flags = A.Flags | ZCC_ClearScope; }
|
||||
struct_flags(X) ::= struct_flags(A) NATIVE. { X.Flags = A.Flags | ZCC_Native; }
|
||||
struct_flags(X) ::= . { X.Flags = 0; X.Version = {0, 0}; }
|
||||
struct_flags(X) ::= struct_flags(A) UI. { X.Flags = A.Flags | ZCC_UIFlag; X.Version = A.Version; }
|
||||
struct_flags(X) ::= struct_flags(A) PLAY. { X.Flags = A.Flags | ZCC_Play; X.Version = A.Version; }
|
||||
struct_flags(X) ::= struct_flags(A) CLEARSCOPE. { X.Flags = A.Flags | ZCC_ClearScope; X.Version = A.Version; }
|
||||
struct_flags(X) ::= struct_flags(A) NATIVE. { X.Flags = A.Flags | ZCC_Native; X.Version = A.Version; }
|
||||
struct_flags(X) ::= struct_flags(A) UNSAFE LPAREN INTERNAL RPAREN. { X.Flags = A.Flags | ZCC_VMInternalStruct; X.Version = A.Version; }
|
||||
struct_flags(X) ::= struct_flags(A) VERSION LPAREN STRCONST(C) RPAREN. { X.Flags = A.Flags | ZCC_Version; X.Version = C.String->GetChars(); }
|
||||
|
||||
opt_struct_body(X) ::= . { X = NULL; }
|
||||
|
|
@ -957,6 +958,7 @@ type_name(X) ::= DOT dottable_id(A).
|
|||
|
||||
/* Aggregate types */
|
||||
%type aggregate_type {ZCC_Type *}
|
||||
%type aggregate_type_pre {ZCC_Type *}
|
||||
%type type {ZCC_Type *}
|
||||
%type type_list {ZCC_Type *}
|
||||
%type type_list_or_void {ZCC_Type *}
|
||||
|
|
@ -965,30 +967,92 @@ type_name(X) ::= DOT dottable_id(A).
|
|||
%type array_size{ZCC_Expression *}
|
||||
%type array_size_expr{ZCC_Expression *}
|
||||
|
||||
aggregate_type(X) ::= MAP(T) LT type_or_array(A) COMMA type_or_array(B) GT. /* ZSMap<K, V> */
|
||||
aggregate_type_pre(X) ::= MAP(T) LT type_or_array(A) COMMA type_or_array(B). /* ZSMap<K, V> */
|
||||
{
|
||||
NEW_AST_NODE(MapType,map,T);
|
||||
map->KeyType = A;
|
||||
map->ValueType = B;
|
||||
X = map;
|
||||
X->ArraySize = NULL;
|
||||
}
|
||||
|
||||
aggregate_type(X) ::= MAPITERATOR(T) LT type_or_array(A) COMMA type_or_array(B) GT. /* ZSMapIterator<K, V> */
|
||||
aggregate_type_pre(X) ::= MAPITERATOR(T) LT type_or_array(A) COMMA type_or_array(B). /* ZSMapIterator<K, V> */
|
||||
{
|
||||
NEW_AST_NODE(MapIteratorType,map_it,T);
|
||||
map_it->KeyType = A;
|
||||
map_it->ValueType = B;
|
||||
X = map_it;
|
||||
X->ArraySize = NULL;
|
||||
}
|
||||
|
||||
aggregate_type(X) ::= ARRAY(T) LT type_or_array(A) GT. /* TArray<type> */
|
||||
aggregate_type_pre(X) ::= ARRAY(T) LT type_or_array(A). /* TArray<type> */
|
||||
{
|
||||
NEW_AST_NODE(DynArrayType,arr,T);
|
||||
arr->ElementType = A;
|
||||
X = arr;
|
||||
X->ArraySize = NULL;
|
||||
}
|
||||
|
||||
aggregate_type(X) ::= func_ptr_type(A). { X = A; /*X-overwrites-A*/ }
|
||||
aggregate_type_pre(X) ::= func_ptr_type(A). { X = A; /*X-overwrites-A*/ X->ArraySize = NULL; }
|
||||
|
||||
aggregate_type_pre(X) ::= CLASS(T) LT dottable_id(A). /* class<type> */
|
||||
{
|
||||
NEW_AST_NODE(ClassType,cls,T);
|
||||
cls->Restriction = A;
|
||||
X = cls;
|
||||
X->ArraySize = NULL;
|
||||
}
|
||||
|
||||
aggregate_type(X) ::= aggregate_type_pre(A) GT. { X = A; X->ArraySize = NULL; }
|
||||
|
||||
aggregate_type(X) ::= MAP(T) LT type_or_array(A) COMMA aggregate_type_pre(B) RSH. /* ZSMap<K, V<...>> */
|
||||
{
|
||||
if(!stat->sc->CheckParseVersion(MakeVersion(4, 15, 1)))
|
||||
{
|
||||
stat->sc->ScriptMessage(">> without space in parametrized types only supported for zscript >= 4.15.1");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
NEW_AST_NODE(MapType,map,T);
|
||||
map->KeyType = A;
|
||||
map->ValueType = B;
|
||||
X = map;
|
||||
X->ArraySize = NULL;
|
||||
}
|
||||
|
||||
aggregate_type(X) ::= MAPITERATOR(T) LT type_or_array(A) COMMA aggregate_type_pre(B) RSH. /* ZSMapIterator<K, V<...>> */
|
||||
{
|
||||
if(!stat->sc->CheckParseVersion(MakeVersion(4, 15, 1)))
|
||||
{
|
||||
stat->sc->ScriptMessage(">> without space in parametrized types only supported for zscript >= 4.15.1");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
NEW_AST_NODE(MapIteratorType,map_it,T);
|
||||
map_it->KeyType = A;
|
||||
map_it->ValueType = B;
|
||||
X = map_it;
|
||||
X->ArraySize = NULL;
|
||||
}
|
||||
|
||||
aggregate_type(X) ::= ARRAY(T) LT aggregate_type_pre(A) RSH. /* TArray<T<...>> */
|
||||
{
|
||||
if(!stat->sc->CheckParseVersion(MakeVersion(4, 15, 1)))
|
||||
{
|
||||
stat->sc->ScriptMessage(">> without space in parametrized types only supported for zscript >= 4.15.1");
|
||||
FScriptPosition::ErrorCounter++;
|
||||
}
|
||||
NEW_AST_NODE(DynArrayType,arr,T);
|
||||
arr->ElementType = A;
|
||||
X = arr;
|
||||
X->ArraySize = NULL;
|
||||
}
|
||||
|
||||
aggregate_type(X) ::= CLASS(T). /* class<type> */
|
||||
{
|
||||
NEW_AST_NODE(ClassType,cls,T);
|
||||
cls->Restriction = NULL;
|
||||
X = cls;
|
||||
X->ArraySize = NULL;
|
||||
}
|
||||
|
||||
%type func_ptr_type {ZCC_FuncPtrType *}
|
||||
%type func_ptr_params {ZCC_FuncPtrParamDecl *}
|
||||
|
|
@ -1002,7 +1066,7 @@ fn_ptr_flag(X) ::= CLEARSCOPE. { X.Int = ZCC_ClearScope; }
|
|||
//fn_ptr_flag(X) ::= VIRTUALSCOPE. { X.Int = ZCC_VirtualScope; } //virtual scope not allowed
|
||||
|
||||
|
||||
func_ptr_type(X) ::= FNTYPE(T) LT fn_ptr_flag(F) type_list_or_void(A) LPAREN func_ptr_params(B) RPAREN GT. /* Function<...(...)> */
|
||||
func_ptr_type(X) ::= FNTYPE(T) LT fn_ptr_flag(F) type_list_or_void(A) LPAREN func_ptr_params(B) RPAREN. /* Function<...(...)> */
|
||||
{
|
||||
NEW_AST_NODE(FuncPtrType,fn_ptr,T);
|
||||
fn_ptr->RetType = A;
|
||||
|
|
@ -1011,7 +1075,7 @@ func_ptr_type(X) ::= FNTYPE(T) LT fn_ptr_flag(F) type_list_or_void(A) LPAREN fun
|
|||
X = fn_ptr;
|
||||
}
|
||||
|
||||
func_ptr_type(X) ::= FNTYPE(T) LT VOID GT. /* Function<void> */
|
||||
func_ptr_type(X) ::= FNTYPE(T) LT VOID. /* Function<void> */
|
||||
{
|
||||
NEW_AST_NODE(FuncPtrType,fn_ptr,T);
|
||||
fn_ptr->RetType = nullptr;
|
||||
|
|
@ -1053,15 +1117,6 @@ func_ptr_param(X) ::= func_param_flags(A) type(B) AND.
|
|||
X = parm;
|
||||
}
|
||||
|
||||
aggregate_type(X) ::= CLASS(T) class_restrictor(A). /* class<type> */
|
||||
{
|
||||
NEW_AST_NODE(ClassType,cls,T);
|
||||
cls->Restriction = A;
|
||||
X = cls;
|
||||
}
|
||||
class_restrictor(X) ::= . { X = NULL; }
|
||||
class_restrictor(X) ::= LT dottable_id(A) GT. { X = A; /*X-overwrites-A*/ }
|
||||
|
||||
type(X) ::= type_name(A). { X = A; /*X-overwrites-A*/ X->ArraySize = NULL; }
|
||||
type(X) ::= aggregate_type(A). { X = A; /*X-overwrites-A*/ X->ArraySize = NULL; }
|
||||
|
||||
|
|
@ -1474,7 +1529,7 @@ primary(X) ::= LPAREN CLASS LT IDENTIFIER(A) GT RPAREN LPAREN func_expr_list(B)
|
|||
X = expr;
|
||||
}
|
||||
|
||||
primary(X) ::= LPAREN func_ptr_type(A) RPAREN LPAREN expr(B) RPAREN. [DOT] // function pointer type cast
|
||||
primary(X) ::= LPAREN func_ptr_type(A) GT RPAREN LPAREN expr(B) RPAREN. [DOT] // function pointer type cast
|
||||
{
|
||||
NEW_AST_NODE(FunctionPtrCast, expr, A);
|
||||
expr->Operation = PEX_FunctionPtrCast;
|
||||
|
|
|
|||
|
|
@ -734,6 +734,8 @@ void ZCCCompiler::CreateStructTypes()
|
|||
syms = &OutNamespace->Symbols;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (s->NodeName() == NAME__ && fileSystem.GetFileContainer(Lump) == 0)
|
||||
{
|
||||
// This is just a container for syntactic purposes.
|
||||
|
|
@ -748,11 +750,24 @@ void ZCCCompiler::CreateStructTypes()
|
|||
{
|
||||
s->strct->Type = NewStruct(s->NodeName(), outer, false, AST.FileNo);
|
||||
}
|
||||
|
||||
if (s->strct->Flags & ZCC_Version)
|
||||
{
|
||||
s->strct->Type->mVersion = s->strct->Version;
|
||||
}
|
||||
|
||||
if (s->strct->Flags & ZCC_VMInternalStruct)
|
||||
{
|
||||
if(fileSystem.GetFileContainer(Lump) == 0)
|
||||
{
|
||||
s->strct->Type->VMInternalStruct = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(s->strct, "Internal structs are only allowed in the root pk3");
|
||||
}
|
||||
}
|
||||
|
||||
auto &sf = s->Type()->ScopeFlags;
|
||||
if (mVersion >= MakeVersion(2, 4, 0))
|
||||
{
|
||||
|
|
@ -814,6 +829,12 @@ void ZCCCompiler::CreateClassTypes()
|
|||
PClass *parent;
|
||||
auto ParentName = c->cls->ParentName;
|
||||
|
||||
if (c->cls->Flags & ZCC_Internal)
|
||||
{
|
||||
Error(c->cls, "'Internal' not allowed for classes");
|
||||
}
|
||||
|
||||
// The parent exists, we may create a type for this class
|
||||
if (ParentName != nullptr && ParentName->SiblingNext == ParentName)
|
||||
{
|
||||
parent = PClass::FindClass(ParentName->Id);
|
||||
|
|
@ -850,7 +871,6 @@ void ZCCCompiler::CreateClassTypes()
|
|||
Error(c->cls, "Class '%s' cannot extend sealed class '%s'", FName(c->NodeName()).GetChars(), parent->TypeName.GetChars());
|
||||
}
|
||||
|
||||
// The parent exists, we may create a type for this class
|
||||
if (c->cls->Flags & ZCC_Native)
|
||||
{
|
||||
// If this is a native class, its own type must also already exist and not be a runtime class.
|
||||
|
|
@ -1873,7 +1893,7 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
|
|||
{
|
||||
Error(field, "%s: @ not allowed for user scripts", name.GetChars());
|
||||
}
|
||||
retval = ResolveUserType(btype, btype->UserType, outertype? &outertype->Symbols : nullptr, true);
|
||||
retval = ResolveUserType(outertype, btype, btype->UserType, outertype? &outertype->Symbols : nullptr, true);
|
||||
break;
|
||||
|
||||
case ZCC_UserType:
|
||||
|
|
@ -1903,7 +1923,7 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
|
|||
|
||||
|
||||
default:
|
||||
retval = ResolveUserType(btype, btype->UserType, outertype ? &outertype->Symbols : nullptr, false);
|
||||
retval = ResolveUserType(outertype, btype, btype->UserType, outertype ? &outertype->Symbols : nullptr, false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
@ -2158,7 +2178,7 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
|
|||
* @param nativetype Distinguishes between searching for a native type or a user type.
|
||||
* @returns the PType found for this user type
|
||||
*/
|
||||
PType *ZCCCompiler::ResolveUserType(ZCC_BasicType *type, ZCC_Identifier *id, PSymbolTable *symt, bool nativetype)
|
||||
PType *ZCCCompiler::ResolveUserType(PType *outertype, ZCC_BasicType *type, ZCC_Identifier *id, PSymbolTable *symt, bool nativetype)
|
||||
{
|
||||
// Check the symbol table for the identifier.
|
||||
PSymbol *sym = nullptr;
|
||||
|
|
@ -2175,10 +2195,18 @@ PType *ZCCCompiler::ResolveUserType(ZCC_BasicType *type, ZCC_Identifier *id, PSy
|
|||
return TypeError;
|
||||
}
|
||||
|
||||
//only allow references to internal types inside internal types
|
||||
if (ptype->VMInternalStruct && !outertype->VMInternalStruct)
|
||||
{
|
||||
Error(type, "Type %s not accessible", FName(type->UserType->Id).GetChars());
|
||||
return TypeError;
|
||||
}
|
||||
|
||||
if (id->SiblingNext != type->UserType)
|
||||
{
|
||||
assert(id->SiblingNext->NodeType == AST_Identifier);
|
||||
ptype = ResolveUserType(
|
||||
outertype,
|
||||
type,
|
||||
static_cast<ZCC_Identifier *>(id->SiblingNext),
|
||||
&ptype->Symbols,
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ protected:
|
|||
FString FlagsToString(uint32_t flags);
|
||||
PType *DetermineType(PType *outertype, ZCC_TreeNode *field, FName name, ZCC_Type *ztype, bool allowarraytypes, bool formember);
|
||||
PType *ResolveArraySize(PType *baseType, ZCC_Expression *arraysize, PContainerType *cls, bool *nosize);
|
||||
PType *ResolveUserType(ZCC_BasicType *type, ZCC_Identifier *id, PSymbolTable *sym, bool nativetype);
|
||||
PType *ResolveUserType(PType *outertype, ZCC_BasicType *type, ZCC_Identifier *id, PSymbolTable *sym, bool nativetype);
|
||||
static FString UserTypeName(ZCC_BasicType *type);
|
||||
TArray<ZCC_StructWork *> OrderStructs();
|
||||
void AddStruct(TArray<ZCC_StructWork *> &new_order, ZCC_StructWork *struct_def);
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ static void InitTokenMap()
|
|||
TOKENDEF (TK_Do, ZCC_DO);
|
||||
TOKENDEF (TK_For, ZCC_FOR);
|
||||
TOKENDEF (TK_ForEach, ZCC_FOREACH);
|
||||
TOKENDEF (TK_Unsafe, ZCC_UNSAFE);
|
||||
TOKENDEF (TK_While, ZCC_WHILE);
|
||||
TOKENDEF (TK_Until, ZCC_UNTIL);
|
||||
TOKENDEF (TK_If, ZCC_IF);
|
||||
|
|
|
|||
|
|
@ -41,30 +41,31 @@ struct ZCCToken
|
|||
// Variable / Function / Class modifiers
|
||||
enum
|
||||
{
|
||||
ZCC_Native = 1 << 0,
|
||||
ZCC_Static = 1 << 1,
|
||||
ZCC_Private = 1 << 2,
|
||||
ZCC_Protected = 1 << 3,
|
||||
ZCC_Latent = 1 << 4,
|
||||
ZCC_Final = 1 << 5,
|
||||
ZCC_Meta = 1 << 6,
|
||||
ZCC_Action = 1 << 7,
|
||||
ZCC_Deprecated = 1 << 8,
|
||||
ZCC_ReadOnly = 1 << 9,
|
||||
ZCC_FuncConst = 1 << 10,
|
||||
ZCC_Abstract = 1 << 11,
|
||||
ZCC_Extension = 1 << 12,
|
||||
ZCC_Virtual = 1 << 13,
|
||||
ZCC_Override = 1 << 14,
|
||||
ZCC_Transient = 1 << 15,
|
||||
ZCC_VarArg = 1 << 16,
|
||||
ZCC_UIFlag = 1 << 17, // there's also token called ZCC_UI
|
||||
ZCC_Play = 1 << 18,
|
||||
ZCC_ClearScope = 1 << 19,
|
||||
ZCC_VirtualScope = 1 << 20,
|
||||
ZCC_Version = 1 << 21,
|
||||
ZCC_Internal = 1 << 22,
|
||||
ZCC_Sealed = 1 << 23,
|
||||
ZCC_Native = 1 << 0,
|
||||
ZCC_Static = 1 << 1,
|
||||
ZCC_Private = 1 << 2,
|
||||
ZCC_Protected = 1 << 3,
|
||||
ZCC_Latent = 1 << 4,
|
||||
ZCC_Final = 1 << 5,
|
||||
ZCC_Meta = 1 << 6,
|
||||
ZCC_Action = 1 << 7,
|
||||
ZCC_Deprecated = 1 << 8,
|
||||
ZCC_ReadOnly = 1 << 9,
|
||||
ZCC_FuncConst = 1 << 10,
|
||||
ZCC_Abstract = 1 << 11,
|
||||
ZCC_Extension = 1 << 12,
|
||||
ZCC_Virtual = 1 << 13,
|
||||
ZCC_Override = 1 << 14,
|
||||
ZCC_Transient = 1 << 15,
|
||||
ZCC_VarArg = 1 << 16,
|
||||
ZCC_UIFlag = 1 << 17, // there's also token called ZCC_UI
|
||||
ZCC_Play = 1 << 18,
|
||||
ZCC_ClearScope = 1 << 19,
|
||||
ZCC_VirtualScope = 1 << 20,
|
||||
ZCC_Version = 1 << 21,
|
||||
ZCC_Internal = 1 << 22,
|
||||
ZCC_Sealed = 1 << 23,
|
||||
ZCC_VMInternalStruct = 1 << 24,
|
||||
};
|
||||
|
||||
// Function parameter modifiers
|
||||
|
|
|
|||
|
|
@ -853,6 +853,27 @@ DEFINE_ACTION_FUNCTION(_Wads, GetLumpFullName)
|
|||
ACTION_RETURN_STRING(fileSystem.GetFileFullName(lump));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Wads, GetLumpContainer)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(lump);
|
||||
ACTION_RETURN_INT(fileSystem.GetFileContainer(lump));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Wads, GetContainerName)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(lump);
|
||||
ACTION_RETURN_STRING(fileSystem.GetResourceFileName(lump));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Wads, GetLumpFullPath)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(lump);
|
||||
ACTION_RETURN_STRING(fileSystem.GetFileFullPath(lump));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Wads, GetLumpNamespace)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
|
|
|
|||
|
|
@ -539,15 +539,9 @@ struct TVector3
|
|||
return *this;
|
||||
}
|
||||
|
||||
// returns the XY fields as a 2D-vector.
|
||||
constexpr const Vector2& XY() const
|
||||
constexpr Vector2 XY() const
|
||||
{
|
||||
return *reinterpret_cast<const Vector2*>(this);
|
||||
}
|
||||
|
||||
constexpr Vector2& XY()
|
||||
{
|
||||
return *reinterpret_cast<Vector2*>(this);
|
||||
return Vector2(X, Y);
|
||||
}
|
||||
|
||||
// Add a 3D vector and a 2D vector.
|
||||
|
|
@ -792,28 +786,16 @@ struct TVector4
|
|||
}
|
||||
|
||||
// returns the XY fields as a 2D-vector.
|
||||
constexpr const Vector2& XY() const
|
||||
constexpr Vector2 XY() const
|
||||
{
|
||||
return *reinterpret_cast<const Vector2*>(this);
|
||||
return Vector2(X, Y);
|
||||
}
|
||||
|
||||
constexpr Vector2& XY()
|
||||
constexpr Vector3 XYZ() const
|
||||
{
|
||||
return *reinterpret_cast<Vector2*>(this);
|
||||
return Vector3(X, Y, Z);
|
||||
}
|
||||
|
||||
// returns the XY fields as a 2D-vector.
|
||||
constexpr const Vector3& XYZ() const
|
||||
{
|
||||
return *reinterpret_cast<const Vector3*>(this);
|
||||
}
|
||||
|
||||
constexpr Vector3& XYZ()
|
||||
{
|
||||
return *reinterpret_cast<Vector3*>(this);
|
||||
}
|
||||
|
||||
|
||||
// Test for approximate equality
|
||||
bool ApproximatelyEquals(const TVector4 &other) const
|
||||
{
|
||||
|
|
@ -1796,7 +1778,9 @@ struct TRotator
|
|||
template<class T>
|
||||
inline TVector3<T>::TVector3 (const TRotator<T> &rot)
|
||||
{
|
||||
XY() = rot.Pitch.Cos() * rot.Yaw.ToVector();
|
||||
auto XY = rot.Pitch.Cos() * rot.Yaw.ToVector();
|
||||
X = XY.X;
|
||||
Y = XY.Y;
|
||||
Z = rot.Pitch.Sin();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -251,14 +251,18 @@ void CT_Drawer (void)
|
|||
{
|
||||
// [MK] allow the status bar to take over chat prompt drawing
|
||||
bool skip = false;
|
||||
IFVIRTUALPTR(StatusBar, DBaseStatusBar, DrawChat)
|
||||
|
||||
if(StatusBar)
|
||||
{
|
||||
FString txt = ChatQueue;
|
||||
VMValue params[] = { (DObject*)StatusBar, &txt };
|
||||
int rv;
|
||||
VMReturn ret(&rv);
|
||||
VMCall(func, params, countof(params), &ret, 1);
|
||||
if (!!rv) return;
|
||||
IFVIRTUALPTR(StatusBar, DBaseStatusBar, DrawChat)
|
||||
{
|
||||
FString txt = ChatQueue;
|
||||
VMValue params[] = { (DObject*)StatusBar, &txt };
|
||||
int rv;
|
||||
VMReturn ret(&rv);
|
||||
VMCall(func, params, countof(params), &ret, 1);
|
||||
if (!!rv) return;
|
||||
}
|
||||
}
|
||||
|
||||
FStringf prompt("%s ", GStrings.GetString("TXT_SAY"));
|
||||
|
|
@ -269,8 +273,8 @@ void CT_Drawer (void)
|
|||
scalex = 1;
|
||||
int scale = active_con_scale(drawer);
|
||||
int screen_width = twod->GetWidth() / scale;
|
||||
int screen_height= twod->GetHeight() / scale;
|
||||
int st_y = StatusBar->GetTopOfStatusbar() / scale;
|
||||
int screen_height = twod->GetHeight() / scale;
|
||||
int st_y = StatusBar ? (StatusBar->GetTopOfStatusbar() / scale) : screen_height;
|
||||
|
||||
y += ((twod->GetHeight() == viewheight && viewactive) || gamestate != GS_LEVEL) ? screen_height : st_y;
|
||||
|
||||
|
|
|
|||
|
|
@ -316,7 +316,6 @@ CUSTOM_CVAR(Int, I_FriendlyWindowTitle, 1, CVAR_GLOBALCONFIG|CVAR_ARCHIVE|CVAR_N
|
|||
CVAR(Bool, cl_nointros, false, CVAR_ARCHIVE)
|
||||
|
||||
bool RunningAsTool = false;
|
||||
bool hud_toggled = false;
|
||||
bool wantToRestart;
|
||||
bool DrawFSHUD; // [RH] Draw fullscreen HUD?
|
||||
bool devparm; // started game with -devparm
|
||||
|
|
@ -361,16 +360,18 @@ static int pagetic;
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
CVAR(Int, saved_screenblocks, 10, CVAR_ARCHIVE)
|
||||
CVAR(Bool, saved_drawplayersprite, true, CVAR_ARCHIVE)
|
||||
CVAR(Bool, saved_showmessages, true, CVAR_ARCHIVE)
|
||||
CVAR(Bool, hud_toggled, false, CVAR_ARCHIVE)
|
||||
|
||||
void D_ToggleHud()
|
||||
{
|
||||
static int saved_screenblocks;
|
||||
static bool saved_drawplayersprite, saved_showmessages;
|
||||
|
||||
if ((hud_toggled = !hud_toggled))
|
||||
{
|
||||
saved_screenblocks = screenblocks;
|
||||
saved_drawplayersprite = r_drawplayersprites;
|
||||
saved_showmessages = show_messages;
|
||||
saved_screenblocks = *screenblocks;
|
||||
saved_drawplayersprite = *r_drawplayersprites;
|
||||
saved_showmessages = *show_messages;
|
||||
screenblocks = 12;
|
||||
r_drawplayersprites = false;
|
||||
show_messages = false;
|
||||
|
|
@ -379,9 +380,9 @@ void D_ToggleHud()
|
|||
}
|
||||
else
|
||||
{
|
||||
screenblocks = saved_screenblocks;
|
||||
r_drawplayersprites = saved_drawplayersprite;
|
||||
show_messages = saved_showmessages;
|
||||
screenblocks =*saved_screenblocks;
|
||||
r_drawplayersprites = *saved_drawplayersprite;
|
||||
show_messages = *saved_showmessages;
|
||||
}
|
||||
}
|
||||
CCMD(togglehud)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#include "c_cvars.h"
|
||||
|
||||
extern bool advancedemo;
|
||||
extern bool hud_toggled;
|
||||
EXTERN_CVAR(Bool, hud_toggled);
|
||||
void D_ToggleHud();
|
||||
|
||||
struct event_t;
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ CCMD (turnspeeds)
|
|||
}
|
||||
if (i <= 4)
|
||||
{
|
||||
*angleturn[3] = *angleturn[2];
|
||||
*angleturn[3] = **angleturn[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1000,6 +1000,8 @@ bool G_Responder (event_t *ev)
|
|||
if (gameaction == ga_nothing &&
|
||||
(demoplayback || gamestate == GS_DEMOSCREEN || gamestate == GS_TITLELEVEL))
|
||||
{
|
||||
if (chatmodeon) chatmodeon = 0;
|
||||
|
||||
const char *cmd = Bindings.GetBind (ev->data1);
|
||||
|
||||
if (ev->type == EV_KeyDown)
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ CUSTOM_CVAR(Bool, gl_notexturefill, false, CVAR_NOINITCALL)
|
|||
|
||||
CUSTOM_CVAR(Int, gl_maplightmode, -1, CVAR_NOINITCALL | CVAR_CHEAT) // this is just for testing. -1 means 'inactive'
|
||||
{
|
||||
if (self > 5 || self < -1) self = -1;
|
||||
if (self > 4 || self < -1) self = -1;
|
||||
}
|
||||
|
||||
CUSTOM_CVARD(Int, gl_lightmode, 1, CVAR_ARCHIVE, "Select lighting mode. 2 is vanilla accurate, 1 is accurate to the ZDoom software renderer and 0 is a less demanding non-shader implementation")
|
||||
|
|
|
|||
|
|
@ -1441,10 +1441,10 @@ class CommandDrawNumber : public CommandDrawString
|
|||
static VMFunction *func = nullptr;
|
||||
if (func == nullptr) PClass::FindFunction(&func, NAME_PlayerPawn, "GetEffectTicsForItem");
|
||||
VMValue params[] = { statusBar->CPlayer->mo, inventoryItem };
|
||||
int retv;
|
||||
VMReturn ret(&retv);
|
||||
VMCall(func, params, 2, &ret, 1);
|
||||
num = retv < 0? 0 : retv / TICRATE + 1;
|
||||
int ret1 = 0, ret2 = 0;
|
||||
VMReturn rets[] = { &ret1, &ret2 };
|
||||
VMCall(func, params, 2, rets, 2);
|
||||
num = ret1 < 0? 0 : ret1 / TICRATE + 1;
|
||||
break;
|
||||
}
|
||||
case INVENTORY:
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ EXTERN_CVAR (Bool, am_showsecrets)
|
|||
EXTERN_CVAR (Bool, am_showitems)
|
||||
EXTERN_CVAR (Bool, am_showtime)
|
||||
EXTERN_CVAR (Bool, am_showtotaltime)
|
||||
EXTERN_CVAR (Bool, am_showlevelname)
|
||||
EXTERN_CVAR(Bool, inter_subtitles)
|
||||
EXTERN_CVAR(Bool, ui_screenborder_classic_scaling)
|
||||
|
||||
|
|
@ -598,6 +599,8 @@ void DBaseStatusBar::DoDrawAutomapHUD(int crdefault, int highlight)
|
|||
}
|
||||
|
||||
FormatMapName(primaryLevel, crdefault, &textbuffer);
|
||||
if (textbuffer.IsEmpty())
|
||||
return;
|
||||
|
||||
if (!generic_ui)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ static PClassActor* FindInfoName(int index, bool mustexist = false)
|
|||
cls = static_cast<PClassActor*>(RUNTIME_CLASS(AActor)->CreateDerivedClass(name.GetChars(), (unsigned)sizeof(AActor)));
|
||||
NewClassType(cls, -1); // This needs a VM type to work as intended.
|
||||
cls->InitializeDefaults();
|
||||
PClassActor::AllActorClasses.Push(cls);
|
||||
}
|
||||
if (cls)
|
||||
{
|
||||
|
|
@ -1203,6 +1204,8 @@ static int PatchThing (int thingy, int flags)
|
|||
AActor *info;
|
||||
uint8_t dummy[sizeof(AActor)];
|
||||
bool hadHeight = false;
|
||||
bool hadProjHeight = false;
|
||||
bool hadPhysHeight = false;
|
||||
bool hadTranslucency = false;
|
||||
bool hadStyle = false;
|
||||
FStateDefinitions statedef;
|
||||
|
|
@ -1262,8 +1265,17 @@ static int PatchThing (int thingy, int flags)
|
|||
}
|
||||
else if (linelen == 6 && stricmp (Line1, "Height") == 0)
|
||||
{
|
||||
info->Height = DEHToDouble(val);
|
||||
info->projectilepassheight = 0; // needs to be disabled
|
||||
// [XA] This is a bit more complex now, since projectilepassheight
|
||||
// and "physical height" now both exist. if either of these are
|
||||
// defined, then override the Height field accordingly.
|
||||
if(!hadPhysHeight)
|
||||
{
|
||||
info->Height = DEHToDouble(val);
|
||||
}
|
||||
if(!hadProjHeight)
|
||||
{
|
||||
info->projectilepassheight = 0; // needs to be disabled
|
||||
}
|
||||
hadHeight = true;
|
||||
}
|
||||
else if (linelen == 14 && stricmp (Line1, "Missile damage") == 0)
|
||||
|
|
@ -1459,6 +1471,47 @@ static int PatchThing (int thingy, int flags)
|
|||
info->missilechancemult = DEHToDouble(val);
|
||||
}
|
||||
|
||||
// [XA] Fields for common GZDoom-specific values that
|
||||
// are desirable to set in a cross-port DEHACKED mod.
|
||||
// adding these prevents users from having to reimplement
|
||||
// actors in zscript just to define these few fields.
|
||||
else if (!stricmp(Line1, "Projectile pass height"))
|
||||
{
|
||||
info->projectilepassheight = DEHToDouble(val);
|
||||
hadProjHeight = true;
|
||||
}
|
||||
else if (!stricmp(Line1, "Physical height"))
|
||||
{
|
||||
// [XA] This is a synonym for Height that is intended
|
||||
// to be ignored in any ports that don't support
|
||||
// projectilepassheight -- this is needed because
|
||||
// other ports' "Height x" is actually equivalent
|
||||
// to Zdoom's "ProjectilePassHeight x; Height y",
|
||||
// i.e. the definition of the Height var is different.
|
||||
info->Height = DEHToDouble(val);
|
||||
hadPhysHeight = true;
|
||||
}
|
||||
else if (!stricmp(Line1, "Tag"))
|
||||
{
|
||||
stripwhite(Line2);
|
||||
info->SetTag(Line2);
|
||||
}
|
||||
else if (!stricmp(Line1, "Obituary"))
|
||||
{
|
||||
stripwhite(Line2);
|
||||
info->StringVar(NAME_Obituary) = Line2;
|
||||
}
|
||||
else if (!stricmp(Line1, "Melee obituary"))
|
||||
{
|
||||
stripwhite(Line2);
|
||||
info->StringVar(NAME_HitObituary) = Line2;
|
||||
}
|
||||
else if (!stricmp(Line1, "Self obituary"))
|
||||
{
|
||||
stripwhite(Line2);
|
||||
info->StringVar(NAME_SelfObituary) = Line2;
|
||||
}
|
||||
|
||||
else if (linelen > 6)
|
||||
{
|
||||
if (stricmp (Line1 + linelen - 6, " frame") == 0)
|
||||
|
|
@ -1727,12 +1780,23 @@ static int PatchThing (int thingy, int flags)
|
|||
else Printf (unknown_str, Line1, "Thing", thingy);
|
||||
}
|
||||
|
||||
// [XA] sanity check: to avoid ambiguity, an actor that defines
|
||||
// ProjectilePassHeight must also define PhysicalHeight, and vice-versa.
|
||||
if(hadPhysHeight && !hadProjHeight)
|
||||
{
|
||||
I_Error("Thing %d: DEHACKED actors that set 'Physical height' must also set 'Projectile pass height'\n", thingy);
|
||||
}
|
||||
else if(!hadPhysHeight && hadProjHeight)
|
||||
{
|
||||
I_Error("Thing %d: DEHACKED actors that set 'Projectile pass height' must also set 'Physical height'\n", thingy);
|
||||
}
|
||||
|
||||
if (info != (AActor *)&dummy)
|
||||
{
|
||||
// Reset heights for things hanging from the ceiling that
|
||||
// don't specify a new height.
|
||||
if (info->flags & MF_SPAWNCEILING &&
|
||||
!hadHeight &&
|
||||
!hadHeight && !hadPhysHeight &&
|
||||
thingy <= (int)OrgHeights.Size() && thingy > 0)
|
||||
{
|
||||
info->Height = OrgHeights[thingy - 1];
|
||||
|
|
@ -3714,7 +3778,11 @@ void FinishDehPatch ()
|
|||
mysnprintf(typeNameBuilder, countof(typeNameBuilder), "DehackedPickup%d", nameindex++);
|
||||
bool newlycreated;
|
||||
subclass = static_cast<PClassActor *>(dehtype->CreateDerivedClass(typeNameBuilder, dehtype->Size, &newlycreated, 0));
|
||||
if (newlycreated) subclass->InitializeDefaults();
|
||||
if (newlycreated)
|
||||
{
|
||||
subclass->InitializeDefaults();
|
||||
PClassActor::AllActorClasses.Push(subclass);
|
||||
}
|
||||
}
|
||||
while (subclass == nullptr);
|
||||
NewClassType(subclass, 0); // This needs a VM type to work as intended.
|
||||
|
|
|
|||
|
|
@ -1582,7 +1582,7 @@ DEFINE_MAP_OPTION(lightmode, false)
|
|||
parse.sc.MustGetNumber();
|
||||
|
||||
if (parse.sc.Number == 8 || parse.sc.Number == 16) info->lightmode = ELightMode::NotSet;
|
||||
else if (parse.sc.Number >= 0 && parse.sc.Number <= 5)
|
||||
else if (parse.sc.Number >= 0 && parse.sc.Number < 5)
|
||||
{
|
||||
info->lightmode = ELightMode(parse.sc.Number);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -325,8 +325,10 @@ void DIntermissionScreenCutscene::Drawer ()
|
|||
ScaleOverrider ovr(twod);
|
||||
IFVIRTUALPTRNAME(mScreenJobRunner, NAME_ScreenJobRunner, RunFrame)
|
||||
{
|
||||
int res = 0;
|
||||
VMValue parm[] = { mScreenJobRunner, I_GetTimeFrac() };
|
||||
VMCall(func, parm, 2, nullptr, 0);
|
||||
VMReturn ret[] = { &res };
|
||||
VMCall(func, parm, 2, ret, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -483,6 +483,9 @@ xx(PowerupType)
|
|||
xx(PlayerPawn)
|
||||
xx(RipSound)
|
||||
xx(Archvile)
|
||||
xx(Obituary)
|
||||
xx(HitObituary)
|
||||
xx(SelfObituary)
|
||||
|
||||
xx(ResolveState)
|
||||
|
||||
|
|
|
|||
|
|
@ -218,8 +218,10 @@ static void TakeStrifeItem (player_t *player, PClassActor *itemtype, int amount)
|
|||
|
||||
IFVM(Actor, TakeInventory)
|
||||
{
|
||||
int taken = false;
|
||||
VMValue params[] = { player->mo, itemtype, amount, false, false };
|
||||
VMCall(func, params, 5, nullptr, 0);
|
||||
VMReturn rets[] = { &taken };
|
||||
VMCall(func, params, 5, rets, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -509,6 +509,7 @@ enum ActorRenderFlag2
|
|||
RF2_ISOMETRICSPRITES = 0x0080,
|
||||
RF2_SQUAREPIXELS = 0x0100, // apply +ROLLSPRITE scaling math so that non rolling sprites get the same scaling
|
||||
RF2_STRETCHPIXELS = 0x0200, // don't apply SQUAREPIXELS for ROLLSPRITES
|
||||
RF2_LIGHTMULTALPHA = 0x0400, // attached lights use alpha as intensity multiplier
|
||||
};
|
||||
|
||||
// This translucency value produces the closest match to Heretic's TINTTAB.
|
||||
|
|
|
|||
|
|
@ -355,12 +355,12 @@ void FThinkerCollection::SerializeThinkers(FSerializer &arc, bool hubLoad)
|
|||
else if (thinker->ObjectFlags & OF_JustSpawned)
|
||||
{
|
||||
FreshThinkers[i].AddTail(thinker);
|
||||
thinker->PostSerialize();
|
||||
thinker->CallPostSerialize();
|
||||
}
|
||||
else
|
||||
{
|
||||
Thinkers[i].AddTail(thinker);
|
||||
thinker->PostSerialize();
|
||||
thinker->CallPostSerialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -773,6 +773,16 @@ void DThinker::PostSerialize()
|
|||
{
|
||||
}
|
||||
|
||||
void DThinker::CallPostSerialize()
|
||||
{
|
||||
PostSerialize();
|
||||
IFOVERRIDENVIRTUALPTRNAME(this, NAME_Thinker, OnLoad)
|
||||
{
|
||||
VMValue params[] = { this };
|
||||
VMCall(func, params, 1, nullptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ public:
|
|||
virtual void PostBeginPlay (); // Called just before the first tick
|
||||
virtual void CallPostBeginPlay(); // different in actor.
|
||||
virtual void PostSerialize();
|
||||
void CallPostSerialize();
|
||||
void Serialize(FSerializer &arc) override;
|
||||
size_t PropagateMark();
|
||||
|
||||
|
|
|
|||
|
|
@ -2532,8 +2532,10 @@ void FParser::SF_PlayerWeapon()
|
|||
|
||||
IFVM(PlayerPawn, PickNewWeapon)
|
||||
{
|
||||
AActor* weap = nullptr;
|
||||
VMValue param[] = { Level->Players[playernum]->mo, (void*)nullptr };
|
||||
VMCall(func, param, 2, nullptr, 0);
|
||||
VMReturn rets[] = { (void**)&weap };
|
||||
VMCall(func, param, 2, rets, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,31 @@ void DCeiling::Serialize(FSerializer &arc)
|
|||
.Enum("crushmode", m_CrushMode);
|
||||
}
|
||||
|
||||
DEFINE_FIELD(DCeiling, m_Type)
|
||||
DEFINE_FIELD(DCeiling, m_BottomHeight)
|
||||
DEFINE_FIELD(DCeiling, m_TopHeight)
|
||||
DEFINE_FIELD(DCeiling, m_Speed)
|
||||
DEFINE_FIELD(DCeiling, m_Speed1)
|
||||
DEFINE_FIELD(DCeiling, m_Speed2)
|
||||
DEFINE_FIELD(DCeiling, m_Silent)
|
||||
DEFINE_FIELD(DCeiling, m_CrushMode)
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DCeiling, getCrush)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DCeiling);
|
||||
ACTION_RETURN_INT(self->getCrush());
|
||||
}
|
||||
DEFINE_ACTION_FUNCTION(DCeiling, getDirection)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DCeiling);
|
||||
ACTION_RETURN_INT(self->getDirection());
|
||||
}
|
||||
DEFINE_ACTION_FUNCTION(DCeiling, getOldDirection)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DCeiling);
|
||||
ACTION_RETURN_INT(self->getOldDirection());
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
|||
|
|
@ -47,6 +47,14 @@ public:
|
|||
crushSlowdown = 2
|
||||
};
|
||||
|
||||
ECeiling m_Type;
|
||||
double m_BottomHeight;
|
||||
double m_TopHeight;
|
||||
double m_Speed;
|
||||
double m_Speed1; // [RH] dnspeed of crushers
|
||||
double m_Speed2; // [RH] upspeed of crushers
|
||||
ECrushMode m_CrushMode;
|
||||
int m_Silent;
|
||||
|
||||
void Construct(sector_t *sec);
|
||||
void Construct(sector_t *sec, double speed1, double speed2, int silent);
|
||||
|
|
@ -56,17 +64,10 @@ public:
|
|||
|
||||
int getCrush() const { return m_Crush; }
|
||||
int getDirection() const { return m_Direction; }
|
||||
int getOldDirection() const { return m_OldDirection; }
|
||||
|
||||
protected:
|
||||
ECeiling m_Type;
|
||||
double m_BottomHeight;
|
||||
double m_TopHeight;
|
||||
double m_Speed;
|
||||
double m_Speed1; // [RH] dnspeed of crushers
|
||||
double m_Speed2; // [RH] upspeed of crushers
|
||||
int m_Crush;
|
||||
ECrushMode m_CrushMode;
|
||||
int m_Silent;
|
||||
int m_Direction; // 1 = up, 0 = waiting, -1 = down
|
||||
|
||||
// [RH] Need these for BOOM-ish transferring ceilings
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "g_levellocals.h"
|
||||
#include "animations.h"
|
||||
#include "texturemanager.h"
|
||||
#include "vm.h"
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
|
|
@ -64,6 +65,17 @@ void DDoor::Serialize(FSerializer &arc)
|
|||
("lighttag", m_LightTag);
|
||||
}
|
||||
|
||||
DEFINE_FIELD(DDoor, m_Type)
|
||||
DEFINE_FIELD(DDoor, m_TopDist)
|
||||
DEFINE_FIELD(DDoor, m_BotSpot)
|
||||
DEFINE_FIELD(DDoor, m_BotDist)
|
||||
DEFINE_FIELD(DDoor, m_OldFloorDist)
|
||||
DEFINE_FIELD(DDoor, m_Speed)
|
||||
DEFINE_FIELD(DDoor, m_Direction)
|
||||
DEFINE_FIELD(DDoor, m_TopWait)
|
||||
DEFINE_FIELD(DDoor, m_TopCountdown)
|
||||
DEFINE_FIELD(DDoor, m_LightTag)
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// T_VerticalDoor
|
||||
|
|
|
|||
|
|
@ -17,16 +17,10 @@ public:
|
|||
doorWaitClose,
|
||||
};
|
||||
|
||||
void Construct(sector_t *sector);
|
||||
void Construct(sector_t *sec, EVlDoor type, double speed, int delay, int lightTag, int topcountdown);
|
||||
|
||||
void Serialize(FSerializer &arc);
|
||||
void Tick ();
|
||||
protected:
|
||||
EVlDoor m_Type;
|
||||
double m_TopDist;
|
||||
double m_BotDist, m_OldFloorDist;
|
||||
vertex_t *m_BotSpot;
|
||||
vertex_t* m_BotSpot;
|
||||
double m_Speed;
|
||||
|
||||
// 1 = up, 0 = waiting at top, -1 = down
|
||||
|
|
@ -40,6 +34,12 @@ protected:
|
|||
|
||||
int m_LightTag;
|
||||
|
||||
void Construct(sector_t *sector);
|
||||
void Construct(sector_t *sec, EVlDoor type, double speed, int delay, int lightTag, int topcountdown);
|
||||
|
||||
void Serialize(FSerializer &arc);
|
||||
void Tick ();
|
||||
protected:
|
||||
void DoorSound (bool raise, class DSeqNode *curseq=NULL) const;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -96,6 +96,22 @@ void DFloor::Serialize(FSerializer &arc)
|
|||
("instant", m_Instant);
|
||||
}
|
||||
|
||||
DEFINE_FIELD(DFloor, m_Type)
|
||||
DEFINE_FIELD(DFloor, m_Crush)
|
||||
DEFINE_FIELD(DFloor, m_Direction)
|
||||
DEFINE_FIELD(DFloor, m_NewSpecial)
|
||||
DEFINE_FIELD(DFloor, m_Texture)
|
||||
DEFINE_FIELD(DFloor, m_FloorDestDist)
|
||||
DEFINE_FIELD(DFloor, m_Speed)
|
||||
DEFINE_FIELD(DFloor, m_ResetCount)
|
||||
DEFINE_FIELD(DFloor, m_OrgDist)
|
||||
DEFINE_FIELD(DFloor, m_Delay)
|
||||
DEFINE_FIELD(DFloor, m_PauseTime)
|
||||
DEFINE_FIELD(DFloor, m_StepTime)
|
||||
DEFINE_FIELD(DFloor, m_PerStepTime)
|
||||
DEFINE_FIELD(DFloor, m_Hexencrush)
|
||||
DEFINE_FIELD(DFloor, m_Instant)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// MOVE A FLOOR TO ITS DESTINATION (UP OR DOWN)
|
||||
|
|
@ -887,6 +903,12 @@ void DElevator::Serialize(FSerializer &arc)
|
|||
("interp_ceiling", m_Interp_Ceiling);
|
||||
}
|
||||
|
||||
DEFINE_FIELD(DElevator, m_Type)
|
||||
DEFINE_FIELD(DElevator, m_Direction)
|
||||
DEFINE_FIELD(DElevator, m_FloorDestDist)
|
||||
DEFINE_FIELD(DElevator, m_CeilingDestDist)
|
||||
DEFINE_FIELD(DElevator, m_Speed)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
@ -957,7 +979,7 @@ void DElevator::Tick ()
|
|||
}
|
||||
}
|
||||
|
||||
if (res == EMoveResult::pastdest) // if destination height acheived
|
||||
if (res == EMoveResult::pastdest) // if destination height achieved
|
||||
{
|
||||
// make floor stop sound
|
||||
SN_StopSequence (m_Sector, CHAN_FLOOR);
|
||||
|
|
|
|||
|
|
@ -105,6 +105,13 @@ public:
|
|||
elevateLower
|
||||
};
|
||||
|
||||
EElevator m_Type;
|
||||
int m_Direction;
|
||||
double m_FloorDestDist;
|
||||
double m_CeilingDestDist;
|
||||
double m_Speed;
|
||||
|
||||
|
||||
void Construct(sector_t *sec);
|
||||
|
||||
void OnDestroy() override;
|
||||
|
|
@ -112,11 +119,6 @@ public:
|
|||
void Tick ();
|
||||
|
||||
protected:
|
||||
EElevator m_Type;
|
||||
int m_Direction;
|
||||
double m_FloorDestDist;
|
||||
double m_CeilingDestDist;
|
||||
double m_Speed;
|
||||
TObjPtr<DInterpolation*> m_Interp_Ceiling;
|
||||
TObjPtr<DInterpolation*> m_Interp_Floor;
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "serializer.h"
|
||||
#include "p_spec.h"
|
||||
#include "g_levellocals.h"
|
||||
#include "vm.h"
|
||||
|
||||
static FRandom pr_doplat ("DoPlat");
|
||||
|
||||
|
|
@ -62,6 +63,17 @@ void DPlat::Serialize(FSerializer &arc)
|
|||
("tag", m_Tag);
|
||||
}
|
||||
|
||||
DEFINE_FIELD(DPlat, m_Type)
|
||||
DEFINE_FIELD(DPlat, m_Speed)
|
||||
DEFINE_FIELD(DPlat, m_Low)
|
||||
DEFINE_FIELD(DPlat, m_High)
|
||||
DEFINE_FIELD(DPlat, m_Wait)
|
||||
DEFINE_FIELD(DPlat, m_Count)
|
||||
DEFINE_FIELD(DPlat, m_Status)
|
||||
DEFINE_FIELD(DPlat, m_OldStatus)
|
||||
DEFINE_FIELD(DPlat, m_Crush)
|
||||
DEFINE_FIELD(DPlat, m_Tag)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
|
|
|
|||
|
|
@ -38,8 +38,6 @@ public:
|
|||
bool IsLift() const { return m_Type == platDownWaitUpStay || m_Type == platDownWaitUpStayStone; }
|
||||
void Construct(sector_t *sector);
|
||||
|
||||
protected:
|
||||
|
||||
double m_Speed;
|
||||
double m_Low;
|
||||
double m_High;
|
||||
|
|
@ -50,6 +48,7 @@ protected:
|
|||
int m_Crush;
|
||||
int m_Tag;
|
||||
EPlatType m_Type;
|
||||
protected:
|
||||
|
||||
void PlayPlatSound (const char *sound);
|
||||
const char *GetSoundByType () const;
|
||||
|
|
|
|||
|
|
@ -1108,7 +1108,8 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, SpawnVisualThinker, SpawnVisualThink
|
|||
void DVisualThinker::UpdateSpriteInfo()
|
||||
{
|
||||
PT.style = ERenderStyle(GetRenderStyle());
|
||||
if((PT.flags & SPF_LOCAL_ANIM) && PT.texture != AnimatedTexture)
|
||||
|
||||
if ((PT.flags & SPF_LOCAL_ANIM) && PT.texture != AnimatedTexture)
|
||||
{
|
||||
AnimatedTexture = PT.texture;
|
||||
TexAnim.InitStandaloneAnimation(PT.animData, PT.texture, Level->maptime);
|
||||
|
|
@ -1127,6 +1128,10 @@ DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, UpdateSpriteInfo, UpdateSpriteInfo
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool DVisualThinker::ValidTexture()
|
||||
{
|
||||
return ((flags & VTF_IsParticle) || PT.texture.isValid());
|
||||
}
|
||||
|
||||
// This runs just like Actor's, make sure to call Super.Tick() in ZScript.
|
||||
void DVisualThinker::Tick()
|
||||
|
|
@ -1134,10 +1139,8 @@ void DVisualThinker::Tick()
|
|||
if (ObjectFlags & OF_EuthanizeMe)
|
||||
return;
|
||||
|
||||
// There won't be a standard particle for this, it's only for graphics.
|
||||
if (!PT.texture.isValid())
|
||||
if (!ValidTexture())
|
||||
{
|
||||
Printf("No valid texture, destroyed");
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
|
|
@ -1156,7 +1159,6 @@ void DVisualThinker::Tick()
|
|||
PT.Pos.X = newxy.X;
|
||||
PT.Pos.Y = newxy.Y;
|
||||
PT.Pos.Z += PT.Vel.Z;
|
||||
|
||||
subsector_t * ss = Level->PointInRenderSubsector(PT.Pos);
|
||||
|
||||
// Handle crossing a sector portal.
|
||||
|
|
@ -1246,7 +1248,33 @@ DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, SetTranslation, SetTranslation)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int IsFrozen(DVisualThinker * self)
|
||||
int DVisualThinker::GetParticleType() const
|
||||
{
|
||||
int flag = (flags & VTF_IsParticle);
|
||||
switch (flag)
|
||||
{
|
||||
case VTF_ParticleSquare:
|
||||
return PT_SQUARE;
|
||||
case VTF_ParticleRound:
|
||||
return PT_ROUND;
|
||||
case VTF_ParticleSmooth:
|
||||
return PT_SMOOTH;
|
||||
}
|
||||
return PT_DEFAULT;
|
||||
}
|
||||
|
||||
static int GetParticleType(DVisualThinker* self)
|
||||
{
|
||||
return self->GetParticleType();
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, GetParticleType, GetParticleType)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DVisualThinker);
|
||||
ACTION_RETURN_INT(self->GetParticleType());
|
||||
}
|
||||
|
||||
static int IsFrozen(DVisualThinker* self)
|
||||
{
|
||||
return !!(self->Level->isFrozen() && !(self->PT.flags & SPF_NOTIMEFREEZE));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,14 @@ struct FLevelLocals;
|
|||
|
||||
// [RH] Particle details
|
||||
|
||||
enum EParticleStyle
|
||||
{
|
||||
PT_DEFAULT = -1, // Use gl_particles_style
|
||||
PT_SQUARE = 0,
|
||||
PT_ROUND = 1,
|
||||
PT_SMOOTH = 2,
|
||||
};
|
||||
|
||||
enum EParticleFlags
|
||||
{
|
||||
SPF_FULLBRIGHT = 1 << 0,
|
||||
|
|
|
|||
|
|
@ -336,7 +336,10 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf
|
|||
}
|
||||
}
|
||||
|
||||
VMCall(func, params, 1, nullptr, 0);
|
||||
AActor* unused = nullptr;
|
||||
int unused2 = 0, unused3 = 0;
|
||||
VMReturn ret[] = { (void**)&unused, &unused2, &unused3 };
|
||||
VMCall(func, params, 1, ret, 3);
|
||||
|
||||
// Kill the dummy Actor if it didn't unmorph, otherwise checking the morph flags. Player pawns need
|
||||
// to stay, otherwise they won't respawn correctly.
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ enum EPuffFlags
|
|||
};
|
||||
|
||||
AActor *P_SpawnPuff(AActor *source, PClassActor *pufftype, const DVector3 &pos, DAngle hitdir, DAngle particledir, int updown, int flags = 0, AActor *vict = NULL);
|
||||
void P_SpawnBlood (const DVector3 &pos, DAngle angle, int damage, AActor *originator);
|
||||
AActor *P_SpawnBlood (const DVector3 &pos, DAngle angle, int damage, AActor *originator);
|
||||
void P_BloodSplatter (const DVector3 &pos, AActor *originator, DAngle hitangle);
|
||||
void P_BloodSplatter2 (const DVector3 &pos, AActor *originator, DAngle hitangle);
|
||||
void P_RipperBlood (AActor *mo, AActor *bleeder);
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ bool P_CanCrossLine(AActor *mo, line_t *line, DVector3 next)
|
|||
assert(VIndex != ~0u);
|
||||
}
|
||||
|
||||
VMValue params[] = { mo, line, next.X, next.Y, next.Z, false };
|
||||
VMValue params[] = { mo, line, next.X, next.Y, next.Z };
|
||||
VMReturn ret;
|
||||
int retval;
|
||||
ret.IntAt(&retval);
|
||||
|
|
|
|||
|
|
@ -217,7 +217,6 @@ void AActor::Serialize(FSerializer &arc)
|
|||
A("angles", Angles)
|
||||
A("frame", frame)
|
||||
A("scale", Scale)
|
||||
A("nolocalrender", NoLocalRender) // Note: This will probably be removed later since a better solution is needed
|
||||
A("renderstyle", RenderStyle)
|
||||
A("renderflags", renderflags)
|
||||
A("renderflags2", renderflags2)
|
||||
|
|
@ -5751,8 +5750,10 @@ AActor *FLevelLocals::SpawnPlayer (FPlayerStart *mthing, int playernum, int flag
|
|||
|
||||
IFVIRTUALPTRNAME(p->mo, NAME_PlayerPawn, ResetAirSupply)
|
||||
{
|
||||
int drowning = 0;
|
||||
VMValue params[] = { p->mo, false };
|
||||
VMCall(func, params, 2, nullptr, 0);
|
||||
VMReturn rets[] = { &drowning };
|
||||
VMCall(func, params, 2, rets, 1);
|
||||
}
|
||||
|
||||
for (int ii = 0; ii < MAXPLAYERS; ++ii)
|
||||
|
|
@ -5787,7 +5788,7 @@ AActor *FLevelLocals::SpawnPlayer (FPlayerStart *mthing, int playernum, int flag
|
|||
IFVM(PlayerPawn, FilterCoopRespawnInventory)
|
||||
{
|
||||
VMValue params[] = { p->mo, oldactor, ((heldWeap == nullptr || (heldWeap->ObjectFlags & OF_EuthanizeMe)) ? nullptr : heldWeap) };
|
||||
VMCall(func, params, 2, nullptr, 0);
|
||||
VMCall(func, params, 3, nullptr, 0);
|
||||
}
|
||||
}
|
||||
if (oldactor != NULL)
|
||||
|
|
@ -6441,9 +6442,9 @@ DEFINE_ACTION_FUNCTION(AActor, SpawnPuff)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void P_SpawnBlood (const DVector3 &pos1, DAngle dir, int damage, AActor *originator)
|
||||
AActor *P_SpawnBlood (const DVector3 &pos1, DAngle dir, int damage, AActor *originator)
|
||||
{
|
||||
AActor *th;
|
||||
AActor *th = nullptr;
|
||||
PClassActor *bloodcls = originator->GetBloodType();
|
||||
DVector3 pos = pos1;
|
||||
pos.Z += pr_spawnblood.Random2() / 64.;
|
||||
|
|
@ -6528,6 +6529,8 @@ void P_SpawnBlood (const DVector3 &pos1, DAngle dir, int damage, AActor *origina
|
|||
|
||||
if (bloodtype >= 1)
|
||||
P_DrawSplash2 (originator->Level, 40, pos, dir, 2, originator->BloodColor);
|
||||
|
||||
return th;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, SpawnBlood)
|
||||
|
|
@ -6538,8 +6541,7 @@ DEFINE_ACTION_FUNCTION(AActor, SpawnBlood)
|
|||
PARAM_FLOAT(z);
|
||||
PARAM_ANGLE(dir);
|
||||
PARAM_INT(damage);
|
||||
P_SpawnBlood(DVector3(x, y, z), dir, damage, self);
|
||||
return 0;
|
||||
ACTION_RETURN_OBJECT(P_SpawnBlood(DVector3(x, y, z), dir, damage, self));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ bool P_Teleport (AActor *thing, DVector3 pos, DAngle angle, int flags)
|
|||
IFVIRTUALPTR(thing, AActor, PostTeleport)
|
||||
{
|
||||
VMValue params[] = { thing, pos.X, pos.Y, pos.Z, angle.Degrees(), flags };
|
||||
VMCall(func, params, countof(params), nullptr, 1);
|
||||
VMCall(func, params, countof(params), nullptr, 0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,12 @@ enum EVisualThinkerFlags
|
|||
VTF_FlipY = 1 << 3, // flip the sprite on the x/y axis.
|
||||
VTF_DontInterpolate = 1 << 4, // disable all interpolation
|
||||
VTF_AddLightLevel = 1 << 5, // adds sector light level to 'LightLevel'
|
||||
|
||||
VTF_ParticleDefault = 0x40,
|
||||
VTF_ParticleSquare = 0x80,
|
||||
VTF_ParticleRound = 0xC0,
|
||||
VTF_ParticleSmooth = 0x100,
|
||||
VTF_IsParticle = 0x1C0, // Renders as a particle instead
|
||||
};
|
||||
|
||||
class DVisualThinker : public DThinker
|
||||
|
|
@ -54,6 +60,8 @@ public:
|
|||
void SetTranslation(FName trname);
|
||||
int GetRenderStyle() const;
|
||||
bool isFrozen();
|
||||
bool ValidTexture();
|
||||
int GetParticleType() const;
|
||||
int GetLightLevel(sector_t *rendersector) const;
|
||||
FVector3 InterpolatedPosition(double ticFrac) const;
|
||||
float InterpolatedRoll(double ticFrac) const;
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ void AddLightToList(FDynLightData &dld, int group, FDynamicLight * light, bool f
|
|||
cs = 1.0f;
|
||||
}
|
||||
|
||||
if (light->target)
|
||||
if (light->target && (light->target->renderflags2 & RF2_LIGHTMULTALPHA))
|
||||
cs *= (float)light->target->Alpha;
|
||||
|
||||
info.r = light->GetRed() / 255.0f * cs;
|
||||
|
|
|
|||
|
|
@ -288,19 +288,25 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip, FRenderState& state)
|
|||
angle_t startAngle = clipper.GetClipAngle(seg->v2);
|
||||
angle_t endAngle = clipper.GetClipAngle(seg->v1);
|
||||
auto &clipperr = *rClipper;
|
||||
angle_t startAngleR = clipperr.PointToPseudoAngle(seg->v2->fX(), seg->v2->fY());
|
||||
angle_t endAngleR = clipperr.PointToPseudoAngle(seg->v1->fX(), seg->v1->fY());
|
||||
angle_t startAngleR = 0;
|
||||
angle_t endAngleR = 0;
|
||||
angle_t paddingR = 0x00200000; // Make radar clipping more aggressive (reveal less)
|
||||
|
||||
if(Viewpoint.IsAllowedOoB() && r_radarclipper && !(Level->flags3 & LEVEL3_NOFOGOFWAR) && (startAngleR - endAngleR >= ANGLE_180))
|
||||
if(Viewpoint.IsAllowedOoB() && r_radarclipper && !(Level->flags3 & LEVEL3_NOFOGOFWAR))
|
||||
{
|
||||
if (!seg->backsector) clipperr.SafeAddClipRange(startAngleR - paddingR, endAngleR + paddingR);
|
||||
else if((seg->sidedef != nullptr) && !uint8_t(seg->sidedef->Flags & WALLF_POLYOBJ) && (currentsector->sectornum != seg->backsector->sectornum))
|
||||
startAngleR = clipperr.PointToPseudoAngle(seg->v2->fX(), seg->v2->fY());
|
||||
endAngleR = clipperr.PointToPseudoAngle(seg->v1->fX(), seg->v1->fY());
|
||||
|
||||
if (startAngleR - endAngleR >= ANGLE_180)
|
||||
{
|
||||
if (in_area == area_default) in_area = hw_CheckViewArea(seg->v1, seg->v2, seg->frontsector, seg->backsector);
|
||||
backsector = hw_FakeFlat(drawctx, seg->backsector, in_area, true);
|
||||
if (hw_CheckClip(seg->sidedef, currentsector, backsector)) clipperr.SafeAddClipRange(startAngleR - paddingR, endAngleR + paddingR);
|
||||
backsector = nullptr;
|
||||
if (!seg->backsector) clipperr.SafeAddClipRange(startAngleR - paddingR, endAngleR + paddingR);
|
||||
else if((seg->sidedef != nullptr) && !uint8_t(seg->sidedef->Flags & WALLF_POLYOBJ) && (currentsector->sectornum != seg->backsector->sectornum))
|
||||
{
|
||||
if (in_area == area_default) in_area = hw_CheckViewArea(seg->v1, seg->v2, seg->frontsector, seg->backsector);
|
||||
backsector = hw_FakeFlat(drawctx, seg->backsector, in_area, true);
|
||||
if (hw_CheckClip(seg->sidedef, currentsector, backsector)) clipperr.SafeAddClipRange(startAngleR - paddingR, endAngleR + paddingR);
|
||||
backsector = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -711,7 +717,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub, FRenderState& state)
|
|||
if(Viewpoint.IsAllowedOoB() && sector->isSecret() && sector->wasSecret() && !r_radarclipper) return;
|
||||
|
||||
// cull everything if subsector outside all relevant clippers
|
||||
if ((sub->polys == nullptr))
|
||||
if (Viewpoint.IsAllowedOoB() && (sub->polys == nullptr))
|
||||
{
|
||||
auto &clipper = *mClipper;
|
||||
auto &clipperv = *vClipper;
|
||||
|
|
|
|||
|
|
@ -224,8 +224,8 @@ void HWDrawInfo::ClearBuffers()
|
|||
void HWDrawInfo::UpdateCurrentMapSection()
|
||||
{
|
||||
int mapsection = Level->PointInRenderSubsector(Viewpoint.Pos)->mapsection;
|
||||
if (Viewpoint.IsAllowedOoB())
|
||||
mapsection = Level->PointInRenderSubsector(Viewpoint.camera->Pos())->mapsection;
|
||||
if (Viewpoint.IsAllowedOoB() || Viewpoint.IsOrtho())
|
||||
mapsection = Level->PointInRenderSubsector(Viewpoint.OffPos)->mapsection;
|
||||
CurrentMapSections.Set(mapsection);
|
||||
}
|
||||
|
||||
|
|
@ -319,20 +319,19 @@ int HWDrawInfo::SetFullbrightFlags(player_t *player)
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
angle_t HWDrawInfo::FrustumAngle()
|
||||
angle_t OoBFrustumAngle(FRenderViewpoint* Viewpoint)
|
||||
{
|
||||
// If pitch is larger than this you can look all around at an FOV of 90 degrees
|
||||
if (fabs(Viewpoint.HWAngles.Pitch.Degrees()) > 89.0) return 0xffffffff;
|
||||
else if (fabs(Viewpoint.HWAngles.Pitch.Degrees()) > 46.0 && !Viewpoint.IsAllowedOoB()) return 0xffffffff; // Just like 4.12.2 and older did
|
||||
if (fabs(Viewpoint->HWAngles.Pitch.Degrees()) > 89.0) return 0xffffffff;
|
||||
int aspMult = AspectMultiplier(r_viewwindow.WidescreenRatio); // 48 == square window
|
||||
double absPitch = fabs(Viewpoint.HWAngles.Pitch.Degrees());
|
||||
double absPitch = fabs(Viewpoint->HWAngles.Pitch.Degrees());
|
||||
// Smaller aspect ratios still clip too much. Need a better solution
|
||||
if (aspMult > 36 && absPitch > 30.0) return 0xffffffff;
|
||||
else if (aspMult > 40 && absPitch > 25.0) return 0xffffffff;
|
||||
else if (aspMult > 45 && absPitch > 20.0) return 0xffffffff;
|
||||
else if (aspMult > 47 && absPitch > 10.0) return 0xffffffff;
|
||||
|
||||
double xratio = r_viewwindow.FocalTangent / Viewpoint.PitchCos;
|
||||
double xratio = r_viewwindow.FocalTangent / Viewpoint->PitchCos;
|
||||
double floatangle = 0.05 + atan ( xratio ) * 48.0 / aspMult; // this is radians
|
||||
angle_t a1 = DAngle::fromRad(floatangle).BAMs();
|
||||
|
||||
|
|
@ -340,6 +339,28 @@ angle_t HWDrawInfo::FrustumAngle()
|
|||
return a1;
|
||||
}
|
||||
|
||||
angle_t HWDrawInfo::FrustumAngle()
|
||||
{
|
||||
if (Viewpoint.IsAllowedOoB())
|
||||
{
|
||||
return OoBFrustumAngle(&Viewpoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
float tilt = fabs(Viewpoint.HWAngles.Pitch.Degrees());
|
||||
|
||||
// If the pitch is larger than this you can look all around at a FOV of 90°
|
||||
if (tilt > 46.0f) return 0xffffffff;
|
||||
|
||||
// ok, this is a gross hack that barely works...
|
||||
// but at least it doesn't overestimate too much...
|
||||
double floatangle = 2.0 + (45.0 + ((tilt / 1.9)))*Viewpoint.FieldOfView.Degrees() * 48.0 / AspectMultiplier(r_viewwindow.WidescreenRatio) / 90.0;
|
||||
angle_t a1 = DAngle::fromDeg(floatangle).BAMs();
|
||||
if (a1 >= ANGLE_180) return 0xffffffff;
|
||||
return a1;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Setup the modelview matrix
|
||||
|
|
@ -425,7 +446,9 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state)
|
|||
{
|
||||
double a2 = 20.0 + 0.5*Viewpoint.FieldOfView.Degrees(); // FrustumPitch for vertical clipping
|
||||
if (a2 > 179.0) a2 = 179.0;
|
||||
vClipper->SafeAddClipRangeDegPitches(vp.HWAngles.Pitch.Degrees() - a2, vp.HWAngles.Pitch.Degrees() + a2); // clip the suplex range
|
||||
double pitchmult = !!(portalState.PlaneMirrorFlag & 1) ? -1.0 : 1.0;
|
||||
vClipper->SafeAddClipRangeDegPitches(pitchmult * vp.HWAngles.Pitch.Degrees() - a2, pitchmult * vp.HWAngles.Pitch.Degrees() + a2); // clip the suplex range
|
||||
Viewpoint.PitchSin *= pitchmult;
|
||||
}
|
||||
|
||||
// reset the portal manager
|
||||
|
|
@ -1292,8 +1315,8 @@ void HWDrawInfo::ProcessScene(bool toscreen, FRenderState& state)
|
|||
drawctx->portalState.BeginScene();
|
||||
|
||||
int mapsection = Level->PointInRenderSubsector(Viewpoint.Pos)->mapsection;
|
||||
if (Viewpoint.IsAllowedOoB())
|
||||
mapsection = Level->PointInRenderSubsector(Viewpoint.camera->Pos())->mapsection;
|
||||
if (Viewpoint.IsAllowedOoB() || Viewpoint.IsOrtho())
|
||||
mapsection = Level->PointInRenderSubsector(Viewpoint.OffPos)->mapsection;
|
||||
CurrentMapSections.Set(mapsection);
|
||||
DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN, state);
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include "hw_renderstate.h"
|
||||
#include "texturemanager.h"
|
||||
#include "hw_flatdispatcher.h"
|
||||
#include "hw_viewpointbuffer.h"
|
||||
|
||||
EXTERN_CVAR(Bool, lm_dynlights);
|
||||
|
||||
|
|
|
|||
|
|
@ -332,6 +332,7 @@ void HWPortal::RemoveStencil(HWDrawInfo *di, FRenderState &state, bool usestenci
|
|||
bool needdepth = NeedDepthBuffer();
|
||||
|
||||
// Restore the old view
|
||||
|
||||
auto &vp = di->Viewpoint;
|
||||
if (vp.camera != nullptr) vp.camera->renderflags = (vp.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility;
|
||||
|
||||
|
|
|
|||
|
|
@ -165,7 +165,6 @@ void HWWall::SkyPlane(HWWallDispatcher *di, FRenderState& state, sector_t *secto
|
|||
if (glport != NULL)
|
||||
{
|
||||
if (sector->PortalBlocksView(plane)) return;
|
||||
|
||||
if (di->di && screen->instack[1 - plane]) return;
|
||||
ptype = PORTALTYPE_SECTORSTACK;
|
||||
portal = glport;
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, sun_trace_cache_t * traceCache,
|
|||
lg = light->GetGreen() / 255.0f;
|
||||
lb = light->GetBlue() / 255.0f;
|
||||
|
||||
if (light->target)
|
||||
if (light->target && (light->target->renderflags2 & RF2_LIGHTMULTALPHA))
|
||||
{
|
||||
float alpha = (float)light->target->Alpha;
|
||||
lr *= alpha;
|
||||
|
|
|
|||
|
|
@ -1494,7 +1494,7 @@ void HWSprite::ProcessParticle(HWDrawInfo *di, FRenderState& state, particle_t *
|
|||
if (!particle || particle->alpha <= 0)
|
||||
return;
|
||||
|
||||
if (spr && spr->PT.texture.isNull())
|
||||
if (spr && !spr->ValidTexture())
|
||||
return;
|
||||
|
||||
lightlevel = hw_ClampLight(spr ? spr->GetLightLevel(sector) : sector->GetSpriteLight());
|
||||
|
|
@ -1563,17 +1563,29 @@ void HWSprite::ProcessParticle(HWDrawInfo *di, FRenderState& state, particle_t *
|
|||
if (paused || (di->Level->isFrozen() && !(particle->flags & SPF_NOTIMEFREEZE)))
|
||||
timefrac = 0.;
|
||||
|
||||
if (spr)
|
||||
|
||||
if (spr && !(spr->flags & VTF_IsParticle))
|
||||
{
|
||||
AdjustVisualThinker(di, spr, sector);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool has_texture = particle->texture.isValid();
|
||||
bool custom_animated_texture = (particle->flags & SPF_LOCAL_ANIM) && particle->animData.ok;
|
||||
|
||||
int particle_style = has_texture ? 2 : gl_particles_style; // Treat custom texture the same as smooth particles
|
||||
|
||||
bool has_texture = false;
|
||||
bool custom_animated_texture = false;
|
||||
int particle_style = 0;
|
||||
float size = particle->size;
|
||||
if (!spr)
|
||||
{
|
||||
has_texture = particle->texture.isValid();
|
||||
custom_animated_texture = (particle->flags & SPF_LOCAL_ANIM) && particle->animData.ok;
|
||||
particle_style = has_texture ? 2 : gl_particles_style; // Treat custom texture the same as smooth particles
|
||||
}
|
||||
else
|
||||
{
|
||||
size = float(spr->Scale.X);
|
||||
const int ptype = spr->GetParticleType();
|
||||
particle_style = (ptype != PT_DEFAULT) ? ptype : gl_particles_style;
|
||||
}
|
||||
// [BB] Load the texture for round or smooth particles
|
||||
if (particle_style)
|
||||
{
|
||||
|
|
@ -1635,7 +1647,7 @@ void HWSprite::ProcessParticle(HWDrawInfo *di, FRenderState& state, particle_t *
|
|||
if (particle_style == 1) factor = 1.3f / 7.f;
|
||||
else if (particle_style == 2) factor = 2.5f / 7.f;
|
||||
else factor = 1 / 7.f;
|
||||
float scalefac=particle->size * factor;
|
||||
float scalefac= size * factor;
|
||||
|
||||
float ps = di->Level->pixelstretch;
|
||||
|
||||
|
|
|
|||
|
|
@ -389,6 +389,7 @@ static FFlagDef ActorFlagDefs[]=
|
|||
DEFINE_FLAG(RF2, ISOMETRICSPRITES, AActor, renderflags2),
|
||||
DEFINE_FLAG(RF2, SQUAREPIXELS, AActor, renderflags2),
|
||||
DEFINE_FLAG(RF2, STRETCHPIXELS, AActor, renderflags2),
|
||||
DEFINE_FLAG(RF2, LIGHTMULTALPHA, AActor, renderflags2),
|
||||
|
||||
// Bounce flags
|
||||
DEFINE_FLAG2(BOUNCE_Walls, BOUNCEONWALLS, AActor, BounceFlags),
|
||||
|
|
|
|||
|
|
@ -2269,6 +2269,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, GetSpotState, GetSpotState)
|
|||
//---------------------------------------------------------------------------
|
||||
|
||||
EXTERN_CVAR(Int, am_showmaplabel)
|
||||
EXTERN_CVAR(Bool, am_showlevelname)
|
||||
|
||||
void FormatMapName(FLevelLocals *self, int cr, FString *result)
|
||||
{
|
||||
|
|
@ -2282,13 +2283,19 @@ void FormatMapName(FLevelLocals *self, int cr, FString *result)
|
|||
if (self->info->MapLabel.IsNotEmpty())
|
||||
{
|
||||
if (self->info->MapLabel.Compare("*"))
|
||||
*result << self->info->MapLabel << ": ";
|
||||
*result << self->info->MapLabel;
|
||||
}
|
||||
else if (am_showmaplabel == 1 || (am_showmaplabel == 2 && !ishub))
|
||||
{
|
||||
*result << self->MapName << ": ";
|
||||
*result << self->MapName;
|
||||
}
|
||||
|
||||
if (am_showlevelname)
|
||||
{
|
||||
if (!result->IsEmpty())
|
||||
*result << ": ";
|
||||
*result << mapnamecolor << self->LevelName;
|
||||
}
|
||||
*result << mapnamecolor << self->LevelName;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, FormatMapName, FormatMapName)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue