Skilled player (1464)
Location: RU
Joined: 11/26/2011
Posts: 656
Location: RU
Я тут недавно, записался в помощники к бэтмену, чтобы сдвинуть замечательный TAOBAR-проект с мертвой точки. Сейчас у нас как раз будет самый долгий, невероятно неописуемо длинный уровень. Своего рода Рубикон, преодолев который можно будет достичь самую интересную часть игры - территорию безумного шляпника. Что бы благополучно преодолеть это необъятное препятствие было бы здорово оборудовать бэт-самолеты парой новых приборов перед вылетом. Полет будет проходить высоко над городом, ночью, видимость там почти нулевая, нет основной Х-координаты и очень трудно ориентироваться. Вопрос в том, как, не имея ориентиров отслеживать прогресс, отражая бесчисленные атаки орд вражеских вертолетов, похожих одна на другую, как чешуйки змеи, что греется в последних лучах заходящего солнца?? Я придумал простой и элегантный способ как это можно организовать, но нужна твоя помощь с улучшением скрипта. Поможешь?
I show you how deep the rabbit hole goes. Current projects: NES: Tetris "fastest 999999" (improvement, with r57shell) Genesis: Adventures of Batman & Robin (with Truncated); Pocahontas; Comix Zone (improvement); Mickey Mania (improvement); RoboCop versus The Terminator (improvement); Gargoyles (with feos)
Emulator Coder, Site Admin, Skilled player (1229)
Joined: 4/17/2010
Posts: 11974
А чо в теме не сказал что нужно?
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Skilled player (1464)
Location: RU
Joined: 11/26/2011
Posts: 656
Location: RU
Нужны счетчики врагов. Первый счетчик Глобальный, единственная его задача считать порядковый номер врага появляющегося на экране. Счетчик начинает свою работу в начале уровня и заканчивает при появлении гигантской летающей платформы в последней четверти уровня. Пример: Уровень начался, прилетело 10 вертолетов. ГС=10. Прилетел еще один показание ГС стало =11. Прилетело 20 самолетиков ГС=31. Это число только увеличивается. Причем, Важно! Что бы избежать путаницы считать нужно только настоящих первородных врагов, вторичные враги, такие как маленькие ракеты образовавшиеся из большой разделенной на 4 части, а так же ракета или мина-ловушка выпущенная вертолетом/самолетом счетчик затрагивать никак не должны. Второй счетчик Локальный, несет информацию о том что происходит на экране сейчас. Имеет три значения 0/0/0. Первое значение - количество настоящих врагов на экране. Второе значение - количество вторичных врагов на экране, выпущенных (ракеты, мины ловушек и т.п.). Третье - количество на экране подбираемых предметов (оружейная монетка, жизнь и т.д. и т.п. включая маленькие сердечки). Ступенчатый пример для обоих счетчиков: Летим-летим все тихо. Показание Глобально Счетчика = 830. Показание Локального Счетчика = 0/0/0. Вдруг появилось две больших ракеты. Показание Глобально Счетчика = 832. Показание Локального Счетчика = 2/0/0. Одна ракета разделилась на 4 маленьких. Показание Глобально Счетчика = 832. Показание Локального Счетчика = 1/4/0. Взорвали вторую большую ракету, из нее высыпалось 3 сердечка. Показание Глобально Счетчика = 832. Показание Локального Счетчика = 0/4/3
I show you how deep the rabbit hole goes. Current projects: NES: Tetris "fastest 999999" (improvement, with r57shell) Genesis: Adventures of Batman & Robin (with Truncated); Pocahontas; Comix Zone (improvement); Mickey Mania (improvement); RoboCop versus The Terminator (improvement); Gargoyles (with feos)
Emulator Coder, Site Admin, Skilled player (1229)
Joined: 4/17/2010
Posts: 11974
И как этот глобальный счетчик в сэйвах сохранять?
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Skilled player (1464)
Location: RU
Joined: 11/26/2011
Posts: 656
Location: RU
Глобальный счетчик самый важный, от него нельзя отказаться ибо лишь он адекватно отражает реальный прогресс по уровню.
feos wrote:
И как этот глобальный счетчик в сэйвах сохранять?
Хмм, о сейвах я как то не подумал... Для начала хотя бы никак, пусть даже и придется прокручивать уровень с самого сначала. Сам понимаю, без сейвов плохо. Но как известно, полбуханки лучше, чем вовсе ничего.
I show you how deep the rabbit hole goes. Current projects: NES: Tetris "fastest 999999" (improvement, with r57shell) Genesis: Adventures of Batman & Robin (with Truncated); Pocahontas; Comix Zone (improvement); Mickey Mania (improvement); RoboCop versus The Terminator (improvement); Gargoyles (with feos)
Emulator Coder, Site Admin, Skilled player (1229)
Joined: 4/17/2010
Posts: 11974
Второй вечер ковыраюсь в этом говне и до сих пор не понимаю, как можно отличить эти твои мелкие ракеты от прочих врагов. Это прям критично?
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Skilled player (1464)
Location: RU
Joined: 11/26/2011
Posts: 656
Location: RU
А разве тупо по исходному здоровью отличить нельзя? Да, критично, иначе не стал бы и просить. Кстати когда/если удастся доделать сей чудный скрипт и будешь постить его в общую тему, для поддержания театрально эффекта скажи пожалуйста пару слов об установке новейшего оборудования. Так же крайне приветствуется юмор, например можешь добавить, что помимо локаторов заодно поставил в машину мастеру Брюсу новое кожаное кресло, а Робин пусть и дальше летает сидя на табуретке. Или про забытый 2 года назад, на заднем сидении завтрак, что был неожиданно обнаружен входе работ.
I show you how deep the rabbit hole goes. Current projects: NES: Tetris "fastest 999999" (improvement, with r57shell) Genesis: Adventures of Batman & Robin (with Truncated); Pocahontas; Comix Zone (improvement); Mickey Mania (improvement); RoboCop versus The Terminator (improvement); Gargoyles (with feos)
Emulator Coder, Site Admin, Skilled player (1229)
Joined: 4/17/2010
Posts: 11974
Archanfel wrote:
А разве тупо по исходному здоровью отличить нельзя?
Оно у них не уникальное. Но вроде таки нашел отличие в другом. А чо за мины?
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Skilled player (1464)
Location: RU
Joined: 11/26/2011
Posts: 656
Location: RU
feos wrote:
А чо за мины?
Это такие круглые черные штуки, что большие самолеты мини боссы могут выбрасывать. Конечно, 99% что эти мини боссы прекратят свое существование задолго до того как кто то из них додумается выбросить мины, но для полноты картины было славно их учитывать тоже. Хотя, если возникнут непреодолимые трудности с их идентификацией, то на мины вполне можно забить.
I show you how deep the rabbit hole goes. Current projects: NES: Tetris "fastest 999999" (improvement, with r57shell) Genesis: Adventures of Batman & Robin (with Truncated); Pocahontas; Comix Zone (improvement); Mickey Mania (improvement); RoboCop versus The Terminator (improvement); Gargoyles (with feos)
Emulator Coder, Site Admin, Skilled player (1229)
Joined: 4/17/2010
Posts: 11974
А знать, какой враг своим спавном увеличил счетчик, надо?
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Skilled player (1464)
Location: RU
Joined: 11/26/2011
Posts: 656
Location: RU
feos wrote:
А знать, какой враг своим спавном увеличил счетчик, надо?
О, я даже не думал об этом, но раз предложил, то можно контур последнего новоприбывшего красным цветом выделить. Лишним это точно не будет.
I show you how deep the rabbit hole goes. Current projects: NES: Tetris "fastest 999999" (improvement, with r57shell) Genesis: Adventures of Batman & Robin (with Truncated); Pocahontas; Comix Zone (improvement); Mickey Mania (improvement); RoboCop versus The Terminator (improvement); Gargoyles (with feos)
Emulator Coder, Site Admin, Skilled player (1229)
Joined: 4/17/2010
Posts: 11974
Тестируй глобальный счетчик. Download TheAdventuresOfBatmanAndRobin.lua
Language: lua

