179 lines
6.3 KiB
Ucode
179 lines
6.3 KiB
Ucode
//==============================================================================
|
|
// NicePack / NiceAbilityManager
|
|
//==============================================================================
|
|
// Class that manager active abilities, introduced along with a NicePack.
|
|
// Can support at most 5 ('maxAbilitiesAmount') different abilities at once.
|
|
// NICETODO: refactor later
|
|
//==============================================================================
|
|
// 'Nice pack' source
|
|
// Do whatever the fuck you want with it
|
|
// Author: dkanus
|
|
// E-mail: dkanus@gmail.com
|
|
//==============================================================================
|
|
class NiceAbilityManager extends Actor;
|
|
var const int maxAbilitiesAmount;
|
|
// Defines a list of all possible ability's states
|
|
enum EAbilityState{
|
|
// Ability is ready to use
|
|
ASTATE_READY,
|
|
// Ability is being used
|
|
ASTATE_ACTIVE,
|
|
// Ability is on cooldown
|
|
ASTATE_COOLDOWN
|
|
};
|
|
// Describes all the necessary information about an ability
|
|
struct NiceAbilityDescription{
|
|
// Ability's ID, supposed to be unique per ability,
|
|
// but no checks are enforced yet
|
|
var string ID;
|
|
// Image to be used as an ability's icon
|
|
var Texture icon;
|
|
// Default cooldown duration
|
|
var int cooldownLength;
|
|
// Can ability be canceled once activated?
|
|
var bool canBeCancelled;
|
|
};
|
|
// Complete description of current status of an ability,
|
|
// including it's complete description.
|
|
struct NiceAbilityStatus{
|
|
// Complete description of ability in question
|
|
var NiceAbilityDescription description;
|
|
// Current cooldown value
|
|
var int cooldown;
|
|
// Current state of an ability
|
|
var EAbilityState myState;
|
|
};
|
|
var NiceAbilityStatus currentAbilities[5];
|
|
var int currentAbilitiesAmount;
|
|
// Refers to the player whose abilities we manage
|
|
var NicePlayerController relatedPlayer;
|
|
var const class<NiceAbilitiesEvents> events;
|
|
// Unfortunately this hackk is required to force replication of structure array
|
|
var int hackCounter;
|
|
replication{
|
|
reliable if(Role == ROLE_Authority)
|
|
currentAbilities, currentAbilitiesAmount, hackCounter;
|
|
}
|
|
simulated function PostBeginPlay(){
|
|
relatedPlayer = NicePlayerController(owner);
|
|
}
|
|
function AddAbility(NiceAbilityDescription description){
|
|
local int i;
|
|
local NiceAbilityStatus newRecord;
|
|
if(currentAbilitiesAmount >= maxAbilitiesAmount) return;
|
|
for(i = 0;i < currentAbilitiesAmount;i ++)
|
|
if(currentAbilities[i].description.ID ~= description.ID)
|
|
return;
|
|
newRecord.description = description;
|
|
newRecord.cooldown = 0;
|
|
newRecord.myState = ASTATE_READY;
|
|
currentAbilities[currentAbilitiesAmount] = newRecord;
|
|
currentAbilitiesAmount += 1;
|
|
events.static.CallAbilityAdded(description.ID, relatedPlayer);
|
|
netUpdateTime = level.timeSeconds - 1;
|
|
}
|
|
function RemoveAbility(string abilityID){
|
|
local int i, j;
|
|
local bool wasRemoved;
|
|
j = 0;
|
|
for(i = 0;i < currentAbilitiesAmount;i ++){
|
|
if(currentAbilities[i].description.ID ~= abilityID){
|
|
wasRemoved = true;
|
|
continue;
|
|
}
|
|
currentAbilities[j] = currentAbilities[i];
|
|
j += 1;
|
|
}
|
|
currentAbilitiesAmount = j;
|
|
if(wasRemoved)
|
|
events.static.CallAbilityRemoved(abilityID, relatedPlayer);
|
|
netUpdateTime = level.timeSeconds - 1;
|
|
}
|
|
function ClearAbilities(){
|
|
currentAbilitiesAmount = 0;
|
|
netUpdateTime = level.timeSeconds - 1;
|
|
}
|
|
// Returns index of the ability with a given name.
|
|
// Returns '-1' if such ability doesn't exist.
|
|
simulated function int GetAbilityIndex(string abilityID){
|
|
local int i;
|
|
for(i = 0;i < currentAbilitiesAmount;i ++)
|
|
if(currentAbilities[i].description.ID ~= abilityID)
|
|
return i;
|
|
return -1;
|
|
}
|
|
simulated function bool IsAbilityActive(string abilityID){
|
|
local int index;
|
|
index = GetAbilityIndex(abilityID);
|
|
if(index < 0)
|
|
return false;
|
|
return (currentAbilities[index].myState == ASTATE_ACTIVE);
|
|
}
|
|
// Sets ability to a proper state.
|
|
// Does nothing if ability is already in a specified state.
|
|
// Setting active ability to a ready state is only allowed
|
|
// if ability can be canceled.
|
|
// Updates cooldown to full length if new state is 'ASTATE_COOLDOWN'.
|
|
function SetAbilityState(int abilityIndex, EAbilityState newState){
|
|
local float cooldown;
|
|
local EAbilityState currentState;
|
|
if(abilityIndex < 0 || abilityIndex >= currentAbilitiesAmount) return;
|
|
currentState = currentAbilities[abilityIndex].myState;
|
|
if(currentState == newState)
|
|
return;
|
|
if( currentState == ASTATE_ACTIVE && newState == ASTATE_READY
|
|
&& !currentAbilities[abilityIndex].description.canBeCancelled)
|
|
return;
|
|
currentAbilities[abilityIndex].myState = newState;
|
|
if(newState == ASTATE_COOLDOWN){
|
|
cooldown = currentAbilities[abilityIndex].description.cooldownLength;
|
|
events.static.CallModAbilityCooldown(
|
|
currentAbilities[abilityIndex].description.ID,
|
|
relatedPlayer,
|
|
cooldown
|
|
);
|
|
currentAbilities[abilityIndex].cooldown = cooldown;
|
|
}
|
|
hackCounter ++;
|
|
netUpdateTime = level.timeSeconds - 1;
|
|
// Fire off events
|
|
if(newState == ASTATE_ACTIVE){
|
|
events.static.CallAbilityActivated(
|
|
currentAbilities[abilityIndex].description.ID,
|
|
relatedPlayer
|
|
);
|
|
}
|
|
}
|
|
// Changes ability's cooldown by a given amount.
|
|
// If this brings cooldown to zero or below -
|
|
// resets current ability to a 'ready' (ASTATE_READY) state.
|
|
function AddToCooldown(int abilityIndex, int delta){
|
|
if(abilityIndex < 0 || abilityIndex >= currentAbilitiesAmount) return;
|
|
if(currentAbilities[abilityIndex].myState != ASTATE_COOLDOWN) return;
|
|
currentAbilities[abilityIndex].cooldown += delta;
|
|
if(currentAbilities[abilityIndex].cooldown <= 0)
|
|
SetAbilityState(abilityIndex, ASTATE_READY);
|
|
hackCounter ++;
|
|
}
|
|
|
|
function AddToAllCooldowns(int delta){
|
|
local int i;
|
|
|
|
for (i = 0; i < currentAbilitiesAmount; i += 1) {
|
|
if (currentAbilities[i].myState == ASTATE_COOLDOWN) {
|
|
currentAbilities[i].cooldown += delta;
|
|
if(currentAbilities[i].cooldown <= 0) {
|
|
SetAbilityState(i, ASTATE_READY);
|
|
}
|
|
}
|
|
}
|
|
hackCounter ++;
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
maxAbilitiesAmount=5
|
|
Events=class'NiceAbilitiesEvents'
|
|
DrawType=DT_None
|
|
}
|