Added client-side Thinkers
Adds support for client-side Thinkers, Actors, and ACS scripts (ACS uses the existing CLIENTSIDE keyword). These will tick regardless of the network state allowing for localized client handling and are put in their own separate lists so they can't be accidentally accessed by server code. They currently aren't serialized since this would have no meaning for other clients in the game that would get saved. Other logic like the menu, console, HUD, and particles have also been moved to client-side ticking to prevent them from becoming locked up by poor network conditions. Additionally, screenshotting and the automap are now handled immediately instead of having to wait for any game tick to run first, making them free of net lag.
This commit is contained in:
parent
e4081df0db
commit
f7e62a8cd6
28 changed files with 507 additions and 215 deletions
|
|
@ -75,6 +75,7 @@ extern float BackbuttonAlpha;
|
|||
#define DEFINE_FLAG(prefix, name, type, variable) { (unsigned int)prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native }
|
||||
#define DEFINE_PROTECTED_FLAG(prefix, name, type, variable) { (unsigned int)prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native|VARF_ReadOnly|VARF_InternalAccess }
|
||||
#define DEFINE_FLAG2(symbol, name, type, variable) { (unsigned int)symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native }
|
||||
#define DEFINE_PROTECTED_FLAG2(symbol, name, type, variable) { (unsigned int)symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native|VARF_ReadOnly|VARF_InternalAccess }
|
||||
#define DEFINE_FLAG2_DEPRECATED(symbol, name, type, variable, version) { (unsigned int)symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable), VARF_Native|VARF_Deprecated }
|
||||
#define DEFINE_DEPRECATED_FLAG(name, version) { DEPF_##name, #name, -1, 0, VARF_Deprecated, version }
|
||||
#define DEFINE_DUMMY_FLAG(name, deprec) { DEPF_UNUSED, #name, -1, 0, deprec? VARF_Deprecated:0 }
|
||||
|
|
@ -412,6 +413,7 @@ static FFlagDef ActorFlagDefs[]=
|
|||
DEFINE_FLAG2(BOUNCE_ModifyPitch, BOUNCEMODIFIESPITCH, AActor, BounceFlags),
|
||||
|
||||
DEFINE_FLAG2(OF_Transient, NOSAVEGAME, AActor, ObjectFlags),
|
||||
DEFINE_PROTECTED_FLAG2(OF_ClientSide, CLIENTSIDE, AActor, ObjectFlags),
|
||||
|
||||
// Deprecated flags which need a ZScript workaround.
|
||||
DEFINE_DEPRECATED_FLAG(MISSILEMORE, MakeVersion(4, 13, 0)),
|
||||
|
|
@ -463,7 +465,6 @@ static FFlagDef MoreFlagDefs[] =
|
|||
// [BB] New DECORATE network related flag defines here.
|
||||
DEFINE_DUMMY_FLAG(NONETID, false),
|
||||
DEFINE_DUMMY_FLAG(ALLOWCLIENTSPAWN, false),
|
||||
DEFINE_DUMMY_FLAG(CLIENTSIDEONLY, false),
|
||||
DEFINE_DUMMY_FLAG(SERVERSIDEONLY, false),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ class DThinkerIterator : public DObject, public FThinkerIterator
|
|||
DECLARE_ABSTRACT_CLASS(DThinkerIterator, DObject)
|
||||
|
||||
public:
|
||||
DThinkerIterator(FLevelLocals *Level, PClass *cls, int statnum = MAX_STATNUM + 1)
|
||||
: FThinkerIterator(Level, cls, statnum)
|
||||
DThinkerIterator(FLevelLocals *Level, PClass *cls, int statnum = MAX_STATNUM + 1, bool clientside = false)
|
||||
: FThinkerIterator(Level, cls, statnum, clientside)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
@ -62,6 +62,19 @@ DEFINE_ACTION_FUNCTION_NATIVE(DThinkerIterator, Create, CreateThinkerIterator)
|
|||
ACTION_RETURN_OBJECT(CreateThinkerIterator(type, statnum));
|
||||
}
|
||||
|
||||
static DThinkerIterator* CreateClientsideThinkerIterator(PClass* type, int statnum)
|
||||
{
|
||||
return Create<DThinkerIterator>(currentVMLevel, type, statnum, true);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(DThinkerIterator, CreateClientside, CreateClientsideThinkerIterator)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_CLASS(type, DThinker);
|
||||
PARAM_INT(statnum);
|
||||
ACTION_RETURN_OBJECT(CreateClientsideThinkerIterator(type, statnum));
|
||||
}
|
||||
|
||||
static DThinker *NextThinker(DThinkerIterator *self, bool exact)
|
||||
{
|
||||
return self->Next(exact);
|
||||
|
|
@ -365,6 +378,19 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, CreateActorIterator, CreateActI)
|
|||
ACTION_RETURN_OBJECT(CreateActI(self, tid, type));
|
||||
}
|
||||
|
||||
static DActorIterator* CreateClientSideActI(FLevelLocals* Level, int tid, PClassActor* type)
|
||||
{
|
||||
return Create<DActorIterator>(Level->ClientSideTIDHash, type, tid);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, CreateClientSideActorIterator, CreateClientSideActI)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
PARAM_INT(tid);
|
||||
PARAM_CLASS(type, AActor);
|
||||
ACTION_RETURN_OBJECT(CreateClientSideActI(self, tid, type));
|
||||
}
|
||||
|
||||
static AActor *NextActI(DActorIterator *self)
|
||||
{
|
||||
return self->Next();
|
||||
|
|
|
|||
|
|
@ -2615,6 +2615,26 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, setFrozen, setFrozen)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static DThinker* CreateClientsideThinker(FLevelLocals* self, PClass* type, int statnum)
|
||||
{
|
||||
if (type->IsDescendantOf(NAME_Actor))
|
||||
{
|
||||
ThrowAbortException(X_OTHER, "Clientside Actors cannot be created from this function");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return self->CreateClientsideThinker(type, statnum);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, CreateClientsideThinker, CreateClientsideThinker)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
PARAM_POINTER_NOT_NULL(type, PClass);
|
||||
PARAM_INT(statnum);
|
||||
|
||||
ACTION_RETURN_OBJECT(CreateClientsideThinker(self, type, statnum));
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
|||
|
|
@ -999,9 +999,9 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, GetFloorTerrain, GetFloorTerrain)
|
|||
ACTION_RETURN_POINTER(GetFloorTerrain(self));
|
||||
}
|
||||
|
||||
static int P_FindUniqueTID(FLevelLocals *Level, int start, int limit)
|
||||
static int P_FindUniqueTID(FLevelLocals *Level, int start, int limit, bool clientside)
|
||||
{
|
||||
return Level->FindUniqueTID(start, limit);
|
||||
return Level->FindUniqueTID(start, limit, clientside);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, FindUniqueTid, P_FindUniqueTID)
|
||||
|
|
@ -1009,7 +1009,8 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, FindUniqueTid, P_FindUniqueTID)
|
|||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
PARAM_INT(start);
|
||||
PARAM_INT(limit);
|
||||
ACTION_RETURN_INT(P_FindUniqueTID(self, start, limit));
|
||||
PARAM_BOOL(clientside);
|
||||
ACTION_RETURN_INT(P_FindUniqueTID(self, start, limit, clientside));
|
||||
}
|
||||
|
||||
static void RemoveFromHash(AActor *self)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue