class_name Wave # 元数据 var entity: String var minCount: int = 1 var maxCount: int = 1 var isBoss: bool = false var from: float = 0 var to: float = 0 var per: int = 0 # 实例数据 var entityPosition: Vector2 func duplicate() -> Wave: var wave = Wave.new() wave.entity = entity wave.minCount = minCount wave.maxCount = maxCount wave.isBoss = isBoss wave.from = from wave.to = to wave.per = per return wave static var GAME_BOSSES = ["Chick", "Deepsea", "KukeMC", "CyberCat", "Kernyr", "EnergyBlock", "Bear"] static var WAVE_NORMAL = [ Wave.create("Hen", 1, 3, false, 2, INF, 1), Wave.create("Cat", 1, 5, false, 0, INF, 1), Wave.create("Dog", 1, 2, false, 4, INF, 1), Wave.create("MTY", 0, 1, false, 6, INF, 7), Wave.create("Chick", 0, 0, true, 9, INF, 20), Wave.create("KukeMC", 0, 0, true, 19, INF, 20), Wave.create("Bear", 0, 0, true, 29, INF, 23), ] static var WAVE_BOSSRUSH = ArrayTool.betterMap(GAME_BOSSES, func(x: String, i: int, _arr: Array): return Wave.create(x, 0, 0, true, i, INF, len(GAME_BOSSES))) static var WAVE_MOWING = [ Wave.create("Hen", 15, 30, false, 0, INF, 1), Wave.create("Cat", 15, 30, false, 0, INF, 1), Wave.create("Dog", 15, 30, false, 0, INF, 1), Wave.create("MTY", 0, 2, false, 0, INF, 1), ] static var WAVE_TESTBOSS = [ Wave.create("EnergyBlock", 0, 0, true, 0, INF, 1), ] static var WAVE_TESTMOB = [] static var WAVE_EMPTY = [] static var waveReleaseConfig = [WAVE_TESTBOSS, 1] static var waveDebugConfig = [WAVE_TESTMOB, 1] static var current: int = startWith(waveReleaseConfig[1]) if WorldManager.isRelease() else startWith(waveDebugConfig[1]) static var usingWaveData = waveReleaseConfig[0] if WorldManager.isRelease() else waveDebugConfig[0] static func create( entity_: String, minCount_: int = 1, maxCount_: int = 1, isBoss_: bool = false, from_: float = 0, to_: float = 0, per_: int = 0 ) -> Wave: var wave = Wave.new() wave.entity = entity_ wave.minCount = minCount_ wave.maxCount = maxCount_ wave.isBoss = isBoss_ wave.from = from_ wave.to = to_ wave.per = per_ return wave static func hasBoss() -> bool: for wave in usingWaveData: if canSpawn(wave): if wave.isBoss: return true return false static func canSpawn(wave: Wave) -> bool: return wave.from <= current and wave.to >= current and int(current - wave.from) % wave.per == 0 static func entityCountOf(wave: Wave) -> int: if canSpawn(wave): if wave.isBoss: return 1 elif !hasBoss() || GameRule.canSpawnMobWhenBossWave: return randi_range(ceil(wave.minCount), floor(wave.maxCount * (1 + GameRule.entityCountBoostPerWave * current))) return 0 static func getNextBossInfo() -> Array: var nextBossName = "" var minWavesLeft = INF for wave in usingWaveData: if wave.isBoss: var wavesLeft = wave.from - current if wavesLeft > 0 and wavesLeft < minWavesLeft: minWavesLeft = wavesLeft nextBossName = ComponentManager.getCharacter(wave.entity).instantiate().displayName if minWavesLeft < INF: return [nextBossName, minWavesLeft] return [] static func spawn(center: Vector2) -> Array: var result: Array = [] for i in range(len(usingWaveData)): var wave: Wave = usingWaveData[i] for j in range(entityCountOf(wave)): var currentWave = wave.duplicate() currentWave.entityPosition = MathTool.sampleInRing(400, 800) + center result.append(currentWave) return result static func next(waves: Array): for wave in waves: if wave is EncodedObjectAsID: wave = instance_from_id(wave.get_instance_id()) EntityBase.generate(ComponentManager.getCharacter(wave.entity), wave.entityPosition, true, wave.isBoss) current += 1 UIState.showTip("第%d波开始!" % current, TipBox.MessageType.INFO) showNextBossReminder() static func showNextBossReminder(): var nextBossInfo = getNextBossInfo() if nextBossInfo: var bossName = nextBossInfo[0] var wavesLeft = nextBossInfo[1] if wavesLeft > 0: UIState.showTip("Boss [b]%s[/b] 将在[b]%d[/b]波后到来!" % [bossName, wavesLeft], TipBox.MessageType.WARNING) static func startWith(wave: int): return wave - 1