Хм. Вроде бы не должно 2 раза выскакивать сообщение. За исключением одного момента.
Попробуем разобрать логику скрипта с самого начала.
Предположим, что игрок нажал на клавишу 5. Тогда, согласно стр. 12 (if IsKeyPressed 6), переменная tap примет значение 1. Кстати, это значение она менять не будет никогда, пока игрок не нажмет клавишу 8. Далее, при проверках на строках 20 и 21
20 if (tap == 1) && (player.GetEquipped итем)
21 if IsKeyPressed 6 && key == 0
(предположим, что итем оборудован и игрок еще не успел отжать клавишу 5), переменная timer примет значение 25, а key станет равно 1. Опять предположим, что есть какая-то цель у игрока, она жива и это человек, тогда переменная target не примет нулевое значение. После этого игра доберется до строки
49 if timer > 0
не изменит значения timer и прекратит выполнение скрипта в этом фрейме.
В следующем фрейме если игрок еще не отжал клавишу 5, завалится проверка в строке 21, но пройдется проверка в строке 45 и скрипт опять будет завершен строкой 46 до следующего фрейма. И только когда игрок отпустит клавишу 5 завалятся проверки в строках 21 и 45
21 if IsKeyPressed 6 && key == 0
45 elseif IsKeyPressed 6 && key == 1
Игра опять получит возможность продолжить выполнение скрипта в строке
49 if timer > 0
Проверка пройдена, выполняется
50 set timer to timer - GetSecondsPassed
51 return
Опять следующий фрейм, и опять строки 49, 50, 51. И так до тех пор, пока timer не станет отрицательным (прошло более 25 секунд).
Когда это случится, пройдется проверка
52 elseif timer <= 0 && key == 1
И будет выдано необходимое сообщение, обнулятся key и target, а timer так и останется отрицательным.
Совокупность этих новых значений вкупе с предыдущими проверками воспрепятствует повторному показу сообщения.
Вроде бы все в порядке, но тут игрок нажимает клавишу 8, переменная tap устанавливается в значение 2. Предыдущие проверки игнорируются, а key при определенных условиях устанавливается в 1. При этом вспомним, что timer остается все еще отрицательным. Вот тут-то, при проходе скрипта в следующем фрейме, положительно пройдется проверка
52 elseif timer <= 0 && key == 1
и будет показано сообщение еще один раз. При этом key и target будут принудительно обнулены, что, возможно не предусматривается логикой блока if (tap == 2) и приведет к непредсказуемым последствиям (точнее, вполне предсказуемым, но я не хочу углубляться в логику этого блока потому, что цель, вроде бы достигнута и объяснено повторное получение сообщения).
Решение, если я прав во всем, что написал выше и угадал проблему, то решение тут вполне тривиально - не допустить срабатывания блока с таймером вне блока if (tap == 1)
Возможно вот так:
if (tap == 1) && (player.GetEquipped итем)
if IsKeyPressed 6 && key == 0
set timer to 25
set target to player.GetCombatTarget
set key to 1
... бла-бла-бла...
elseif IsKeyPressed 6 && key == 1
return
endif
if timer > 0
set timer to timer - GetSecondsPassed
return
elseif timer <= 0 && key == 1
; вывод сообщения+переменных
set key to 0
set target to 0
endif
endif
elseif (tap == 2) && (player.GetEquipped итем)
if IsKeyPressed 9 && key == 0
set target to player.GetCombatTarget
set key to 1
endif
... бла-бла-бла...
endif
Отредактировано evp (2011-10-27 00:45:23)