Anton Tarasenko
2 years ago
13 changed files with 66 additions and 505 deletions
@ -1,115 +0,0 @@ |
|||||||
/** |
|
||||||
* Standard implementation for simple API for managing a list of |
|
||||||
* `SideEffect` info objects: can add, remove, return all and by package. |
|
||||||
* 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 <https://www.gnu.org/licenses/>. |
|
||||||
*/ |
|
||||||
class KF1_SideEffectAPI extends SideEffectAPI; |
|
||||||
|
|
||||||
var private array<SideEffect> activeSideEffects; |
|
||||||
|
|
||||||
public function array<SideEffect> GetAll() |
|
||||||
{ |
|
||||||
local int i; |
|
||||||
|
|
||||||
for (i = 0; i < activeSideEffects.length; i += 1) { |
|
||||||
activeSideEffects[i].NewRef(); |
|
||||||
} |
|
||||||
return activeSideEffects; |
|
||||||
} |
|
||||||
|
|
||||||
public function SideEffect GetClass(class<SideEffect> sideEffectClass) |
|
||||||
{ |
|
||||||
local int i; |
|
||||||
|
|
||||||
if (sideEffectClass == none) { |
|
||||||
return none; |
|
||||||
} |
|
||||||
for (i = 0; i < activeSideEffects.length; i += 1) |
|
||||||
{ |
|
||||||
if (activeSideEffects[i].class == sideEffectClass) |
|
||||||
{ |
|
||||||
activeSideEffects[i].NewRef(); |
|
||||||
return activeSideEffects[i]; |
|
||||||
} |
|
||||||
} |
|
||||||
return none; |
|
||||||
} |
|
||||||
|
|
||||||
public function array<SideEffect> GetFromPackage(BaseText packageName) |
|
||||||
{ |
|
||||||
local int i; |
|
||||||
local Text nextPackage; |
|
||||||
local array<SideEffect> result; |
|
||||||
|
|
||||||
if (packageName == none) { |
|
||||||
return result; |
|
||||||
} |
|
||||||
for (i = 0; i < activeSideEffects.length; i += 1) |
|
||||||
{ |
|
||||||
nextPackage = activeSideEffects[i].GetPackage(); |
|
||||||
if (nextPackage.Compare(packageName, SCASE_INSENSITIVE)) |
|
||||||
{ |
|
||||||
activeSideEffects[i].NewRef(); |
|
||||||
result[result.length] = activeSideEffects[i]; |
|
||||||
} |
|
||||||
_.memory.Free(nextPackage); |
|
||||||
} |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
public function bool Add(SideEffect newSideEffect) |
|
||||||
{ |
|
||||||
local int i; |
|
||||||
|
|
||||||
if (newSideEffect == none) { |
|
||||||
return false; |
|
||||||
} |
|
||||||
for (i = 0; i < activeSideEffects.length; i += 1) |
|
||||||
{ |
|
||||||
if (activeSideEffects[i].class == newSideEffect.class) { |
|
||||||
return false; |
|
||||||
} |
|
||||||
} |
|
||||||
newSideEffect.NewRef(); |
|
||||||
activeSideEffects[activeSideEffects.length] = newSideEffect; |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
public function bool RemoveClass( |
|
||||||
class<SideEffect> sideEffectClass) |
|
||||||
{ |
|
||||||
local int i; |
|
||||||
|
|
||||||
if (sideEffectClass == none) { |
|
||||||
return false; |
|
||||||
} |
|
||||||
for (i = 0; i < activeSideEffects.length; i += 1) |
|
||||||
{ |
|
||||||
if (activeSideEffects[i].class == sideEffectClass) |
|
||||||
{ |
|
||||||
_.memory.Free(activeSideEffects[i]); |
|
||||||
activeSideEffects.Remove(i, 1); |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
defaultproperties |
|
||||||
{ |
|
||||||
} |
|
@ -1,65 +0,0 @@ |
|||||||
/** |
|
||||||
* Object representing a side effect introduced into the game/server. |
|
||||||
* Side effects in Acedia refer to changes that aren't a part of mod's main |
|
||||||
* functionality, but rather something necessary to make that functionality |
|
||||||
* possible that might also affect how other mods work. |
|
||||||
* This is a simple data container that is meant to describe relevant |
|
||||||
* changes to the human user. |
|
||||||
* 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 <https://www.gnu.org/licenses/>. |
|
||||||
*/ |
|
||||||
class BroadcastSideEffect extends SideEffect |
|
||||||
dependson(BroadcastAPI); |
|
||||||
|
|
||||||
public final function Initialize(BroadcastAPI.InjectionLevel usedInjectionLevel) |
|
||||||
{ |
|
||||||
sideEffectName = |
|
||||||
_.text.FromString("AcediaCore's `BroadcastHandler` injected"); |
|
||||||
sideEffectDescription = |
|
||||||
_.text.FromString("Handling text and localized messages between server" |
|
||||||
@ "and clients requires AcediaCore to add its own `BroadcastHandler`" |
|
||||||
@ "into their linked list." |
|
||||||
@ "This is normal, since `BroadcastHandler` class was designed to allow" |
|
||||||
@ "mods to do that, however, for full functionality Acedia requires to" |
|
||||||
@ "inject it as the very first element (`BHIJ_Root` level injection)," |
|
||||||
@ "since some of the events become otherwise inaccessible." |
|
||||||
@ "This can result in incompatibility with other mods that are trying" |
|
||||||
@ "to do the same." |
|
||||||
@ "For that reason AcediaCore can also inject its `BroadcastHandler` as" |
|
||||||
@ "`BHIJ_Registered`."); |
|
||||||
sideEffectPackage = _.text.FromString("AcediaCore"); |
|
||||||
sideEffectSource = _.text.FromString("UnrealAPI"); |
|
||||||
if (usedInjectionLevel == BHIJ_Root) |
|
||||||
{ |
|
||||||
sideEffectStatus = |
|
||||||
_.text.FromFormattedString("{$TextPositive BHIJ_Root}"); |
|
||||||
} |
|
||||||
else if (usedInjectionLevel == BHIJ_Registered) |
|
||||||
{ |
|
||||||
sideEffectStatus = |
|
||||||
_.text.FromFormattedString("{$TextNetutral BHIJ_Registered}"); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
sideEffectStatus = |
|
||||||
_.text.FromFormattedString("{$TextNegative BHIJ_None (???)}"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
defaultproperties |
|
||||||
{ |
|
||||||
} |
|
@ -1,43 +0,0 @@ |
|||||||
/** |
|
||||||
* Object representing a side effect introduced into the game/server. |
|
||||||
* Side effects in Acedia refer to changes that aren't a part of mod's main |
|
||||||
* functionality, but rather something necessary to make that functionality |
|
||||||
* possible that might also affect how other mods work. |
|
||||||
* This is a simple data container that is meant to describe relevant |
|
||||||
* changes to the human user. |
|
||||||
* 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 <https://www.gnu.org/licenses/>. |
|
||||||
*/ |
|
||||||
class GameRulesSideEffect extends SideEffect; |
|
||||||
|
|
||||||
public final function Initialize() |
|
||||||
{ |
|
||||||
sideEffectName = |
|
||||||
_.text.FromString("AcediaCore's `AcediaGameRules` added"); |
|
||||||
sideEffectDescription = |
|
||||||
_.text.FromString("`GameRule`s is one of the main ways to get notified" |
|
||||||
@ "about various gameplay-related events in Unreal Engine." |
|
||||||
@ "Of course AcediaCore would require handling some of those events," |
|
||||||
@ "depending on how it's used."); |
|
||||||
sideEffectPackage = _.text.FromString("AcediaCore"); |
|
||||||
sideEffectSource = _.text.FromString("UnrealAPI"); |
|
||||||
sideEffectStatus = _.text.FromFormattedString("{$TextPositive active}"); |
|
||||||
} |
|
||||||
|
|
||||||
defaultproperties |
|
||||||
{ |
|
||||||
} |
|
@ -1,164 +0,0 @@ |
|||||||
/** |
|
||||||
* Object representing a side effect introduced into the game/server. |
|
||||||
* Side effects in Acedia refer to changes that aren't a part of mod's main |
|
||||||
* functionality, but rather something necessary to make that functionality |
|
||||||
* possible that might also affect how other mods work. |
|
||||||
* This is a simple data container that is meant to describe relevant |
|
||||||
* changes to the human user. |
|
||||||
* 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 <https://www.gnu.org/licenses/>. |
|
||||||
*/ |
|
||||||
class SideEffect extends AcediaObject |
|
||||||
abstract; |
|
||||||
|
|
||||||
/** |
|
||||||
* # Side effects |
|
||||||
* |
|
||||||
* In Acedia "side effect" refers to changes that aren't a part of mod's |
|
||||||
* main functionality, but rather something necessary to make that |
|
||||||
* functionality possible that might also affect how other mods work. Their |
|
||||||
* purpose is to help developers and server admins figure out what changes were |
|
||||||
* performed by Acedia or mods based on it. |
|
||||||
* What needs to be considered a side effect is loosely defined and they |
|
||||||
* are simply a tool to inform others that something they might not have |
|
||||||
* expected has happened, that can possibly break other (their) mods. |
|
||||||
* AcediaCore, for example, tried to leave a minimal footprint, avoiding |
|
||||||
* making any changes to the game classes unless requested, but it still has to |
|
||||||
* do some changes (adding `GameRules`, replacing damage types for some zeds, |
|
||||||
* etc.) and `SideEffect`s can be used to document these changes. They can be |
|
||||||
* used in a similar way for AcediaFixes - a package that is only meant for |
|
||||||
* fixing bugs, but inevitably has to make a lot of under the hood changes to |
|
||||||
* achieve that. |
|
||||||
* On the other hand gameplay mods like Futility can make a lot of changes, |
|
||||||
* but they can all be just expected part of its direct functionality: we |
|
||||||
* expect feature that shares dosh of leavers to alter players' dosh values, so |
|
||||||
* this is not a side effect. Such mods are likely not going to have to specify |
|
||||||
* any side effects whatsoever. |
|
||||||
* |
|
||||||
* ## Implementing your own `SideEffect`s |
|
||||||
* |
|
||||||
* Simply make a non-abstract child class based on `SideEffect`, create its |
|
||||||
* instance filled with necessary data and register it in `SideEffectAPI` once |
|
||||||
* side effect is introduced. If you revert introduced side effect, you should |
|
||||||
* remove registered object through the same API. |
|
||||||
* Each class of the `SideEffect` is supposed to represent a particular |
|
||||||
* side effect introduced into the game engine. Whether side effect is active |
|
||||||
* is decided by whether it is currently registered in `SideEffectAPI`. |
|
||||||
* |
|
||||||
* NOTE: `SideEffect` should not have any logic and should serve as |
|
||||||
* an immutable data container. |
|
||||||
*/ |
|
||||||
|
|
||||||
var protected Text sideEffectName; |
|
||||||
var protected Text sideEffectDescription; |
|
||||||
var protected Text sideEffectPackage; |
|
||||||
var protected Text sideEffectSource; |
|
||||||
var protected Text sideEffectStatus; |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns name (short description) of the caller `SideEffect`. User need to |
|
||||||
* be able to tell what this `SideEffect` is generally about from the glance at |
|
||||||
* this name. |
|
||||||
* |
|
||||||
* Guideline is for this value to not exceed `80` characters, but this is not |
|
||||||
* enforced. |
|
||||||
* |
|
||||||
* Must not be `none`. |
|
||||||
* |
|
||||||
* @return Name (short description) of the caller `SideEffect`. |
|
||||||
* Guaranteed to not be `none`. |
|
||||||
*/ |
|
||||||
public function Text GetName() |
|
||||||
{ |
|
||||||
if (sideEffectName != none) { |
|
||||||
return sideEffectName.Copy(); |
|
||||||
} |
|
||||||
return none; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns description of the caller `SideEffect`. This should describe what |
|
||||||
* was done and why relevant change was necessary. |
|
||||||
* |
|
||||||
* Must not be `none`. |
|
||||||
* |
|
||||||
* @return Description of the caller `SideEffect`. |
|
||||||
* Guaranteed to not be `none`. |
|
||||||
*/ |
|
||||||
public function Text GetDescription() |
|
||||||
{ |
|
||||||
if (sideEffectDescription != none) { |
|
||||||
return sideEffectDescription.Copy(); |
|
||||||
} |
|
||||||
return none; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns name of the package ("*.u" file) that introduced this change. |
|
||||||
* |
|
||||||
* Note that if package "A" actually performed the change because another |
|
||||||
* package "B" requested certain functionality, it is still package "A" that is |
|
||||||
* responsible for the side effect. |
|
||||||
* |
|
||||||
* Must not be `none`. |
|
||||||
* |
|
||||||
* @return Name of the package ("*.u" file) that introduced this change. |
|
||||||
* Guaranteed to not be `none`. |
|
||||||
*/ |
|
||||||
public function Text GetPackage() |
|
||||||
{ |
|
||||||
if (sideEffectPackage != none) { |
|
||||||
return sideEffectPackage.Copy(); |
|
||||||
} |
|
||||||
return none; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* What part of package caused this change. For huge packages can be used to |
|
||||||
* further specify what introduced the change. |
|
||||||
* |
|
||||||
* Returned value can be `none` (e.g. when it is unnecessary for small |
|
||||||
* packages). |
|
||||||
* |
|
||||||
* @return Name (short description) of the part of the package that caused |
|
||||||
* caller `SideEffect`. |
|
||||||
*/ |
|
||||||
public function Text GetSource() |
|
||||||
{ |
|
||||||
if (sideEffectSource != none) { |
|
||||||
return sideEffectSource.Copy(); |
|
||||||
} |
|
||||||
return none; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Status of the caller `SideEffect`. Some side effects can be introduced in |
|
||||||
* several different ways - this value needs to help distinguish between them. |
|
||||||
* |
|
||||||
* @return Status of the caller `SideEffect`. |
|
||||||
*/ |
|
||||||
public function Text GetStatus() |
|
||||||
{ |
|
||||||
if (sideEffectStatus != none) { |
|
||||||
return sideEffectStatus.Copy(); |
|
||||||
} |
|
||||||
return none; |
|
||||||
} |
|
||||||
|
|
||||||
defaultproperties |
|
||||||
{ |
|
||||||
} |
|
@ -1,76 +0,0 @@ |
|||||||
/** |
|
||||||
* Base class for simple API for managing a list of `SideEffect` info |
|
||||||
* objects: can add, remove, return all and by package. |
|
||||||
* 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 <https://www.gnu.org/licenses/>. |
|
||||||
*/ |
|
||||||
class SideEffectAPI extends AcediaObject |
|
||||||
abstract; |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns all so far registered `SideEffect`s. |
|
||||||
* |
|
||||||
* @return Array of all registered `SideEffect`s. |
|
||||||
*/ |
|
||||||
public function array<SideEffect> GetAll(); |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns active `SideEffect` instance of the specified class |
|
||||||
* `sideEffectClass`. |
|
||||||
* |
|
||||||
* @param sideEffectClass Class of side effect to return active instance of. |
|
||||||
* @return Active `SideEffect` instance of the specified class |
|
||||||
* `sideEffectClass`. |
|
||||||
* `none` if either `sideEffectClass` is `none` or side effect of such |
|
||||||
* class is not currently active. |
|
||||||
*/ |
|
||||||
public function SideEffect GetClass(class<SideEffect> sideEffectClass); |
|
||||||
|
|
||||||
/** |
|
||||||
* Returns all so far registered `SideEffect`s from a package `packageName` |
|
||||||
* (case insensitive). |
|
||||||
* |
|
||||||
* @param packageName Name of the package, in `SideEffect`s from which we are |
|
||||||
* interested. Must be not `none`. |
|
||||||
* @return Array of all registered `SideEffect`s from a package `packageName`. |
|
||||||
* If `none`, returns an empty array. |
|
||||||
*/ |
|
||||||
public function array<SideEffect> GetFromPackage(BaseText packageName); |
|
||||||
|
|
||||||
/** |
|
||||||
* Registers a new `SideEffect` object as active. |
|
||||||
* |
|
||||||
* @param newSideEffect Instance of some `SideEffect` class to register as |
|
||||||
* active side effect. Must not be `none`. |
|
||||||
* @return `true` if new side effect was added and `false` otherwise. |
|
||||||
*/ |
|
||||||
public function bool Add(SideEffect newSideEffect); |
|
||||||
|
|
||||||
/** |
|
||||||
* Removes `SideEffect` of the specified sub-class from the list of active |
|
||||||
* side effects. |
|
||||||
* |
|
||||||
* @param sideEffectClass Class of the side effect to remove. |
|
||||||
* @return `true` if some side effect was removed as a result of this operation |
|
||||||
* and `false` otherwise (even if there was no side effect of specified |
|
||||||
* class to begin with). |
|
||||||
*/ |
|
||||||
public function bool RemoveClass(class<SideEffect> sideEffectClass); |
|
||||||
|
|
||||||
defaultproperties |
|
||||||
{ |
|
||||||
} |
|
Loading…
Reference in new issue