Merge pull request #10946 from abcdefg30/lobby-bots
Add a "Lonestar AI" to Fort Lonestar
This commit is contained in:
43
OpenRA.Mods.Common/AI/DummyAI.cs
Normal file
43
OpenRA.Mods.Common/AI/DummyAI.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2016 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version. For more
|
||||
* information, see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.AI
|
||||
{
|
||||
public sealed class DummyAIInfo : ITraitInfo, IBotInfo
|
||||
{
|
||||
[Desc("Ingame name this bot uses.")]
|
||||
public readonly string Name = "Unnamed Bot";
|
||||
|
||||
string IBotInfo.Name { get { return Name; } }
|
||||
|
||||
public object Create(ActorInitializer init) { return new DummyAI(this); }
|
||||
}
|
||||
|
||||
public sealed class DummyAI : IBot
|
||||
{
|
||||
readonly DummyAIInfo info;
|
||||
public bool Enabled { get; private set; }
|
||||
|
||||
public DummyAI(DummyAIInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
void IBot.Activate(Player p)
|
||||
{
|
||||
Enabled = true;
|
||||
}
|
||||
|
||||
IBotInfo IBot.Info { get { return info; } }
|
||||
}
|
||||
}
|
||||
@@ -739,6 +739,7 @@
|
||||
<Compile Include="Traits\Radar\ProvidesRadar.cs" />
|
||||
<Compile Include="Traits\Radar\RadarColorFromTerrain.cs" />
|
||||
<Compile Include="Traits\Radar\JamsRadar.cs" />
|
||||
<Compile Include="AI\DummyAI.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -82,6 +82,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Red Alert Lua scripts", "Re
|
||||
mods\ra\maps\soviet-07\soviet07.lua = mods\ra\maps\soviet-07\soviet07.lua
|
||||
mods\ra\maps\survival01\survival01.lua = mods\ra\maps\survival01\survival01.lua
|
||||
mods\ra\maps\survival02\survival02.lua = mods\ra\maps\survival02\survival02.lua
|
||||
mods\ra\maps\fort-lonestar\fort-lonestar-AI.lua = mods\ra\maps\fort-lonestar\fort-lonestar-AI.lua
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dune 2000 Lua scripts", "Dune 2000 Lua scripts", "{06B1AE07-DDB0-4287-8700-A8CD9A0E652E}"
|
||||
|
||||
180
mods/ra/maps/fort-lonestar/fort-lonestar-AI.lua
Normal file
180
mods/ra/maps/fort-lonestar/fort-lonestar-AI.lua
Normal file
@@ -0,0 +1,180 @@
|
||||
|
||||
AIPlayers = { }
|
||||
AIBarracks = { }
|
||||
AIDerricks = { }
|
||||
AIBaseLocation = { }
|
||||
IdlingAIActors = { }
|
||||
IdlingAISupportActors = { }
|
||||
AIOnDefense = { }
|
||||
|
||||
-- It's good to start with 10 rifle man, one medic and 5 rocket soldiers
|
||||
InitialUnitsToBuild = { "e1", "e1", "e1", "e1", "e1", "medi", "e1", "e1", "e1", "e1", "e1", "e3", "e3", "e3", "e3", "e3" }
|
||||
UnitsToBuild = { "e1", "e1", "e1", "e1", "e1", "e3", "e3", "e3", "medi" }
|
||||
|
||||
ActivateAI = function(player, id)
|
||||
AIPlayers[id] = player
|
||||
|
||||
Trigger.AfterDelay(0, function()
|
||||
local barracks = player.GetActorsByType("tent")
|
||||
if #barracks > 0 then
|
||||
AIBarracks[id] = barracks[1]
|
||||
AIBaseLocation[id] = barracks[1].Location + CVec.New(2, 1)
|
||||
IdlingAIActors[id] = { }
|
||||
IdlingAISupportActors[id] = { }
|
||||
InitialInfantryProduction(id, InitialUnitsToBuild)
|
||||
DefendActor(id, barracks[1])
|
||||
RepairBarracks(id)
|
||||
SellWalls(id)
|
||||
|
||||
Trigger.AfterDelay(DateTime.Seconds(10), function() LookOutForCrates(id) end)
|
||||
end
|
||||
|
||||
local derricks = player.GetActorsByType("oilb")
|
||||
if #derricks > 0 then
|
||||
AIDerricks[id] = derricks[1]
|
||||
DefendActor(id, derricks[1])
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
InitialInfantryProduction = function(id, units)
|
||||
local productionComplete = AIPlayers[id].Build(units, function(actors)
|
||||
InfantryProduction(id)
|
||||
end)
|
||||
|
||||
Trigger.OnProduction(AIBarracks[id], function(producer, produced)
|
||||
BuildComplete(id, produced)
|
||||
end)
|
||||
end
|
||||
|
||||
InfantryProduction = function(id)
|
||||
local productionComplete = AIPlayers[id].Build({ Utils.Random(UnitsToBuild) }, function(actors)
|
||||
Trigger.AfterDelay(0, function() InfantryProduction(id) end)
|
||||
end)
|
||||
|
||||
if not productionComplete then
|
||||
Trigger.AfterDelay(0, function() InfantryProduction(id) end)
|
||||
end
|
||||
end
|
||||
|
||||
BuildComplete = function(id, actor)
|
||||
if actor.Type == "medi" then
|
||||
local number = #IdlingAISupportActors[id] + 1
|
||||
IdlingAISupportActors[id][number] = actor
|
||||
|
||||
Trigger.OnKilled(actor, function()
|
||||
table.remove(IdlingAISupportActors[id], number)
|
||||
end)
|
||||
else
|
||||
local number = #IdlingAIActors[id] + 1
|
||||
IdlingAIActors[id][number] = actor
|
||||
|
||||
Trigger.OnKilled(actor, function()
|
||||
table.remove(IdlingAIActors[id], number)
|
||||
end)
|
||||
end
|
||||
|
||||
Trigger.AfterDelay(0, function() DefendActor(id, actor) end)
|
||||
end
|
||||
|
||||
AttackGroupSize = 5
|
||||
SetupAttackGroup = function(id)
|
||||
local units = { }
|
||||
|
||||
for i = 0, AttackGroupSize, 1 do
|
||||
if (#IdlingAIActors[id] == 0) then
|
||||
return units
|
||||
end
|
||||
|
||||
local number = Utils.RandomInteger(0, #IdlingAIActors[id]) + 1
|
||||
units[#units + 1] = IdlingAIActors[id][number]
|
||||
table.remove(IdlingAIActors[id], number)
|
||||
end
|
||||
|
||||
return units
|
||||
end
|
||||
|
||||
DefendActor = function(id, actorToDefend)
|
||||
if not actorToDefend or actorToDefend.IsDead or not actorToDefend.IsInWorld then
|
||||
return
|
||||
end
|
||||
|
||||
Trigger.OnDamaged(actorToDefend, function(self, attacker)
|
||||
if AIOnDefense[id] or not attacker or attacker.IsDead then
|
||||
return
|
||||
end
|
||||
|
||||
-- Don't try to kill something you can't kill
|
||||
if attacker.Type == "sniper.soviets" then
|
||||
return
|
||||
end
|
||||
|
||||
AIOnDefense[id] = true
|
||||
local attackLoc = attacker.Location
|
||||
|
||||
local defenders = SetupAttackGroup(id)
|
||||
if not defenders or #defenders == 0 then
|
||||
Trigger.AfterDelay(DateTime.Seconds(30), function() AIOnDefense[id] = false end)
|
||||
return
|
||||
end
|
||||
|
||||
Utils.Do(defenders, function(unit)
|
||||
if unit.IsDead then
|
||||
return
|
||||
end
|
||||
|
||||
unit.AttackMove(attackLoc)
|
||||
|
||||
local home = AIBaseLocation[id]
|
||||
Trigger.OnIdle(unit, function()
|
||||
if unit.Location == home then
|
||||
IdlingAIActors[id][#IdlingAIActors[id] + 1] = unit
|
||||
Trigger.Clear(unit, "OnIdle")
|
||||
AIOnDefense[id] = false
|
||||
else
|
||||
unit.AttackMove(home)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
RepairBarracks = function(id)
|
||||
Trigger.OnDamaged(AIBarracks[id], function(self, attacker)
|
||||
self.StartBuildingRepairs(AIPlayers[id])
|
||||
end)
|
||||
end
|
||||
|
||||
SellWalls = function(id)
|
||||
Media.DisplayMessage("Lonestar AI " .. id .. " sold its walls for better combat experience.")
|
||||
|
||||
local walls = AIPlayers[id].GetActorsByType("brik")
|
||||
Utils.Do(walls, function(wall)
|
||||
wall.Destroy()
|
||||
end)
|
||||
end
|
||||
|
||||
LookOutForCrates = function(id)
|
||||
Trigger.OnEnteredProximityTrigger(AIBarracks[id].CenterPosition, WDist.New(12 * 1024), function(actor)
|
||||
if actor.Type ~= "fortcrate" or #IdlingAIActors[id] == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local unit = Utils.Random(IdlingAIActors[id])
|
||||
local home = AIBaseLocation[id]
|
||||
local aim = actor.Location
|
||||
if unit.IsDead then
|
||||
return
|
||||
end
|
||||
|
||||
unit.AttackMove(aim)
|
||||
Trigger.OnIdle(unit, function()
|
||||
if unit.Location == aim or not actor.IsInWorld then
|
||||
unit.AttackMove(home)
|
||||
Trigger.Clear(unit, "OnIdle")
|
||||
else
|
||||
unit.AttackMove(aim)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
@@ -197,9 +197,13 @@ end
|
||||
WorldLoaded = function()
|
||||
soviets = Player.GetPlayer("Soviets")
|
||||
players = { }
|
||||
for i = 0, 4, 1 do
|
||||
for i = 0, 4 do
|
||||
local player = Player.GetPlayer("Multi" ..i)
|
||||
players[i] = player
|
||||
|
||||
if players[i] and players[i].IsBot then
|
||||
ActivateAI(players[i], i)
|
||||
end
|
||||
end
|
||||
|
||||
Media.DisplayMessage("Defend Fort Lonestar at all costs!")
|
||||
|
||||
@@ -25,7 +25,6 @@ Players:
|
||||
PlayerReference@Multi0:
|
||||
Name: Multi0
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockTeam: True
|
||||
Team: 1
|
||||
LockFaction: True
|
||||
@@ -35,7 +34,6 @@ Players:
|
||||
PlayerReference@Multi1:
|
||||
Name: Multi1
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockTeam: True
|
||||
Team: 1
|
||||
LockFaction: True
|
||||
@@ -45,7 +43,6 @@ Players:
|
||||
PlayerReference@Multi2:
|
||||
Name: Multi2
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockTeam: True
|
||||
Team: 1
|
||||
LockFaction: True
|
||||
@@ -55,7 +52,6 @@ Players:
|
||||
PlayerReference@Multi3:
|
||||
Name: Multi3
|
||||
Playable: True
|
||||
AllowBots: False
|
||||
LockTeam: True
|
||||
Team: 1
|
||||
LockFaction: True
|
||||
|
||||
@@ -27,7 +27,7 @@ World:
|
||||
FlashPaletteEffect@LIGHTNINGSTRIKE:
|
||||
Type: LightningStrike
|
||||
LuaScript:
|
||||
Scripts: fort-lonestar.lua
|
||||
Scripts: fort-lonestar.lua, fort-lonestar-AI.lua
|
||||
ScriptUpgradesCache:
|
||||
Upgrades: invulnerability
|
||||
MapBuildRadius:
|
||||
@@ -86,6 +86,12 @@ Player:
|
||||
PlayerResources:
|
||||
DefaultCashLocked: True
|
||||
DefaultCash: 50
|
||||
-HackyAI@RushAI:
|
||||
-HackyAI@NormalAI:
|
||||
-HackyAI@NavalAI:
|
||||
-HackyAI@TurtleAI:
|
||||
DummyAI@LonestarAI:
|
||||
Name: Lonestar AI
|
||||
|
||||
^Infantry:
|
||||
Inherits@IC: ^IronCurtainable
|
||||
|
||||
Reference in New Issue
Block a user