diff --git a/sources/ClientRealm/API/Unreal/ClientUnrealAPI.uc b/sources/ClientRealm/API/Unreal/ClientUnrealAPI.uc
new file mode 100644
index 0000000..beee114
--- /dev/null
+++ b/sources/ClientRealm/API/Unreal/ClientUnrealAPI.uc
@@ -0,0 +1,137 @@
+/**
+ * Acedia's default implementation for `ClientUnrealAPIBase`.
+ * Copyright 2021-2022 Anton Tarasenko
+ *------------------------------------------------------------------------------
+ * This file is part of Acedia.
+ *
+ * Acedia is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Acedia is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Acedia. If not, see .
+ */
+class ClientUnrealAPI extends ClientUnrealAPIBase;
+
+var private LoggerAPI.Definition fatalNoStalker;
+
+protected function Constructor()
+{
+ _.environment.OnShutDownSystem(self).connect = HandleShutdown;
+}
+
+protected function HandleShutdown()
+{
+ local ServerUnrealService service;
+
+ service = ServerUnrealService(
+ class'ServerUnrealService'.static.GetInstance());
+ // This has to clean up anything we've added
+ if (service != none) {
+ service.Destroy();
+ }
+}
+
+/* SIGNAL */
+public function Unreal_OnTick_Slot OnTick(
+ AcediaObject receiver)
+{
+ local Signal signal;
+ local ServerUnrealService service;
+
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
+ signal = service.GetSignal(class'Unreal_OnTick_Signal');
+ return Unreal_OnTick_Slot(signal.NewSlot(receiver));
+}
+
+/* SIGNAL */
+public function SimpleSlot OnDestructionFor(
+ AcediaObject receiver,
+ Actor targetToStalk)
+{
+ local ActorStalker stalker;
+
+ if (receiver == none) return none;
+ if (targetToStalk == none) return none;
+
+ // Failing to spawn this actor without any collision flags is considered
+ // completely unexpected and grounds for fatal failure on Acedia' part
+ stalker = ActorStalker(class'ClientLevelCore'.static
+ .GetInstance()
+ .Allocate(class'ActorStalker'));
+ if (stalker == none)
+ {
+ _.logger.Auto(fatalNoStalker);
+ return none;
+ }
+ // This will not fail, since we have already ensured that
+ // `targetToStalk == none`
+ stalker.Initialize(targetToStalk);
+ return stalker.OnActorDestruction(receiver);
+}
+
+public function LevelInfo GetLevel()
+{
+ return class'ClientLevelCore'.static.GetInstance().level;
+}
+
+public function GameReplicationInfo GetGameRI()
+{
+ return class'ClientLevelCore'.static.GetInstance().level.GRI;
+}
+
+public function KFGameReplicationInfo GetKFGameRI()
+{
+ return KFGameReplicationInfo(GetGameRI());
+}
+
+public function GameInfo GetGameType()
+{
+ return class'ClientLevelCore'.static.GetInstance().level.game;
+}
+
+public function KFGameType GetKFGameType()
+{
+ return KFGameType(GetGameType());
+}
+
+public function Actor FindActorInstance(class classToFind)
+{
+ local Actor result;
+ local LevelCore core;
+
+ core = class'ClientLevelCore'.static.GetInstance();
+ foreach core.AllActors(classToFind, result)
+ {
+ if (result != none) {
+ break;
+ }
+ }
+ return result;
+}
+
+public function PlayerController GetLocalPlayer()
+{
+ return class'ClientLevelCore'.static.GetInstance().level
+ .GetLocalPlayerController();
+}
+
+public function NativeActorRef ActorRef(optional Actor value)
+{
+ local NativeActorRef ref;
+
+ ref = NativeActorRef(_.memory.Allocate(class'NativeActorRef'));
+ ref.Set(value);
+ return ref;
+}
+
+defaultproperties
+{
+ fatalNoStalker = (l=LOG_Fatal,m="Cannot spawn `PawnStalker`")
+}
\ No newline at end of file
diff --git a/sources/ClientRealm/API/Unreal/ClientUnrealAPIBase.uc b/sources/ClientRealm/API/Unreal/ClientUnrealAPIBase.uc
new file mode 100644
index 0000000..1470307
--- /dev/null
+++ b/sources/ClientRealm/API/Unreal/ClientUnrealAPIBase.uc
@@ -0,0 +1,35 @@
+/**
+ * Low-level API that provides set of utility methods for working with
+ * unreal script classes on the clients.
+ * Copyright 2022 Anton Tarasenko
+ *------------------------------------------------------------------------------
+ * This file is part of Acedia.
+ *
+ * Acedia is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Acedia is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Acedia. If not, see .
+ */
+class ClientUnrealAPIBase extends UnrealAPIBase
+ abstract;
+
+/**
+ * Returns current local player's `Controller`. Useful because `level`
+ * is not accessible inside objects.
+ *
+ * @return `PlayerController` instance for the local player. `none` iff run on
+ * dedicated servers.
+ */
+public function PlayerController GetLocalPlayer();
+
+defaultproperties
+{
+}
\ No newline at end of file
diff --git a/sources/ClientRealm/ClientAcediaAdapter.uc b/sources/ClientRealm/ClientAcediaAdapter.uc
new file mode 100644
index 0000000..22a17ed
--- /dev/null
+++ b/sources/ClientRealm/ClientAcediaAdapter.uc
@@ -0,0 +1,30 @@
+/**
+ * Base class for objects that will provide an access to a Acedia's client- and
+ * server-specific functionality by giving a reference to this object to all
+ * Acedia's objects and actors, emulating a global API namespace.
+ * Copyright 2022 Anton Tarasenko
+ *------------------------------------------------------------------------------
+ * This file is part of Acedia.
+ *
+ * Acedia is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Acedia is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Acedia. If not, see .
+ */
+class ClientAcediaAdapter extends AcediaAdapter
+ abstract;
+
+var public const class clientUnrealAPIClass;
+
+defaultproperties
+{
+ clientUnrealAPIClass = class'ClientUnrealAPI'
+}
\ No newline at end of file
diff --git a/sources/ClientRealm/ClientGlobal.uc b/sources/ClientRealm/ClientGlobal.uc
index c5e57e3..2432701 100644
--- a/sources/ClientRealm/ClientGlobal.uc
+++ b/sources/ClientRealm/ClientGlobal.uc
@@ -25,6 +25,10 @@ class ClientGlobal extends CoreGlobal;
// main instance in this variable's default value.
var protected ClientGlobal myself;
+var public ClientUnrealAPIBase unreal;
+
+var private LoggerAPI.Definition fatBadAdapterClass;
+
public final static function ClientGlobal GetInstance()
{
if (default.myself == none)
@@ -38,13 +42,41 @@ public final static function ClientGlobal GetInstance()
protected function Initialize()
{
+ local Global _;
+ local class clientAdapterClass;
+
if (initialized) {
return;
}
super.Initialize();
initialized = true;
+ clientAdapterClass = class(adapterClass);
+ if (adapterClass != none && clientAdapterClass == none)
+ {
+ class'Global'.static.GetInstance().logger
+ .Auto(fatBadAdapterClass)
+ .ArgClass(self.class);
+ return;
+ }
+ if (clientAdapterClass == none) {
+ return;
+ }
+ _ = class'Global'.static.GetInstance();
+ unreal = ClientUnrealAPIBase(
+ _.memory.Allocate(clientAdapterClass.default.clientUnrealAPIClass));
+}
+
+public final function bool ConnectClientLevelCore()
+{
+ if (class'ClientLevelCore'.static.GetInstance() == none) {
+ return false;
+ }
+ Initialize();
+ return true;
}
defaultproperties
{
+ adapterClass = class'ClientAcediaAdapter'
+ fatBadAdapterClass = (l=LOG_Fatal,m="non-`ClientAcediaAdapter` class was specified as an adapter for `%1` level core class. This should not have happened. AcediaCore cannot properly function.")
}
\ No newline at end of file
diff --git a/sources/ClientLevelCore.uc b/sources/ClientRealm/ClientLevelCore.uc
similarity index 79%
rename from sources/ClientLevelCore.uc
rename to sources/ClientRealm/ClientLevelCore.uc
index 79d1fc4..850624a 100644
--- a/sources/ClientLevelCore.uc
+++ b/sources/ClientRealm/ClientLevelCore.uc
@@ -18,12 +18,18 @@
*/
class ClientLevelCore extends LevelCore;
-public static function LevelCore CreateLevelCore(Actor source)
+public simulated static function LevelCore CreateLevelCore(Actor source)
{
+ local LevelCore newCore;
+
if (source == none) return none;
if (source.level.netMode == NM_DedicatedServer) return none;
- return super.CreateLevelCore(source);
+ newCore = super.CreateLevelCore(source);
+ if (newCore != none) {
+ __client().ConnectClientLevelCore();
+ }
+ return newCore;
}
defaultproperties
diff --git a/sources/Types/ActorService.uc b/sources/CoreRealm/API/UnrealAPI/ActorService.uc
similarity index 100%
rename from sources/Types/ActorService.uc
rename to sources/CoreRealm/API/UnrealAPI/ActorService.uc
diff --git a/sources/CoreRealm/API/UnrealAPI/UnrealAPIBase.uc b/sources/CoreRealm/API/UnrealAPI/UnrealAPIBase.uc
new file mode 100644
index 0000000..a62b8db
--- /dev/null
+++ b/sources/CoreRealm/API/UnrealAPI/UnrealAPIBase.uc
@@ -0,0 +1,133 @@
+/**
+ * Low-level API that provides set of utility methods for working with
+ * unreal script classes.
+ * Copyright 2021-2022 Anton Tarasenko
+ *------------------------------------------------------------------------------
+ * This file is part of Acedia.
+ *
+ * Acedia is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Acedia is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Acedia. If not, see .
+ */
+class UnrealAPIBase extends AcediaObject
+ abstract;
+
+/**
+ * Signal that will be emitted every tick.
+ *
+ * [Signature]
+ * void (float delta, float dilationCoefficient)
+ *
+ * @param delta In-game time in seconds that has passed since
+ * the last tick. To obtain real time passed from the last tick divide
+ * `delta` by `dilationCoefficient`.
+ * @param dilationCoefficient How fast is in-game time flow compared to
+ * the real world's one? `2` means twice as fast and
+ * `0.5` means twice as slow.
+ */
+/* SIGNAL */
+public function Unreal_OnTick_Slot OnTick(AcediaObject receiver);
+
+/**
+ * Signal that will be emitted when a passed `targetToStalk` is destroyed.
+ *
+ * Passed parameter `targetToStalk` cannot be `none`, otherwise `none` will be
+ * returned instead of a valid slot.
+ *
+ * @param receiver Specify a receiver like for any other signal.
+ * @param targetToStalk Actor whose destruction we want to detect.
+ *
+ * [Signature]
+ * void ()
+ */
+/* SIGNAL */
+public function SimpleSlot OnDestructionFor(
+ AcediaObject receiver,
+ Actor targetToStalk);
+
+/**
+ * Returns current game's `LevelInfo`. Useful because `level` variable
+ * is not defined inside objects.
+ *
+ * @return `LevelInfo` instance for the current game. Guaranteed to
+ * not be `none`.
+ */
+public function LevelInfo GetLevel();
+
+/**
+ * Returns current game's `GameReplicationInfo`. Useful because `level.game`
+ * is not accessible inside objects.
+ *
+ * @return `GameReplicationInfo` instance for the current game. Guaranteed to
+ * not be `none`.
+ */
+public function GameReplicationInfo GetGameRI();
+
+/**
+ * Returns current game's `GameReplicationInfo` as `KFGameReplicationInfo`.
+ * Useful because `level.game` is not accessible inside objects and because it
+ * auto converts game replication info type to `KFGameReplicationInfo`, which
+ * virtually all mods for killing floor use (by itself or as a base class).
+ *
+ * @return `KFGameReplicationInfo` instance for the current game.
+ * Can be `none` only if game was modded to run a `KFGameReplicationInfo`
+ * not derived from `KFGameType`.
+ */
+public function KFGameReplicationInfo GetKFGameRI();
+
+/**
+ * Returns current game's `GameInfo`. Useful because `level.game` is not
+ * accessible inside objects.
+ *
+ * @return `GameInfo` instance for the current game. Guaranteed to
+ * not be `none`.
+ */
+public function GameInfo GetGameType();
+
+/**
+ * Returns current game's `GameInfo` as `KFGameType`. Useful because
+ * `level.game` is not accessible inside objects and because it auto converts
+ * game type to `KFGameType`, which virtually all mods for killing floor use
+ * (by itself or as a base class).
+ *
+ * @return `KFGameType` instance for the current game. Can be `none` only if
+ * game was modded to run a `GameInfo` not derived from `KFGameType`.
+ */
+public function KFGameType GetKFGameType();
+
+/**
+ * Searches all `Actor`s on the level for an instance of specific class and
+ * returns it.
+ *
+ * @param classToFind Class we want to find an instance of.
+ * @result A pre-existing instance of class `classToFind`, `none` if
+ * no instances exist at the moment of this method's call.
+ */
+public function Actor FindActorInstance(class classToFind);
+
+/**
+ * Creates reference object to store a `Actor` value.
+ *
+ * Such references are necessary, since `Actor` references aren't safe to store
+ * inside non-actor `Object`s. To allow that Acedia uses a round about way of
+ * storing all `Actor` references in a special `Actor`, while allowing to refer
+ * to them via `NativeActorRef` (also `ActorRef` for `AcediaActor`s
+ * specifically).
+ *
+ * @param value Initial value to store in reference.
+ * @return `NativeActorRef`, containing `value`.
+ */
+public function NativeActorRef ActorRef(optional Actor value);
+
+defaultproperties
+{
+}
\ No newline at end of file
diff --git a/sources/CoreRealm/LevelCore.uc b/sources/CoreRealm/LevelCore.uc
index af0afe4..d883783 100644
--- a/sources/CoreRealm/LevelCore.uc
+++ b/sources/CoreRealm/LevelCore.uc
@@ -78,7 +78,7 @@ public final function SimpleSlot OnShutdown(AcediaObject receiver)
return SimpleSlot(onShutdownSignal.NewSlot(receiver));
}
-public static function LevelCore CreateLevelCore(Actor source)
+public simulated static function LevelCore CreateLevelCore(Actor source)
{
if (GetInstance() != none) return none;
if (source == none) return none;
@@ -89,6 +89,35 @@ public static function LevelCore CreateLevelCore(Actor source)
return default.activeInstance;
}
+/**
+ * Creates new `Actor` in the level as the caller `LevelCore`.
+ *
+ * For `AcediaActor`s calls their constructors.
+ *
+ * @param classToAllocate Class of the `Object` that this method will
+ * create. Must not be subclass of `Actor`.
+ * @return Newly created object.
+ * Will only be `none` if `classToAllocate` is `none` or `classToAllocate`
+ * is abstract.
+ */
+public final function Actor Allocate(class classToAllocate)
+{
+ local Actor allocatedActor;
+ local class acediaClassToAllocate;
+
+ if (classToAllocate == none) {
+ return none;
+ }
+ acediaClassToAllocate = class(classToAllocate);
+ allocatedActor = Spawn(classToAllocate);
+ // Call constructor here, just in case, to make sure constructor is called
+ // as soon as possible
+ if (acediaClassToAllocate != none) {
+ AcediaActor(allocatedActor)._constructor();
+ }
+ return allocatedActor;
+}
+
public final static function LevelCore GetInstance()
{
local bool instanceExists;
diff --git a/sources/ServerRealm/API/Unreal/BroadcastsAPI/BroadcastAPI.uc b/sources/ServerRealm/API/Unreal/BroadcastsAPI/BroadcastAPI.uc
index 61d50df..b13c28c 100644
--- a/sources/ServerRealm/API/Unreal/BroadcastsAPI/BroadcastAPI.uc
+++ b/sources/ServerRealm/API/Unreal/BroadcastsAPI/BroadcastAPI.uc
@@ -31,10 +31,10 @@ var private LoggerAPI.Definition errBroadcasthandlerUnknown;
public function Broadcast_OnBroadcastCheck_Slot OnBroadcastCheck(
AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
TryInjectBroadcastHandler(service);
signal = service.GetSignal(class'Broadcast_OnBroadcastCheck_Signal');
return Broadcast_OnBroadcastCheck_Slot(signal.NewSlot(receiver));
@@ -44,10 +44,10 @@ public function Broadcast_OnBroadcastCheck_Slot OnBroadcastCheck(
public function Broadcast_OnHandleText_Slot OnHandleText(
AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
TryInjectBroadcastHandler(service);
signal = service.GetSignal(class'Broadcast_OnHandleText_Signal');
return Broadcast_OnHandleText_Slot(signal.NewSlot(receiver));
@@ -57,10 +57,10 @@ public function Broadcast_OnHandleText_Slot OnHandleText(
public function Broadcast_OnHandleTextFor_Slot OnHandleTextFor(
AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
TryInjectBroadcastHandler(service);
signal = service.GetSignal(class'Broadcast_OnHandleTextFor_Signal');
return Broadcast_OnHandleTextFor_Slot(signal.NewSlot(receiver));
@@ -70,10 +70,10 @@ public function Broadcast_OnHandleTextFor_Slot OnHandleTextFor(
public function Broadcast_OnHandleLocalized_Slot OnHandleLocalized(
AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
TryInjectBroadcastHandler(service);
signal = service.GetSignal(class'Broadcast_OnHandleLocalized_Signal');
return Broadcast_OnHandleLocalized_Slot(signal.NewSlot(receiver));
@@ -83,10 +83,10 @@ public function Broadcast_OnHandleLocalized_Slot OnHandleLocalized(
public function Broadcast_OnHandleLocalizedFor_Slot OnHandleLocalizedFor(
AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
TryInjectBroadcastHandler(service);
signal = service.GetSignal(class'Broadcast_OnHandleLocalizedFor_Signal');
return Broadcast_OnHandleLocalizedFor_Slot(signal.NewSlot(receiver));
@@ -96,10 +96,10 @@ public function Broadcast_OnHandleLocalizedFor_Slot OnHandleLocalizedFor(
* Method that attempts to inject Acedia's `BroadcastEventObserver`, while
* respecting settings inside `class'SideEffects'`.
*
- * @param service Reference to `UnrealService` to exchange signal and slots
- * classes with.
+ * @param service Reference to `ServerUnrealService` to exchange signal and
+ * slots classes with.
*/
-protected final function TryInjectBroadcastHandler(UnrealService service)
+protected final function TryInjectBroadcastHandler(ServerUnrealService service)
{
local InjectionLevel usedLevel;
local BroadcastSideEffect sideEffect;
diff --git a/sources/ServerRealm/API/Unreal/BroadcastsAPI/BroadcastEventsObserver.uc b/sources/ServerRealm/API/Unreal/BroadcastsAPI/BroadcastEventsObserver.uc
index 36f1657..d220408 100644
--- a/sources/ServerRealm/API/Unreal/BroadcastsAPI/BroadcastEventsObserver.uc
+++ b/sources/ServerRealm/API/Unreal/BroadcastsAPI/BroadcastEventsObserver.uc
@@ -204,7 +204,7 @@ var private Broadcast_OnHandleLocalizedFor_Signal onHandleLocalizedFor;
var private Broadcast_OnHandleText_Signal onHandleText;
var private Broadcast_OnHandleTextFor_Signal onHandleTextFor;
-public final function Initialize(UnrealService service)
+public final function Initialize(ServerUnrealService service)
{
usedInjectionLevel =
class'SideEffects'.default.broadcastHandlerInjectionLevel;
diff --git a/sources/ServerRealm/API/Unreal/GameRulesAPI/AcediaGameRules.uc b/sources/ServerRealm/API/Unreal/GameRulesAPI/AcediaGameRules.uc
index abc4b06..d2c190a 100644
--- a/sources/ServerRealm/API/Unreal/GameRulesAPI/AcediaGameRules.uc
+++ b/sources/ServerRealm/API/Unreal/GameRulesAPI/AcediaGameRules.uc
@@ -29,7 +29,7 @@ var private GameRules_OnNetDamage_Signal onNetDamage;
var private GameRules_OnPreventDeath_Signal onPreventDeath;
var private GameRules_OnScoreKill_Signal onScoreKill;
-public final function Initialize(UnrealService service)
+public final function Initialize(ServerUnrealService service)
{
if (service == none) {
return;
diff --git a/sources/ServerRealm/API/Unreal/GameRulesAPI/GameRulesAPI.uc b/sources/ServerRealm/API/Unreal/GameRulesAPI/GameRulesAPI.uc
index 9e32d62..243e8b3 100644
--- a/sources/ServerRealm/API/Unreal/GameRulesAPI/GameRulesAPI.uc
+++ b/sources/ServerRealm/API/Unreal/GameRulesAPI/GameRulesAPI.uc
@@ -31,10 +31,10 @@ var private LoggerAPI.Definition errGameRulesUnknown;
public function GameRules_OnFindPlayerStart_Slot OnFindPlayerStart(
AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
TryAddingGameRules(service);
signal = service.GetSignal(class'GameRules_OnFindPlayerStart_Signal');
return GameRules_OnFindPlayerStart_Slot(signal.NewSlot(receiver));
@@ -44,10 +44,10 @@ public function GameRules_OnFindPlayerStart_Slot OnFindPlayerStart(
public function GameRules_OnHandleRestartGame_Slot OnHandleRestartGame(
AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
TryAddingGameRules(service);
signal = service.GetSignal(class'GameRules_OnHandleRestartGame_Signal');
return GameRules_OnHandleRestartGame_Slot(signal.NewSlot(receiver));
@@ -57,10 +57,10 @@ public function GameRules_OnHandleRestartGame_Slot OnHandleRestartGame(
public function GameRules_OnCheckEndGame_Slot OnCheckEndGame(
AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
TryAddingGameRules(service);
signal = service.GetSignal(class'GameRules_OnCheckEndGame_Signal');
return GameRules_OnCheckEndGame_Slot(signal.NewSlot(receiver));
@@ -70,10 +70,10 @@ public function GameRules_OnCheckEndGame_Slot OnCheckEndGame(
public function GameRules_OnCheckScore_Slot OnCheckScore(
AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
TryAddingGameRules(service);
signal = service.GetSignal(class'GameRules_OnCheckScore_Signal');
return GameRules_OnCheckScore_Slot(signal.NewSlot(receiver));
@@ -83,10 +83,10 @@ public function GameRules_OnCheckScore_Slot OnCheckScore(
public function GameRules_OnOverridePickupQuery_Slot
OnOverridePickupQuery(AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
TryAddingGameRules(service);
signal = service.GetSignal(class'GameRules_OnOverridePickupQuery_Signal');
return GameRules_OnOverridePickupQuery_Slot(signal.NewSlot(receiver));
@@ -95,10 +95,10 @@ public function GameRules_OnOverridePickupQuery_Slot
/* SIGNAL */
public function GameRules_OnNetDamage_Slot OnNetDamage(AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
TryAddingGameRules(service);
signal = service.GetSignal(class'GameRules_OnNetDamage_Signal');
return GameRules_OnNetDamage_Slot(signal.NewSlot(receiver));
@@ -108,10 +108,10 @@ public function GameRules_OnNetDamage_Slot OnNetDamage(AcediaObject receiver)
public function GameRules_OnPreventDeath_Slot OnPreventDeath(
AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
TryAddingGameRules(service);
signal = service.GetSignal(class'GameRules_OnPreventDeath_Signal');
return GameRules_OnPreventDeath_Slot(signal.NewSlot(receiver));
@@ -121,10 +121,10 @@ public function GameRules_OnPreventDeath_Slot OnPreventDeath(
public function GameRules_OnScoreKill_Slot OnScoreKill(
AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
TryAddingGameRules(service);
signal = service.GetSignal(class'GameRules_OnScoreKill_Signal');
return GameRules_OnScoreKill_Slot(signal.NewSlot(receiver));
@@ -134,10 +134,10 @@ public function GameRules_OnScoreKill_Slot OnScoreKill(
* Method that attempts to inject Acedia's `AcediaGameRules`, while
* respecting settings inside `class'SideEffects'`.
*
- * @param service Reference to `UnrealService` to exchange signal and slots
- * classes with.
+ * @param service Reference to `ServerUnrealService` to exchange signal and
+ * slots classes with.
*/
-protected function TryAddingGameRules(UnrealService service)
+protected function TryAddingGameRules(ServerUnrealService service)
{
local AcediaGameRules gameRules;
local GameRulesSideEffect sideEffect;
diff --git a/sources/ServerRealm/API/Unreal/MutatorsAPI/MutatorAPI.uc b/sources/ServerRealm/API/Unreal/MutatorsAPI/MutatorAPI.uc
index c115faf..d0645b7 100644
--- a/sources/ServerRealm/API/Unreal/MutatorsAPI/MutatorAPI.uc
+++ b/sources/ServerRealm/API/Unreal/MutatorsAPI/MutatorAPI.uc
@@ -23,10 +23,10 @@ class MutatorAPI extends MutatorAPIBase;
public function Mutator_OnCheckReplacement_Slot OnCheckReplacement(
AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
signal = service.GetSignal(class'Mutator_OnCheckReplacement_Signal');
return Mutator_OnCheckReplacement_Slot(signal.NewSlot(receiver));
}
@@ -35,10 +35,10 @@ public function Mutator_OnCheckReplacement_Slot OnCheckReplacement(
public function Mutator_OnMutate_Slot OnMutate(
AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
signal = service.GetSignal(class'Mutator_OnMutate_Signal');
return Mutator_OnMutate_Slot(signal.NewSlot(receiver));
}
@@ -47,10 +47,10 @@ public function Mutator_OnMutate_Slot OnMutate(
public function Mutator_OnModifyLogin_Slot OnModifyLogin(
AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
signal = service.GetSignal(class'Mutator_OnModifyLogin_Signal');
return Mutator_OnModifyLogin_Slot(signal.NewSlot(receiver));
}
diff --git a/sources/ServerRealm/API/Unreal/ServerUnrealAPI.uc b/sources/ServerRealm/API/Unreal/ServerUnrealAPI.uc
index 2fb8889..f7bf8d0 100644
--- a/sources/ServerRealm/API/Unreal/ServerUnrealAPI.uc
+++ b/sources/ServerRealm/API/Unreal/ServerUnrealAPI.uc
@@ -28,9 +28,10 @@ protected function Constructor()
protected function HandleShutdown()
{
- local UnrealService service;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.GetInstance());
+ service =
+ ServerUnrealService(class'ServerUnrealService'.static.GetInstance());
// This has to clean up anything we've added
if (service != none) {
service.Destroy();
@@ -41,10 +42,10 @@ protected function HandleShutdown()
public function Unreal_OnTick_Slot OnTick(
AcediaObject receiver)
{
- local Signal signal;
- local UnrealService service;
+ local Signal signal;
+ local ServerUnrealService service;
- service = UnrealService(class'UnrealService'.static.Require());
+ service = ServerUnrealService(class'ServerUnrealService'.static.Require());
signal = service.GetSignal(class'Unreal_OnTick_Signal');
return Unreal_OnTick_Slot(signal.NewSlot(receiver));
}
@@ -61,7 +62,9 @@ public function SimpleSlot OnDestructionFor(
// Failing to spawn this actor without any collision flags is considered
// completely unexpected and grounds for fatal failure on Acedia' part
- stalker = ActorStalker(_.memory.Allocate(class'ActorStalker'));
+ stalker = ActorStalker(class'ServerLevelCore'.static
+ .GetInstance()
+ .Allocate(class'ActorStalker'));
if (stalker == none)
{
_.logger.Auto(fatalNoStalker);
@@ -113,12 +116,6 @@ public function Actor FindActorInstance(class classToFind)
return result;
}
-public function PlayerController GetLocalPlayer()
-{
- return class'ServerLevelCore'.static.GetInstance().level
- .GetLocalPlayerController();
-}
-
public function NativeActorRef ActorRef(optional Actor value)
{
local NativeActorRef ref;
diff --git a/sources/ServerRealm/API/Unreal/ServerUnrealAPIBase.uc b/sources/ServerRealm/API/Unreal/ServerUnrealAPIBase.uc
index 8c4c80a..5c13cfb 100644
--- a/sources/ServerRealm/API/Unreal/ServerUnrealAPIBase.uc
+++ b/sources/ServerRealm/API/Unreal/ServerUnrealAPIBase.uc
@@ -1,7 +1,7 @@
/**
* Low-level API that provides set of utility methods for working with
* unreal script classes.
- * Copyright 2021-2022 Anton Tarasenko
+ * Copyright 2022 Anton Tarasenko
*------------------------------------------------------------------------------
* This file is part of Acedia.
*
@@ -18,7 +18,7 @@
* You should have received a copy of the GNU General Public License
* along with Acedia. If not, see .
*/
-class ServerUnrealAPIBase extends AcediaObject
+class ServerUnrealAPIBase extends UnrealAPIBase
abstract;
var protected bool initialized;
@@ -47,122 +47,6 @@ public function Initialize(class adapterClass)
adapterClass.default.serverInventoryAPIClass));
}
-/**
- * Signal that will be emitted every tick.
- *
- * [Signature]
- * void (float delta, float dilationCoefficient)
- *
- * @param delta In-game time in seconds that has passed since
- * the last tick. To obtain real time passed from the last tick divide
- * `delta` by `dilationCoefficient`.
- * @param dilationCoefficient How fast is in-game time flow compared to
- * the real world's one? `2` means twice as fast and
- * `0.5` means twice as slow.
- */
-/* SIGNAL */
-public function Unreal_OnTick_Slot OnTick(AcediaObject receiver);
-
-/**
- * Signal that will be emitted when a passed `targetToStalk` is destroyed.
- *
- * Passed parameter `targetToStalk` cannot be `none`, otherwise `none` will be
- * returned instead of a valid slot.
- *
- * @param receiver Specify a receiver like for any other signal.
- * @param targetToStalk Actor whose destruction we want to detect.
- *
- * [Signature]
- * void ()
- */
-/* SIGNAL */
-public function SimpleSlot OnDestructionFor(
- AcediaObject receiver,
- Actor targetToStalk);
-
-/**
- * Returns current game's `LevelInfo`. Useful because `level` variable
- * is not defined inside objects.
- *
- * @return `LevelInfo` instance for the current game. Guaranteed to
- * not be `none`.
- */
-public function LevelInfo GetLevel();
-
-/**
- * Returns current game's `GameReplicationInfo`. Useful because `level.game`
- * is not accessible inside objects.
- *
- * @return `GameReplicationInfo` instance for the current game. Guaranteed to
- * not be `none`.
- */
-public function GameReplicationInfo GetGameRI();
-
-/**
- * Returns current game's `GameReplicationInfo` as `KFGameReplicationInfo`.
- * Useful because `level.game` is not accessible inside objects and because it
- * auto converts game replication info type to `KFGameReplicationInfo`, which
- * virtually all mods for killing floor use (by itself or as a base class).
- *
- * @return `KFGameReplicationInfo` instance for the current game.
- * Can be `none` only if game was modded to run a `KFGameReplicationInfo`
- * not derived from `KFGameType`.
- */
-public function KFGameReplicationInfo GetKFGameRI();
-
-/**
- * Returns current game's `GameInfo`. Useful because `level.game` is not
- * accessible inside objects.
- *
- * @return `GameInfo` instance for the current game. Guaranteed to
- * not be `none`.
- */
-public function GameInfo GetGameType();
-
-/**
- * Returns current game's `GameInfo` as `KFGameType`. Useful because
- * `level.game` is not accessible inside objects and because it auto converts
- * game type to `KFGameType`, which virtually all mods for killing floor use
- * (by itself or as a base class).
- *
- * @return `KFGameType` instance for the current game. Can be `none` only if
- * game was modded to run a `GameInfo` not derived from `KFGameType`.
- */
-public function KFGameType GetKFGameType();
-
-/**
- * Searches all `Actor`s on the level for an instance of specific class and
- * returns it.
- *
- * @param classToFind Class we want to find an instance of.
- * @result A pre-existing instance of class `classToFind`, `none` if
- * no instances exist at the moment of this method's call.
- */
-public function Actor FindActorInstance(class classToFind);
-
-/**
- * Returns current local player's `Controller`. Useful because `level`
- * is not accessible inside objects.
- *
- * @return `PlayerController` instance for the local player. `none` iff run on
- * dedicated servers.
- */
-public function PlayerController GetLocalPlayer();
-
-/**
- * Creates reference object to store a `Actor` value.
- *
- * Such references are necessary, since `Actor` references aren't safe to store
- * inside non-actor `Object`s. To allow that Acedia uses a round about way of
- * storing all `Actor` references in a special `Actor`, while allowing to refer
- * to them via `NativeActorRef` (also `ActorRef` for `AcediaActor`s
- * specifically).
- *
- * @param value Initial value to store in reference.
- * @return `NativeActorRef`, containing `value`.
- */
-public function NativeActorRef ActorRef(optional Actor value);
-
defaultproperties
{
}
\ No newline at end of file
diff --git a/sources/ServerRealm/API/Unreal/UnrealService.uc b/sources/ServerRealm/API/Unreal/ServerUnrealService.uc
similarity index 98%
rename from sources/ServerRealm/API/Unreal/UnrealService.uc
rename to sources/ServerRealm/API/Unreal/ServerUnrealService.uc
index 0f199d0..2bd1a04 100644
--- a/sources/ServerRealm/API/Unreal/UnrealService.uc
+++ b/sources/ServerRealm/API/Unreal/ServerUnrealService.uc
@@ -18,7 +18,7 @@
* You should have received a copy of the GNU General Public License
* along with Acedia. If not, see .
*/
-class UnrealService extends Service;
+class ServerUnrealService extends Service;
struct SignalRecord
{