You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
232 lines
8.1 KiB
232 lines
8.1 KiB
/** |
|
* Low-level API that provides set of utility methods for working with |
|
* `GameRule`s. |
|
* Copyright 2021 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 GameRulesAPI extends AcediaObject; |
|
|
|
var private LoggerAPI.Definition errNoService; |
|
|
|
/** |
|
* Called when game decides on a player's spawn point. If a `NavigationPoint` |
|
* is returned, signal propagation will be interrupted and returned value will |
|
* be used as the player start. |
|
* |
|
* [Signature] |
|
* NavigationPoint <slot>( |
|
* Controller player, |
|
* optional byte inTeam, |
|
* optional string incomingName) |
|
* |
|
* @param player Player for whom we are picking a spawn point. |
|
* @param inTeam Player's team number. |
|
* @param incomingName `Portal` parameter from `GameInfo.Login()` event. |
|
* @return `NavigationPoint` that will player must be spawned at. |
|
* `none` means that slot does not want to modify it. |
|
*/ |
|
/* SIGNAL */ |
|
public final function GameRules_OnFindPlayerStart_Slot OnFindPlayerStart( |
|
AcediaObject receiver) |
|
{ |
|
local Signal signal; |
|
local UnrealService service; |
|
service = UnrealService(class'UnrealService'.static.Require()); |
|
if (service == none) |
|
{ |
|
_.logger.Auto(errNoService); |
|
return none; |
|
} |
|
signal = service.GetSignal(class'GameRules_OnFindPlayerStart_Signal'); |
|
return GameRules_OnFindPlayerStart_Slot(signal.NewSlot(receiver)); |
|
} |
|
|
|
/** |
|
* When pawn wants to pickup something, `GameRule`s are given a chance to |
|
* modify it. If one of the `Slot`s returns `true`, `allowPickup` will |
|
* determine if the object can be picked up. |
|
* Overriding via this method allows to completely bypass check against |
|
* `Pawn`'s inventory's `HandlePickupQuery()` method. |
|
* |
|
* [Signature] |
|
* bool <slot>(Pawn other, Pickup item, out byte allowPickup) |
|
* |
|
* @param other Pawn which will potentially pickup `item`. |
|
* @param item Pickup which `other` might potentially pickup. |
|
* @param allowPickup `true` if you want to force `other` to pickup an item |
|
* and `false` otherwise. This parameter is ignored if returned value of |
|
* your slot call is `false`. |
|
* @return `true` if you wish to override decision about pickup with |
|
* `allowPickup` and `false` if you do not want to make that decision. |
|
* If you do decide to override decision by returning `true` - this signal |
|
* will not be propagated to the rest of the slots. |
|
*/ |
|
/* SIGNAL */ |
|
public final function GameRules_OnOverridePickupQuery_Slot |
|
OnOverridePickupQuery(AcediaObject receiver) |
|
{ |
|
local Signal signal; |
|
local UnrealService service; |
|
service = UnrealService(class'UnrealService'.static.Require()); |
|
if (service == none) |
|
{ |
|
_.logger.Auto(errNoService); |
|
return none; |
|
} |
|
signal = service.GetSignal(class'GameRules_OnOverridePickupQuery_Signal'); |
|
return GameRules_OnOverridePickupQuery_Slot(signal.NewSlot(receiver)); |
|
} |
|
|
|
// TODO: rewrite |
|
/** |
|
* When pawn wants to pickup something, `GameRule`s are given a chance to |
|
* modify it. If one of the `Slot`s returns `true`, `allowPickup` will |
|
* determine if the object can be picked up. |
|
* Overriding via this method allows to completely bypass check against |
|
* `Pawn`'s inventory's `HandlePickupQuery()` method. |
|
* |
|
* [Signature] |
|
* bool <slot>(Pawn other, Pickup item, out byte allowPickup) |
|
* |
|
* @param other Pawn which will potentially pickup `item`. |
|
* @param item Pickup which `other` might potentially pickup. |
|
* @param allowPickup `true` if you want to force `other` to pickup an item |
|
* and `false` otherwise. This parameter is ignored if returned value of |
|
* your slot call is `false`. |
|
* @return `true` if you wish to override decision about pickup with |
|
* `allowPickup` and `false` if you do not want to make that decision. |
|
* If you do decide to override decision by returning `true` - this signal |
|
* will not be propagated to the rest of the slots. |
|
*/ |
|
/* SIGNAL */ |
|
public final function GameRules_OnNetDamage_Slot OnNetDamage( |
|
AcediaObject receiver) |
|
{ |
|
local Signal signal; |
|
local UnrealService service; |
|
service = UnrealService(class'UnrealService'.static.Require()); |
|
if (service == none) |
|
{ |
|
_.logger.Auto(errNoService); |
|
return none; |
|
} |
|
signal = service.GetSignal(class'GameRules_OnNetDamage_Signal'); |
|
return GameRules_OnNetDamage_Slot(signal.NewSlot(receiver)); |
|
} |
|
|
|
/** |
|
* Adds new `GameRules` class to the current `GameInfo`. |
|
* Does nothing if give `GameRules` class was already added before. |
|
* |
|
* @param newRulesClass Class of rules to add. |
|
* @return `true` if `GameRules` were added and `false` otherwise |
|
* (because they were already active.) |
|
*/ |
|
public final function bool Add(class<GameRules> newRulesClass) |
|
{ |
|
if (AreAdded(newRulesClass)) { |
|
return false; |
|
} |
|
_.unreal.GetGameType() |
|
.AddGameModifier(GameRules(_.memory.Allocate(newRulesClass))); |
|
return true; |
|
} |
|
|
|
/** |
|
* Removes given `GameRules` class from the current `GameInfo`, |
|
* if they are active. Does nothing otherwise. |
|
* |
|
* @param rulesClassToRemove Class of rules to try and remove. |
|
* @return `true` if `GameRules` were removed and `false` otherwise |
|
* (if they were not active in the first place). |
|
*/ |
|
public final function bool Remove(class<GameRules> rulesClassToRemove) |
|
{ |
|
local GameInfo game; |
|
local GameRules rulesIter; |
|
local GameRules rulesToDestroy; |
|
if (rulesClassToRemove == none) return false; |
|
game = _.unreal.GetGameType(); |
|
if (game.gameRulesModifiers == none) return false; |
|
|
|
// Check root rules |
|
rulesToDestroy = game.gameRulesModifiers; |
|
if (rulesToDestroy.class == rulesClassToRemove) |
|
{ |
|
game.gameRulesModifiers = rulesToDestroy.nextGameRules; |
|
rulesToDestroy.Destroy(); |
|
return true; |
|
} |
|
// Check rest of the rules |
|
rulesIter = game.gameRulesModifiers; |
|
while (rulesIter != none) |
|
{ |
|
rulesToDestroy = rulesIter.nextGameRules; |
|
if ( rulesToDestroy != none |
|
&& rulesToDestroy.class == rulesClassToRemove) |
|
{ |
|
rulesIter.nextGameRules = rulesToDestroy.nextGameRules; |
|
rulesToDestroy.Destroy(); |
|
return true; |
|
} |
|
rulesIter = rulesIter.nextGameRules; |
|
} |
|
return false; |
|
} |
|
|
|
/** |
|
* Finds given class of `GameRules` if it's currently active in `GameInfo`. |
|
* Returns `none` otherwise. |
|
* |
|
* @param rulesClassToFind Class of rules to find. |
|
* @return `GameRules` of given class `rulesClassToFind` instance added to |
|
* `GameInfo`'s records and `none` if no such rules are currently added. |
|
*/ |
|
public final function GameRules FindInstance( |
|
class<GameRules> rulesClassToFind) |
|
{ |
|
local GameRules rulesIter; |
|
if (rulesClassToFind == none) { |
|
return none; |
|
} |
|
rulesIter = _.unreal.GetGameType().gameRulesModifiers; |
|
while (rulesIter != none) |
|
{ |
|
if (rulesIter.class == rulesClassToFind) { |
|
return rulesIter; |
|
} |
|
rulesIter = rulesIter.nextGameRules; |
|
} |
|
return none; |
|
} |
|
|
|
/** |
|
* Checks if given class of `GameRules` is currently active in `GameInfo`. |
|
* |
|
* @param rulesClassToCheck Class of rules to check for. |
|
* @return `true` if `GameRules` are active and `false` otherwise. |
|
*/ |
|
public final function bool AreAdded( |
|
class<GameRules> rulesClassToCheck) |
|
{ |
|
return (FindInstance(rulesClassToCheck) != none); |
|
} |
|
|
|
defaultproperties |
|
{ |
|
errNoService = (l=LOG_Error,m="`UnrealService` could not be reached.") |
|
} |