Один из относительно простых способов сделать это - нарисовать луч от центра взрыва до центра каждой сущности DISTANCE(explosion,entity) < exlosion.max_radius
(псевдокод).
Для каждого существа следуйте этому лучу, уменьшая базовый урон по мере движения. Всякий раз, когда вы ударяете объект, вычитаете его укрывистость от урона (существенно укорачивая луч).
Когда луч попадает на объект, любой урон остается вашим взрывным уроном.
Для этого подхода вам, вероятно, понадобится довольно высокий базовый урон, который быстро уменьшается с расстоянием (обратно пропорционально квадрату расстояния, что должно хорошо).
Другой подход - нарисовать сектор, полностью содержащий сущность; но не шире; и весь путь к .max_radius
. Вычтите из области этого сектора площадь, покрытую любым покрытием между взрывом и объектом, умноженную на его значение покрытия. Оставшаяся область - ваш урон от взрыва.
Одним из приятных побочных эффектов этого является то, что чем ближе объект к взрыву, тем шире становится сектор и тем больший урон вы получаете (когда вы подсчитываете всю площадь сектора и просто вычитаете площадь покрытия между сущность и взрыв.
Также может быть полезно рассматривать покрытие как сущности; и просто вычтите урон, получаемый более близкими существами, от тех, кто находится дальше, но это может стать грубым.
Несомненно, существует еще более элегантный и умный подход, но он, вероятно, требует довольно неприятного исчисления. Это всегда так.