1
1
forked from 0ad/0ad

Allow setting the passability class depending on formation members.

Improves pathfinding for the general case (no large entities in a
formation).

Differential revision: https://code.wildfiregames.com/D4605
Comments by: @marder, @Stan, @wraitii
This was SVN commit r26873.
This commit is contained in:
Freagarach 2022-05-11 14:47:16 +00:00
parent 13d701e3d0
commit ed4e07e594
3 changed files with 30 additions and 6 deletions

View File

@ -903,21 +903,32 @@ Formation.prototype.ComputeMotionParameters = function()
{
let minSpeed = Infinity;
let minAcceleration = Infinity;
let maxClearance = 0;
let maxPassClass;
const cmpPathfinder = Engine.QueryInterface(SYSTEM_ENTITY, IID_Pathfinder);
for (let ent of this.members)
{
let cmpUnitMotion = Engine.QueryInterface(ent, IID_UnitMotion);
if (cmpUnitMotion)
const cmpUnitMotion = Engine.QueryInterface(ent, IID_UnitMotion);
if (!cmpUnitMotion)
continue;
minSpeed = Math.min(minSpeed, cmpUnitMotion.GetWalkSpeed());
minAcceleration = Math.min(minAcceleration, cmpUnitMotion.GetAcceleration());
const passClass = cmpUnitMotion.GetPassabilityClassName();
const clearance = cmpPathfinder.GetClearance(cmpPathfinder.GetPassabilityClass(passClass));
if (clearance > maxClearance)
{
minSpeed = Math.min(minSpeed, cmpUnitMotion.GetWalkSpeed());
minAcceleration = Math.min(minAcceleration, cmpUnitMotion.GetAcceleration());
maxClearance = clearance;
maxPassClass = passClass;
}
}
minSpeed *= this.GetSpeedMultiplier();
let cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
const cmpUnitMotion = Engine.QueryInterface(this.entity, IID_UnitMotion);
cmpUnitMotion.SetSpeedMultiplier(minSpeed / cmpUnitMotion.GetWalkSpeed());
cmpUnitMotion.SetAcceleration(minAcceleration);
cmpUnitMotion.SetPassabilityClassName(maxPassClass);
};
Formation.prototype.ShapeUpdate = function()

View File

@ -247,12 +247,18 @@ function TestFormationExiting(mode)
"StopMoving": () => {},
"SetSpeedMultiplier": () => {},
"SetAcceleration": (accel) => {},
"SetPassabilityClassName": (name) => {},
"MoveToPointRange": () => true,
"SetFacePointAfterMove": () => {},
"GetFacePointAfterMove": () => true,
"GetPassabilityClassName": () => "default"
});
AddMock(SYSTEM_ENTITY, IID_Pathfinder, {
"GetClearance": () => 1,
"GetPassabilityClass": () => 16
});
controllerAI.OnCreate();
@ -420,6 +426,7 @@ function TestMoveIntoFormationWhileAttacking()
"GetWalkSpeed": () => 1,
"SetSpeedMultiplier": (speed) => {},
"SetAcceleration": (accel) => {},
"SetPassabilityClassName": (name) => {},
"MoveToPointRange": (x, z, minRange, maxRange) => {},
"StopMoving": () => {},
"SetFacePointAfterMove": () => {},
@ -427,6 +434,11 @@ function TestMoveIntoFormationWhileAttacking()
"GetPassabilityClassName": () => "default"
});
AddMock(SYSTEM_ENTITY, IID_Pathfinder, {
"GetClearance": () => 1,
"GetPassabilityClass": () => 16
});
AddMock(controller, IID_Attack, {
"GetRange": function() { return { "max": 10, "min": 0 }; },
"CanAttackAsFormation": function() { return false; },

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2021 Wildfire Games.
/* Copyright (C) 2022 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -24,6 +24,7 @@
BEGIN_INTERFACE_WRAPPER(Pathfinder)
DEFINE_INTERFACE_METHOD("SetDebugOverlay", ICmpPathfinder, SetDebugOverlay)
DEFINE_INTERFACE_METHOD("SetHierDebugOverlay", ICmpPathfinder, SetHierDebugOverlay)
DEFINE_INTERFACE_METHOD("GetClearance", ICmpPathfinder, GetClearance)
DEFINE_INTERFACE_METHOD("GetPassabilityClass", ICmpPathfinder, GetPassabilityClass)
DEFINE_INTERFACE_METHOD("UpdateGrid", ICmpPathfinder, UpdateGrid)
END_INTERFACE_WRAPPER(Pathfinder)