-- The Adventures of Batman and Robin -- 2013-2016, feos and r57shell -- GLOBALS -- MsgTable = {} MsgTime = 30 MsgOffs = 16 MsgCutoff = 60 RNGcount = 0 SpawnCount= 0 SpawnOpac = 192 SpawnX = 0 SpawnY = 0 -- SHORTCUTS -- rb = memory.readbyte rbs = memory.readbytesigned rw = memory.readword rws = memory.readwordsigned rl = memory.readlong rls = memory.readlongsigned rex = memory.registerexec getr= memory.getregister function GetCam() xcam = rws(0xFFDFC4) if rb(0xFFFFF6) == 50 then ycam= rws(0xFFDFE0)-20 else ycam = 0 end end function EnemyPos(Base) GetCam() x1 = rws(Base + 0x12) - xcam y1 = rws(Base + 0x14) - ycam x2 = rws(Base + 0x16) - xcam y2 = rws(Base + 0x18) - ycam hp = rws(Base + 0x1E) end function PlayerPos() local sbase1 = rw(0xFFAD5C) + 0xFF0000 local sbase2 = rw(0xFFADB6) + 0xFF0000 p1speedx = rls(sbase1 + 0x18) / 0x10000 p1speedy = rls(sbase1 + 0x1C) / 0x10000 p2speedx = rls(sbase2 + 0x18) / 0x10000 p2speedy = rls(sbase2 + 0x1C) / 0x10000 end function HandleMsgTable(clear) for i = 1, #MsgTable do if (clear) then MsgTable[i] = nil end if (MsgTable[i]) then GetCam() if (MsgTable[i].y_ > MsgCutoff) then MsgY1 = 0 MsgY2 = 6 else MsgY1 = 203 MsgY2 = 203 end local opacity = (MsgTable[i].timer_ - gens.framecount() + 2)*7 gui.line(i * MsgOffs + 3, MsgY2, MsgTable[i].x_ - xcam, MsgTable[i].y_, 0xFF000000+opacity) gui.text(i * MsgOffs , MsgY1, MsgTable[i].damage_, "red") if (MsgTable[i].timer_ < gens.framecount()) then MsgTable[i] = nil end end end end function HandleDamage() local damage = AND(getr("d0"), 0xFFFF) local base = AND(getr("a2"), 0xFFFFFF) EnemyPos(base) unit = { timer_ = gens.framecount() + MsgTime, damage_ = damage, x_ = x1 + xcam, y_ = y1 } for i = 1, 200 do if MsgTable[i] == nil then MsgTable[i] = unit break end end end function Collision() GetCam() local a0 = AND(getr("a0"), 0xFFFF) local a6 = AND(getr("a6"), 0xFFFF) local damage = rw(a6 + 0xFF0012) local wx2 = getr("d6") - xcam local wy2 = getr("d7") - ycam local wx1 = getr("d4") - xcam local wy1 = getr("d5") - ycam --gui.text(wx2 + 2, wy1 + 1, string.format("%X",a6)) if (damage == 0) then damage = rw(a0 + 0xFF0034) end if (DamageHitbox) then gui.box(wx1, wy1, wx2, wy2, "#FF000000") gui.text(wx1 + 2, wy1 + 1, damage) else gui.box(wx1, wy1, wx2, wy2, "#FFFF0000") end end function InRange(var, num1, num2) if (var >= num1) and (var <= num2) then return true end end function Item() GetCam() local a6 = AND(getr("a6"), 0xFFFF) local x = rw(a6 + 0xFF003E) - xcam local y = rw(a6 + 0xFF0042) local code = rb(a6 + 0xFF0019) if InRange(code, 0, 1) then return elseif InRange(code, 7, 19) then item = "Amo" -- ammo elseif InRange(code, 21, 23) then item = "Cha" -- fast charge elseif InRange(code, 24, 26) then item = "Bom" -- bomb elseif InRange(code, 27, 29) then item = "Lif" -- life elseif InRange(code, 30, 47) then item = "HiP" -- hearts else item = tostring(code) end gui.text(x-7, y, string.format("%s" , item ), "yellow") -- gui.text(x-7, y, string.format("\n%X", a6+0x19), "yellow") end function Hitbox(address) local i = 0 local base = rw(address) while (base ~= 0) do base = base + 0xFF0000 if (rw(base + 2) == 0) then break end EnemyPos(base) if (address == 0xFFDEB2) then gui.box(x1, y1, x2, y2, "#00FF0000") elseif (address == 0xFFDEBA) then gui.box(x1, y1, x2, y2, "#00FFFF00") gui.text(x1 + 2, y1 + 1, hp, "#FF00FF") --if (x2 < 0) then gui.text(x1 + 2, y2 - 7, "x:" .. x1 ) end --if (x1 >= 320) then gui.text(x1 + 2, y2 - 7, "x:" .. x1 - 320) end --if (y2 < 0) then gui.text(x2 + 2, y2 - 7, "y:" .. y2 ) end local offtext = "" if (x2 < 0) then offtext = offtext .. "x:" .. x1 end if (x1 >= 320) then offtext = offtext .. "x:" .. x1 - 320 end if (y2 < 0) then offtext = offtext .. "y:" .. y2 end if (y2 >= 224) then offtext = offtext .. "y:" .. y2 - 224 end if offtext ~= "" then gui.text(x1 + 2, y2 - 7, offtext) end end -- gui.text(x1 + 2, y1 + 1, string.format("\n%X", base + 0x1E - 0xFF0000), "#FF00FF") base = rw(base + 2) i = i + 1 if (i > 400) then break end end end function Objects() GetCam() local base = 0xFFAD54 for i=0,100 do local a5 = rl (base) local link = rw (base+ 6) local ptr1 = rw (base+0x0A)+0xFF0000 local x = rws(base+0x3E) local xsub = rb (base+0x40) local y = rws(base+0x42) local ysub = rb (base+0x44) local hp = rw (base+0x52) local ptr2 = rl (ptr1+0x2A) local code = rw (ptr2) if a5 == 0x88BE then return end if base == 0xFFC320 then -- gui.text(x - xcam, y - ycam, string.format("%X", base)) end base = link + 0xFF0000 end end function Counters() local base = AND(getr("a6"), 0xFFFFFF) local ptr1 = rw(base+0x0A) + 0xFF0000 local ptr2 = rl(ptr1+0x2A) local code = rw(ptr2) SpawnX = rws(base+0x3E) - xcam SpawnY = rws(base+0x42) - ycam if code ~= 0xAE6 -- helicopter bomb and code ~= 0xAF2 -- mini-missile and code ~= 0x2384 -- item then SpawnOpac = 192 SpawnCount = SpawnCount + 1 print(string.format("%X", code)) end end function Main() local color0 = "yellow" local color1 = "yellow" local color2 = "yellow" local base1 = 0xFFAD54 local base2 = 0xFFADAE -- local hp1 = rw (0xFFF650) / 0x10 -- local life1 = rw (0xFFF644) local X1 = rw (base1 + 0x3E) local X1sub = rb (base1 + 0x40) local Y1 = rws(base1 + 0x42) local Y1sub = rb (base1 + 0x44) local X2 = rw (base2 + 0x3E) local X2sub = rb (base2 + 0x40) local Y2 = rws(base2 + 0x42) local Y2sub = rb (base2 + 0x44) local RNG1 = rw (0xFFF5FC) -- local RNG2 = rl (0xFFF5FE) local Weapon1 = rb (0xFFF67B) local Weapon2 = rb (0xFFF6BB) local Charge1 = (rw(0xFFF658) - 0x2800) / -0x80 local Charge2 = (rw(0xFFF698) - 0x2800) / -0x80 local ScreenLock = rw(0xFFDFC0) if Charge1 <= 0 then Charge1 = 0; color1 = "red" end if Charge2 <= 0 then Charge2 = 0; color2 = "red" end if RNGcount > 1 then color0 = "red" end -- HandleMsgTable() PlayerPos() Objects() gui.line( 34, 37, SpawnX, SpawnY, 0x00FF0000+SpawnOpac) gui.text( 0, 30, string.format("Spawns: %d",SpawnCount),"green") gui.text( 0, 210, string.format("\nRNG:%X" , RNG1)) gui.text( 40, 210, string.format("\nLock:%d", ScreenLock)) gui.text( 34, 210, string.format("\n%d" , RNGcount), color0) gui.text( 80, 20, string.format("%2d" , Charge1), color1) gui.text(235, 20, string.format("%2d" , Charge2), color2) -- gui.text(180, 210, string.format("%2d" , Charge1), color1) -- gui.text(300, 210, string.format("%2d" , Charge2), color2) gui.text(180, 210, string.format("\n%2d" , Weapon1+1), "yellow") gui.text(300, 210, string.format("\n%2d" , Weapon2+1), "yellow") gui.text( 81, 210, string.format("Pos: %d.%d\nSpd: %.5f", X1, X1sub, p1speedx), "#AAAAAA") gui.text(137, 210, string.format("/ %d.%d\n/ %.5f" , Y1, Y1sub, p1speedy), "#AAAAAA") gui.text(203, 210, string.format("Pos: %d.%d\nSpd: %.5f", X2, X2sub, p2speedx), "#00BB00") gui.text(260, 210, string.format("/ %d.%d\n/ %.5f" , Y2, Y2sub, p2speedy), "#00BB00") Hitbox(0xFFDEB2) -- Hitbox(0xFFDEBA) RNGcount = 0 end emu.registerafter(function() SpawnOpac = SpawnOpac - 4 if SpawnOpac < 0 then SpawnOpac = 0 end end) savestate.registerload(function() SpawnCount = 0 SpawnOpac = 192 return HandleMsgTable(1) end) gui.register(Main) rex(0x375A, function() DamageHitbox = false end) rex(0x375E, function() DamageHitbox = true end) rex(0x3768, function() DamageHitbox = false end) rex(0x376C, function() DamageHitbox = true end) rex(0x65C4, function() DamageHitbox = false end) rex(0x65C8, function() DamageHitbox = true end) rex(0x995C, function() RNGcount = RNGcount + 1 end) rex(0x4738, Item) rex(0x4534, Item) rex(0x8DE6, Counters) rex(0x8DCE, Counters) --rex(0x8C9A, Collision) rex(0x1085A, HandleDamage) -- meelee rex(0x10CBA, HandleDamage) -- weapon rex(0x10CC4, HandleDamage) -- weapon
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Skilled player (1464)
Location: RU
Joined: 11/26/2011
Posts: 656
Location: RU
Глобальный счетчик работает прекрасно! От двух разных тестовых мувиков до первого босса поплыл только на единичку. Эта разница, как обнаружилось, образовалось за счет того что некоторые пилотажные группы мелких самолетиков могут рандомно состоять из разного количества самолетов +/-1 (и иметь разное построение). В общем, счетчик свою функцию выполняет как надо, а вышеописанный самолетно-групповой сдвиг, там где он имеет место, легко можно учесть и посчитать в уме.
I show you how deep the rabbit hole goes. Current projects: NES: Tetris "fastest 999999" (improvement, with r57shell) Genesis: Adventures of Batman & Robin (with Truncated); Pocahontas; Comix Zone (improvement); Mickey Mania (improvement); RoboCop versus The Terminator (improvement); Gargoyles (with feos)
Emulator Coder, Site Admin, Skilled player (1229)
Joined: 4/17/2010
Posts: 11974
Дерижабль нужен?
Второе значение - количество вторичных врагов на экране, выпущенных (ракеты, мины ловушек и т.п.).
В т.п. что входит?
Archanfel wrote:
Я придумал простой и элегантный способ как это можно организовать
Да уж, проще некуда.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Skilled player (1464)
Location: RU
Joined: 11/26/2011
Posts: 656
Location: RU
feos wrote:
Дерижабль нужен?
Нет, спасибо. С дирижаблем вроде и так все понятно. Там хоть нормальная координата есть 0xFFAEA0, так что ориентироваться будет много проще.
feos wrote:
В т.п. что входит?
Для летательного уровня, пожалуй больше ничего и нет. Но, если распространить концепцию вторичных врагов на другие уровни, то сюда еще можно отнеси нейтральные разрушаемые объекты, урны/вазы/бочки/фонари, шляпу шляпника, сахар выпрыгивающий из сахарницы и прочее.
I show you how deep the rabbit hole goes. Current projects: NES: Tetris "fastest 999999" (improvement, with r57shell) Genesis: Adventures of Batman & Robin (with Truncated); Pocahontas; Comix Zone (improvement); Mickey Mania (improvement); RoboCop versus The Terminator (improvement); Gargoyles (with feos)
Emulator Coder, Site Admin, Skilled player (1229)
Joined: 4/17/2010
Posts: 11974
Archanfel wrote:
Для летательного уровня, пожалуй больше ничего и нет.
Какой смысл считать ракеты и дронов, если у них и так показывается удаленность, когда они за экраном, а на экране их и так видно?
Archanfel wrote:
Но, если распространить концепцию вторичных врагов на другие уровни, то сюда еще можно отнеси нейтральные разрушаемые объекты, урны/вазы/бочки/фонари, шляпу шляпника, сахар выпрыгивающий из сахарницы и прочее.
Губа не дура. Как насчет "нет"? Хитбоксы есть, удаленность есть, считать зачем?
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Skilled player (1464)
Location: RU
Joined: 11/26/2011
Posts: 656
Location: RU
feos wrote:
Какой смысл считать ракеты и дронов, если у них и так показывается удаленность, когда они за экраном, а на экране их и так видно?
Проблема в том, что экран не совсем стандартный, он больше обычного и его можно вверх/вниз скролить. Иногда получается враги как бы на экране, а их и не хрена не видно и удаленность не пишут.
feos wrote:
Да уж, проще некуда.
Скромность — мать великих деяний. О. Бальзак
feos wrote:
Губа не дура. Как насчет "нет"?
"Нет" вполне устраивает :) Главное сквозь летательный уровень продраться, а в остальных и так все хорошо.
I show you how deep the rabbit hole goes. Current projects: NES: Tetris "fastest 999999" (improvement, with r57shell) Genesis: Adventures of Batman & Robin (with Truncated); Pocahontas; Comix Zone (improvement); Mickey Mania (improvement); RoboCop versus The Terminator (improvement); Gargoyles (with feos)
Emulator Coder, Site Admin, Skilled player (1229)
Joined: 4/17/2010
Posts: 11974
Вощем так как за экраном видно врага начиная с первых версий скрипта (пофиксил низ), а считать мелкие сердески вместе с нормальными айтемами слишком мозголомно, счетчики такие: спавн, враги, айтемы, сердечки. Тести.
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Skilled player (1464)
Location: RU
Joined: 11/26/2011
Posts: 656
Location: RU
feos wrote:
счетчики такие: спавн, враги, айтемы, сердечки. Тести.
Единственно немного печально что нет счетчика мелких ракет и мин... но в остальном просто великолепно. Кстати любопытно, что в прошлой версии глобальный Spawn счетчик работал везде, а теперь вдруг стал работоспособным только в узком диапазоне летательного уровня. Ты его специально выключил вне этого промежутка?
I show you how deep the rabbit hole goes. Current projects: NES: Tetris "fastest 999999" (improvement, with r57shell) Genesis: Adventures of Batman & Robin (with Truncated); Pocahontas; Comix Zone (improvement); Mickey Mania (improvement); RoboCop versus The Terminator (improvement); Gargoyles (with feos)
Emulator Coder, Site Admin, Skilled player (1229)
Joined: 4/17/2010
Posts: 11974
Ну да, если хочешь могу включить обратно. И вот поправил еще кое-что: Download TheAdventuresOfBatmanAndRobin.lua
Language: lua

-- The Adventures of Batman and Robin -- 2013-2016, feos and r57shell -- GLOBALS -- MsgTable = {} MsgTime = 30 MsgOffs = 16 MsgCutoff = 60 RNGcount = 0 SpawnCount= 0 SpawnOpac = 192 SpawnX = 0 SpawnY = 0 Enemies = 0 Items = 0 Hearts = 0 -- SHORTCUTS -- rb = memory.readbyte rbs = memory.readbytesigned rw = memory.readword rws = memory.readwordsigned rl = memory.readlong rls = memory.readlongsigned rex = memory.registerexec getr= memory.getregister function GetCam() xcam = rws(0xFFDFC4) if rb(0xFFFFF6) == 50 then ycam= rws(0xFFDFE0)-20 else ycam = 0 end end function EnemyPos(Base) GetCam() x1 = rws(Base + 0x12) - xcam y1 = rws(Base + 0x14) - ycam x2 = rws(Base + 0x16) - xcam y2 = rws(Base + 0x18) - ycam hp = rws(Base + 0x1E) end function PlayerPos() local sbase1 = rw(0xFFAD5C) + 0xFF0000 local sbase2 = rw(0xFFADB6) + 0xFF0000 p1speedx = rls(sbase1 + 0x18) / 0x10000 p1speedy = rls(sbase1 + 0x1C) / 0x10000 p2speedx = rls(sbase2 + 0x18) / 0x10000 p2speedy = rls(sbase2 + 0x1C) / 0x10000 end function HandleMsgTable(clear) for i = 1, #MsgTable do if (clear) then MsgTable[i] = nil end if (MsgTable[i]) then GetCam() if (MsgTable[i].y_ > MsgCutoff) then MsgY1 = 0 MsgY2 = 6 else MsgY1 = 203 MsgY2 = 203 end local opacity = AND((MsgTable[i].timer_ - gens.framecount() + 2)*7, 0xFF) gui.line(i * MsgOffs + 3, MsgY2, MsgTable[i].x_ - xcam, MsgTable[i].y_, 0xFF000000+opacity) gui.text(i * MsgOffs , MsgY1, MsgTable[i].damage_, "red") if (MsgTable[i].timer_ < gens.framecount()) then MsgTable[i] = nil end end end end function HandleDamage() local damage = AND(getr("d0"), 0xFFFF) local base = AND(getr("a2"), 0xFFFFFF) EnemyPos(base) unit = { timer_ = gens.framecount() + MsgTime, damage_ = damage, x_ = x1 + xcam, y_ = y1 } for i = 1, 200 do if MsgTable[i] == nil then MsgTable[i] = unit break end end end function Collision() GetCam() local a0 = AND(getr("a0"), 0xFFFFFF) local a6 = AND(getr("a6"), 0xFFFFFF) local damage = rw(a6 + 0x12) local id = rw(a6 + 2) local wx2 = getr("d6") - xcam local wy2 = getr("d7") - ycam local wx1 = getr("d4") - xcam local wy1 = getr("d5") - ycam -- gui.text(wx2 + 2, wy1 + 1, string.format("%X",a6)) if (damage == 0) then damage = rw(a0 + 0x34) end if (DamageHitbox) then gui.box(wx1, wy1, wx2, wy2, "#FF000000") gui.text(wx1 + 2, wy1 + 1, damage) else gui.box(wx1, wy1, wx2, wy2, "#FFFF0000") if id == 0x53B4 then Hearts = Hearts + 1 end end end function InRange(var, num1, num2) if (var >= num1) and (var <= num2) then return true end end function Item() GetCam() local a6 = AND(getr("a6"), 0xFFFFFF) local x = rw(a6 + 0x3E) - xcam local y = rw(a6 + 0x42) local code = rb(a6 + 0x19) if InRange(code, 0, 1) then return elseif InRange(code, 7, 19) then item = "Amo" -- ammo elseif InRange(code, 21, 23) then item = "Cha" -- fast charge elseif InRange(code, 24, 26) then item = "Bom" -- bomb elseif InRange(code, 27, 29) then item = "Lif" -- life elseif InRange(code, 30, 47) then item = "HiP" -- hearts else item = tostring(code) end gui.text(x-7, y, string.format("%s" , item ), "yellow") -- gui.text(x-7, y, string.format("\n%X", a6+0x19), "yellow") end function Hitbox(address) local i = 0 local base = rw(address) while (base ~= 0) do base = base + 0xFF0000 if (rw(base + 2) == 0) then break end EnemyPos(base) if (address == 0xFFDEB2) then gui.box(x1, y1, x2, y2, "#00FF0000") elseif (address == 0xFFDEBA) then gui.box(x1, y1, x2, y2, "#00FFFF00") gui.text(x1 + 2, y1 + 1, hp, "#FF00FF") -- if (x2 < 0) then gui.text(x1 + 2, y2 - 7, "x:" .. x1 ) end -- if (x1 >= 320) then gui.text(x1 + 2, y2 - 7, "x:" .. x1 - 320) end -- if (y2 < 0) then gui.text(x2 + 2, y2 - 7, "y:" .. y2 ) end local offtext = "" if (x2 < 0) then offtext = offtext .. "x:" .. x1 end if (x1 >= 320) then offtext = offtext .. "x:" .. x1 - 320 end if (y2 < 0) then offtext = offtext .. "y:" .. y2 end if (y2 >= 224) then offtext = offtext .. "y:" .. y2 - 224 end if offtext ~= "" then gui.text(x1 + 2, y2 - 7, offtext) end end base = rw(base + 2) i = i + 1 if (i > 400) then break end end end function Objects() if rb(0xFFFFF6) ~= 50 then return end Enemies = 0 Items = 0 GetCam() local base = 0xFFAD54 for i=0,100 do local link = rw (base+ 6) local ptr1 = rw (base+0x0A)+0xFF0000 local x = rws(base+0x3E) local xsub = rb (base+0x40) local y = rws(base+0x42) local ysub = rb (base+0x44) local hp = rw (base+0x52) local ptr2 = rl (ptr1+0x2A) local code = rw (ptr2) if base > 0 then if ptr2 == 0x27DEE -- helicopter black or ptr2 == 0x27F9C -- helicopter red or ptr2 == 0x2804E -- plane black or ptr2 == 0x28134 -- helicopter green or ptr2 == 0x282B8 -- plane red or ptr2 == 0x2860A -- missile or ptr2 == 0x28DD2 -- helicopter red phase 1 or ptr2 == 0x28E08 -- helicopter red phase 2 then Enemies = Enemies + 1 elseif ptr2 == 0x13326 or ptr2 == 0x13BDE then Items = Items + 1 else -- gui.text(x - xcam, y - ycam, string.format("%X", ptr2), "green") end end base = link + 0xFF0000 local a5 = rl (base) if a5 == 0x88BE then return end end end function Spawns() if rb(0xFFFFF6) ~= 50 then return end local base = AND(getr("a6"), 0xFFFFFF) local ptr1 = rw(base+0x0A) + 0xFF0000 local ptr2 = rl(ptr1+0x2A) local code = rw(ptr2) SpawnX = rws(base+0x3E) - xcam SpawnY = rws(base+0x42) - ycam if code ~= 0xAE6 -- drone and code ~= 0xAF2 -- mini-missile and code ~= 0x2384 -- item then SpawnOpac = 192 SpawnCount = SpawnCount + 1 end end function Main() local color0 = "yellow" local color1 = "yellow" local color2 = "yellow" local base1 = 0xFFAD54 local base2 = 0xFFADAE -- local hp1 = rw (0xFFF654) -- local life1 = rw (0xFFF644) local X1 = rw (base1 + 0x3E) local X1sub = rb (base1 + 0x40) local Y1 = rws(base1 + 0x42) local Y1sub = rb (base1 + 0x44) local X2 = rw (base2 + 0x3E) local X2sub = rb (base2 + 0x40) local Y2 = rws(base2 + 0x42) local Y2sub = rb (base2 + 0x44) local RNG1 = rw (0xFFF5FC) -- local RNG2 = rl (0xFFF5FE) local Weapon1 = rb (0xFFF67B) local Weapon2 = rb (0xFFF6BB) local Charge1 = (rw(0xFFF658) - 0x2800) / -0x80 local Charge2 = (rw(0xFFF698) - 0x2800) / -0x80 local ScreenLock = rw(0xFFDFC0) if Charge1 <= 0 then Charge1 = 0; color1 = "red" end if Charge2 <= 0 then Charge2 = 0; color2 = "red" end if RNGcount > 1 then color0 = "red" end HandleMsgTable() PlayerPos() Objects() if rb(0xFFFFF6) == 50 then gui.line( 34, 37, SpawnX, SpawnY, 0x00FF0000+ SpawnOpac) gui.text( 0, 30, string.format("Obj: %d" , SpawnCount),"green") gui.text( 0, 38, string.format("%d %d %d" , Enemies, Items, Hearts/2)) end gui.text( 0, 210, string.format("\nRNG:%X" , RNG1)) gui.text( 40, 210, string.format("\nLock:%d" , ScreenLock)) gui.text( 34, 210, string.format("\n%d" , RNGcount), color0) gui.text( 80, 20, string.format("%2d" , Charge1), color1) gui.text(235, 20, string.format("%2d" , Charge2), color2) gui.text(180, 210, string.format("\n%2d" , Weapon1+1), "yellow") gui.text(300, 210, string.format("\n%2d" , Weapon2+1), "yellow") gui.text( 81, 210, string.format("Pos: %d.%d\nSpd: %.5f", X1, X1sub, p1speedx), "#AAAAAA") gui.text(137, 210, string.format("/ %d.%d\n/ %.5f" , Y1, Y1sub, p1speedy), "#AAAAAA") gui.text(203, 210, string.format("Pos: %d.%d\nSpd: %.5f", X2, X2sub, p2speedx), "#00BB00") gui.text(260, 210, string.format("/ %d.%d\n/ %.5f" , Y2, Y2sub, p2speedy), "#00BB00") Hitbox(0xFFDEB2) Hitbox(0xFFDEBA) RNGcount = 0 end emu.registerafter(function() SpawnOpac = SpawnOpac - 4 if SpawnOpac < 0 then SpawnOpac = 0 end end) emu.registerbefore(function() Hearts = 0 end) savestate.registerload(function() SpawnCount = 0 SpawnOpac = 192 Enemies = 0 Items = 0 Hearts = 0 return HandleMsgTable(1) end) gui.register(Main) rex(0x375A, function() DamageHitbox = false end) rex(0x375E, function() DamageHitbox = true end) rex(0x3768, function() DamageHitbox = false end) rex(0x376C, function() DamageHitbox = true end) rex(0x65C4, function() DamageHitbox = false end) rex(0x65C8, function() DamageHitbox = true end) rex(0x995C, function() RNGcount = RNGcount + 1 end) rex(0x4738, Item) rex(0x4534, Item) rex(0x8DE6, Spawns) rex(0x8DCE, Spawns) rex(0x8C9A, Collision) rex(0x1085A, HandleDamage) -- meelee rex(0x10CBA, HandleDamage) -- weapon rex(0x10CC4, HandleDamage) -- weapon
Warning: When making decisions, I try to collect as much data as possible before actually deciding. I try to abstract away and see the principles behind real world events and people's opinions. I try to generalize them and turn into something clear and reusable. I hate depending on unpredictable and having to make lottery guesses. Any problem can be solved by systems thinking and acting.
Skilled player (1464)
Location: RU
Joined: 11/26/2011
Posts: 656
Location: RU
feos wrote:
Ну да, если хочешь могу включить обратно.
Да не, все и так устраивает. Отправил Усеченному, будем начинать пилить потихоньку :) Спасибо за скрипт.
I show you how deep the rabbit hole goes. Current projects: NES: Tetris "fastest 999999" (improvement, with r57shell) Genesis: Adventures of Batman & Robin (with Truncated); Pocahontas; Comix Zone (improvement); Mickey Mania (improvement); RoboCop versus The Terminator (improvement); Gargoyles (with feos)