// these macros get expanded on the host if the @1 army is AI controlled

// Summary of node control AI approach is this:
//
// At startup, randomly pick one of these actions:
// 1. send sarge and group 1 to nearest non-owned node to sarge, send group 2, 4 and 6 to
//    second nearest non-owned node to sarge and send group 3, 5 and 7 to third nearest
//    non-owned node.
// 2. send sarge and group 1, 4, 5 to nearest non-owned node to sarge and send groups
//    2, 3, 6, 7 to second closest non-owned node to sarge
// 3. send sarge and all groups to nearest non-owned node to sarge
// When choosing a new action, it depends on the number of nodes owned by my team plus
// whether my team is winning the game.
// Depending on these plus random calls we select one of above actions or one of the
// following:
// 4. send sarge and group1 to nearest non-owned node to sarge,
//    send group 2,4,6 to closest owned node to sarge,
//    send group 3,5,7 to second closest non-owned node to sarge
// 5. send sarge and group1 to nearest non-owned node to sarge,
//    send group 2,4,6 to closest owned node to sarge,
//    send group 3,5,7 to second closest owned node to sarge
// 6. send sarge and group1 to nearest owned node to sarge,
//    send group 2,4,6 to second closest owned node to sarge,
//    send group 3,5,7 to third closest owned node to sarge
// 7. send sarge and group 1, 3, 5, 7 to nearest owned node to sarge,
//    send group 2,4,6 to second closest owned node to sarge,
//
// The rules for selecting amoung these actions are:
// if we own no nodes then
//    randomly pick from 1, 2, 3
// else if we own one node only then
//    randomly pick from 4, 1, 2, 3
// else if we own two nodes and are winning then
//    randomly pick from 5, 4, 7
// else if we own two nodes and are not winning then
//    randomly pick from 1, 2, 3, 4, 5
// else if we own three nodes or more and are winning
//    pick action 6
// else if we own three nodes or more and are not winning
//    pick option 5

// @1 = color of army to do AI for, @2 = enemy color, @3 = enemy color number
macro ai_score_compare_enemy 3
{
	if @1check@2score testvar teamscore @2 >= @1winningScore and IsAlly @1 @2 = 0 then
		setvar @1winningScore teamscore @2,
		setvar @1winningColor @3
}

// @1 = color of army to do AI for, @2-4 = enemy colors
macro ai_score_compare 4
{
	// this variable is set to the winning score if @1 is not winning
	variable @1winningScore 0

	// this variable is set to the winning color (e.g. green, tan) if @1 is not winning
	variable @1winningColor 0

	expand ai_score_compare_enemy ( @1 @2 1 )
	expand ai_score_compare_enemy ( @1 @3 2 )
	expand ai_score_compare_enemy ( @1 @4 3 )

	if @1CalculateWinningTeam then
		setvar @1winningScore 0,
		setvar @1winningColor 0,
		trigger @1check@2score,
		trigger @1check@3score,
		trigger @1check@4score
}

// @1 = color of army to do AI for,
// @2 = a node number, @3 = a group number
macro node_ai_per_node_per_group 3
{
	if @1GroupGotoNode testvar @1gotoNode = @2 and @1gotoGroup = @3 then
		order @1 group @3 goto @1node@2pad inmode defend
}

