-
Notifications
You must be signed in to change notification settings - Fork 0
/
AbilityManager.cs
198 lines (184 loc) · 7.88 KB
/
AbilityManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ScriptableObjectArchitecture;
// Manage the player's abilities
public class AbilityManager : MonoBehaviour
{
[Header("Setup all Abilities and Pick-able Abilites")]
[SerializeField] private AbilityCollection playerAbilities; // All PlayerType Abilities in the game
[SerializeField] private AbilityCollection allPassives; // All Common Passives
[SerializeField] private AbilityCollection allDamages; // All Common Damages
[SerializeField] private AbilityCollection allStatsBuff; // All Stats Buff
[SerializeField] private AbilityCollection allProtections; // All Common Protection
private List<AbilityBase> availableAbilities = new List<AbilityBase>(); // What Ability can appear in the Scene
[Header("First and current Abilities")]
[SerializeField] private PlayerData stagePlayerData; // Mapping of PlayerType and Starting Ability
[SerializeField] private AbilityCollection currentAbilities; // Current abilities that player have
[Header("Modify Abilities stuff")]
[SerializeField] private AbilityGameEvent modifyAbility; // Let player changes ability (Raised in UIManager.cs)
[SerializeField] private GameEvent levelUpSetUpAbility; // Show 4 Abilities when Level Up (Raised in GameManager.cs)
[SerializeField] private AbilityCollection abilitiesToPick; // List of 4 Abilities to pick when LvlUp
[SerializeField] private GameEvent levelUpAbilityUIPopUp; // Setup in UIManager.cs
[SerializeField] private AbilityDistribution _abilityDistribution; // Act as a reference to abilityDistribution
[SerializeField] private AbilityGameEvent updateAbilityPanel; // Setup in UIManager.cs
[SerializeField] private AbilityGameEvent updateAbilityInfo; // Setup in UIManager.cs
private AbilityDistribution abilityDistribution;
private void Awake()
{
// Setup ScriptableObjects Variables and Game Events
currentAbilities.Clear();
modifyAbility.AddListener(ModifyAbility);
levelUpSetUpAbility.AddListener(SetupAbilitiesWhenLvlUp);
// Which Ability can be picked in the scene
PlayerType runtimePlayerType = stagePlayerData.type;
foreach (AbilityBase ability in playerAbilities)
{
if (ability.playerType == runtimePlayerType)
{
ability.PreInit();
if (ability is DamageAbilityBase _damageAbility)
{
_damageAbility.SetupCritChance(stagePlayerData.critChance);
}
availableAbilities.Add(ability);
}
}
for (int i = 0; i < allPassives.Count; i++)
{
AbilityBase passiveAbility = allPassives[i];
passiveAbility.PreInit();
availableAbilities.Add(passiveAbility);
}
for (int i = 0; i < allDamages.Count; i++)
{
DamageAbilityBase damageAbility = allDamages[i] as DamageAbilityBase;
damageAbility.PreInit();
damageAbility.SetupCritChance(stagePlayerData.critChance);
availableAbilities.Add(damageAbility);
}
for (int i = 0; i < allStatsBuff.Count; i++)
{
AbilityBase statBuff = allStatsBuff[i];
statBuff.PreInit();
availableAbilities.Add(statBuff);
}
for (int i = 0; i < allProtections.Count; i++)
{
AbilityBase protectionAbility = allProtections[i];
protectionAbility.PreInit();
availableAbilities.Add(protectionAbility);
}
// Set up AbilityDistribution
abilityDistribution = gameObject.GetComponent<AbilityDistribution>();
foreach (AbilityBase ability in availableAbilities)
{
abilityDistribution.Add(ability, ability.weight);
}
_abilityDistribution.SetItems(abilityDistribution.items);
}
private void Start()
{
currentAbilities.Add(stagePlayerData.startingAbility);
currentAbilities[0].Initialize();
updateAbilityPanel.Raise(stagePlayerData.startingAbility);
updateAbilityInfo.Raise(stagePlayerData.startingAbility);
}
private void OnDisable()
{
modifyAbility.RemoveListener(ModifyAbility);
levelUpSetUpAbility.RemoveListener(SetupAbilitiesWhenLvlUp);
}
private void Update()
{
// Loop through list of ability, if ability is ready, trigger it
// Switching from COOLDOWN to READY state is handled through this function since every ability follows a SINGLE COOLDOWN RULE
// Switching from READY to COOLDOWN state is handled IN THE BULLET SCRIPT
for (int i = 0; i < currentAbilities.Count; i++)
{
AbilityBase ability = currentAbilities[i];
if (ability.state == AbilityBase.AbilityState.ready)
{
ability.TriggerAbility();
ability.state = AbilityBase.AbilityState.active;
}
if (ability.state == AbilityBase.AbilityState.cooldown)
{
if (ability.internalCooldownTime < ability.currentCooldownTime)
{
ability.internalCooldownTime += Time.deltaTime;
}
else
{
ability.state = AbilityBase.AbilityState.ready;
ability.internalCooldownTime = 0;
}
}
}
}
// Allow player to add/ increase the level of Ability
private void ModifyAbility(AbilityBase ability)
{
// If player does not have this ability
if (!currentAbilities.Contains(ability))
{
// Create a new BulletPool for this ability and add it to the List
currentAbilities.Add(ability);
ability.Initialize();
// Update the Ability panel
updateAbilityPanel.Raise(ability);
updateAbilityInfo.Raise(ability);
}
// If player already has this ability
else
{
ability.UpgradeAbility(); // Upgrade
}
// De-Active the ability selection UI
levelUpAbilityUIPopUp.Raise();
}
// Setup Abilities to pick in UI
// Then activate the UI for picking Ability
private void SetupAbilitiesWhenLvlUp()
{
_abilityDistribution.items.Clear();
// Init Referenced Distribution
_abilityDistribution.SetItems(abilityDistribution.items);
// Check if Abilities meets requirements to be picked
// Loop through all Abilities
for (int i = _abilityDistribution.items.Count - 1; i >= 0; i--)
{
AbilityBase ability = _abilityDistribution.items[i].value;
// Perform the check:
// 1. If max level
// 2. If not ready to be init
if (ability.IsMaxLevel() || !ability.CanBeInit())
{
int index = _abilityDistribution.IndexOf(ability);
_abilityDistribution.RemoveAt(index);
}
// Check if Ability is initialized, which player already have
// Then re-adjust the weight
if (ability.isInitialized)
{
float w = ability.GetUpgradeDataInfo().weight;
_abilityDistribution.items[i].weight = w;
}
}
abilitiesToPick.Clear();
for (int i = 0; i < 4; i++)
{
if (_abilityDistribution.items.Count > 0)
{
AbilityBase ability = _abilityDistribution.Draw();
int abilityIndex = _abilityDistribution.IndexOf(ability);
// Remove from the Referenced Distribution so we don't draw it AGAIN!
_abilityDistribution.RemoveAt(abilityIndex);
abilitiesToPick.Add(ability);
}
}
// Active the ability selection UI
levelUpAbilityUIPopUp.Raise();
}
}