TribesReplay/base/scripts/aiHumanTasks.cs
2017-07-17 22:51:48 -04:00

292 lines
9 KiB
C#

function aiAddHumanObjective(%client, %objective, %targetClient, %fromCmdMap)
{
//first, make sure the objective Q for the given team exists
if (!isObject($ObjectiveQ[%client.team]))
return 0;
//if a target client is specified, create a link if we can...
if (%targetClient > 0)
{
if (aiHumanHasControl(%client, %targetClient) || (%targetClient.isAIControlled() && !aiAlreadyControlled(%targetClient)))
aiSetHumanControl(%client, %targetClient);
else
return 0;
}
//special (hacky) case here for AIOBombLocation objectives
if (%objective.getName() $= "AIOBombLocation")
{
if (!isObject($AIBombLocationSet))
return 0;
%objective.team = %client.team;
$AIBombLocationSet.add(%objective);
return %objective;
}
//parse the type of objective, and see if it already exists...
%useThisObjective = -1;
%objQ = $ObjectiveQ[%client.team];
if (%objective.getName() $= "AIOEscortPlayer" || %objective.getName() $= "AIOAttackPlayer")
{
//first, make sure the objective is legit
if (!AIClientIsAlive(%objective.targetClientId))
return 0;
//fill in the description:
%objective.description = %objective.getName() SPC getTaggedString(%objective.targetClientId.name);
//now see if the objective already exists...
%count = %objQ.getCount();
for (%i = 0; %i < %count; %i++)
{
%obj = %objQ.getObject(%i);
if (%obj.getName() $= %objective.getName())
{
//if we've found a previously existing version, use it instead of the new objective
if (%obj.issuedByClientId == %client && %obj.targetClientId == %objective.targetClientId)
{
%useThisObjective = %obj;
break;
}
}
}
}
else if (%objective.getName() $= "AIODefendLocation" || %objective.getName() $= "AIOAttackLocation")
{
//make sure it's a valid objective
if (%objective.location $= "" || %objective.location $= "0 0 0")
return 0;
//fill in the description:
%objective.description = %objective.getName() @ " at" SPC %objective.location;
//look for a duplicate...
%count = %objQ.getCount();
for (%i = 0; %i < %count; %i++)
{
%obj = %objQ.getObject(%i);
if (%obj.getName() $= %objective.getName())
{
if (%obj.issuedByClientId == %client && VectorDist(%objective.location, %obj.location) < 30)
{
%useThisObjective = %obj;
break;
}
}
}
}
else if (%objective.getName() $= "AIOAttackObject" || %objective.getName() $= "AIORepairObject" ||
%objective.getName() $= "AIOLazeObject" || %objective.getName() $= "AIOMortarObject" ||
%objective.getName() $= "AIOTouchObject")
{
//make sure it's a valid objective
if (!isObject(%objective.targetObjectId))
return 0;
//fill in the description:
%objective.description = %objective.getName() SPC %objective.targetObjectId.getDataBlock().getName();
//look for a duplicate...
%count = %objQ.getCount();
for (%i = 0; %i < %count; %i++)
{
%obj = %objQ.getObject(%i);
if (%obj.getName() $= %objective.getName())
{
if (%obj.issuedByClientId == %client && %objective.targetObjectId == %obj.targetObjectId)
{
%useThisObjective = %obj;
break;
}
}
}
}
else if (%objective.getName() $= "AIODeployEquipment")
{
//make sure it's a valid objective
if (%objective.location $= "" || %objective.location $= "0 0 0" || %objective.equipment $= "")
return 0;
//fill in the description:
%objective.description = %objective.getName() SPC %objective.equipment SPC "at" SPC %objective.location;
//look for a duplicate...
%count = %objQ.getCount();
for (%i = 0; %i < %count; %i++)
{
%obj = %objQ.getObject(%i);
if (%obj.getName() $= %objective.getName())
{
if (%obj.issuedByClientId == %client && VectorDist(%objective.location, %obj.location) < 8 && %objective.equipment == %obj.equipment)
{
%useThisObjective = %obj;
break;
}
}
}
}
//if we found a previously added objective, delete the submitted one
if (%useThisObjective > 0)
{
%objective.delete();
}
//otherwise add it to the objective Q
else
{
%useThisObjective = %objective;
$ObjectiveQ[%client.team].add(%useThisObjective);
%objective.shouldAcknowledge = true;
//now that it's been added, see if anyone picks it up within 10 seconds
schedule(10000, %objective, "AIReassessHumanObjective", %objective);
}
//now see if we're supposed to force the target to the objective
//the link will have already been checked at the top...
if (%targetClient > 0)
{
//if we were previously assigned to an objective which was forced on this client, we need to delete it...
%prevObjective = %targetClient.objective;
if (%prevObjective != %useThisObjective && %prevObjective.issuedByClientId == %targetClient.controlByHuman)
{
AIClearObjective(%prevObjective);
%prevObjective.delete();
}
//if the command is an escort command, issue it at the forced escort weight instead
%forcedWeight = $AIWeightHumanIssuedCommand;
if (%useThisObjective.getName() $= "AIOEscortPlayer")
%forcedWeight = $AIWeightHumanIssuedEscort;
//reweight the client's objective
%testWeight = 0;
if (isObject(%client.objective))
%testWeight = %client.objective.weight(%client, %client.objectiveLevel, 0, %inventoryStr);
if (%testWeight <= 0 || %testWeight > %client.objectiveWeight)
%client.objectiveWeight = %testWeight;
//see if we should force the objective
if (%targetClient.objectiveWeight <= %forcedWeight)
{
AIForceObjective(%targetClient, %useThisObjective, %forcedWeight);
//clearing the prev objective will undo the link - re-do it here
aiSetHumanControl(%client, %targetClient);
//send the "command accepted response"
if (!%fromCmdMap)
{
if (isObject(%client.player) && VectorDist(%targetClient.player.position, %client.player.position) <= 40)
schedule(250, %targetClient.player, "AIPlayAnimSound", %targetClient, %client.player.getWorldBoxCenter(), "cmd.acknowledge", 1, 1, 0);
}
else
serverCmdAcceptTask(%targetClient, %client, -1, %useThisObjective.ackDescription);
}
else
{
//send the "command declined response"
if (!%fromCmdMap)
{
if (isObject(%client.player) && VectorDist(%targetClient.player.position, %client.player.position) <= 40)
{
schedule(250, %targetClient.player, "AIPlayAnimSound", %targetClient, %client.player.getWorldBoxCenter(), "cmd.decline", -1, -1, 0);
schedule(2000, %client.player, "AIRespondToEvent", %client, 'ChatCmdWhat', %targetClient);
}
}
else
serverCmdDeclineTask(%targetClient, %client, %useThisObjective.ackDescription);
}
}
//return the objective used, so the calling function can know whether to delete the parameter one...
return %useThisObjective;
}
function AIReassessHumanObjective(%objective)
{
if (%objective.issuedByHuman)
{
//see if there's anyone still assigned to this objective
if (!AIClientIsAlive(%objective.clientLevel1) && !AIClientIsAlive(%objective.clientLevel2) && !AIClientIsAlive(%objective.clientLevel3))
{
AIClearObjective(%objective);
%objective.delete();
}
//else reassess this objective in another 10 seconds
else
schedule(10000, %objective, "AIReassessHumanObjective", %objective);
}
}
function aiAttemptHumanControl(%humanClient, %aiClient)
{
if (!aiAlreadyControlled(%aiClient))
{
aiSetHumanControl(%humanClient, %aiClient);
return true;
}
else
return false;
}
function aiHumanHasControl(%humanClient, %aiClient)
{
if (AIClientIsAlive(%humanClient) && AIClientIsAlive(%aiClient))
if (%humanClient.controlAI == %aiClient && %aiClient.controlByHuman == %humanClient)
return true;
return false;
}
function aiAlreadyControlled(%aiClient)
{
if (AIClientIsAlive(%aiClient) && AIClientIsAlive(%aiClient.controlByHuman))
if (%aiClient.controlByHuman.controlAI == %aiClient)
return true;
return false;
}
function aiReleaseHumanControl(%humanClient, %aiClient)
{
//make sure they were actually linked
if (!aiHumanHasControl(%humanClient, %aiClient))
return;
aiBreakHumanControl(%humanClient, %aiClient);
}
function aiSetHumanControl(%humanClient, %aiClient)
{
//make sure it's from a human to an ai
if (%humanClient.isAIControlled() || !%aiClient.isAIControlled())
return;
//these checks should be redundant, but...
if (%humanClient.controlAI > 0)
aiBreakHumanControl(%humanClient, %humanClient.controlAI);
if (%aiClient.controlByHuman > 0)
aiBreakHumanControl(%aiClient.controlByHuman, %aiClient);
//create the link
%humanClient.controlAI = %aiClient;
%aiClient.controlByHuman = %humanClient;
}
function aiBreakHumanControl(%humanClient, %aiClient)
{
//make sure they were actually linked
if (!aiHumanHasControl(%humanClient, %aiClient))
return;
//for now, just break the link, and worry about unassigning objectives later...
%humanClient.controlAI = "";
%aiClient.controlByHuman = "";
}