// @1 = color of army to do AI for,
// @2 = a node number
// @3 = owner number for this color
macro node_ai_per_node 3
{
	expand node_ai_per_node_per_group ( @1 @2 0 )
	expand node_ai_per_node_per_group ( @1 @2 1 )
	expand node_ai_per_node_per_group ( @1 @2 2 )
	expand node_ai_per_node_per_group ( @1 @2 3 )
	expand node_ai_per_node_per_group ( @1 @2 4 )
	expand node_ai_per_node_per_group ( @1 @2 5 )
	expand node_ai_per_node_per_group ( @1 @2 6 )
	expand node_ai_per_node_per_group ( @1 @2 7 )

	if @1SargeGotoNode testvar @1gotoNode = @2 then
		order @1sarge1 goto @1node@2pad inmode attack

	// if any node changes owner then reconsider our actions
	if node@2OwnerChanged then
		triggerdelay 200 @1ChooseNewAction

	// stuff for working out closest owned/non-owned nodes
	variable @1TeamOwnsNode@2 0

	if @1ClearTeamOwns then
		setvar @1TeamOwnsNode@2 0

	if @1CalcTeamOwns testvar node@2owner = @3 then
		setvar @1TeamOwnsNode@2 1

	if @1FindClosest1OwnedNode
	testvar @1TeamOwnsNode@2 = 1
	and @1Closest1OwnedNodeDist > ItemToPadDistance @1sarge1 @1node@2pad then
		setvar @1Closest1OwnedNode @2,
		setvar @1Closest1OwnedNodeDist ItemToPadDistance @1sarge1 @1node@2pad

	if @1FindClosest2OwnedNode
	testvar @1TeamOwnsNode@2 = 1
	and @2 <> @1Closest1OwnedNode
	and @1Closest2OwnedNodeDist > ItemToPadDistance @1sarge1 @1node@2pad then
		setvar @1Closest2OwnedNode @2,
		setvar @1Closest2OwnedNodeDist ItemToPadDistance @1sarge1 @1node@2pad

	if @1FindClosest3OwnedNode
	testvar @1TeamOwnsNode@2 = 1
	and @2 <> @1Closest1OwnedNode
	and @2 <> @1Closest2OwnedNode
	and @1Closest3OwnedNodeDist > ItemToPadDistance @1sarge1 @1node@2pad then
		setvar @1Closest3OwnedNode @2,
		setvar @1Closest3OwnedNodeDist ItemToPadDistance @1sarge1 @1node@2pad

	if @1FindClosest1NonOwnedNode
	testvar @1TeamOwnsNode@2 = 0
	and @1Closest1NonOwnedNodeDist > ItemToPadDistance @1sarge1 @1node@2pad then
		setvar @1Closest1NonOwnedNode @2,
		setvar @1Closest1NonOwnedNodeDist ItemToPadDistance @1sarge1 @1node@2pad

	if @1FindClosest2NonOwnedNode
	testvar @1TeamOwnsNode@2 = 0
	and @2 <> @1Closest1NonOwnedNode
	and @1Closest2NonOwnedNodeDist > ItemToPadDistance @1sarge1 @1node@2pad then
		setvar @1Closest2NonOwnedNode @2,
		setvar @1Closest2NonOwnedNodeDist ItemToPadDistance @1sarge1 @1node@2pad

	if @1FindClosest3NonOwnedNode
	testvar @1TeamOwnsNode@2 = 0
	and @2 <> @1Closest1NonOwnedNode
	and @2 <> @1Closest2NonOwnedNode
	and @1Closest3NonOwnedNodeDist > ItemToPadDistance @1sarge1 @1node@2pad then
		setvar @1Closest3NonOwnedNode @2,
		setvar @1Closest3NonOwnedNodeDist ItemToPadDistance @1sarge1 @1node@2pad
}

// @1 = color of army to do AI for, @2 = enemy color,
// @3 = this colors owner number, @4 = enemy colors owner numbers
// @5 = node number
macro node_ai_per_enemy_per_node 5
{
	if @1CalcTeamOwns testvar isAlly @1 @2 = 1 and node@5owner = @4 then
		setvar @1TeamOwnsNode@5 1
}

// @1 = color of army to do AI for, @2 = enemy color,
// @3 = this colors owner number, @4 = enemy colors owner numbers
// @5 = action number for attacking this enemy
macro node_ai_per_enemy 5
{
	expand node_ai_per_enemy_per_node ( @1 @2 @3 @4 1 )
	expand node_ai_per_enemy_per_node ( @1 @2 @3 @4 2 )
	expand node_ai_per_enemy_per_node ( @1 @2 @3 @4 3 )
	expand node_ai_per_enemy_per_node ( @1 @2 @3 @4 4 )
	expand node_ai_per_enemy_per_node ( @1 @2 @3 @4 5 )
}

// @1 = color of army to do AI for, @2-@4 = other colors,
// @5 = this colors owner number, @6-8 = other colors owner numbers
macro node_ai_macro 8
{
	expand ai_score_compare ( @1 @2 @3 @4 )

	// calculate the closest owned and unowned nodes
	variable @1Closest1OwnedNode 0
	variable @1Closest2OwnedNode 0
	variable @1Closest3OwnedNode 0
	variable @1Closest1NonOwnedNode 0
	variable @1Closest2NonOwnedNode 0
	variable @1Closest3NonOwnedNode 0
	variable @1Closest1OwnedNodeDist 10000
	variable @1Closest2OwnedNodeDist 10000
	variable @1Closest3OwnedNodeDist 10000
	variable @1Closest1NonOwnedNodeDist 10000
	variable @1Closest2NonOwnedNodeDist 10000
	variable @1Closest3NonOwnedNodeDist 10000

	if @1CalculateClosestNodes then
		trigger @1ClearTeamOwns,
		trigger @1CalcTeamOwns,
		setvar @1Closest1OwnedNode 0,
		setvar @1Closest2OwnedNode 0,
		setvar @1Closest3OwnedNode 0,
		setvar @1Closest1NonOwnedNode 0,
		setvar @1Closest2NonOwnedNode 0,
		setvar @1Closest3NonOwnedNode 0,
		setvar @1Closest1OwnedNodeDist 10000,
		setvar @1Closest2OwnedNodeDist 10000,
		setvar @1Closest3OwnedNodeDist 10000,
		setvar @1Closest1NonOwnedNodeDist 10000,
		setvar @1Closest2NonOwnedNodeDist 10000,
		setvar @1Closest3NonOwnedNodeDist 10000,
		trigger @1FindClosest1OwnedNode,
		trigger @1FindClosest2OwnedNode,
		trigger @1FindClosest3OwnedNode,
		trigger @1FindClosest1NonOwnedNode,
		trigger @1FindClosest2NonOwnedNode,
		trigger @1FindClosest3NonOwnedNode

	// This variable holds the current action for @1
	// 0 means no action, other actions are explained in header of this file

	variable @1gotoNode 0
	variable @1gotoGroup 0

	expand node_ai_per_node ( @1 1 @5 )
	expand node_ai_per_node ( @1 2 @5 )
	expand node_ai_per_node ( @1 3 @5 )
	expand node_ai_per_node ( @1 4 @5 )
	expand node_ai_per_node ( @1 5 @5 )

	expand node_ai_per_enemy ( @1 @2 @5 @6 4 )
	expand node_ai_per_enemy ( @1 @3 @5 @7 5 )
	expand node_ai_per_enemy ( @1 @4 @5 @8 6 )

	if startup1 then
		triggerdelay 1000 @1ChooseNewAction

	// events to choose an action based on who owns what and who is winning

	if @1ChooseNewAction then
		setvar @1Action -1,
		trigger @1CalculateWinningTeam,
		trigger @1ChooseAction,
		trigger @1PerformAction,
		trigger @1StartTimeOut

	if @1ChooseAction testvar @1nodesOwned = 0 then random
		setvar @1Action 1,
		setvar @1Action 2,
		setvar @1Action 3

	if @1ChooseAction testvar @1nodesOwned = 1 then random
		setvar @1Action 4,
		setvar @1Action 1,
		setvar @1Action 2,
		setvar @1Action 3

	if @1ChooseAction testvar @1nodesOwned = 2
	and @1winningscore < teamscore @1 then random
		setvar @1Action 4,
		setvar @1Action 5,
		setvar @1Action 6,
		setvar @1Action 7

	if @1ChooseAction testvar @1nodesOwned = 2
	and @1winningscore >= teamscore @1 then random
		setvar @1Action 1,
		setvar @1Action 2,
		setvar @1Action 3,
		setvar @1Action 4,
		setvar @1Action 5

	if @1ChooseAction testvar @1nodesOwned >= 3
	and @1winningscore < teamscore @1 then random
		setvar @1Action 6

	if @1ChooseAction testvar @1nodesOwned >= 3
	and @1winningscore >= teamscore @1 then random
		setvar @1Action 5

	// events to perform the chosen action

	if @1PerformAction testvar @1Action = -1 then
		triggerdelay 3000 @1ChooseNewAction

	if @1PerformAction testvar @1Action = 1 then
		trigger @1CalculateClosestNodes,
		// sarge and 1 to closest non-owned node
		setvar @1gotoNode @1Closest1NonOwnedNode,
		trigger @1SargeGotoNode,
		setvar @1gotoGroup 1,
		trigger @1GroupGotoNode,
		// 2, 4, 6 to second closest non-owned node
		setvar @1gotoNode @1Closest2NonOwnedNode,
		setvar @1gotoGroup 2,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 4,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 6,
		trigger @1GroupGotoNode,
		// 3, 5, 7 to third closest non-owned node
		setvar @1gotoNode @1Closest3NonOwnedNode,
		setvar @1gotoGroup 3,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 5,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 7,
		trigger @1GroupGotoNode

	if @1PerformAction testvar @1Action = 2 then
		trigger @1CalculateClosestNodes,
		// sarge and 1, 4, 5 to closest non-owned node
		setvar @1gotoNode @1Closest1NonOwnedNode,
		trigger @1SargeGotoNode,
		setvar @1gotoGroup 1,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 4,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 5,
		trigger @1GroupGotoNode,
		// 2, 3, 6, 7 to second closest non-owned node
		setvar @1gotoNode @1Closest2NonOwnedNode,
		setvar @1gotoGroup 2,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 3,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 6,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 7,
		trigger @1GroupGotoNode

	if @1PerformAction testvar @1Action = 3 then
		trigger @1CalculateClosestNodes,
		// sarge and 1, 2, 3, 4, 5, 6, 7 to closest non-owned node
		setvar @1gotoNode @1Closest1NonOwnedNode,
		trigger @1SargeGotoNode,
		setvar @1gotoGroup 1,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 2,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 3,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 4,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 5,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 6,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 7,
		trigger @1GroupGotoNode

	if @1PerformAction testvar @1Action = 4 then
		trigger @1CalculateClosestNodes,
		// sarge and 1 to closest non-owned node
		setvar @1gotoNode @1Closest1NonOwnedNode,
		trigger @1SargeGotoNode,
		setvar @1gotoGroup 1,
		trigger @1GroupGotoNode,
		// 2, 4, 6 to closest owned node
		setvar @1gotoNode @1Closest1OwnedNode,
		setvar @1gotoGroup 2,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 4,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 6,
		trigger @1GroupGotoNode,
		// 3, 5, 7 to second closest non-owned node
		setvar @1gotoNode @1Closest2NonOwnedNode,
		setvar @1gotoGroup 3,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 5,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 7,
		trigger @1GroupGotoNode

	if @1PerformAction testvar @1Action = 5 then
		trigger @1CalculateClosestNodes,
		// sarge and 1 to closest non-owned node
		setvar @1gotoNode @1Closest1NonOwnedNode,
		trigger @1SargeGotoNode,
		setvar @1gotoGroup 1,
		trigger @1GroupGotoNode,
		// 2, 4, 6 to closest owned node
		setvar @1gotoNode @1Closest1OwnedNode,
		setvar @1gotoGroup 2,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 4,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 6,
		trigger @1GroupGotoNode,
		// 3, 5, 7 to second closest owned node
		setvar @1gotoNode @1Closest2OwnedNode,
		setvar @1gotoGroup 3,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 5,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 7,
		trigger @1GroupGotoNode

	if @1PerformAction testvar @1Action = 6 then
		trigger @1CalculateClosestNodes,
		// sarge and 1 to closest owned node
		setvar @1gotoNode @1Closest1OwnedNode,
		trigger @1SargeGotoNode,
		setvar @1gotoGroup 1,
		trigger @1GroupGotoNode,
		// 2, 4, 6 to second closest owned node
		setvar @1gotoNode @1Closest2OwnedNode,
		setvar @1gotoGroup 2,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 4,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 6,
		trigger @1GroupGotoNode,
		// 3, 5, 7 to third closest owned node
		setvar @1gotoNode @1Closest3OwnedNode,
		setvar @1gotoGroup 3,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 5,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 7,
		trigger @1GroupGotoNode

	if @1PerformAction testvar @1Action = 7 then
		trigger @1CalculateClosestNodes,
		// sarge and 1 , 3, 5, 7 to closest owned node
		setvar @1gotoNode @1Closest1OwnedNode,
		trigger @1SargeGotoNode,
		setvar @1gotoGroup 1,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 3,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 5,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 7,
		trigger @1GroupGotoNode,
		// 2, 4, 6 to second closest owned node
		setvar @1gotoNode @1Closest2OwnedNode,
		setvar @1gotoGroup 2,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 4,
		trigger @1GroupGotoNode,
		setvar @1gotoGroup 6,
		trigger @1GroupGotoNode

	// timeout code - if mode has not changed for a while then change it

	variable @1TimeOutVar 0
	variable @1LastTimeOutVar 1

	if @1StartTimeOut then
		addvar @1TimeOutVar 1,
		triggerdelay 120000 @1CheckTimeOut

	if @1CheckTimeOut testvar @1TimeOutVar = @1LastTimeOutVar then
		trigger @1ChooseNewAction

	if @1CheckTimeOut testvar @1TimeOutVar <> @1LastTimeOutVar then
		addvar @1LastTimeOutVar 1
}