134 lines
3.6 KiB
GDScript
134 lines
3.6 KiB
GDScript
extends NpcScript
|
|
|
|
# Mission parameters
|
|
var rewardExp : int = 1000
|
|
var rewardGP : int = 10000
|
|
|
|
# Wave parameters
|
|
var monstersPool : Array[EntityData] = []
|
|
const checkDelay : float = 2.0
|
|
const waveDelay : float = 300.0
|
|
const maxWave : int = 10
|
|
const spawnCenter : Vector2i = Vector2i(54 * 32, 67 * 32)
|
|
const spawnRadius : Vector2i = Vector2i(200, 200)
|
|
const startFightDelay : float = 10.0
|
|
const warmUpTickDelay : float = 1.0
|
|
|
|
# Local variables
|
|
var waveTimer : Timer = null
|
|
var waveCount : int = 0
|
|
var originalPlayerCount : int = 0
|
|
var waveMaxMonsters : int = 0
|
|
var playerList : Array[PlayerAgent] = []
|
|
|
|
#
|
|
func OnStart():
|
|
for mobID in DB.EntitiesDB:
|
|
var mob : EntityData = DB.EntitiesDB[mobID]
|
|
if !!(mob._behaviour & AICommons.Behaviour.AGGRESSIVE) and !(mob._behaviour & AICommons.Behaviour.IMMOBILE) and !mob._isBoss:
|
|
monstersPool.append(mob)
|
|
|
|
func OnCancel():
|
|
ClearTimer(waveTimer)
|
|
ClearPlayerList()
|
|
Reset()
|
|
if IsTriggering():
|
|
Trigger()
|
|
ClearTracker()
|
|
KillMonsters()
|
|
|
|
func OnTrigger():
|
|
AddTimer(npc, startFightDelay, StartFight)
|
|
TickWarmUp(0)
|
|
|
|
func TickWarmUp(tick : int):
|
|
if not IsTriggering():
|
|
return
|
|
DisplayTracker("Warm Up", tick, int(startFightDelay), "s")
|
|
if tick < int(startFightDelay):
|
|
AddTimer(npc, warmUpTickDelay, TickWarmUp.bind(tick + 1), "WarmUpTimer")
|
|
|
|
#
|
|
func RemoveFromPlayerList(player : PlayerAgent):
|
|
playerList.erase(player)
|
|
|
|
func ClearPlayerList():
|
|
for player in playerList:
|
|
Callback.ClearOneShot(player.tree_exiting)
|
|
Callback.ClearOneShot(player.agent_killed)
|
|
playerList.clear()
|
|
|
|
func StartFight():
|
|
Reset()
|
|
var ownInstance : WorldInstance = WorldAgent.GetInstanceFromAgent(own)
|
|
if ownInstance:
|
|
for player : PlayerAgent in ownInstance.players:
|
|
if ActorCommons.IsAlive(player):
|
|
playerList.append(player)
|
|
Callback.OneShotCallback(player.tree_exiting, RemoveFromPlayerList.bind(player))
|
|
Callback.OneShotCallback(player.agent_killed, RemoveFromPlayerList.bind(player))
|
|
originalPlayerCount = playerList.size()
|
|
waveTimer = AddTimer(npc, waveDelay, TimeoutWave)
|
|
NextWave()
|
|
|
|
func NextWave():
|
|
waveCount += 1
|
|
if waveCount > maxWave:
|
|
Reward()
|
|
else:
|
|
Notification("Wave %d." % waveCount)
|
|
SpawnMonsters()
|
|
waveMaxMonsters = AliveMonsterCount()
|
|
DisplayTracker("Monsters", 0, waveMaxMonsters)
|
|
waveTimer.start(waveDelay)
|
|
AddTimer(npc, checkDelay, CheckWave, "CheckTimer")
|
|
|
|
func Reset():
|
|
waveTimer = null
|
|
waveCount = 0
|
|
originalPlayerCount = 0
|
|
waveMaxMonsters = 0
|
|
|
|
func Reward():
|
|
Notification("Congrats, you won")
|
|
ClearTracker()
|
|
for player : PlayerAgent in playerList:
|
|
NpcCommons.AddExp(player, rewardExp)
|
|
NpcCommons.AddGP(player, rewardGP)
|
|
ClearPlayerList()
|
|
Reset()
|
|
if IsTriggering():
|
|
Trigger()
|
|
|
|
func SpawnMonsters():
|
|
var isStuck : bool = false
|
|
var remainingPoints : int = (5 * waveCount) + ceili(originalPlayerCount * 0.7)
|
|
monstersPool.shuffle()
|
|
while(remainingPoints > 0 and not isStuck):
|
|
isStuck = true
|
|
for mob in monstersPool:
|
|
var mobPoint : int = mob._stats["Level"] if "Level" in mob._stats else 1
|
|
if mobPoint > 0 and mobPoint <= remainingPoints:
|
|
var spawnAmount : int = randi_range(1, int(remainingPoints / floor(mobPoint)))
|
|
remainingPoints -= mobPoint * spawnAmount
|
|
Spawn(mob._id, spawnAmount, spawnCenter, spawnRadius)
|
|
|
|
func CheckWave():
|
|
if not IsTriggering():
|
|
return
|
|
|
|
if AlivePlayerCount() == 0:
|
|
OnCancel()
|
|
else:
|
|
var mobCount : int = AliveMonsterCount()
|
|
if mobCount > 0:
|
|
waveMaxMonsters = max(waveMaxMonsters, mobCount)
|
|
DisplayTracker("Monsters", waveMaxMonsters - mobCount, waveMaxMonsters)
|
|
AddTimer(npc, checkDelay, CheckWave, "CheckTimer")
|
|
else:
|
|
NextWave()
|
|
|
|
func TimeoutWave():
|
|
Notification("You were not able to clear the corruption in time.")
|
|
OnCancel()
|