Garik66 Опубликовано 8 февраля, 2016 Поделиться Опубликовано 8 февраля, 2016 (изменено) Выполнял этот запрос - Assassin’s Creed Chronicles: India и решил написать заодно небольшую статейку для новичков. Статья будет короткой, пояснения внутри скриптов, работа скриптов показана на видео. Поиск самих значений таймера в этой статье не рассматривается. По поискам значений есть много статей и видео. Варианты решения задачи с таймером (какой вариант использовать и где, решать Вам). 1. Заморозка таймера. 1.1. С помощь опкода NOP пример скрипт "Timer Mission Freeze v. Nop": Скрытый текст [ENABLE] aobscan(aob_timer,xx89xxxxxxxxc2xxxxxxxxxxxxxxxxxxxxxxxxxx8bxxxx85xx74xx8bxxxxxxxxxx8bxxffxxxxxxxxxx85) registersymbol(aob_timer) aob_timer: db 90 // NOP [DISABLE] aob_timer: db 40 // inc eax unregistersymbol(aob_timer) // Т.е. при активации вместо инструкции inc eax ничего не делаем 1.2.* С помощью опкода DEC пример скрипт "Timer Mission Freeze v. dec " Скрытый текст [ENABLE] aobscan(aob_timer,xx89xxxxxxxxc2xxxxxxxxxxxxxxxxxxxxxxxxxx8bxxxx85xx74xx8bxxxxxxxxxx8bxxffxxxxxxxxxx85) alloc(newmem_timer,2048) label(returnhere_timer) registersymbol(aob_timer) newmem_timer: inc eax // игровая инструкция - увеличения таймера на 1 dec eax // инструкция нашей инъекции - ументшение таймера на 1 mov [ecx+08],eax pop esi jmp returnhere_timer aob_timer: jmp newmem_timer returnhere_timer: [DISABLE] aob_timer: db 40 89 41 08 5E unregistersymbol(aob_timer) dealloc(newmem_timer) 2. Обнуление таймера при достижении определённого значения пример скрипт "Timer Mission v. Adding a limit to the timer": Скрытый текст [ENABLE] aobscan(aob_TimerMission,xx89xxxxxxxxc2xxxxxxxxxxxxxxxxxxxxxxxxxx8bxxxx85xx74xx8bxxxxxxxxxx8bxxffxxxxxxxxxx85) alloc(newmem_TimerMission,2048) label(returnhere_TimerMission) label(timer1) // timer1 добавлен в скрипт и в таблицу для большей // наглядности, в самом чите он не нужен. registersymbol(timer1) label(timer2) // В данном случае timer2 - это значение, после которого // игровой таймер будет обнулён. Вводиться // вручную в таблице. registersymbol(timer2) registersymbol(aob_TimerMission) newmem_TimerMission: inc eax mov [timer1],eax // Записываем в timer1 значение игрового таймера. cmp [timer2],0 // Сравниваем значение в timer2 c 0 je @f // Если 0, то никакого изменения в игровом коде, // прыгаем на метку @@. // Если не 0, то cmp [timer2],eax // Сравниваем значение игрового таймера (eax) cо значением // в timer2. jne @f // Если неравно, то никакого изменения в игровом коде, // прыгаем на метку @@. // Если равно, то push 0 // выгружаем в стек 0 pop eax // выгружаем из стека 0 в eax. ем самым обнуляя таймер. @@: // Оригинальные игровые инструкции. mov [ecx+08],eax pop esi jmp returnhere_TimerMission timer1: dd 0 timer2: dd 0 aob_TimerMission: jmp newmem_TimerMission returnhere_TimerMission: [DISABLE] aob_TimerMission: db 40 89 41 08 5E unregistersymbol(timer1) unregistersymbol(timer2) unregistersymbol(aob_TimerMission) dealloc(newmem_TimerMission) 3. Замедление таймера 3.1. Вариант с добавлением дополнительного внутрискриптового таймера: пример скрипт "Timer Mission v. timer slowdown v. Adding a timer inside the script": Скрытый текст [ENABLE] aobscan(aob_TimerMission,xx89xxxxxxxxc2xxxxxxxxxxxxxxxxxxxxxxxxxx8bxxxx85xx74xx8bxxxxxxxxxx8bxxffxxxxxxxxxx85) alloc(newmem_TimerMission,2048) label(returnhere_TimerMission) label(code) label(timer1) // timer1 добавлен в скрипт и в таблицу для большей // наглядности, в самом чите он не нужен. registersymbol(timer1) label(timer2) // timer2 внутрискриптовый таймер в таблицу для // большей наглядности, в самом чите в таблице // он не нужен. registersymbol(timer2) label(Coefficient) // Coefficient - нужен и в таблице и в скрипте. Это // во сколько раз нужно замедлить таймер. Вводиться // вручную в таблице. registersymbol(Coefficient) registersymbol(aob_TimerMission) newmem_TimerMission: push ebx // Сохраняем регистр ebx перед использованием. mov ebx,[Coefficient] // Загружаем в него значение в Coefficient cmp ebx,[timer2] // Сравниваем это значение со значением в timer2. pop ebx // Восстанавливаем регистр ebx. je @f // Если значения равны, то прыгаем на метку @@. // Если не равны, то inc [timer2] // увеличиваем внутрискриптовый таймер на 1. jmp code // и прыгаем на метку code. @@: mov [timer2],1 // Записываем в timer2 1, для того, чтобы он заново // начинал считать. inc eax // Увеличиваем на 1 игровой таймер. code: mov dword ptr [timer1],eax // Записываем в timer1 значение игрового таймера. mov [ecx+08],eax // Далее идут Оригинальные игровые инструкции. pop esi jmp returnhere_TimerMission timer1: dd 0 timer2: dd 1 Coefficient: dd 1 aob_TimerMission: jmp newmem_TimerMission returnhere_TimerMission: [DISABLE] aob_TimerMission: // 016674EC db 40 89 41 08 5E unregistersymbol(timer1) unregistersymbol(timer2) unregistersymbol(Coefficient) unregistersymbol(aob_TimerMission) dealloc(newmem_TimerMission) * - вариант скрипта может приводить в некоторых играх к вылету, в конце в видео я это показал. В этом случае нужно выяснять из-за чего происходит вылет (для данной игры я не делал этого). Но что-то подобное происходило у меня при написании скрипта на патроны для Fallout 3 и там я решил проблемы с вылетами и объяснил почему происходил вылет, если появиться желание можете почитать в той теме - Видео: Ну и сама табличка со скриптами и уже назначенными адресами: PS: Табличку выложил ниже. Изменено 11 февраля, 2016 пользователем Garik66 8 Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 9 февраля, 2016 Автор Поделиться Опубликовано 9 февраля, 2016 (изменено) Продолжим. Скрипт 3.1. имеет ограничение - мы можем замедлить таймер только в 2 раза, в 3, в 4 и т.д. Т.е. можем использовать только целые (Integer) числа. А что, если пользователю нужно замедлить таймер в полтора раза, в 2.5, в 8,5 и т.д. В этом случае скрипт 3.1. нам не поможет, придётся переписать его. В работе с нецелыми числами (дробными, вещественными, числами с плавающей точкой - короче FLOAT) нам поможет математический сопроцессор, т.е. FPU. Для изучения вопроса наберите например работа с вещественными числами в поисковике. Лично мне понравилась вот эта статья Скрытый текст http://pblog.ru/?p=241 часто к ней обращаюсь, если пишу что-нибудь для дробных чисел. Как разберётесь не много, то уже задавайте более конкретный вопрос поисковику - например ассемблер fadd. Выложу написанный скрипт, как всегда, для понимания - что он делает, прочтите комментарии внутри скрипта. То, что уже комментировал раньше в скрипте не стал комментировать. Закомментировал, только что делают новые опкоды: FLD1, FDIV, FADD, FSTP и FSUBR. 3.2. Вариант с делением шага игрового таймера: пример скрипт "Timer Mission v. timer slowdown v. division step of the game timer". Скрытый текст [ENABLE] aobscan(aob_TimerMission,xx89xxxxxxxxc2xxxxxxxxxxxxxxxxxxxxxxxxxx8bxxxx85xx74xx8bxxxxxxxxxx8bxxffxxxxxxxxxx85) alloc(newmem_TimerMission,2048) label(returnhere_TimerMission) label(code) label(timer1) registersymbol(timer1) label(timer2) registersymbol(timer2) label(NewStepTimer) label(Coefficient) registersymbol(Coefficient) registersymbol(aob_TimerMission) newmem_TimerMission: fld1 // Загружаем в стек (в st(0), при этом сдвигаем стек) 1, // где 1 - это (шаг игрового таймера - 1 сек). fdiv [Coefficient] // Делим 1 (st(0)) на значение в Coefficient, // тем самым получая новый шаг для внутрискриптового // таймера [timer2]. // Результат заносится в st(0) не сдвигая стека. fadd [timer2] // Прибавляем st(0) к значению в [timer2]. // Результат также заносится в st(0) не сдвигая стека. fstp [timer2] // Выгружаем, полученную сумму в [timer2], при этом // стек сдвигается, возвращаясь в первоначальное // состояние. cmp [timer2],(float)1 // Сравниваем это значение с 1. jb code // Если меньше 1, то прыгаем на метку code. // Если больше 1, то inc eax // Увеличиваем игровой таймер на 1. И отнимем 1 // от внутрискриптового таймера [timer2]. fld1 // Загружаем в стек (в st(0), при этом сдвигаем стек) 1 fsubr [timer2] // Отнимаем от значения в [timer2] 1 // Результат также заносится в st(0) не сдвигая стека. fstp [timer2] // Выгружаем, полученное значение в [timer2], при этом // стек сдвигается, возвращаясь в первоначальное // состояние. code: mov dword ptr [timer1],eax mov [ecx+08],eax pop esi jmp returnhere_TimerMission timer1: dd 0 timer2: dd (float)0 Coefficient: dd (float)1 NewStepTimer: dd (float)0 aob_TimerMission: jmp newmem_TimerMission returnhere_TimerMission: [DISABLE] aob_TimerMission: // 016674EC db 40 89 41 08 5E unregistersymbol(timer1) unregistersymbol(timer2) unregistersymbol(Coefficient) unregistersymbol(aob_TimerMission) dealloc(newmem_TimerMission) Скрипт 3.2. более универсальный подойдёт как для целых, так и для не целых значений. На видео показана работа скрипта и половина видео посвящена, как отслеживать онлайн значения регистров FPU. Видео: Ну и табличка с 6 скриптами и нужными адресами: Ниже залита табличка со всеми скриптами этой темы. Изменено 11 февраля, 2016 пользователем Garik66 4 Ссылка на комментарий Поделиться на другие сайты Поделиться
Submarina Опубликовано 10 февраля, 2016 Поделиться Опубликовано 10 февраля, 2016 ХОРОШАЯ ТЕМА Garik66 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 10 февраля, 2016 Автор Поделиться Опубликовано 10 февраля, 2016 (изменено) Ну и для закрепления. Мы написали скрипт, выложили его в паблик и нам пишет ну допустим "Несообразительный пользователь". "Несообразительный пользователь" - "Я включил скрипт, а время не как в игре. Сделайте пожалуйста как в игре. Из сообщения мы понимаем, что пользователь хочет, чтобы таймер был поделён на минуты и секунды. И тут вмешиваетесь Вы, так как уже написали скрипт 2. Обнуление таймера при достижении определённого значения пример скрипт "Timer Mission v. Adding a limit to the timer": Вы - "Это просто, добавим ещё один таймер и каждые 60 секунд будем обнулять секундомер, а минутный таймер увеличивать на 1." Немного подумав, Я - "И это всё? Вы точно всё учли?" И через паузу - "А если "Несообразительный пользователь" активирует скрипт не вначале миссии, когда таймер равен 0, а в середине, например после 10 минут? В этом случае нам нужно разово сделать пересчёт секунд в минуты и остаток записать в секундомер." Итак с первым заданием разобрались. Но "Несообразительный пользователь" не унимается - "Я поставил уровень сложности "Кошмар", а там интерфейса нет, как в Hitman: Absolution и таймера не видно, сделайте мне пожалуйста, чтобы скрипт хотя бы каждую минуту сообщал мне об этом." Итак со вторым заданием тоже всё ясно - нужно добавить какой-нибудь звуковой сигнал и чтобы он звучал каждую минуту. Для этого уже ассемблера СЕ нам не хватит, придётся использовать вставки на LUA. И снова "Несообразительный пользователь" - "И сделайте пожалуйста, чтобы таймер обнулился на 12 минутах, а потом каждые 2 минуты. (время подобрано, чтобы не удлинять видео) Ну вот и третье задание. Сам скрипт на этот раз комментировать не буду. После скрипта опишу некоторые новые опкоды и немного LUA. 4. Скрипт по заданию "Timer Mission v. Sound" Скрытый текст [ENABLE] {$LUA} timer = createTimer(true) timer:setInterval(5) timer.OnTimer = function() if getAddressList().getMemoryRecordByID("63").Value == "59" then PlaySound(findTableFile([[Activate]])) sleep "1000" end end {$ASM} aobscan(aob_TimerMission,xx89xxxxxxxxc2xxxxxxxxxxxxxxxxxxxxxxxxxx8bxxxx85xx74xx8bxxxxxxxxxx8bxxffxxxxxxxxxx85) alloc(newmem_TimerMission,2048) label(returnhere_TimerMission) label(code) label(code1) label(code2) label(timer1) registersymbol(timer1) label(timer2) registersymbol(timer2) label(timer3) registersymbol(timer3) label(once) label(Coefficient) label(Coefficient1) registersymbol(aob_TimerMission) newmem_TimerMission: cmp [once],1 jne code1 mov dword ptr [timer2],eax fild dword ptr [timer2] fdiv [Coefficient] fistp dword ptr [timer2] push eax push ebx push ecx mov ebx,[timer2] mov ecx,0 imul ecx,ebx,#60 cmp eax,ecx jb @f sub eax,ecx mov [timer3],eax jmp code2 @@: sub [timer2],1 add eax,#60 sub eax,ecx mov [timer3],eax code2: pop ecx pop ebx pop eax mov [once],0 code1: inc eax push ebx mov ebx,[Coefficient1] cmp [timer2],ebx pop ebx jne @f mov [Coefficient1],2 mov [timer2],0 mov [timer3],0 mov eax,0 jmp code @@: inc [timer3] cmp [timer3],#60 jne code mov [timer3],0 inc [timer2] code: mov dword ptr [timer1],eax mov [ecx+08],eax pop esi jmp returnhere_TimerMission timer1: dd 0 timer2: dd 0 timer3: dd 0 once: dd 1 Coefficient: dd (float)60 Coefficient1: dd #12 aob_TimerMission: jmp newmem_TimerMission returnhere_TimerMission: [DISABLE] {$LUA} timer:setEnabled(false) {$ASM} aob_TimerMission: // 016674EC db 40 89 41 08 5E unregistersymbol(timer1) unregistersymbol(timer2) unregistersymbol(timer3) unregistersymbol(aob_TimerMission) dealloc(newmem_TimerMission) Новое на ассемблер: 1. fild dword ptr [timer2] - копируем значение в [timer2] в st(0), сдвигая стек, одновременно переводя значение из Integer во Float. 2. fistp dword ptr [timer2] - выталкиваем из st(0) в [timer2], восстанавливая стек, одновременно переводя значение из Float в Integer, но fistp при этом делает либо усечение (в нашем случае если остаток меньше 30 секунд), либо округление (если больше 30 секунд). На самом деле есть более подходящий для нас опкод fisttp (который отбрасывает дробную часть), но он почему то не компилируется СЕ, поэтому пришлось добавить дополнительные 6 строчек в код: jb @f //1 sub eax,ecx mov [timer3],eax jmp code2 @@: //2 sub [timer2],1 //3 add eax,#60 //4 sub eax,ecx //5 mov [timer3],eax //6 Про вставку на LUA. {$LUA} - выполнить LUA код. {$ASM} - выполнить код на ассемблер СЕ. timer = createTimer(true) - активируем таймер, обратите внимание на это, обязательно деактивируйте таймер при выключении скрипта: [DISABLE] {$LUA} timer:setEnabled(false) timer:setInterval(5) - устанавливаем интервал timer.OnTimer = function() - функция таймера, т.е. что нужно проверять и делать. getAddressList() - функция получающая данные с Вашей таблицы getAddressList().getMemoryRecordByID("63").Value == "59" - проверяет равно ли, значение записи в таблице с ID=63, 59. (в нашем случае это Second Timer). как узнать ID записи в таблице -> посмотрите эту тему - Как посмотреть название, ID и индекс записи в табличке СЕ. Используется LUA-скрипт от MasterGH. PlaySound(findTableFile([[Activate]])) - проигрывание встроенного звука активации скриптов в СЕ, если Вы хотите какой-нибудь другой звук, то посмотрите мой видео урок Скрытый текст sleep "1000" - нужен для того, чтобы сигнал прозвучал один раз, уменьшая 1000 Вы можете добиться, чтобы сигнал прозвучал два раза, три и т.д. Если убрать sleep "1000" совсем, то вместо сигнала будет тарахтение в течении 1 секунды. Полностью прокомментировать, что делает скрипт попробуйте сами. На видео показана работа скрипта: И залил табличку со всеми скриптами этой темы. Добавил ещё один скрипт и перезалил табличку в следующем сообщении. Изменено 11 февраля, 2016 пользователем Garik66 3 Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 11 февраля, 2016 Автор Поделиться Опубликовано 11 февраля, 2016 (изменено) Благодаря MasterGH и этой теме - СЕ не хочет компилировать fisttp dword ptr [value] было найдено решение для использования опкода fisttp в СЕ. опкод fisttp для нашего случая = push eax lea eax,[timer2] db DB 08 pop eax Так что выложу новый скрипт: 4.1. Timer Mission v. fisttp Скрытый текст [ENABLE] {$LUA} timer = createTimer(true) timer:setInterval(5) timer.OnTimer = function() if getAddressList().getMemoryRecordByID("63").Value == "59" then PlaySound(findTableFile([[Activate]])) sleep "1000" end end {$ASM} aobscan(aob_TimerMission,xx89xxxxxxxxc2xxxxxxxxxxxxxxxxxxxxxxxxxx8bxxxx85xx74xx8bxxxxxxxxxx8bxxffxxxxxxxxxx85) alloc(newmem_TimerMission,2048) label(returnhere_TimerMission) label(code) label(code1) label(code2) label(timer1) registersymbol(timer1) label(timer2) registersymbol(timer2) label(timer3) registersymbol(timer3) label(once) label(Coefficient) label(Coefficient1) registersymbol(aob_TimerMission) newmem_TimerMission: cmp [once],1 jne code1 mov dword ptr [timer2],eax fild dword ptr [timer2] fdiv [Coefficient] push eax lea eax,[timer2] db DB 08 pop eax push eax push ebx push ecx mov ebx,[timer2] mov ecx,0 imul ecx,ebx,#60 cmp eax,ecx sub eax,ecx mov [timer3],eax jmp code2 code2: pop ecx pop ebx pop eax mov [once],0 code1: inc eax push ebx mov ebx,[Coefficient1] cmp [timer2],ebx pop ebx jne @f mov [Coefficient1],2 mov [timer2],0 mov [timer3],0 mov eax,0 jmp code @@: inc [timer3] cmp [timer3],#60 jne code mov [timer3],0 inc [timer2] code: mov dword ptr [timer1],eax mov [ecx+08],eax pop esi jmp returnhere_TimerMission timer1: dd 0 timer2: dd 0 timer3: dd 0 once: dd 1 Coefficient: dd (float)60 Coefficient1: dd #12 aob_TimerMission: jmp newmem_TimerMission returnhere_TimerMission: [DISABLE] {$LUA} timer:setEnabled(false) {$ASM} aob_TimerMission: // 016674EC db 40 89 41 08 5E unregistersymbol(timer1) unregistersymbol(timer2) unregistersymbol(timer3) unregistersymbol(aob_TimerMission) dealloc(newmem_TimerMission) И перезалью табличку: перезалил ниже, добавив ещё один скрипт. Изменено 13 февраля, 2016 пользователем Garik66 2 Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 13 февраля, 2016 Автор Поделиться Опубликовано 13 февраля, 2016 (изменено) Благодаря gmz и этой теме Sleep для ассемблер СЕ. было найдено ещё одно решение для пункта 3. Замедление таймера 3.3. Вариант с получением времени работы инструкции inc eax (Call GetTickCount64) и с созданием отдельного потока под неё. пример скрипт "Timer Mission v. GetTickCount64". Скрытый текст [ENABLE] aobscan(aob_TimerMission,xx89xxxxxxxxc2xxxxxxxxxxxxxxxxxxxxxxxxxx8bxxxx85xx74xx8bxxxxxxxxxx8bxxffxxxxxxxxxx85) alloc(newmem_TimerMission,2048) label(returnhere_TimerMission) label(TimeCheck) registersymbol(aob_TimerMission) newmem_TimerMission: newmem_TimerMission: push eax push ecx push edx call GetTickCount64 cmp [TimeCheck],0 jnz @f mov [TimeCheck],eax @@: sub eax,[TimeCheck] cmp eax,1000 jb @f mov [TimeCheck],0 @@: pop edx pop ecx pop eax cmp [TimeCheck],0 jnz @f inc eax @@: mov [ecx+08],eax pop esi jmp returnhere_TimerMission TimeCheck: dd 0 aob_TimerMission: jmp newmem_TimerMission returnhere_TimerMission: [DISABLE] aob_TimerMission: db 40 89 41 08 5E unregistersymbol(aob_TimerMission) dealloc(newmem_TimerMission) Подробности прочитайте в теме по ссылке. Изменено 13 февраля, 2016 пользователем Garik66 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 13 февраля, 2016 Автор Поделиться Опубликовано 13 февраля, 2016 (изменено) Ну и напоследок (надеюсь , что напоследок). 3.4. Вариант с использованием функции Sleep. пример скрипт "Timer Mission v. Sleep LUA". Скрытый текст [ENABLE] {$LUA} timer = createTimer(true) timer:setInterval(5) timer.OnTimer = function() if getAddressList().getMemoryRecordByID("79").Value == "0" then sleep "3000" getAddressList().getMemoryRecordByID("79").Value = "1" end end {$ASM} aobscan(aob_TimerMission,xx89xxxxxxxxc2xxxxxxxxxxxxxxxxxxxxxxxxxx8bxxxx85xx74xx8bxxxxxxxxxx8bxxffxxxxxxxxxx85) alloc(newmem_TimerMission,2048) label(returnhere_TimerMission) label(flag) registersymbol(flag) registersymbol(aob_TimerMission) newmem_TimerMission: cmp [flag],1 jne @f mov [flag],0 inc eax @@: mov [ecx+08],eax pop esi jmp returnhere_TimerMission flag: dd 1 aob_TimerMission: jmp newmem_TimerMission returnhere_TimerMission: [DISABLE] {$LUA} timer:setEnabled(false) {$ASM} aob_TimerMission: db 40 89 41 08 5E unregistersymbol(flag) unregistersymbol(aob_TimerMission) dealloc(newmem_TimerMission) Этот метод всё-таки точнее, т.е. Sleep "3000" соответствует ровно 3 сек задержки таймера. Табличку перезалил ниже. Изменено 21 февраля, 2016 пользователем Garik66 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 21 февраля, 2016 Автор Поделиться Опубликовано 21 февраля, 2016 (изменено) Наткнулся на урок от MasterGH на форуме СЕ. (Интересные возможности - автоподключение к процессу и хук в окно игры). Ссылка на урок в видео и в таблице. Комментировать скрипт не буду, попробуйте сами. Скрипт 4.2. Timer Mission v. ShowMessageInGame Скрытый текст [ENABLE] {$LUA} processName = 'ACCGame-Win32-Shipping.exe' isD3dhook_initializeHook = false isTimerShowingMessageInGameMenu = false autoAttachList = getAutoAttachList() stringlist_add(autoAttachList, processName); function onOpenProcess(processid) if not isD3dhook_initializeHook then reinitializeSymbolhandler() d3dhook_initializeHook() isD3dhook_initializeHook = true ShowMessageInGame('d3dhook initialize Hook!', 400, 100, 2) createHotkey(OnKeyPressSomeActivate,VK_HOME) end end function OnTickTimerShowingMessageInGameMenu(senderTimer) timer_setEnabled(senderTimer, false) object_destroy(senderTimer) object_destroy(displayedTextObject) object_destroy(fontmap) object_destroy(font) isTimerShowingMessageInGameMenu = false end function ShowMessageInGame(stringMessage, fontWidthTextContainer, fontHeightTextContainer, timeShowing) font = createFont() font_setSize(font, 24) font_setColor(font,0x0000ff) --red rgb fontmap = d3dhook_createFontmap(font) displayedTextObject = d3dhook_createTextContainer(fontmap, fontWidthTextContainer, fontHeightTextContainer, stringMessage ) d3dhook_renderobject_setY(displayedTextObject, -1) d3dhook_renderobject_setX(displayedTextObject, -1) messageTimer = createTimer(nil, false) timer_setInterval(messageTimer, timeShowing * 1000) timer_onTimer(messageTimer, OnTickTimerShowingMessageInGameMenu) timer_setEnabled(messageTimer, true) isTimerShowingMessageInGameMenu = true end function OnKeyPressSomeActivate() if not isTimerShowingMessageInGameMenu then Seconds = getAddressList().getMemoryRecordByID("82").Value Minute = getAddressList().getMemoryRecordByID("83").Value ShowMessageInGame('Have passed'..Minute..'minutes'..Seconds..'seconds!', 400, 100, 2) end end {$ASM} aobscan(aob_TimerMission,xx89xxxxxxxxc2xxxxxxxxxxxxxxxxxxxxxxxxxx8bxxxx85xx74xx8bxxxxxxxxxx8bxxffxxxxxxxxxx85) alloc(newmem_TimerMission,2048) label(returnhere_TimerMission) label(code) label(code1) label(code2) label(timer1) registersymbol(timer1) label(timer2) registersymbol(timer2) label(timer3) registersymbol(timer3) label(once) label(Coefficient) registersymbol(aob_TimerMission) newmem_TimerMission: cmp [once],1 jne code1 mov dword ptr [timer2],eax fild dword ptr [timer2] fdiv [Coefficient] push eax lea eax,[timer2] db DB 08 pop eax push eax push ebx push ecx mov ebx,[timer2] mov ecx,0 imul ecx,ebx,#60 cmp eax,ecx sub eax,ecx mov [timer3],eax jmp code2 code2: pop ecx pop ebx pop eax mov [once],0 code1: inc eax inc [timer3] cmp [timer3],#60 jne code mov [timer3],0 inc [timer2] code: mov dword ptr [timer1],eax mov [ecx+08],eax pop esi jmp returnhere_TimerMission timer1: dd 0 timer2: dd 0 timer3: dd 0 once: dd 1 Coefficient: dd (float)60 aob_TimerMission: jmp newmem_TimerMission returnhere_TimerMission: [DISABLE] {$LUA} {$ASM} aob_TimerMission: // 016674EC db 40 89 41 08 5E unregistersymbol(timer1) unregistersymbol(timer2) unregistersymbol(timer3) unregistersymbol(aob_TimerMission) dealloc(newmem_TimerMission) Видео: Табличка Залил ниже Изменено 8 марта, 2016 пользователем Garik66 3 Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 8 марта, 2016 Автор Поделиться Опубликовано 8 марта, 2016 По запросу ( Возможно ли в форму, которую создает CE вставить три адреса ) пользователя Razi написал ещё один скрипт. Скрипт Timer Mission v. long timer: Скрытый текст [ENABLE] {$LUA} timer = createTimer(true) timer:setInterval(100) timer.OnTimer = function() Second = getAddressList().getMemoryRecordByID("91").Value Minute = getAddressList().getMemoryRecordByID("92").Value Hour = getAddressList().getMemoryRecordByID("93").Value Daily = getAddressList().getMemoryRecordByID("94").Value control_setCaption(UDF1_CEEdit1,Second) control_setCaption(UDF1_CEEdit2,Minute) control_setCaption(UDF1_CEEdit3,Hour) control_setCaption(UDF1_CEEdit4,Daily) end {$ASM} aobscan(aob_TimerMission,xx89xxxxxxxxc2xxxxxxxxxxxxxxxxxxxxxxxxxx8bxxxx85xx74xx8bxxxxxxxxxx8bxxffxxxxxxxxxx85) alloc(newmem_TimerMission,2048) label(returnhere_TimerMission) label(code) label(code1) label(timer_address) // Ввёл для того, чтобы изменить количество registersymbol(timer_address) // в игре в ручную в таблице. label(timer1) // Игровой таймер в сек. registersymbol(timer1) label(timer2) // Таймер в сек. registersymbol(timer2) label(timer3) // Таймер в мин. registersymbol(timer3) label(timer4) // Таймер в часах. registersymbol(timer4) label(timer5) // Таймер в днях. registersymbol(timer5) label(once) // Чтобы пересчёт происходил один раз. label(Coefficient) // Для пересчёта сек в минуты. label(Coefficient1) // Для пересчёта сек в часы. label(Coefficient2) // Для пересчёта сек в дни. registersymbol(aob_TimerMission) newmem_TimerMission: mov [timer_address],ecx cmp [once],1 jne code1 mov dword ptr [timer5],eax // Расчёт дней. fild dword ptr [timer5] fdiv [Coefficient2] push eax lea eax,[timer5] db DB 08 pop eax push eax push ebx push ecx mov ebx,[timer5] mov ecx,0 imul ecx,ebx,#86400 cmp eax,ecx sub eax,ecx mov [timer4],eax fild dword ptr [timer4] // Расчёт часов. fdiv [Coefficient1] push eax lea eax,[timer4] db DB 08 pop eax mov ebx,[timer4] mov ecx,0 imul ecx,ebx,#3600 cmp eax,ecx sub eax,ecx mov [timer3],eax fild dword ptr [timer3] // Расчёт минут. fdiv [Coefficient] push eax lea eax,[timer3] db DB 08 pop eax mov ebx,[timer3] mov ecx,0 imul ecx,ebx,#60 cmp eax,ecx sub eax,ecx mov [timer2],eax pop ecx pop ebx pop eax mov [once],0 code1: inc eax inc [timer2] cmp [timer2],#60 jne code mov [timer2],0 inc [timer3] cmp [timer3],#60 jne code mov [timer3],0 inc [timer4] cmp [timer4],#24 jne code mov [timer4],0 inc [timer5] code: mov dword ptr [timer1],eax mov [ecx+08],eax pop esi jmp returnhere_TimerMission timer_address: dd 0 timer1: dd 0 timer2: dd 0 timer3: dd 0 timer4: dd 0 timer5: dd 0 once: dd 1 Coefficient: dd (float)60 // в 1 минуте 60 сек Coefficient1: dd (float)3600 // в 1 часе 3600 сек Coefficient2: dd (float)86400 // в 1 дне 86400 сек aob_TimerMission: jmp newmem_TimerMission returnhere_TimerMission: [DISABLE] {$LUA} timer:setEnabled(false) {$ASM} aob_TimerMission: // 016674EC db 40 89 41 08 5E unregistersymbol(timer_address) unregistersymbol(timer1) unregistersymbol(timer2) unregistersymbol(timer3) unregistersymbol(timer4) unregistersymbol(timer5) unregistersymbol(aob_TimerMission) dealloc(newmem_TimerMission) Видео: Табличка: ACCGame-Win32-Shipping-for-Gamechacklab.CT 2 Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения