Browse Source

Add more `GameRule` events

pull/8/head
Anton Tarasenko 4 years ago
parent
commit
6133cc334f
  1. 46
      sources/Unreal/GameRules/AcediaGameRules.uc
  2. 47
      sources/Unreal/GameRules/Events/GameRules_OnCheckEndGame_Signal.uc
  3. 41
      sources/Unreal/GameRules/Events/GameRules_OnCheckEndGame_Slot.uc
  4. 44
      sources/Unreal/GameRules/Events/GameRules_OnCheckScore_Signal.uc
  5. 41
      sources/Unreal/GameRules/Events/GameRules_OnCheckScore_Slot.uc
  6. 7
      sources/Unreal/GameRules/Events/GameRules_OnFindPlayerStart_Signal.uc
  7. 44
      sources/Unreal/GameRules/Events/GameRules_OnHandleRestartGame_Signal.uc
  8. 41
      sources/Unreal/GameRules/Events/GameRules_OnHandleRestartGame_Slot.uc
  9. 4
      sources/Unreal/GameRules/Events/GameRules_OnOverridePickupQuery_Signal.uc
  10. 93
      sources/Unreal/GameRules/GameRulesAPI.uc
  11. 7
      sources/Unreal/UnrealService.uc

46
sources/Unreal/GameRules/AcediaGameRules.uc

@ -21,6 +21,9 @@
class AcediaGameRules extends GameRules; class AcediaGameRules extends GameRules;
var private GameRules_OnFindPlayerStart_Signal onFindPlayerStartSignal; var private GameRules_OnFindPlayerStart_Signal onFindPlayerStartSignal;
var private GameRules_OnHandleRestartGame_Signal onHandleRestartGameSignal;
var private GameRules_OnCheckEndGame_Signal onCheckEndGameSignal;
var private GameRules_OnCheckScore_Signal onCheckScoreSignal;
var private GameRules_OnOverridePickupQuery_Signal onOverridePickupQuery; var private GameRules_OnOverridePickupQuery_Signal onOverridePickupQuery;
var private GameRules_OnNetDamage_Signal onNetDamage; var private GameRules_OnNetDamage_Signal onNetDamage;
@ -31,6 +34,12 @@ public final function Initialize(unrealService service)
} }
onFindPlayerStartSignal = GameRules_OnFindPlayerStart_Signal( onFindPlayerStartSignal = GameRules_OnFindPlayerStart_Signal(
service.GetSignal(class'GameRules_OnFindPlayerStart_Signal')); service.GetSignal(class'GameRules_OnFindPlayerStart_Signal'));
onHandleRestartGameSignal = GameRules_OnHandleRestartGame_Signal(
service.GetSignal(class'GameRules_OnHandleRestartGame_Signal'));
onCheckEndGameSignal = GameRules_OnCheckEndGame_Signal(
service.GetSignal(class'GameRules_OnCheckEndGame_Signal'));
onCheckScoreSignal = GameRules_OnCheckScore_Signal(
service.GetSignal(class'GameRules_OnCheckScore_Signal'));
onOverridePickupQuery = GameRules_OnOverridePickupQuery_Signal( onOverridePickupQuery = GameRules_OnOverridePickupQuery_Signal(
service.GetSignal(class'GameRules_OnOverridePickupQuery_Signal')); service.GetSignal(class'GameRules_OnOverridePickupQuery_Signal'));
onNetDamage = GameRules_OnNetDamage_Signal( onNetDamage = GameRules_OnNetDamage_Signal(
@ -62,6 +71,43 @@ function NavigationPoint FindPlayerStart(
return result; return result;
} }
function bool HandleRestartGame()
{
local bool result;
if (onHandleRestartGameSignal != none) {
result = onHandleRestartGameSignal.Emit();
}
if (nextGameRules != none && nextGameRules.HandleRestartGame()) {
return true;
}
return result;
}
function bool CheckEndGame(PlayerReplicationInfo winner, string reason)
{
local bool result;
result = true;
if (onCheckEndGameSignal != none) {
result = onCheckEndGameSignal.Emit(winner, reason);
}
if (nextGameRules != none && !nextGameRules.HandleRestartGame()) {
return false;
}
return result;
}
function bool CheckScore(PlayerReplicationInfo scorer)
{
local bool result;
if (onCheckScoreSignal != none) {
result = onCheckScoreSignal.Emit(scorer);
}
if (nextGameRules != none && nextGameRules.CheckScore(Scorer)) {
return true;
}
return result;
}
function bool OverridePickupQuery( function bool OverridePickupQuery(
Pawn other, Pawn other,
Pickup item, Pickup item,

47
sources/Unreal/GameRules/Events/GameRules_OnCheckEndGame_Signal.uc

@ -0,0 +1,47 @@
/**
* Signal class implementation for `GameRulesAPI`'s `OnCheckEndGame` signal.
* 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 GameRules_OnCheckEndGame_Signal extends Signal;
public final function bool Emit(
PlayerReplicationInfo winner,
string reason)
{
local Slot nextSlot;
local bool result, nextReply;
StartIterating();
nextSlot = GetNextSlot();
result = true;
while (nextSlot != none)
{
nextReply = GameRules_OnCheckEndGame_Slot(nextSlot)
.connect(winner, reason);
if (!nextReply && !nextSlot.IsEmpty()) {
result = result && nextReply;
}
nextSlot = GetNextSlot();
}
CleanEmptySlots();
return result;
}
defaultproperties
{
relatedSlotClass = class'GameRules_OnCheckEndGame_Slot'
}

41
sources/Unreal/GameRules/Events/GameRules_OnCheckEndGame_Slot.uc

@ -0,0 +1,41 @@
/**
* Slot class implementation for `GameRulesAPI`'s `OnCheckEndGame` signal.
* 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 GameRules_OnCheckEndGame_Slot extends Slot;
delegate bool connect(PlayerReplicationInfo winner, string reason)
{
DummyCall();
return true;
}
protected function Constructor()
{
connect = none;
}
protected function Finalizer()
{
super.Finalizer();
connect = none;
}
defaultproperties
{
}

44
sources/Unreal/GameRules/Events/GameRules_OnCheckScore_Signal.uc

@ -0,0 +1,44 @@
/**
* Signal class implementation for `GameRulesAPI`'s `OnCheckScore` signal.
* 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 GameRules_OnCheckScore_Signal extends Signal;
public final function bool Emit(PlayerReplicationInfo scorer)
{
local Slot nextSlot;
local bool result, nextReply;
StartIterating();
nextSlot = GetNextSlot();
result = true;
while (nextSlot != none)
{
nextReply = GameRules_OnCheckScore_Slot(nextSlot).connect(scorer);
if (!nextReply && !nextSlot.IsEmpty()) {
result = result && nextReply;
}
nextSlot = GetNextSlot();
}
CleanEmptySlots();
return result;
}
defaultproperties
{
relatedSlotClass = class'GameRules_OnCheckScore_Slot'
}

41
sources/Unreal/GameRules/Events/GameRules_OnCheckScore_Slot.uc

@ -0,0 +1,41 @@
/**
* Slot class implementation for `GameRulesAPI`'s `OnCheckScore` signal.
* 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 GameRules_OnCheckScore_Slot extends Slot;
delegate bool connect(PlayerReplicationInfo scorer)
{
DummyCall();
return true;
}
protected function Constructor()
{
connect = none;
}
protected function Finalizer()
{
super.Finalizer();
connect = none;
}
defaultproperties
{
}

7
sources/Unreal/GameRules/Events/GameRules_OnFindPlayerStart_Signal.uc

@ -22,8 +22,7 @@ class GameRules_OnFindPlayerStart_Signal extends Signal;
public final function NavigationPoint Emit( public final function NavigationPoint Emit(
Controller player, Controller player,
optional byte inTeam, optional byte inTeam,
optional string incomingName optional string incomingName)
)
{ {
local Slot nextSlot; local Slot nextSlot;
local NavigationPoint nextPoint; local NavigationPoint nextPoint;
@ -33,7 +32,9 @@ public final function NavigationPoint Emit(
{ {
nextPoint = GameRules_OnFindPlayerStart_Slot(nextSlot) nextPoint = GameRules_OnFindPlayerStart_Slot(nextSlot)
.connect(player, inTeam, incomingName); .connect(player, inTeam, incomingName);
if (nextPoint != none && !nextSlot.IsEmpty()) { if (nextPoint != none && !nextSlot.IsEmpty())
{
CleanEmptySlots();
return nextPoint; return nextPoint;
} }
nextSlot = GetNextSlot(); nextSlot = GetNextSlot();

44
sources/Unreal/GameRules/Events/GameRules_OnHandleRestartGame_Signal.uc

@ -0,0 +1,44 @@
/**
* Signal class implementation for `GameRulesAPI`'s
* `OnHandleRestartGame` signal.
* 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 GameRules_OnHandleRestartGame_Signal extends Signal;
public final function bool Emit()
{
local Slot nextSlot;
local bool doPrevent, nextResult;
StartIterating();
nextSlot = GetNextSlot();
while (nextSlot != none)
{
nextResult = GameRules_OnHandleRestartGame_Slot(nextSlot).connect();
if (nextResult && !nextSlot.IsEmpty()) {
doPrevent = doPrevent || nextResult;
}
nextSlot = GetNextSlot();
}
CleanEmptySlots();
return doPrevent;
}
defaultproperties
{
relatedSlotClass = class'GameRules_OnHandleRestartGame_Slot'
}

41
sources/Unreal/GameRules/Events/GameRules_OnHandleRestartGame_Slot.uc

@ -0,0 +1,41 @@
/**
* Slot class implementation for `GameRulesAPI`'s `OnHandleRestartGame` signal.
* 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 GameRules_OnHandleRestartGame_Slot extends Slot;
delegate bool connect()
{
DummyCall();
return false;
}
protected function Constructor()
{
connect = none;
}
protected function Finalizer()
{
super.Finalizer();
connect = none;
}
defaultproperties
{
}

4
sources/Unreal/GameRules/Events/GameRules_OnOverridePickupQuery_Signal.uc

@ -30,7 +30,9 @@ public final function bool Emit(Pawn other, Pickup item, out byte allowPickup)
{ {
shouldOverride = GameRules_OnOverridePickupQuery_Slot(nextSlot) shouldOverride = GameRules_OnOverridePickupQuery_Slot(nextSlot)
.connect(other, item, allowPickup); .connect(other, item, allowPickup);
if (shouldOverride && !nextSlot.IsEmpty()) { if (shouldOverride && !nextSlot.IsEmpty())
{
CleanEmptySlots();
return shouldOverride; return shouldOverride;
} }
nextSlot = GetNextSlot(); nextSlot = GetNextSlot();

93
sources/Unreal/GameRules/GameRulesAPI.uc

@ -20,8 +20,6 @@
*/ */
class GameRulesAPI extends AcediaObject; class GameRulesAPI extends AcediaObject;
var private LoggerAPI.Definition errNoService;
/** /**
* Called when game decides on a player's spawn point. If a `NavigationPoint` * Called when game decides on a player's spawn point. If a `NavigationPoint`
* is returned, signal propagation will be interrupted and returned value will * is returned, signal propagation will be interrupted and returned value will
@ -46,15 +44,84 @@ public final function GameRules_OnFindPlayerStart_Slot OnFindPlayerStart(
local Signal signal; local Signal signal;
local UnrealService service; local UnrealService service;
service = UnrealService(class'UnrealService'.static.Require()); service = UnrealService(class'UnrealService'.static.Require());
if (service == none)
{
_.logger.Auto(errNoService);
return none;
}
signal = service.GetSignal(class'GameRules_OnFindPlayerStart_Signal'); signal = service.GetSignal(class'GameRules_OnFindPlayerStart_Signal');
return GameRules_OnFindPlayerStart_Slot(signal.NewSlot(receiver)); return GameRules_OnFindPlayerStart_Slot(signal.NewSlot(receiver));
} }
/**
* Called in `GameInfo`'s `RestartGame()` method and allows to prevent
* game's restart.
*
* This signal will always be propagated to all registered slots.
*
* [Signature]
* bool <slot>()
*
* @return `true` if you want to prevent game restart and `false` otherwise.
*/
/* SIGNAL */
public final function GameRules_OnHandleRestartGame_Slot OnHandleRestartGame(
AcediaObject receiver)
{
local Signal signal;
local UnrealService service;
service = UnrealService(class'UnrealService'.static.Require());
signal = service.GetSignal(class'GameRules_OnHandleRestartGame_Signal');
return GameRules_OnHandleRestartGame_Slot(signal.NewSlot(receiver));
}
/**
* Allows modification of game ending conditions.
* Return `false` to prevent game from ending.
*
* This signal will always be propagated to all registered slots.
*
* [Signature]
* bool <slot>(PlayerReplicationInfo winner, string reason)
*
* @param winner Replication info of the supposed winner of the game.
* @param reason String with a description about how/why `winner` has won.
* @return `false` if you want to prevent game from ending
* and `false` otherwise.
*/
/* SIGNAL */
public final function GameRules_OnCheckEndGame_Slot OnCheckEndGame(
AcediaObject receiver)
{
local Signal signal;
local UnrealService service;
service = UnrealService(class'UnrealService'.static.Require());
signal = service.GetSignal(class'GameRules_OnHandleRestartGame_Signal');
return GameRules_OnCheckEndGame_Slot(signal.NewSlot(receiver));
}
/* CheckScore()
*/
/**
* Check if this score means the game ends.
*
* Return `true` to override `GameInfo`'s `CheckScore()`, or if game was ended
* (with a call to `Level.Game.EndGame()`).
*
* [Signature]
* bool <slot>(PlayerReplicationInfo scorer)
*
* @param scorer For whom to do a score check.
* @return `true` to override `GameInfo`'s `CheckScore()`, or if game was ended
* and `false` otherwise.
*/
/* SIGNAL */
public final function GameRules_OnCheckScore_Slot OnCheckScore(
AcediaObject receiver)
{
local Signal signal;
local UnrealService service;
service = UnrealService(class'UnrealService'.static.Require());
signal = service.GetSignal(class'GameRules_OnCheckScore_Signal');
return GameRules_OnCheckScore_Slot(signal.NewSlot(receiver));
}
/** /**
* When pawn wants to pickup something, `GameRule`s are given a chance to * 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 * modify it. If one of the `Slot`s returns `true`, `allowPickup` will
@ -82,16 +149,10 @@ public final function GameRules_OnOverridePickupQuery_Slot
local Signal signal; local Signal signal;
local UnrealService service; local UnrealService service;
service = UnrealService(class'UnrealService'.static.Require()); service = UnrealService(class'UnrealService'.static.Require());
if (service == none)
{
_.logger.Auto(errNoService);
return none;
}
signal = service.GetSignal(class'GameRules_OnOverridePickupQuery_Signal'); signal = service.GetSignal(class'GameRules_OnOverridePickupQuery_Signal');
return GameRules_OnOverridePickupQuery_Slot(signal.NewSlot(receiver)); return GameRules_OnOverridePickupQuery_Slot(signal.NewSlot(receiver));
} }
// TODO: rewrite
/** /**
* When pawn wants to pickup something, `GameRule`s are given a chance to * 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 * modify it. If one of the `Slot`s returns `true`, `allowPickup` will
@ -119,11 +180,6 @@ public final function GameRules_OnNetDamage_Slot OnNetDamage(
local Signal signal; local Signal signal;
local UnrealService service; local UnrealService service;
service = UnrealService(class'UnrealService'.static.Require()); service = UnrealService(class'UnrealService'.static.Require());
if (service == none)
{
_.logger.Auto(errNoService);
return none;
}
signal = service.GetSignal(class'GameRules_OnNetDamage_Signal'); signal = service.GetSignal(class'GameRules_OnNetDamage_Signal');
return GameRules_OnNetDamage_Slot(signal.NewSlot(receiver)); return GameRules_OnNetDamage_Slot(signal.NewSlot(receiver));
} }
@ -228,5 +284,4 @@ public final function bool AreAdded(
defaultproperties defaultproperties
{ {
errNoService = (l=LOG_Error,m="`UnrealService` could not be reached.")
} }

7
sources/Unreal/UnrealService.uc

@ -87,6 +87,9 @@ public event Tick(float delta)
defaultproperties defaultproperties
{ {
serviceSignals(0) = (signalClass=class'GameRules_OnFindPlayerStart_Signal') serviceSignals(0) = (signalClass=class'GameRules_OnFindPlayerStart_Signal')
serviceSignals(1) = (signalClass=class'GameRules_OnOverridePickupQuery_Signal') serviceSignals(1) = (signalClass=class'GameRules_OnHandleRestartGame_Signal')
serviceSignals(2) = (signalClass=class'GameRules_OnNetDamage_Signal') serviceSignals(2) = (signalClass=class'GameRules_OnCheckEndGame_Signal')
serviceSignals(3) = (signalClass=class'GameRules_OnCheckScore_Signal')
serviceSignals(4) = (signalClass=class'GameRules_OnOverridePickupQuery_Signal')
serviceSignals(5) = (signalClass=class'GameRules_OnNetDamage_Signal')
} }
Loading…
Cancel
Save