Raven
Пользователь
Откуда: Владик Регистрация: Февр. 2004
Всего: 408 сообщений
|
Кто про что, а я опять про строки и использование msg-файлов в своих корыстных, сугубо скриптерских целях :-) Наверное, каждый скриптер сталкивался с необходимостью организовать "ходьбу" НПС по маршруту. Лёгкого стандартного метода для этого не существует, приходилось набивать кучу animate_move_to и пользовать timed_event/map_update/critter_p_proc. Я попытался сделать универсальное решение - с использованием своих любимых строк :-) Итак, суть. Чего я хотел: возможность легко задавать маршрут любой сложности и с любым количеством чекпоинтов. Желательно, без перекомпиляции. Как реализовано. Одна строчка в msg следующего формата: {n}{}{X|COORD_1|COORD_2|COORD_3|...|COORD_X} X - число чекпоинтов, COORD_I - координата i-го чекпоинта. Код. Использую заранее написанную atoimar. Эта процедура получает три параметра - строку-оригинал, строку-стартер и номер ячейки. Возвращает число (int, не str) из указанной ячейки. Разделителем служит символ "|". Строка-стартер - произвольный набор символов до начала массива, он будет отброшен. Строка-оригинал должна иметь вид: {n}{}{заголовок:1|2|3|4} Чтобы получить содержимое второй ячейки, мы должны вызвать её так: atoimar(mstr(n),"заголовок:",1). Цифра "1" - т.к. ячейки нумеруются с нуля. Код процедуры: ---------------------------------------- procedure atoimar(var ostr, var bstr, var cell) begin var i;var val; var str:=""; var c_cell; var j; var flag; str:=bstr; while c_cell<=cell do begin val:=0; flag:=1; j:=0; while ((ostr!=str) and (flag)) and j<32 do begin while not((ostr>str+i and ostr<str+(i+1)) or ostr==str+i) and i<9 do i+=1; if i==9 and ostr>str+"|" and ostr<str+"}" then begin flag:=0; str+="|"; end else begin str+=i; val:=val*10+i; end j+=1; i:=0; end c_cell+=1; end return val; end ---------------------------------------- Если вы разобрались в работе atoi, то поймёте и эту процедуру. Теперь собственно ходьба по маршруту. Логика простая. Есть набор мест. Есть текущее место (выносим в глобальную скриптовую переменную). Если мы на месте - выбираем следующую по списку координату и идём туда. Если не на месте (а значит - в движении) - ничего не делаем. Процедура должна постоянно вызывает сама себя, чтобы определить момент прибытия. Итоговый код: ---------------------------------------- #define var variable var next_place; procedure walk; procedure start begin end procedure map_enter_p_proc begin add_timer_event(self_obj,0,1); end procedure walk begin var aim_tile; var place_num; //получаем общее число чекпоинтом place_num:=atoimar(mstr(10),"",0); //инизиализируем скрипт, стартуем переход к первому чекпоинту if not next_place then begin aim_tile:=atoimar(mstr(10),"",1); animate_move_to_tile(aim_tile); next_place:=1; end aim_tile:=atoimar(mstr(10),"",next_place); //выбираем следующий чекпоинт и идём к нему if tile_num(self_obj)==aim_tile then begin if next_place<place_num then next_place+=1; else next_place:=1; aim_tile:=atoimar(mstr(10),"",next_place); animate_move_to_tile(aim_tile); end add_timer_event(self_obj,10,1); end procedure timed_event_p_proc begin if fixed_param==1 then call walk; end ---------------------------------------- Тестовая строчка для artemple.map: {10}{}{4|18494|18888|20292|19898} Всё. Надеюсь, будет полезным.
|