Сделал скрипт для обработки модов для игры OpenXcom, добавляющий возможность использовать нестандартное стреляющее оружие в рукопашной (аналог Gun Melee). Он берёт YAML-файл с описанием предметов (наподобие https://pastebin.com/u39XtczR), анализирует массив «categories» и создаёт новый YAML-файл, содержащий по 4 поля для каждого стреляющего оружия: тип, силу удара, скорость и точность (наподобие https://pastebin.com/0Tkfpwpq).
use YAML qw/ LoadFile DumpFile /;
use List::Util qw/ any none /;
$YAML::UseHeader = 0;
$YAML::Preserve = 1;
my ($filename) = @ARGV;
my $data = LoadFile($filename);
my $items_new = [];
# In case the single root key isn't 'items'
my @key_list = keys(%$data);
my $single_key = $key_list[0];
for my $item (@{ $data->{ $single_key } }) {
my $categories = $item->{categories};
# if categories doesn't exist or is empty
if (not $categories or not @$categories) {
next;
}
# if categories doesn't contain any ranged weapon
if ( ( none { $_ eq "STR_PISTOLS" or
# длинный список категорий пропущен
$_ eq "STR_RIFLES" or
$_ eq "STR_LAUNCHERS" } @$categories ) or
( any { $_ eq "STR_CLIPS" } @$categories ) ) {
next;
}
# delete all unnecessary fields; 'categories' is still needed
foreach my $key (keys %$item) {
if ( ($key ne 'categories') and ($key ne 'type') ) {
delete $item->{$key};
}
}
# add melee power/TUs/accuracy fields
if (any { $_ eq "STR_PISTOLS" } @$categories) {
$item->{meleePower} = 20;
$item->{tuMelee} = 15;
$item->{accuracyMelee} = 100;
}
# куча присвоений пропущена
if (any { $_ eq "STR_LAUNCHERS" } @$categories) {
$item->{meleePower} = 80;
$item->{tuMelee} = 80;
$item->{accuracyMelee} = 100;
}
delete $item->{categories};
push @$items_new, $item;
}
$data->{ $single_key } = $items_new;
DumpFile "Gun_Melee_nonstandard.rul", $data;
Вопрос: можно ли как-то оптимизировать этот скрипт? Сократить? Ускорить? Сейчас он в цикле удаляет из каждой ноды все поля кроме 4, а не лучше ли будет создавать новый список нод, содержащих по 4 пары имя-значение? Как это сделать? Можно ли сделать доступ к единственному элементу массива data короче, чем в 3 строки?