mirror of
https://github.com/exogen/t2-mapper.git
synced 2026-01-20 04:35:05 +00:00
320 lines
9.6 KiB
C#
320 lines
9.6 KiB
C#
// bounty game support
|
|
|
|
function BountyGame::onAIRespawn(%game, %client)
|
|
{
|
|
//add the default task
|
|
if (! %client.defaultTasksAdded)
|
|
{
|
|
%client.defaultTasksAdded = true;
|
|
%client.addTask(AIPickupItemTask);
|
|
%client.addTask(AIUseInventoryTask);
|
|
%client.addTask(AITauntCorpseTask);
|
|
%client.addTask(AIEngageTurretTask);
|
|
%client.addTask(AIDetectMineTask);
|
|
%client.addTask(AIBountyPatrolTask);
|
|
%client.bountyTask = %client.addTask(AIBountyEngageTask);
|
|
}
|
|
|
|
//set the inv flag
|
|
%client.spawnUseInv = true;
|
|
}
|
|
|
|
function BountyGame::AIInit(%game)
|
|
{
|
|
AIInit();
|
|
}
|
|
|
|
function BountyGame::aiBountyAssignTarget(%game, %client, %target)
|
|
{
|
|
if (!isObject(%client.bountyTask))
|
|
%client.bountyTask = %client.addTask(AIBountyEngageTask);
|
|
%task = %client.bountyTask;
|
|
|
|
%task.baseWeight = $AIWeightKillFlagCarrier[1];
|
|
%task.buyEquipmentSet = "LightEnergySniper";
|
|
}
|
|
|
|
function AIBountyEngageTask::assume(%task, %client)
|
|
{
|
|
%task.setWeightFreq(15);
|
|
%task.setMonitorFreq(15);
|
|
}
|
|
|
|
function AIBountyEngageTask::retire(%task, %client)
|
|
{
|
|
%client.setEngageTarget(-1);
|
|
}
|
|
|
|
function AIBountyEngageTask::weight(%task, %client)
|
|
{
|
|
%player = %client.player;
|
|
if (!isObject(%player))
|
|
return;
|
|
|
|
%clientPos = %player.getWorldBoxCenter();
|
|
%client.shouldEngage = -1;
|
|
|
|
//first, make sure we actually can fight
|
|
if (AIEngageOutOfAmmo(%client))
|
|
{
|
|
%task.setWeight(0);
|
|
return;
|
|
}
|
|
|
|
//see if anyone has fired on us recently...
|
|
%mustEngage = false;
|
|
%losTimeout = $AIClientMinLOSTime + ($AIClientLOSTimeout * %client.getSkillLevel());
|
|
if (AIClientIsAlive(%client.lastDamageClient, %losTimeout) && getSimTime() - %client.lastDamageTime < %losTimeout)
|
|
{
|
|
//see if the attacker is either our target or, we are their target
|
|
if (%client.lastDamageClient == %client.objectiveTarget || %client.lastDamageClient.objectiveTarget == %client)
|
|
{
|
|
%mustEngage = true;
|
|
%currentTarget = %client.getEngageTarget();
|
|
|
|
//see if this is a new attacker
|
|
if (AIClientIsAlive(%currentTarget) && %currentTarget != %client.lastDamageClient)
|
|
{
|
|
%targPos = %currentTarget.player.getWorldBoxCenter();
|
|
%curTargDist = %client.getPathDistance(%targPos);
|
|
|
|
%newTargPos = %client.lastDamageClient.player.getWorldBoxCenter();
|
|
%newTargDist = %client.getPathDistance(%newTargPos);
|
|
|
|
//see if the new targ is no more than 30 m further
|
|
if (%newTargDist > 0 && %newTargDist < %curTargDist + 30)
|
|
%client.shouldEngage = %client.lastDamageClient;
|
|
else
|
|
%client.shouldEngage = %currentTarget;
|
|
}
|
|
else
|
|
%client.shouldEngage = %client.lastDamageClient;
|
|
}
|
|
|
|
//otherwise we should run react to an attacker who is not really supposed to be attacking us...
|
|
else
|
|
%client.setDangerLocation(%client.player.position, 20);
|
|
}
|
|
|
|
//no one has fired at us recently, see if we're near our objective target...
|
|
else
|
|
{
|
|
//see if we still have sight of the current target
|
|
%hasLOS = %client.hasLOSToClient(%client.objectiveTarget);
|
|
%losTime = %client.getClientLOSTime(%client.objectiveTarget);
|
|
if (%hasLOS || %losTime < %losTimeout)
|
|
%client.shouldEngage = %client.objectiveTarget;
|
|
else
|
|
%client.shouldEngage = -1;
|
|
}
|
|
|
|
//now set the weight
|
|
if (%client.shouldEngage > 0)
|
|
{
|
|
//if we've been fired upon...
|
|
if (%mustEngage)
|
|
%task.setWeight($AIWeightReturnFire);
|
|
|
|
//see if we can allow the bot to use an inv station...
|
|
else if (%client.spawnUseInv)
|
|
{
|
|
//see if there's an available inv station
|
|
%result = AIFindClosestInventory(%client, false);
|
|
%closestInv = getWord(%result, 0);
|
|
%closestDist = getWord(%result, 1);
|
|
if (isObject(%closestInv))
|
|
{
|
|
if (isObject(%client.shouldEngage.player))
|
|
{
|
|
%dist = %client.getPathDistance(%client.shouldEngage.player.position);
|
|
if (%dist < 70 || %closestDist > 200)
|
|
%task.setWeight($AIWeightReturnFire);
|
|
else
|
|
%task.setWeight($AIBountyWeightShouldEngage);
|
|
}
|
|
else
|
|
%task.setWeight($AIBountyWeightShouldEngage);
|
|
}
|
|
else
|
|
{
|
|
%client.spawnUseInv = false;
|
|
%task.setWeight($AIWeightReturnFire);
|
|
}
|
|
}
|
|
else
|
|
%task.setWeight($AIWeightReturnFire);
|
|
}
|
|
else
|
|
%task.setWeight(0);
|
|
}
|
|
|
|
function AIBountyEngageTask::monitor(%task, %client)
|
|
{
|
|
if (AIClientIsAlive(%client.shouldEngage))
|
|
%client.stepEngage(%client.shouldEngage);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//AIPatrolTask used to wander around the map (DM and Hunters mainly) looking for something to do...
|
|
|
|
function AIBountyPatrolTask::init(%task, %client)
|
|
{
|
|
}
|
|
|
|
function AIBountyPatrolTask::assume(%task, %client)
|
|
{
|
|
%task.setWeightFreq(13);
|
|
%task.setMonitorFreq(13);
|
|
%task.findLocation = true;
|
|
%task.patrolLocation = "0 0 0";
|
|
%task.idleing = false;
|
|
%task.idleEndTime = 0;
|
|
}
|
|
|
|
function AIBountyPatrolTask::retire(%task, %client)
|
|
{
|
|
}
|
|
|
|
function AIBountyPatrolTask::weight(%task, %client)
|
|
{
|
|
%task.setWeight($AIWeightPatrolling);
|
|
}
|
|
|
|
function AIBountyPatrolTask::monitor(%task, %client)
|
|
{
|
|
//this call works in conjunction with AIEngageTask
|
|
%client.setEngageTarget(%client.shouldEngage);
|
|
|
|
//see if we're close enough to our patrol point
|
|
if (%task.idleing)
|
|
{
|
|
if (getSimTime() > %task.idleEndTime)
|
|
{
|
|
%task.findLocation = true;
|
|
%task.idleing = false;
|
|
}
|
|
}
|
|
|
|
//see if we need to find a place to go...
|
|
else if (%task.findLocation)
|
|
{
|
|
//first, see if we're in need of either health, or ammo
|
|
//note: normally, I'd be tempted to put this kind of "looking for health" code
|
|
//into the AIPickupItemTask, however, that task will be used in CTF, where you
|
|
//don't want people on AIDefendLocation to leave their post to hunt for health, etc...
|
|
//AIPickupItemTask only deals with items within a 30m radius around the bot.
|
|
//AIPatrolTask will move the bot to the vicinity of an item, then AIPickUpItemTask
|
|
//will finish the job...
|
|
%foundItemLocation = false;
|
|
%damage = %client.player.getDamagePercent();
|
|
if (%damage > 0.7)
|
|
{
|
|
//search for a health kit
|
|
%closestHealth = AIFindSafeItem(%client, "Health");
|
|
if (%closestHealth > 0)
|
|
{
|
|
%task.patrolLocation = %closestHealth.getWorldBoxCenter();
|
|
%foundItemLocation = true;
|
|
}
|
|
}
|
|
else if (AIEngageOutOfAmmo(%client))
|
|
{
|
|
//search for a Ammo or a weapon...
|
|
%closestItem = AIFindSafeItem(%client, "Ammo");
|
|
if (%closestItem > 0)
|
|
{
|
|
%task.patrolLocation = %closestItem.getWorldBoxCenter();
|
|
%foundItemLocation = true;
|
|
}
|
|
}
|
|
|
|
//now see if we don't really have good equipment...
|
|
if (!%foundItemLocation && AIEngageWeaponRating(%client) < 20)
|
|
{
|
|
//search for any useful item
|
|
%closestItem = AIFindSafeItem(%client, "Any");
|
|
if (%closestItem > 0)
|
|
{
|
|
%task.patrolLocation = %closestItem.getWorldBoxCenter();
|
|
%foundItemLocation = true;
|
|
}
|
|
}
|
|
//choose a randomish location only if we're not in need of health or ammo
|
|
if (!%foundItemLocation)
|
|
{
|
|
//find a random item/inventory in the map, and pick a spawn point near it...
|
|
%pickGraphNode = false;
|
|
%chooseSet = 0;
|
|
if ($AIInvStationSet.getCount() > 0)
|
|
%chooseSet = $AIInvStationSet;
|
|
else if ($AIWeaponSet.getCount() > 0)
|
|
%chooseSet = $AIWeaponSet;
|
|
else if ($AIItemSet.getCount() > 0)
|
|
%chooseSet = $AIItemSet;
|
|
|
|
if (!%chooseSet)
|
|
%pickGraphNode = true;
|
|
|
|
//here we pick whether we choose a random map point, or a point based on an item...
|
|
if (getRandom() < 0.3)
|
|
%pickGraphNode = true;
|
|
|
|
//here we decide whether we should choose a player location... a bit of a cheat but
|
|
//it's scaled by the bot skill level
|
|
%pickPlayerLocation = false;
|
|
%skill = %client.getSkillLevel();
|
|
if (%skill < 1.0)
|
|
%skill = %skill / 2.0;
|
|
if (getRandom() < (%skill * %skill) && AIClientIsAlive(%client.objectiveTarget))
|
|
{
|
|
%task.patrolLocation = %client.objectiveTarget.player.getWorldBoxCenter();
|
|
%pickGraphNode = false;
|
|
%pickPlayerLocation = true;
|
|
}
|
|
|
|
if (!%pickGraphNode && !%pickPlayerLocation)
|
|
{
|
|
%itemCount = %chooseSet.getCount();
|
|
%item = %chooseSet.getObject(getRandom() * (%itemCount - 0.1));
|
|
%nodeIndex = navGraph.randNode(%item.getWorldBoxCenter(), 10, true, true);
|
|
if (%nodeIndex <= 0)
|
|
%pickGraphNode = true;
|
|
else
|
|
%task.patrolLocation = navGraph.randNodeLoc(%nodeIndex);
|
|
}
|
|
|
|
//see if we failed above or have to pick just a random spot on the graph - use the spawn points...
|
|
if (%pickGraphNode)
|
|
{
|
|
%task.patrolLocation = Game.pickPlayerSpawn(%client, true);
|
|
if (%task.patrolLocation == -1)
|
|
{
|
|
%client.stepIdle(%client.player.getWorldBoxCenter());
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//now that we have a new location - move towards it
|
|
%task.findLocation = false;
|
|
%client.stepMove(%task.patrolLocation, 8.0);
|
|
}
|
|
|
|
//else we're on patrol - see if we're close to our destination
|
|
else
|
|
{
|
|
%client.stepMove(%task.patrolLocation, 8.0);
|
|
%distToDest = %client.getPathDistance(%task.patrolLocation);
|
|
if (%distToDest > 0 && %distToDest < 10)
|
|
{
|
|
%task.idleing = true;
|
|
%task.idleEndTime = 4000 + getSimTime() + (getRandom() * 6000);
|
|
%client.stepIdle(%client.player.getWorldBoxCenter());
|
|
}
|
|
}
|
|
}
|
|
|
|
function aiB()
|
|
{
|
|
exec("scripts/aiBountyGame");
|
|
} |