2025-08-26 17:28:20 +08:00
|
|
|
class_name Wave
|
|
|
|
|
|
2025-11-13 22:39:36 +08:00
|
|
|
# 元数据
|
2025-09-21 14:47:43 +08:00
|
|
|
var entity: String
|
2025-08-26 17:28:20 +08:00
|
|
|
var minCount: int = 1
|
|
|
|
|
var maxCount: int = 1
|
|
|
|
|
var isBoss: bool = false
|
|
|
|
|
var from: float = 0
|
|
|
|
|
var to: float = 0
|
|
|
|
|
var per: int = 0
|
2025-11-13 22:39:36 +08:00
|
|
|
# 实例数据
|
|
|
|
|
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
|
2025-08-26 17:28:20 +08:00
|
|
|
|
2026-02-04 23:00:17 +08:00
|
|
|
static var current: int = startWith(1) if WorldManager.isRelease() else startWith(1)
|
2025-09-13 19:55:21 +08:00
|
|
|
static var WAVE_NORMAL = [
|
2025-11-16 14:51:36 +08:00
|
|
|
Wave.create("Hen", 1, 3, false, 0, INF, 1),
|
2026-01-17 11:46:01 +08:00
|
|
|
Wave.create("Cat", 1, 5, false, 0, INF, 1),
|
|
|
|
|
Wave.create("Dog", 1, 2, false, 0, INF, 1),
|
|
|
|
|
Wave.create("MTY", 0, 1, false, 4, INF, 4),
|
2025-12-06 19:59:16 +08:00
|
|
|
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, 20),
|
2025-09-13 19:55:21 +08:00
|
|
|
]
|
2025-09-19 22:26:08 +08:00
|
|
|
static var WAVE_TESTBOSS_ALL = [
|
2025-11-09 10:56:13 +08:00
|
|
|
Wave.create("Chick", 0, 0, true, 0, INF, 3),
|
|
|
|
|
Wave.create("KukeMC", 0, 0, true, 1, INF, 3),
|
|
|
|
|
Wave.create("Bear", 0, 0, true, 2, INF, 3),
|
2025-09-19 22:26:08 +08:00
|
|
|
]
|
|
|
|
|
static var WAVE_TESTBOSS_KUKE = [
|
2025-09-21 14:47:43 +08:00
|
|
|
Wave.create("KukeMC", 0, 0, true, 0, INF, 10),
|
2025-09-13 19:55:21 +08:00
|
|
|
]
|
2025-09-25 22:41:04 +08:00
|
|
|
static var WAVE_TESTBOSS_BEAR = [
|
|
|
|
|
Wave.create("Bear", 0, 0, true, 0, INF, 10),
|
|
|
|
|
]
|
|
|
|
|
static var WAVE_TESTBOSS_CHICK = [
|
|
|
|
|
Wave.create("Chick", 0, 0, true, 0, INF, 10),
|
|
|
|
|
]
|
2025-09-18 22:42:43 +08:00
|
|
|
static var WAVE_EMPTY = []
|
2025-12-14 15:31:53 +08:00
|
|
|
static var data = WAVE_NORMAL if WorldManager.isRelease() else WAVE_NORMAL
|
2025-08-26 17:28:20 +08:00
|
|
|
|
|
|
|
|
static func create(
|
2025-09-21 14:47:43 +08:00
|
|
|
entity_: String,
|
2025-08-26 17:28:20 +08:00
|
|
|
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
|
2025-11-16 16:01:03 +08:00
|
|
|
static func hasBoss() -> bool:
|
|
|
|
|
for wave in data:
|
|
|
|
|
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
|
2025-08-26 17:28:20 +08:00
|
|
|
static func entityCountOf(wave: Wave) -> int:
|
2025-11-16 16:01:03 +08:00
|
|
|
if canSpawn(wave):
|
2025-08-26 17:38:45 +08:00
|
|
|
if wave.isBoss:
|
|
|
|
|
return 1
|
2025-11-16 16:01:03 +08:00
|
|
|
elif !hasBoss():
|
2025-08-28 07:45:50 +08:00
|
|
|
return randi_range(ceil(wave.minCount), floor(wave.maxCount * (1 + GameRule.entityCountBoostPerWave * current)))
|
2025-08-26 17:28:20 +08:00
|
|
|
return 0
|
2026-01-24 20:07:06 +08:00
|
|
|
static func getNextBossInfo() -> Array:
|
|
|
|
|
var nextBossName = ""
|
|
|
|
|
var minWavesLeft = INF
|
|
|
|
|
for wave in data:
|
|
|
|
|
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 []
|
2025-12-14 15:01:01 +08:00
|
|
|
static func spawn(center: Vector2) -> Array:
|
2025-11-14 22:44:26 +08:00
|
|
|
var result: Array = []
|
2025-08-26 17:28:20 +08:00
|
|
|
for i in range(len(data)):
|
2025-11-13 22:39:36 +08:00
|
|
|
var wave: Wave = data[i]
|
2025-08-26 17:28:20 +08:00
|
|
|
for j in range(entityCountOf(wave)):
|
2025-11-13 22:39:36 +08:00
|
|
|
var currentWave = wave.duplicate()
|
2026-01-18 15:31:52 +08:00
|
|
|
currentWave.entityPosition = MathTool.sampleInRing(200, 1000) + center
|
2025-11-13 22:39:36 +08:00
|
|
|
result.append(currentWave)
|
|
|
|
|
return result
|
2025-11-14 22:44:26 +08:00
|
|
|
static func next(waves: Array):
|
2025-11-13 22:39:36 +08:00
|
|
|
for wave in waves:
|
2025-11-14 22:44:26 +08:00
|
|
|
if wave is EncodedObjectAsID:
|
|
|
|
|
wave = instance_from_id(wave.get_instance_id())
|
2025-11-13 22:39:36 +08:00
|
|
|
EntityBase.generate(ComponentManager.getCharacter(wave.entity), wave.entityPosition, true, wave.isBoss)
|
2025-08-26 17:28:20 +08:00
|
|
|
current += 1
|
2026-01-25 21:40:26 +08:00
|
|
|
UIState.showTip("第%d波开始!" % current, TipBox.MessageType.INFO)
|
2026-01-24 20:07:06 +08:00
|
|
|
showNextBossReminder()
|
|
|
|
|
static func showNextBossReminder():
|
|
|
|
|
var nextBossInfo = getNextBossInfo()
|
|
|
|
|
if nextBossInfo:
|
|
|
|
|
var bossName = nextBossInfo[0]
|
|
|
|
|
var wavesLeft = nextBossInfo[1]
|
|
|
|
|
if wavesLeft > 0:
|
2026-01-25 21:40:26 +08:00
|
|
|
UIState.showTip("Boss [b]%s[/b] 将在[b]%d[/b]波后到来!" % [bossName, wavesLeft], TipBox.MessageType.WARNING)
|
2026-01-24 20:07:06 +08:00
|
|
|
|
2025-11-09 10:56:13 +08:00
|
|
|
static func startWith(wave: int):
|
|
|
|
|
return wave - 1
|