Performance fixes

This commit is contained in:
Robert MacGregor 2015-10-06 21:43:52 -04:00
parent 5e53dd91ef
commit 53aece4615
5 changed files with 301 additions and 178 deletions

View file

@ -34,6 +34,7 @@ function AICommander::setup(%this)
for (%iteration = 0; %iteration < ClientGroup.getCount(); %iteration++) for (%iteration = 0; %iteration < ClientGroup.getCount(); %iteration++)
{ {
%currentClient = ClientGroup.getObject(%iteration); %currentClient = ClientGroup.getObject(%iteration);
%currentClient.updateVisualAcuity();
if (%currentClient.isAIControlled() && %currentClient.team == %this.team) if (%currentClient.isAIControlled() && %currentClient.team == %this.team)
{ {
@ -138,10 +139,14 @@ function AICommander::assignTasks(%this)
%bot = %this.botList.getObject(%iteration); %bot = %this.botList.getObject(%iteration);
%bot.addTask(AIEnhancedEngageTarget); %bot.addTask(AIEnhancedEngageTarget);
%bot.addTask(AIEnhancedRearmTask); %bot.addTask(AIEnhancedRearmTask);
%bot.addTask(AIEnhancedPathCorrectionTask);
// We only need this task if we're actually playing CTF. // We only need this task if we're actually playing CTF.
if ($CurrentMissionType $= "CTF") if ($CurrentMissionType $= "CTF")
{
%bot.addTask(AIEnhancedReturnFlagTask); %bot.addTask(AIEnhancedReturnFlagTask);
%bot.addTask(AIEnhancedFlagCaptureTask);
}
%bot.targetLoadout = 0; %bot.targetLoadout = 0;
%bot.shouldRearm = true; %bot.shouldRearm = true;

View file

@ -25,7 +25,7 @@ function AIConnection::update(%this)
if (isObject(%this.player) && %this.player.getState() $= "Move") if (isObject(%this.player) && %this.player.getState() $= "Move")
{ {
%this.updateLegs(); %this.updateLegs();
%this.updateVisualAcuity(); %this.updateWeapons();
} }
} }
@ -41,19 +41,74 @@ function AIConnection::isIdle(%this)
return true; return true;
return %this.commander.idleBotList.isMember(%this); return %this.commander.idleBotList.isMember(%this);
} }
function AIConnection::reset(%this)
{
// AIUnassignClient(%this);
%this.stop();
// %this.clearTasks();
%this.clearStep();
%this.lastDamageClient = -1;
%this.lastDamageTurret = -1;
%this.shouldEngage = -1;
%this.setEngageTarget(-1);
%this.setTargetObject(-1);
%this.pilotVehicle = false;
%this.defaultTasksAdded = false;
if (isObject(%this.controlByHuman))
aiReleaseHumanControl(%this.controlByHuman, %this);
}
function AIConnection::setMoveTarget(%this, %position)
{
if (%position == -1)
{
%this.reset();
%this.isMovingToTarget = false;
%this.isFollowingTarget = false;
return;
}
%this.moveTarget = %position;
%this.isMovingToTarget = true;
%this.isFollowingTarget = false;
%this.setPath(%position);
%this.stepMove(%position);
}
function AIConnection::setFollowTarget(%this, %target, %minDistance, %maxDistance, %hostile)
{
if (!isObject(%target))
{
%this.reset();
%this.isMovingToTarget = false;
%this.isFollowingTarget = false;
return;
}
%this.followTarget = %target;
%this.isFollowingTarget = true;
%this.followMinDistance = %minDistance;
%this.followMaxDistance = %maxDistance;
%this.followHostile = %hostile;
%this.stepEscort(%target);
}
function AIConnection::updateLegs(%this) function AIConnection::updateLegs(%this)
{ {
if (%this.isMoving && %this.getTaskID() != 0) if (%this.isMovingToTarget)
{ {
%this.setPath(%this.moveLocation);
%this.stepMove(%this.moveLocation);
if (%this.aimAtLocation) if (%this.aimAtLocation)
%this.aimAt(%this.moveLocation); %this.aimAt(%this.moveTarget);
else if(%this.manualAim) else if(%this.manualAim)
%this.aimAt(%this.aimLocation); %this.aimAt(%this.moveTarget);
}
else if (%this.isFollowingTarget)
{
} }
else else
{ {
@ -62,8 +117,22 @@ function AIConnection::updateLegs(%this)
} }
} }
function AIConnection::updateWeapons(%this)
{
}
function AIConnection::updateVisualAcuity(%this) function AIConnection::updateVisualAcuity(%this)
{ {
if (isEventPending(%this.visualAcuityTick))
cancel(%this.visualAcuityTick);
if (!isObject(%this.player) || %this.player.getState() !$= "Move")
{
%this.visualAcuityTick = %this.schedule(getRandom(230, 400), "updateVisualAcuity");
return;
}
if (%this.enableVisualDebug) if (%this.enableVisualDebug)
{ {
if (!isObject(%this.originMarker)) if (!isObject(%this.originMarker))
@ -118,7 +187,7 @@ function AIConnection::updateVisualAcuity(%this)
%className = %current.getClassName(); %className = %current.getClassName();
// LinearFlareProjectile and LinearProjectile have linear properties, so we can easily determine if a dodge is necessary // LinearFlareProjectile and LinearProjectile have linear trajectories, so we can easily determine if a dodge is necessary
if (%className $= "LinearFlareProjectile" || %className $= "LinearProjectile") if (%className $= "LinearFlareProjectile" || %className $= "LinearProjectile")
{ {
//%this.setDangerLocation(%current.getPosition(), 20); //%this.setDangerLocation(%current.getPosition(), 20);
@ -175,4 +244,5 @@ function AIConnection::updateVisualAcuity(%this)
} }
%result.delete(); %result.delete();
%this.visualAcuityTick = %this.schedule(getRandom(230, 400), "updateVisualAcuity");
} }

View file

@ -1,6 +1,12 @@
//------------------------------------------------------------------------------------------
// config.cs // config.cs
// Configuration for the DXAI System // Configuration file for the experimental DXAI system.
// https://github.com/Ragora/T2-DXAI.git
//
// Copyright (c) 2014 Robert MacGregor // Copyright (c) 2014 Robert MacGregor
// This software is licensed under the MIT license.
// Refer to LICENSE.txt for more information.
//------------------------------------------------------------------------------------------
$DXAI::Commander::minimumFlagDefense = 1; $DXAI::Commander::minimumFlagDefense = 1;
$DXAI::Commander::minimumGeneratorDefense = 1; $DXAI::Commander::minimumGeneratorDefense = 1;

View file

@ -1,6 +1,12 @@
//------------------------------------------------------------------------------------------
// helpers.cs // helpers.cs
// Helper functions for the AI System // Helper functions used in the experimental DXAI system.
// https://github.com/Ragora/T2-DXAI.git
//
// Copyright (c) 2014 Robert MacGregor // Copyright (c) 2014 Robert MacGregor
// This software is licensed under the MIT license.
// Refer to LICENSE.txt for more information.
//------------------------------------------------------------------------------------------
function sameSide(%p1, %p2, %a, %b) function sameSide(%p1, %p2, %a, %b)
{ {
@ -29,25 +35,6 @@ function pointInTriangle(%point, %a, %b, %c)
return false; return false;
} }
function AIConnection::reset(%this)
{
AIUnassignClient(%this);
%this.stop();
%this.clearTasks();
%this.clearStep();
%this.lastDamageClient = -1;
%this.lastDamageTurret = -1;
%this.shouldEngage = -1;
%this.setEngageTarget(-1);
%this.setTargetObject(-1);
%this.pilotVehicle = false;
%this.defaultTasksAdded = false;
if (isObject(%this.controlByHuman))
aiReleaseHumanControl(%this.controlByHuman, %this);
}
// TODO: Return in a faster-to-read format: Could try as static GVar names // TODO: Return in a faster-to-read format: Could try as static GVar names
// as the game's scripting environment for the gameplay is single threaded // as the game's scripting environment for the gameplay is single threaded
// and it probably does a hash to store the values. // and it probably does a hash to store the values.
@ -254,6 +241,4 @@ $TypeMasks::BaseAssetObjectType = $TypeMasks::ForceFieldObjectType | $TypeMasks:
$TypeMasks::GameSupportObjectType = $TypeMasks::TriggerObjectType | $TypeMasks::MarkerObjectType | $TypeMasks::CameraObjectType | $TypeMasks::VehicleBlockerObjectType | $TypeMasks::PhysicalZoneObjectType; $TypeMasks::GameSupportObjectType = $TypeMasks::TriggerObjectType | $TypeMasks::MarkerObjectType | $TypeMasks::CameraObjectType | $TypeMasks::VehicleBlockerObjectType | $TypeMasks::PhysicalZoneObjectType;
$TypeMasks::GameContentObjectType = $TypeMasks::ExplosionObjectType | $TypeMasks::CorpseObjectType | $TypeMasks::DebrisObjectType; $TypeMasks::GameContentObjectType = $TypeMasks::ExplosionObjectType | $TypeMasks::CorpseObjectType | $TypeMasks::DebrisObjectType;
$TypeMasks::DefaultLOSObjectType = $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::StaticObjectType; $TypeMasks::DefaultLOSObjectType = $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::StaticObjectType;
$TypeMasks::AllObjectType = -1;
// We declare the AllObjectType like this instead of -1 because it seems -1 can sometimes not work?
$TypeMasks::AllObjectType = $TypeMasks::InteractiveObjectType | $TypeMasks::DefaultLOSObjectType | $TypeMasks::GameContentObjectType | $TypeMasks::GameSupportObjectType | $TypeMasks::BaseAssetObjectType | $TypeMasks::UnInteractiveObjectType;

View file

@ -7,6 +7,21 @@
// This software is licensed under the MIT license. Refer to LICENSE.txt for more information. // This software is licensed under the MIT license. Refer to LICENSE.txt for more information.
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
// Weights
// AIEnhancedFlagCaptureTask - $DXAI::Task::MediumPriority
// AIEnhancedEscort - $DXAI::Task::MediumPriority
// AIEnhancedDefendLocation - $DXAI::Task::MediumPriority
// AIEnhancedScoutLocation - $DXAI::Task::MediumPriority
// AIEnhancedEngageTarget - $DXAI::Task::VeryHighPriority
// AIEnhancedReturnFlagTask - $DXAI::Task::HighPriority
// AIEnhancedRearmTask - $DXAI::Task::HighPriority
$DXAI::Task::NoPriority = 0;
$DXAI::Task::LowPriority = 100;
$DXAI::Task::MediumPriority = 200;
$DXAI::Task::HighPriority = 500;
$DXAI::Task::VeryHighPriority = 1000;
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
// +Param %bot.escortTarget: The ID of the object to escort. This can be literally // +Param %bot.escortTarget: The ID of the object to escort. This can be literally
// any object that exists in the game world. // any object that exists in the game world.
@ -20,7 +35,7 @@
function AIEnhancedEscort::initFromObjective(%task, %objective, %client) { } function AIEnhancedEscort::initFromObjective(%task, %objective, %client) { }
function AIEnhancedEscort::assume(%task, %client) { %task.setMonitorFreq(1); } function AIEnhancedEscort::assume(%task, %client) { %task.setMonitorFreq(1); }
function AIEnhancedEscort::retire(%task, %client) { %client.isMoving = false; %client.manualAim = false; } function AIEnhancedEscort::retire(%task, %client) { %client.isMoving = false; %client.manualAim = false; }
function AIEnhancedEscort::weight(%task, %client) { %task.setWeight(500); } function AIEnhancedEscort::weight(%task, %client) { %task.setWeight($DXAI::Task::MediumPriority); }
function AIEnhancedEscort::monitor(%task, %client) function AIEnhancedEscort::monitor(%task, %client)
{ {
@ -37,7 +52,7 @@ function AIEnhancedEscort::monitor(%task, %client)
%client.manualAim = true; %client.manualAim = true;
%client.aimLocation = %escortLocation; %client.aimLocation = %escortLocation;
%client.moveLocation = getRandomPositionOnTerrain(%escortLocation, 40); %client.setMoveTarget(getRandomPositionOnTerrain(%escortLocation, 40));
} }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
@ -53,22 +68,22 @@ function AIEnhancedEscort::monitor(%task, %client)
function AIEnhancedDefendLocation::initFromObjective(%task, %objective, %client) { } function AIEnhancedDefendLocation::initFromObjective(%task, %objective, %client) { }
function AIEnhancedDefendLocation::assume(%task, %client) { %task.setMonitorFreq(1); } function AIEnhancedDefendLocation::assume(%task, %client) { %task.setMonitorFreq(1); }
function AIEnhancedDefendLocation::retire(%task, %client) { %client.isMoving = false; } function AIEnhancedDefendLocation::retire(%task, %client) { %client.isMoving = false; }
function AIEnhancedDefendLocation::weight(%task, %client) { %task.setWeight(500); } function AIEnhancedDefendLocation::weight(%task, %client) { %task.setWeight($DXAI::Task::MediumPriority); }
function AIEnhancedDefendLocation::monitor(%task, %client) function AIEnhancedDefendLocation::monitor(%task, %client)
{ {
if (%client.getPathDistance(%client.defendLocation) <= 40) if (%client.getPathDistance(%client.defendTargetLocation) <= 40)
{ {
// Pick a random time to move to a nearby location // Pick a random time to move to a nearby location
if (%client.defendTime == -1) if (%client.defendTime == -1)
{ {
%client.nextDefendRotation = getRandom(5000, 10000); %client.nextDefendRotation = getRandom(5000, 10000);
%client.isMoving = false; %client.setMoveTarget(-1);
} }
// If we're near our random point, just don't move // If we're near our random point, just don't move
if (%client.getPathDistance(%client.moveLocation) <= 10) if (%client.getPathDistance(%client.moveLocation) <= 10)
%client.isMoving = false; %client.setMoveTarget(-1);
%client.defendTime += 32; %client.defendTime += 32;
if (%client.defendTime >= %client.nextDefendRotation) if (%client.defendTime >= %client.nextDefendRotation)
@ -77,15 +92,13 @@ function AIEnhancedDefendLocation::monitor(%task, %client)
%client.nextDefendRotation = getRandom(5000, 10000); %client.nextDefendRotation = getRandom(5000, 10000);
// TODO: Replace with something that detects interiors as well // TODO: Replace with something that detects interiors as well
%client.moveLocation = getRandomPositionOnTerrain(%client.defendLocation, 40); %client.setMoveTarget(getRandomPositionOnTerrain(%client.defendTargetLocation, 40));
%client.isMoving = true;
} }
} }
else else
{ {
%client.defendTime = -1; %client.defendTime = -1;
%client.moveLocation = %client.defendLocation; %client.setMoveTarget(%client.defendTargetLocation);
%client.isMoving = true;
} }
} }
@ -103,7 +116,7 @@ function AIEnhancedDefendLocation::monitor(%task, %client)
function AIEnhancedScoutLocation::initFromObjective(%task, %objective, %client) { } function AIEnhancedScoutLocation::initFromObjective(%task, %objective, %client) { }
function AIEnhancedScoutLocation::assume(%task, %client) { %task.setMonitorFreq(1); %client.currentNode = -1; } function AIEnhancedScoutLocation::assume(%task, %client) { %task.setMonitorFreq(1); %client.currentNode = -1; }
function AIEnhancedScoutLocation::retire(%task, %client) { } function AIEnhancedScoutLocation::retire(%task, %client) { }
function AIEnhancedScoutLocation::weight(%task, %client) { %task.setWeight(500); } function AIEnhancedScoutLocation::weight(%task, %client) { %task.setWeight($DXAI::Task::MediumPriority); }
function AIEnhancedScoutLocation::monitor(%task, %client) function AIEnhancedScoutLocation::monitor(%task, %client)
{ {
@ -117,25 +130,23 @@ function AIEnhancedScoutLocation::monitor(%task, %client)
%client.currentNode = NavGraph.randNode(%client.scoutLocation, %client.scoutDistance, true, true); %client.currentNode = NavGraph.randNode(%client.scoutLocation, %client.scoutDistance, true, true);
if (%client.currentNode != -1) if (%client.currentNode != -1)
{ %client.setMoveTarget(NavGraph.nodeLoc(%client.currentNode));
%client.moveLocation = NavGraph.nodeLoc(%client.currentNode);
%client.isMoving = true;
}
} }
// We're moving, or are near enough to our target // We're moving, or are near enough to our target
else else
{ {
%pathDistance = %client.getPathDistance(%client.moveLocation); %pathDistance = %client.getPathDistance(%client.moveTarget);
// Don't move if we're close enough to our next node // Don't move if we're close enough to our next node
if (%pathDistance <= 40 && %client.isMoving) if (%pathDistance <= 40 && %client.isMoving)
{ {
%client.isMoving = false; %client.setMoveTarget(-1);
%client.nextScoutRotation = getRandom(5000, 10000); %client.nextScoutRotation = getRandom(5000, 10000);
%client.scoutTime += 32; %client.scoutTime += 32;
} }
else if(%client.getPathDistance(%client.moveLocation) > 40) else if(%client.getPathDistance(%client.moveTarget) > 40)
{ {
%client.isMoving = true; // %client.setMoveTarget(%client.moveTarget);
%client.scoutTime = 0; %client.scoutTime = 0;
} }
else else
@ -152,10 +163,7 @@ function AIEnhancedScoutLocation::monitor(%task, %client)
// Ensure that we found a node. // Ensure that we found a node.
if (%client.currentNode != -1) if (%client.currentNode != -1)
{ %client.setMoveTarget(NavGraph.nodeLoc(%client.currentNode));
%client.moveLocation = NavGraph.nodeLoc(%client.currentNode);
%client.isMoving = true;
}
} }
} }
} }
@ -174,90 +182,88 @@ function AIEnhancedEngageTarget::retire(%task, %client) { }
function AIEnhancedEngageTarget::weight(%task, %client) function AIEnhancedEngageTarget::weight(%task, %client)
{ {
if (!isObject(%client.engageTarget)) if (!isObject(%client.engageTarget))
{
%visibleObjects = %client.getObjectsInViewcone($TypeMasks::PlayerObjectType, %client.viewDistance, true);
// Choose the closest target
// TODO: Choose on more advanced metrics like HP
%chosenTarget = -1;
%chosenTargetDistance = 9999;
for (%iteration = 0; %iteration < %visibleObjects.getCount(); %iteration++)
{ {
%potentialTarget = %visibleObjects.getObject(%iteration); %visibleObjects = %client.getObjectsInViewcone($TypeMasks::PlayerObjectType, %client.viewDistance, true);
%potentialTargetDistance = vectorDist(%potentialTarget.getPosition(), %client.player.getPosition()); // Choose the closest target
if (%potentialTarget.client.team != %client.team && %potentialTargetDistance < %chosenTargetDistance) // TODO: Choose on more advanced metrics like HP
{ %chosenTarget = -1;
%chosenTargetDistance = %potentialTargetDistance; %chosenTargetDistance = 9999;
%chosenTarget = %potentialTarget; for (%iteration = 0; %iteration < %visibleObjects.getCount(); %iteration++)
} {
%potentialTarget = %visibleObjects.getObject(%iteration);
%potentialTargetDistance = vectorDist(%potentialTarget.getPosition(), %client.player.getPosition());
if (%potentialTarget.client.team != %client.team && %potentialTargetDistance < %chosenTargetDistance)
{
%chosenTargetDistance = %potentialTargetDistance;
%chosenTarget = %potentialTarget;
}
}
%visibleObjects.delete();
%client.engageTarget = %chosenTarget;
} }
else
%visibleObjects.delete(); {
%client.engageTarget = %chosenTarget; // Can we still see them?
} %rayCast = containerRayCast(%client.player.getWorldBoxCenter(), %client.engageTarget.getWorldBoxCenter(), -1, %client.player);
else %hitObject = getWord(%raycast, 0);
{
// Can we still see them?
%rayCast = containerRayCast(%client.player.getWorldBoxCenter(), %client.engageTarget.getWorldBoxCenter(), -1, %client.player);
%hitObject = getWord(%raycast, 0);
// TODO: Go to the last known position. // TODO: Go to the last known position.
if (%hitObject != %client.engageTarget) if (%hitObject != %client.engageTarget)
%client.engageTarget = -1; %client.engageTarget = -1;
} }
if (!isObject(%client.engageTarget) && %client.engageTargetLastPosition $= "") if (!isObject(%client.engageTarget) && %client.engageTargetLastPosition $= "")
%task.setWeight(0); %task.setWeight($DXAI::Task::NoPriority);
else else
%task.setWeight(1000); %task.setWeight($DXAI::Task::VeryHighPriority);
} }
function AIEnhancedEngageTarget::monitor(%task, %client) function AIEnhancedEngageTarget::monitor(%task, %client)
{ {
if (isObject(%client.engageTarget)) if (isObject(%client.engageTarget))
{ {
%player = %client.player; %player = %client.player;
%targetDistance = vectorDist(%player.getPosition(), %client.engageTarget.getPosition()); %targetDistance = vectorDist(%player.getPosition(), %client.engageTarget.getPosition());
// Firstly, just aim at them for now // Firstly, just aim at them for now
%client.aimAt(%client.engageTarget.getWorldBoxCenter()); %client.aimAt(%client.engageTarget.getWorldBoxCenter());
// What is our current best weapon? Right now we just check target distance and weapon spread. // What is our current best weapon? Right now we just check target distance and weapon spread.
%bestWeapon = 0; %bestWeapon = 0;
for (%iteration = 0; %iteration < %player.weaponSlotCount; %iteration++) for (%iteration = 0; %iteration < %player.weaponSlotCount; %iteration++)
{ {
// Weapons with a decent bit of spread should be used <= 20m // Weapons with a decent bit of spread should be used <= 20m
}
%player.selectWeaponSlot(%bestWeapon);
%client.engageTargetLastPosition = %client.engageTarget.getWorldBoxCenter();
%client.setMoveTarget(getRandomPositionOnTerrain(%client.engageTargetLastPosition, 40));
%client.pressFire();
} }
else if (%client.engageTargetLastPosition !$= "")
%player.selectWeaponSlot(%bestWeapon); {
%client.engageTargetLastPosition = %client.engageTarget.getWorldBoxCenter(); %client.setMoveTarget(%client.engageTargetLastPosition);
%client.isMoving = true;
%client.moveLocation = getRandomPositionOnTerrain(%client.engageTargetLastPosition, 40);
%client.pressFire();
}
else if (%client.engageTargetLastPosition !$= "")
{
%client.isMoving = true;
%client.moveLocation = %client.engageTargetLastPosition;
if (vectorDist(%client.player.getPosition(), %client.engageTargetLastPosition) <= 10) if (vectorDist(%client.player.getPosition(), %client.engageTargetLastPosition) <= 10)
{ {
%client.engageTargetLastPosition = ""; %client.engageTargetLastPosition = "";
%client.isMoving = false; %client.setMoveTarget(-1);
}
} }
}
} }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
// +Param %bot.shouldRearm: A boolean representing whether or not this bot should go // +Param %bot.shouldRearm: A boolean representing whether or not this bot should go
// and rearm. // and rearm.
// +Param %bot.targetInventory: The ID of the inventory station to rearm at. // +Param %bot.rearmTarget: The ID of the inventory station to rearm at.
//------------------------------------------------------------------------------------------` //------------------------------------------------------------------------------------------`
function AIEnhancedRearmTask::initFromObjective(%task, %objective, %client) { } function AIEnhancedRearmTask::initFromObjective(%task, %objective, %client) { }
function AIEnhancedRearmTask::assume(%task, %client) { %task.setMonitorFreq(1); } function AIEnhancedRearmTask::assume(%task, %client) { %task.setMonitorFreq(1); }
@ -265,30 +271,27 @@ function AIEnhancedRearmTask::retire(%task, %client) { }
function AIEnhancedRearmTask::weight(%task, %client) function AIEnhancedRearmTask::weight(%task, %client)
{ {
if (%client.shouldRearm) if (%client.shouldRearm)
%task.setWeight(600); %task.setWeight($DXAI::Task::HighPriority);
else else
%task.setWeight(0); %task.setWeight($DXAI::Task::NoPriority);
} }
function AIEnhancedRearmTask::monitor(%task, %client) function AIEnhancedRearmTask::monitor(%task, %client)
{ {
if (!isObject(%client.targetInventory)) if (!isObject(%client.rearmTarget))
%client.targetInventory = %client.getClosestInventory(); %client.rearmTarget = %client.getClosestInventory();
if (isObject(%client.targetInventory)) if (isObject(%client.rearmTarget))
{
// Politely wait if someone is already on it.
if (vectorDist(%client.targetInventory.getPosition(), %client.player.getPosition()) <= 7 && isObject(%client.targetInventory.triggeredBy))
%client.isMoving = false;
else
{ {
%client.isMoving = true; // Politely wait if someone is already on it.
%client.moveLocation = %client.targetInventory.getPosition(); if (vectorDist(%client.rearmTarget.getPosition(), %client.player.getPosition()) <= 7 && isObject(%client.rearmTarget.triggeredBy))
%client.setMoveTarget(-1);
else
%client.setMoveTarget(%client.rearmTarget.getPosition());
} }
} else
else %client.shouldRearm = false; // No inventories?
%client.shouldRearm = false; // No inventories?
} }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
@ -296,54 +299,108 @@ function AIEnhancedRearmTask::monitor(%task, %client)
// Description: A task that actually makes the bots return a flag that's nearby. // Description: A task that actually makes the bots return a flag that's nearby.
//------------------------------------------------------------------------------------------` //------------------------------------------------------------------------------------------`
function AIEnhancedReturnFlagTask::initFromObjective(%task, %objective, %client) { } function AIEnhancedReturnFlagTask::initFromObjective(%task, %objective, %client) { }
function AIEnhancedReturnFlagTask::assume(%task, %client) { %task.setMonitorFreq(1); } function AIEnhancedReturnFlagTask::assume(%task, %client) { %task.setMonitorFreq(32); }
function AIEnhancedReturnFlagTask::retire(%task, %client) { } function AIEnhancedReturnFlagTask::retire(%task, %client) { }
function AIEnhancedReturnFlagTask::weight(%task, %client) function AIEnhancedReturnFlagTask::weight(%task, %client)
{ {
%flag = nameToID("Team" @ %client.team @ "Flag1"); %flag = nameToID("Team" @ %client.team @ "Flag1");
if (!isObject(%flag) || %flag.isHome) if (!isObject(%flag) || %flag.isHome)
{ {
%task.setWeight(0); // %client.setMoveTarget(-1);
%client.targetFlag = -1; %task.setWeight($DXAI::Task::NoPriority);
%client.isMoving = false; }
} else
else {
{ // TODO: For now, all the bots go after it! Make this check if the bot is range.
// TODO: For now, all the bots go after it! Make this check if the bot is range. %task.setWeight($DXAI::Task::HighPriority);
%task.setWeight(700); %client.returnFlagTarget = %flag;
}
%client.targetFlag = %flag;
}
} }
function AIEnhancedReturnFlagTask::monitor(%task, %client) function AIEnhancedReturnFlagTask::monitor(%task, %client)
{ {
if (!isObject(%client.targetFlag)) if (!isObject(%client.returnFlagTarget))
return; return;
// TODO: Make the bot engage the flag runner if its currently held. // %client.setFollowTarget(%client.returnFlagTarget, 0, 0, false);
%client.isMoving = true; }
%client.moveLocation = %client.targetFlag.getPosition(); //------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------
// Description: A task that performs path correction.
//------------------------------------------------------------------------------------------`
function AIEnhancedPathCorrectionTask::initFromObjective(%task, %objective, %client) { }
function AIEnhancedPathCorrectionTask::assume(%task, %client) { %task.setMonitorFreq(1); }
function AIEnhancedPathCorrectionTask::retire(%task, %client) { }
function AIEnhancedPathCorrectionTask::weight(%task, %client)
{
%task.setWeight(0);
}
function AIEnhancedPathCorrectionTask::monitor(%task, %client)
{
}
//------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------
// Description: A task that triggers bots to grab & run the enemy flag.
//------------------------------------------------------------------------------------------
function AIEnhancedFlagCaptureTask::initFromObjective(%task, %objective, %client) { }
function AIEnhancedFlagCaptureTask::assume(%task, %client) { %task.setMonitorFreq(1); }
function AIEnhancedFlagCaptureTask::retire(%task, %client) { }
function AIEnhancedFlagCaptureTask::weight(%task, %client)
{
if (%client.shouldRunFlag)
{
// First, is the enemy flag home?
%enemyTeam = %client.team == 1 ? 2 : 1;
%enemyFlag = nameToID("Team" @ %enemyTeam @ "Flag1");
if (isObject(%enemyFlag) && %enemyFlag.isHome)
{
%client.targetCaptureFlag = %enemyFlag;
%task.setWeight($DXAI::Task::MediumPriority);
}
}
else
%task.setWeight($DXAI::Task::NoPriority);
}
function AIEnhancedFlagCaptureTask::monitor(%task, %client)
{
if (!isObject(%client.targetCaptureFlag))
return;
%client.isMovingToTarget = true;
// if (%client.targetCaptureFlag.getObjectMount() != %client.player)
// %client.setMoveTarget(%client.targetCaptureFlag.getPosition());
//// else
%client.setMoveTarget(nameToID("Team" @ %client.team @ "Flag1").getPosition());
} }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
function ObjectiveNameToVoice(%objective) function ObjectiveNameToVoice(%objective)
{ {
%result = "avo.grunt"; %result = "avo.grunt";
switch$(%objective) switch$(%objective)
{ {
case "AIEnhancedReturnFlagTask": case "AIEnhancedReturnFlagTask":
%result = "slf.def.flag"; %result = "slf.def.flag";
case "AIEnhancedRearmTask": case "AIEnhancedRearmTask":
%result = "avo.grunt"; %result = "avo.grunt";
case "AIEnhancedEngageTarget": case "AIEnhancedEngageTarget":
%result = "slf.att.attack"; %result = "slf.att.attack";
case "AIEnhancedScoutLocation": case "AIEnhancedScoutLocation":
%result = "slf.def.defend"; %result = "slf.def.defend";
case "AIEnhancedEscort": case "AIEnhancedDefendLocation":
%result = "slf.tsk.cover"; %result = "slf.def.defend";
} case "AIEnhancedEscort":
%result = "slf.tsk.cover";
return %result; }
return %result;
} }