mirror of
https://gitlab.com/the-no-frauds-club/cosmonarchy-bw-prerelease.git
synced 2026-09-17 01:01:12 +00:00
152 lines
4.7 KiB
Lua
152 lines
4.7 KiB
Lua
-- Setup main variables
|
|
local player = Player()
|
|
if player.type ~= PlayerType.Computer then
|
|
return
|
|
end
|
|
local ai = AI()
|
|
local config = PlayerVars().ai_config or {}
|
|
|
|
local main_town = ai:start_town()
|
|
|
|
-- Neat way to organize stuff is to use a table
|
|
local brain = {
|
|
saw_air_units = false,
|
|
}
|
|
|
|
---@param town Town
|
|
local function flyer_watch(town)
|
|
wait_until(function() return brain.saw_air_units end)
|
|
for i = 1, 5 do
|
|
town:build(i, UnitId.TerranWatchdog, 70-i)
|
|
wait(secs(30 + 5 * i))
|
|
end
|
|
end
|
|
|
|
---@param town Town
|
|
local function build_main_town(town)
|
|
town:build(20, UnitId.TerranMason, 90)
|
|
wait(secs(30))
|
|
town:build(1, UnitId.TerranStockade, 100)
|
|
wait(secs(90))
|
|
town:build(2, UnitId.TerranStockade, 90)
|
|
wait(secs(5))
|
|
town:build(3, UnitId.TerranStockade, 70)
|
|
wait(mins(1))
|
|
town:multirun(flyer_watch)
|
|
town:build(4, UnitId.TerranStockade, 70)
|
|
end
|
|
|
|
---@param town Town
|
|
local function build_expo(town)
|
|
cprint(TextColor.Orange, "Expanding:")
|
|
print(town)
|
|
town:build(1, UnitId.TerranMinistry, 90)
|
|
town:wait_build(1, UnitId.TerranMinistry)
|
|
town:transfer_workers(4)
|
|
town:build(20, UnitId.TerranMason, 85)
|
|
town:wait_build(10, UnitId.TerranMason)
|
|
town:multirun(flyer_watch)
|
|
town:build(1, UnitId.TerranStockade, 80)
|
|
wait(secs(30))
|
|
town:build(2, UnitId.TerranStockade, 70)
|
|
-- TODO: town:build_at(UnitId.TerranStockage, Point(69, 69), 90)
|
|
-- TODO: town:new_guard(...)
|
|
end
|
|
|
|
local function expand_loop()
|
|
wait(secs(90))
|
|
while true do
|
|
local town = ai:expand()
|
|
town:multirun(build_expo) -- town:multirun manages script lifetime based on town alive state
|
|
if town.is_alive then
|
|
wait(math.random(mins(3), mins(4)))
|
|
else
|
|
wait(math.random(secs(30), mins(1))) -- if town didn't create we wait for shorter
|
|
end
|
|
|
|
-- NOTE: if we didn't need the town.is_alive check we can use nice shorthand:
|
|
-- ai:expand:multirun(build_expo)
|
|
end
|
|
end
|
|
|
|
local function attack_waves()
|
|
main_town:wait_build(1, UnitId.TerranStockade)
|
|
while true do
|
|
-- Classic attack wave with counts
|
|
--[[
|
|
local attack = ai:new_attack()
|
|
attack.from = Point(3800, 500)
|
|
if Time.elapsed <= mins(5) then
|
|
attack:add(5 + (Time.elapsed // mins(2)), UnitId.TerranMaverick)
|
|
else
|
|
attack:add(4 + (Time.elapsed // mins(4)), UnitId.TerranMaverick)
|
|
attack:add(2 + (Time.elapsed // mins(4)), UnitId.TerranHarakan)
|
|
end
|
|
]]
|
|
|
|
-- Composing attack wave from power value
|
|
local attack_budget = player:unit_count(UnitId.TerranMason) * 50
|
|
+ (player.minerals + player.gas) // 2
|
|
local attack = ai:new_attack(attack_budget)
|
|
attack.budget = attack_budget
|
|
attack.timeout = 120
|
|
-- attack.from = Point(3800, 500)
|
|
if player:unit_count(UnitId.TerranStockade) > 0 then
|
|
attack:compose(config.pref_maverick or 1, UnitId.TerranMaverick)
|
|
attack:compose(config.pref_harakan or 1, UnitId.TerranHarakan)
|
|
attack:compose(config.pref_cyprian or 1, UnitId.TerranCyprian)
|
|
end
|
|
|
|
cprint(TextColor.Red, "Sending attack:")
|
|
print(attack)
|
|
attack:send()
|
|
wait(math.random(secs(5), secs(15)))
|
|
end
|
|
end
|
|
|
|
local function dump_defenses()
|
|
cprint(TextColor.Yellow3, "Defenses:")
|
|
print("build.gg:", ai.defense.build.gg)
|
|
print("use.gg:", ai.defense.use.gg)
|
|
print("build.ag:", ai.defense.build.ag)
|
|
print("use.ag:", ai.defense.use.ag)
|
|
print("build.ga:", ai.defense.build.ga)
|
|
print("use.ga:", ai.defense.use.ga)
|
|
print("build.aa:", ai.defense.build.aa)
|
|
print("use.aa:", ai.defense.use.aa)
|
|
end
|
|
|
|
---@param unit_id UnitId
|
|
---@param cond fun(): boolean
|
|
local function defense_watch_impl(unit_id, cond)
|
|
while true do
|
|
wait_until(cond, secs(1))
|
|
ai.defense:auto_set(unit_id)
|
|
-- dump_defenses()
|
|
wait_while(cond, secs(1))
|
|
ai.defense:auto_remove(unit_id)
|
|
-- dump_defenses()
|
|
end
|
|
end
|
|
|
|
---@param factory_id UnitId
|
|
---@param unit_id UnitId
|
|
local function defense_watch(factory_id, unit_id)
|
|
defense_watch_impl(unit_id, function()
|
|
return player:unit_count(factory_id) > 0
|
|
end)
|
|
end
|
|
|
|
-- Run all the functions
|
|
|
|
-- Special kind of multirun, this script will die when town dies
|
|
-- Equivalent to `multirun(function(town) town:auto_kill() ... end, town)`
|
|
main_town:multirun(build_main_town)
|
|
multirun(expand_loop)
|
|
multirun(attack_waves)
|
|
multirun(defense_watch, UnitId.TerranStockade, UnitId.TerranMaverick)
|
|
multirun(defense_watch, UnitId.TerranStockade, UnitId.TerranHarakan)
|
|
|
|
wait(mins(8))
|
|
brain.saw_air_units = true -- let's pretend, since we don't have api for detecting units yet
|