1 2
6 7
Skilled player (1653)
Joined: 11/15/2004
Posts: 2202
Location: Killjoy
Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
Skilled player (1516)
Joined: 4/28/2005
Posts: 240
Location: Finland
Nice route choice! If only Balbaroy had better agility so he could get turn before all enemies in tower. Would save a lot of time.
Projects: Warlock, Ren & Stimpy (impr) / Generations Lost (impr.)
Skilled player (1653)
Joined: 11/15/2004
Posts: 2202
Location: Killjoy
Here is the last WIP I will be posting until submission. It is the first 7 chapters of Shining Force 1, in 2:02:31. Hopefully, since there are mainly boss battles for chapter 8, the final will be under 2:25. http://dehacked.2y.net/microstorage.php/info/1986206782/Shining%20Force%20%28U%29%20%5B%21%5D.gmv I think Chaos is my new favorite battle. It really demonstrates what happens when you control battle order.
Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
Skilled player (1516)
Joined: 4/28/2005
Posts: 240
Location: Finland
I knew that was possible. Well done. It was a bit corny to see Pelle have 16hp at this point of game :D I hope we'll see nice use for Black(?) Ring (e.g. defeating 3 enemies at the same attack).
Projects: Warlock, Ren & Stimpy (impr) / Generations Lost (impr.)
Joined: 8/13/2005
Posts: 356
Location: Canada
Although I really like this game, that's the first WIP I watched. Very fun stuff. I wondered from the beginning if taking Gort would pay off and it looks like it did. It's too bad you couldn't have made use of any centaurs who die for magic item use, but they're unquestionably useless in the Dragonia region outside battles and a few other places. The character choice seems great. I'm looking forward to see if Musashi comes in handy in the last few battles. The quality of the run seems to improve throughout... it looks like you gradually pay more attention to having your characters close together so the cursor doesn't have to move as far. I wonder if for some of the longer battles it might even be worth moving the characters who do nothing closer to the front because the cursor has to move so far each time their turn comes. Couldn't it save some time if they were sitting there for 5+ turns? I don't think the run is perfect but the strategies themselves are very cool. Good work.
Joined: 8/27/2006
Posts: 883
In the last battle of chapter 6, is it possible to get the evil ring with Bleu ? It would save time, I also note that you gain control of Max where you let him, so it would be faster in battle to bring him toward where he's supposed to go. Edit : If we could calculate how much frame is gain of loss with the difference of moving someone toward the battle vs letting it stay there, it could be faster to move everyone each turn. Edit 2 : Could you luck manipulate the wait caused by the NPC that block your way when you return from the first person you talk (I don't remember her name) Edit 3 : In the battle that you have to kill everyone before Ramladu, wouldn,t it be faster to use the evil ring and the halbert to kill the two groups of 4 monsters ?
Skilled player (1653)
Joined: 11/15/2004
Posts: 2202
Location: Killjoy
ZeXr0 wrote:
In the last battle of chapter 6, is it possible to get the evil ring with Bleu ? It would save time, I also note that you gain control of Max where you let him, so it would be faster in battle to bring him toward where he's supposed to go.
Actually, I agree with the second part. Bleu can't make it to the ring before the battle ends. However, moving Max closer would probably have sped up the end part.
ZeXr0 wrote:
Edit : If we could calculate how much frame is gain of loss with the difference of moving someone toward the battle vs letting it stay there, it could be faster to move everyone each turn.
Well, if we assume the cursor is 2x the speed of the character, then moving 1 character forward saves time in 2 rounds. (since the cursor has to go back and forth.) However, moving multiple characters, the cursor has to move to the character, the character moves, and then the cursor has to go BACK to the next character. This really starts to waste time. This was my theory for the latter part of the run.
ZeXr0 wrote:
Edit 2 : Could you luck manipulate the wait caused by the NPC that block your way when you return from the first person you talk (I don't remember her name)
Mahato? I knew someone would mention this. That NPC moves in an exact pattern, regardless of what happens. I'd considered trying to find another NPC close enough to block him from moving, but there is only one, and it is realtively far away.
ZeXr0 wrote:
Edit 3 : In the battle that you have to kill everyone before Ramladu, wouldn,t it be faster to use the evil ring and the halbert to kill the two groups of 4 monsters ?
I only have the one evil ring, and it is used twice that battle. The time it would take to move it to the other side of the battle proved prohibitive. Plus, the halberd doesn't do near enough damage. Perhaps, grabbing the Black ring earlier could have saved time... I think that all these are good ideas, however, it may wait until someone decides to retry the movie using my tools. I have lots of improvement ideas if that person comes forward.
Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
Skilled player (1653)
Joined: 11/15/2004
Posts: 2202
Location: Killjoy
Due to my absolute obsession with this game, I'm going for a third and final attempt to get complete the entire game in under 2 hours. This will require saving 31204 frames. I've found new ways to manipulate and abuse the game. First and foremost, I determined that ALL character starting statistics can be altered between frames 6:54 and 7:29. (Doing that much manipulation in 35 frames is going to kill me) However, I am vaguely sure that this small portion can be hex-edited in later, as long as I do not alter the frame count going into the game. Second of all, optimizing cursor movements in rounds was done a single round at a time. Thus, I did not account for round transitions. Now, I simulate the ENTIRE BATTLE (so much damn work) in advance, and select the optimal battle, which is an entire set of rounds, as oppose to a single round. (Yes, I do iterate through all 65536^Rounds options, but in a cool way, so it isn't an intractable problem. More on this later.) Finally, when I optimized the rounds last time, it was based on whatever agilities I had obtained at the start and previous battles. Now, I can preset agilities in the super-duper Battle simulator, and determine what agilities complete the round the fastest, and pre-manipulate them. YAY! As a little note, I also found various improvements in the starting few battles, due only to mistakes when starting the last run. These will unfortunately dry up. So, here is a completely uninteresting WIP: (No strategy changes at all) http://dehacked.2y.net/microstorage.php/info/1907964554/Shining%20ForceFinal.gmv It is 860 frames (14.2s) faster to the end of the 3rd battle.
Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
Joined: 8/27/2006
Posts: 883
I'll be sure to watch it as soon as I return on Windows :P I'm currently on Ubuntu using Wubi (which does not need partitionning to be installed, it install linux in a folder on a windows partition. It's pretty nice)
Skilled player (1653)
Joined: 11/15/2004
Posts: 2202
Location: Killjoy
No strategy changes, just better cursor movement. Plus, corrected many errors from the first run http://dehacked.2y.net/microstorage.php/info/1707061999/Shining%20ForceFinal.gmv 52:49 ahead. 7 minutes and 47 seconds left to save, to make sub 2-hours.
Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
Joined: 8/27/2006
Posts: 883
I was just thinking, after the first battle, if you egress ? You can to the little house on the right ?
Skilled player (1653)
Joined: 11/15/2004
Posts: 2202
Location: Killjoy
Yeah, you can't skip the second battle, unfortunately.
Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
Joined: 8/27/2006
Posts: 883
It might save a couple of frame to take Gort before the scene with Kane, I looked at the path you took, and it might save a couple of steps...
Skilled player (1653)
Joined: 11/15/2004
Posts: 2202
Location: Killjoy
Hurray for new strategies (finally)! Another WIP, it is 2 minutes and 2 seconds ahead after Battle 14... About 1 minute of this was saved due to the new character death. However, due to a strange bug, I may lose time in Battle 15. Battle 16 is guaranteed to be shorter, thankfully. Then it's the same exact strategy for quite a few battles :( Apparently, when you bring only 5 people on the ship, The far right Pegasus Knight behaves like he has a 30% land effect, efficiently destroying Amon's ability to kill him. I'm starting to show the new approach to Battle 15, but it hasn't quite panned out. http://dehacked.2y.net/microstorage.php/info/1353144188/Shining%20Force%20%28U%29%20%5B%21%5D.gmv Still have 6 minutes and 38 seconds to bleed out of this run, to get sub 2 hours.
Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
Skilled player (1653)
Joined: 11/15/2004
Posts: 2202
Location: Killjoy
Here is a 3rd version - It's 4 minutes and 1 second faster... but its still not sub 2 hours, which was my goal before submitting a new version. http://dehacked.2y.net/microstorage.php/info/1370306525/DarkKobold_Shining_Force_v3.gmv So, I'm going to try again at some point to obsolete it with a sub 2-hour run. But, if I never finish, at least there is a close version out there. [/quote]
Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
Joined: 8/27/2006
Posts: 883
Awesome, i'll be sure to take a look as soon as I can.
Joined: 11/4/2007
Posts: 1772
Location: Australia, Victoria
Yeesh, any faster and the Jet in my avatar will turn into a Rocket!
Skilled player (1653)
Joined: 11/15/2004
Posts: 2202
Location: Killjoy
Time for a code dump! Start Battle Use this one at the start of a battle, when Nova or other (FACED!) character finishes speech. Press A or C on the correct frame (last character printed frame) then execute the script. The RNG should stay stable for 1 frame past the A or C (check this), and then execute 8 times. This script will find the correct target. [code lua] target = 49258 START = savestate.create(); local buttonmap = {[1]='up',[2]='down',[4]='left',[8]='right',[16]='B',[32]='C',[64]='A',[128]='start'} RNG = 0xFF0EC2; savestate.save(START); --Get all RNG values up to location, figure out # of changes. gens.emulateframefast(); last_RNG = memory.readword(RNG); RNG_Count = 0; gens.emulateframefast(); while (last_RNG ~= memory.readword(RNG)) do last_RNG = memory.readword(RNG); gens.emulateframefast(); RNG_Count = RNG_Count + 1; end; print(RNG_Count); --Calculate the backwards RNG. savestate.load(START); curr_RNG = memory.readword(RNG); multiplier = 1; for t = 1,RNG_Count,1 do multiplier = math.mod((13*multiplier),65536); end; print(multiplier) if last_RNG > target then dist = target + 65536 - last_RNG; else dist = target - last_RNG; end; done = FALSE; offst = 0; print(dist) while not done do if math.mod(dist+offst*65536,multiplier) < (765) then done = true; else offst = offst + 1; end; end temp = 256-math.floor((dist+offst*65536)/multiplier); for bit,button in pairs(buttonmap) do if AND(temp,bit) ~= 0 then joypad.set({[button]=true}) end end for i=1,RNG_Count+1,1 do gens.emulateframefast(); end; while (target ~= memory.readword(RNG)) do if memory.readword(RNG) < (target - 255) then joypad.set(1,{up=true}); else temp = 256 - target + memory.readword(RNG); for bit,button in pairs(buttonmap) do if AND(temp,bit) ~= 0 then joypad.set({[button]=true}) end end end gens.emulateframefast(); end; [/code] BattleOrderExecute Works for any round that ends in either an enemy turn, or a character attack or movement. For character based control, the RNG value must be relatively close (+/- 1000) For an enemy turn, the RNG can be anything, start the program > 20 or so frames from the last enemy turn. For player turn, start at the last input required to end the turn as fast as possible. If it fails, try it with F_Offst = 1. This depends on the round/number of enemies left. [code lua] target = 58680 F_Offst = 2; START = savestate.create(); local buttonmap = {[1]='up',[2]='down',[4]='left',[8]='right',[16]='B',[32]='C',[64]='A',[128]='start'} TURN_COUNT = 0xFF9C07; RNG = 0xFF0EC2; savestate.save(START); --Get all RNG values up to location, figure out # of changes. RNG_Pre = {}; framecnt = 1; RNG_Pre[framecnt] = memory.readword(RNG); gens.emulateframefast(); WasLag = gens.lagged(); RNG_Move_Type = {}; RNG_EX = 0; posdist = 0; negdist = 0; print('Finding Battle Transition'); --and (memory.readbyte(TURN_COUNT) ~= 32) while (memory.readbyte(TURN_COUNT) ~= 0) and (memory.readbyte(TURN_COUNT) ~= 32) do framecnt = framecnt+1; RNG_Pre[framecnt] = memory.readword(RNG); if (RNG_Pre[framecnt] == RNG_Pre[framecnt-1]) then if WasLag then RNG_Move_Type[framecnt-1] = -1; else RNG_Move_Type[framecnt-1] = 0; end; elseif (math.fmod(RNG_Pre[framecnt]+256, 65536) == RNG_Pre[framecnt-1]) then RNG_Move_Type[framecnt-1] = 1; negdist = negdist + 256; elseif (math.fmod(RNG_Pre[framecnt]+512, 65536) == RNG_Pre[framecnt-1]) then RNG_Move_Type[framecnt-1] = 2; negdist = negdist + 512; elseif (RNG_Pre[framecnt] == math.fmod(RNG_Pre[framecnt-1]*13+7,65536)) then RNG_Move_Type[framecnt-1] = 3; RNG_EX = RNG_EX + 1; elseif (RNG_Pre[framecnt] == math.fmod((RNG_Pre[framecnt-1]-256)*13+7,65536)) then RNG_Move_Type[framecnt-1] = 4; RNG_EX = RNG_EX + 1; elseif (RNG_Pre[framecnt]+256 == math.fmod((RNG_Pre[framecnt-1])*13+7,65536)) then RNG_Move_Type[framecnt-1] = 5; RNG_EX = RNG_EX + 1; end; gens.emulateframefast(); WasLag = gens.lagged(); end print(string.format('Battle Transition is %d frames away. RNG Executions: %d', framecnt,RNG_EX)); savestate.load(START); if RNG_EX == 0 then for i = 1,framecnt-F_Offst,1 do curr_RNG = memory.readword(RNG); targtemp = target; if targtemp < curr_RNG then upframes = math.floor((targtemp + 65536 - curr_RNG)/255); downframes = math.floor((curr_RNG-targtemp)/256); else upframes = math.floor((targtemp - curr_RNG)/255); downframes = math.floor((curr_RNG - targtemp + 65536)/255); end; if ((RNG_Move_Type == 0) and (upframes < 40)) then joypad.set(1,{up=true}); elseif ((RNG_Move_Type == 1) and ((downframes > 40) or (downframes == 0))) then joypad.set(1,{up=true}); elseif ((RNG_Move_Type == 2) and ((downframes > 40) or (downframes == 0))) then joypad.set(1,{up=true}); end; gens.emulateframefast(); end; curr_RNG = memory.readword(RNG); temp = curr_RNG-target; for bit,button in pairs(buttonmap) do if AND(temp,bit) ~= 0 then joypad.set({[button]=true}) end end gens.frameadvance(); elseif RNG_EX == 1 then Preframe = 1; curr_RNG = memory.readword(RNG); --Find the RNG execution while (RNG_Move_Type[Preframe+1] < 3) do Preframe = Preframe+1; end; nxtRNG = math.fmod(curr_RNG*13+7,65536); if nxtRNG > target then upframes = math.floor((128+target+65536-nxtRNG)/3315); newtarg = math.fmod(curr_RNG+upframes*255,65536); else upframes = math.floor((128+target-nxtRNG)/3315); newtarg = math.fmod(curr_RNG+upframes*255,65536); end; for i = 1,Preframe,1 do curr_RNG = memory.readword(RNG); if newtarg < curr_RNG then upframes = math.floor((newtarg + 65536 - curr_RNG)/255); downframes = math.floor((curr_RNG-newtarg)/256); else upframes = math.floor((newtarg - curr_RNG)/255); downframes = math.floor((curr_RNG - newtarg + 65536)/255); end; if ((RNG_Move_Type == 0) and (upframes < 40)) then joypad.set(1,{up=true}); elseif ((RNG_Move_Type == 1) and (downframes > 10)) then joypad.set(1,{up=true}); elseif ((RNG_Move_Type == 2) and (downframes > 10)) then joypad.set(1,{up=true}); end; gens.emulateframefast(); end; gens.emulateframefast(); for i = Preframe+2,framecnt-F_Offst,1 do curr_RNG = memory.readword(RNG); targtemp = target; if targtemp < curr_RNG then upframes = math.floor((targtemp + 65536 - curr_RNG)/255); downframes = math.floor((curr_RNG-targtemp)/256); else upframes = math.floor((targtemp - curr_RNG)/255); downframes = math.floor((curr_RNG - targtemp + 65536)/255); end; if ((RNG_Move_Type == 0) and (upframes < 40)) then joypad.set(1,{up=true}); elseif ((RNG_Move_Type == 1) and ((downframes > 40) or (downframes == 0))) then joypad.set(1,{up=true}); elseif ((RNG_Move_Type == 2) and ((downframes > 40) or (downframes == 0))) then joypad.set(1,{up=true}); end; gens.emulateframefast(); end; curr_RNG = memory.readword(RNG); temp = curr_RNG-target; if gens.lagged() then if temp/2 ~= math.floor(temp/2) then print('Script will fail - Wrong parity encountered.') else print('Lag frame encountered.') temp = temp/2; end; end; print(temp) for bit,button in pairs(buttonmap) do if AND(temp,bit) ~= 0 then joypad.set({[button]=true}) end end gens.frameadvance(); end; [/code]
Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
Skilled player (1653)
Joined: 11/15/2004
Posts: 2202
Location: Killjoy
Level Modifier Run the script during a (non-spell) attack animation. Start it at the first character of "Enemy is defeated!" Let the script run, unpause, then select the level up. If distance is longer than the # of characters in "nemy is defeated", the script will fail. [code lua] target =11365 ; LEVEL = 0xFF9C9D; START = savestate.create(); local buttonmap = {[1]='up',[2]='down',[4]='left',[8]='right',[16]='B',[32]='C',[64]='A',[128]='start'} TURN_COUNT = 0xFF9C07; TURN_PLACE = 0xFF9C08; RNG = 0xFF0EC2; STAT_HEX = {0xFF9C9E, 0xFF9C9F, 0xFF9CA0, 0xFF9CA5, 0xFF9CA8,0xFF9CA2}; MAPPLAYER = 0xFFA1B6; savestate.save(START); --Get all RNG values up to location, figure out # of changes. framecnt = 0; RNG_Move_Type = {}; RNG_EX = 0; currchar = memory.readbyte(MAPPLAYER + 16*memory.readbyte(TURN_PLACE + 2*memory.readbyte(TURN_COUNT))); currlev = memory.readbyte(40*currchar + LEVEL); ZeroCheck = 27751; ZeroResult = 12975; last_RNG = memory.readword(RNG); start_RNG = memory.readword(RNG); currstats = {}; for i = 1,6,1 do currstats = memory.readbyte(STAT_HEX + currchar*40); memory.writebyte(STAT_HEX + currchar*40,0); end; joypad.set(1,{up=true}); gens.emulateframefast(); done = false; print('Finding Level Up'); while not done do framecnt = framecnt+1; memory.writeword(RNG,ZeroCheck); joypad.set(1,{up=true}); gens.emulateframefast(); if memory.readbyte(40*currchar + LEVEL) == currlev+1 then done = true; end; end stats = {}; max_stats = {}; min_stats = {}; for i = 1,6,1 do stats = memory.readbyte(STAT_HEX + currchar*40); max_stats = math.max(math.min(math.floor(stats/4),5)-1,0) + stats; min_stats = math.max(-1*math.min(math.floor(stats/4),4) + stats, currstats); end; done = false currcolor = 1; ccount = 0; currloc = 1; plusr = true; minusr = true; leftr = true; rightr = true; savestate.load(START); colors = {'white','gray','black'}; while not done do input_state = input.get(); gens.frameadvance(); gui.text(10,50, ' ATT DEF AGI HP MP CRIT'); gui.text(10,60,string.format('MAX: %02d %02d %02d %02d %02d %02d', max_stats[1], max_stats[2], max_stats[3], max_stats[4], max_stats[5], max_stats[6])); gui.text(6,70,string.format('CURR: %02d %02d %02d %02d %02d %02d', currstats[1], currstats[2], currstats[3], currstats[4], currstats[5], currstats[6])); gui.text(10,80,string.format('MIN: %02d %02d %02d %02d %02d %02d', min_stats[1], min_stats[2], min_stats[3], min_stats[4], min_stats[5], min_stats[6])); gui.text(currloc*24+18,70,'<-'); if input_state.enter then done = true; end; if input_state.numpad8 and plusr then plusr = false; currstats[currloc] = math.min((currstats[currloc] + 1), max_stats[currloc]); end; if input_state.numpad2 and minusr then minusr = false; currstats[currloc] = math.max((currstats[currloc] - 1), min_stats[currloc]); end; if input_state.numpad4 and leftr then leftr = false; currloc = math.max(currloc-1,1); end; if input_state.numpad6 and rightr then rightr = false; currloc = math.min(currloc+1,6); end; if (not input_state.numpad8) then plusr = true; end; if (not input_state.numpad2) then minusr = true; end; if (not input_state.numpad6) then rightr = true; end; if (not input_state.numpad4) then leftr = true; end; end; start_RNG = start_RNG - framecnt; destat = {}; offst = {}; for i = 1,6,1 do destat = currstats - stats; offst = max_stats - stats; end; i = start_RNG-255; done = false; while not done do x = i; fail = false for z=1,6,1 do x = math.mod((x*13 + 7),65536); Y1 = math.floor(x*(offst[z]+1)/65536); x = math.mod((x*13 + 7),65536); Y2 = math.floor(x*(1+offst[z])/65536); Y = Y1 - Y2; if (Y + stats[z]) < math.min(min_stats[z]) then Y = 0; end; if Y ~= destat[z] then fail = true; end; end; if not fail then target = i; done = true; else i = i - 1; if i < 0 then i = 65536; end; end; end; print(string.format("Target: %d Distance: %d",target,math.floor((start_RNG-target)/255))); savestate.load(START); for i = 1,framecnt-1,1 do if memory.readword(RNG)-target < (framecnt-i)+255 then joypad.set(1,{up=true}); end; gens.emulateframefast(); end; temp = memory.readword(RNG)-target; for bit,button in pairs(buttonmap) do if AND(temp,bit) ~= 0 then joypad.set({[button]=true}) end end gens.emulateframefast(); gens.emulateframefast(); gens.emulateframefast(); test = 1; for i = 1,6,1 do if (currstats ~= memory.readbyte(STAT_HEX + currchar*40)) then test = 0; end; end; if (test == 0)then print("Normal method failed - Trying secondary"); savestate.load(START); for i = 1,framecnt-1,1 do if memory.readword(RNG)-(target-255) < (framecnt-i)+255 then joypad.set(1,{up=true}); end; gens.emulateframefast(); end; temp = memory.readword(RNG)-target; for bit,button in pairs(buttonmap) do if AND(temp,bit) ~= 0 then joypad.set({[button]=true}) end end; test = 1; gens.emulateframefast(); gens.emulateframefast(); gens.emulateframefast(); test = 1; for i = 1,6,1 do if (currstats ~= memory.readbyte(STAT_HEX + currchar*40)) then test = 0; end; end; end if (test==0) then print('Level up failed'); end; gens.pause(); [/code] Move Character A fun script that allows you to move characters around the battlefield. The top 2 numbers tell you the X and Y position of a character. The bottom numbers are Character Position in the current battle order, and that characters assigned number in the Battle. Also, [ and ] move a selected character around in the battle order. [code lua] CamPosX =0xFF9C48; CamPosY =0xFF9C49; Alive = 0xFFA1B6; LocX = 0xFFA1B7; LocY = 0xFFA1B8; OL = 0xFF9C08; SizeX = 24; SizeY = 24; Holding = false; leftclickrelease = true; lbrelease = true; lbrelease = true; gens.registerbefore(function() CamX = memory.readbyte(CamPosX); CamY = memory.readbyte(CamPosY); OnScreen = {}; PosX = {}; PosY = {}; Ord = {}; for n = 0,31,1 do Ord[memory.readbyte(OL+n*2)] = n; end; i=0; for c = 0,31,1 do if memory.readbyte(Alive+c*16) ~= 255 then X = memory.readbyte(LocX+c*16); Y = memory.readbyte(LocY+c*16); if ((X > CamX-1) and (X < CamX+11) and (Y > CamY-1) and (Y < CamY+10)) then i = i+1; OnScreen = c; PosX = (X-CamX)*SizeX-4; PosY = (Y-CamY)*SizeY+7; gui.drawbox(PosX,PosY,PosX+SizeX,PosY-SizeY,"clear","white") gui.text(PosX+3,PosY-8,string.format("%d %d",c,Ord[c])); gui.text(PosX+3,PosY-21,string.format("%d %d",X,Y)); end; end; end; input_state = input.get(); xmouse = input_state.xmouse+1; ymouse = input_state.ymouse+1; Mx = math.floor((xmouse+4)/SizeX)+CamX; My = math.floor((ymouse-7)/SizeY)+CamY+1; MDx = (Mx-CamX)*SizeX-4; MDy = (My-CamY)*SizeY+7; if ((xmouse > 0) and (xmouse < 320) and (ymouse > 0) and (ymouse < 224)) then if (not Holding) then gui.drawbox(MDx,MDy,MDx+SizeX,MDy-SizeY,"opaque","black") if (input_state.leftclick) and leftclickrelease then leftclickrelease = false; for m = 1,i,1 do if ((xmouse>=PosX[m]) and (xmouse<=PosX[m]+SizeX) and (ymouse<=PosY[m]) and (ymouse>=PosY[m]-SizeY)) then Holding=true; CharHold = OnScreen[m]; CharOrd = Ord[CharHold]; end; end; end; elseif (Holding) then gui.drawbox(MDx,MDy,MDx+SizeX,MDy-SizeY,"opaque","red") memory.writebyte(LocX+CharHold*16,Mx); memory.writebyte(LocY+CharHold*16,My); if (input_state.leftbracket) and (CharOrd > 0) and lbrelease then lbrelease = false; temp = memory.readbyte(OL+CharOrd*2-2); memory.writebyte(OL+CharOrd*2-2,CharHold); memory.writebyte(OL+CharOrd*2,temp); CharOrd = CharOrd-1; end; if (input_state.rightbracket) and (CharOrd < 31) and rbrelease then rbrelease = false; temp = memory.readbyte(OL+CharOrd*2+2); memory.writebyte(OL+CharOrd*2+2,CharHold); memory.writebyte(OL+CharOrd*2,temp); CharOrd = CharOrd+1; end; if (input_state.leftclick) and leftclickrelease then leftclickrelease = false; Holding = false; end; end; end; if (not input_state.leftclick) then leftclickrelease = true; end; if (not input_state.leftbracket) then lbrelease = true; end; if (not input_state.rightbracket) then rbrelease = true; end; end); [/code]
Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
Skilled player (1653)
Joined: 11/15/2004
Posts: 2202
Location: Killjoy
Crits Allows you to select the critical, miss, double hit/double critical (Doesn't work on Dark Dragon, or when Balbaroy has the doom blade equipped.) The attack portion all assume that you will achieve the correct value of the RNG before the attack is initiated with C (not A!). Thus, if you want to use this 1 frame after C is pressed, you must memorize the previous noted value. [code lua]local crit_rate = 3; local level =5; local miss_rate = 8; local count; local X; local D7; miss={}; crits={}; dhsc = {}; crit_dmg = {}; dhdc = {}; dhdc_dmg ={}; doublehit = math.floor((level*2)/3)+7; count = 2; count2 = 2; count3 = 2; count4 = 2; miss[1] = 0; crits[1] = 0; dhsc[1] = 0; dhdc[1] = 0; for D7 = 1,65535,1 do X = 13 * D7; X = 7+X; X = X % 65536; X = 13 * X; X = 7+X; X = X % 65536; y = 100*X; y = math.floor(y/65536); if (y <= 7) then miss[count] = D7; count = count + 1; elseif (y > miss_rate) then X = 13 * X; X = 7+X; X = X % 65536; X = 13 * X; X = 7+X; X = X % 65536; Y = 100*X; Y = math.floor(Y/65536); X = 13 * X; X = 7+X; X = X % 65536; A = 21*X; A = math.floor(A/65536); X = 13 * X; X = 7+X; X = X % 65536; B = 21*X; B = math.floor(B/65536); if (Y<crit_rate) then crits[count2] = D7-224; crit_dmg[count2] = 80+math.floor((A+B)/2); count2 = count2 + 1; end; end; end; for D7 = 1,65535,1 do X = 13 * D7; X = 7+X; X = X % 65536; y = 100*X; y = math.floor(y/65536); if (y < doublehit) then X = 13 * X; X = 7+X; X = X % 65536; y = 100*X; y = math.floor(y/65536); if (y > miss_rate) then X = 13 * X; X = 7+X; X = X % 65536; X = 13 * X; X = 7+X; X = X % 65536; C1 = 100*X; C1 = math.floor(C1/65536); X = 13 * X; X = 7+X; X = X % 65536; A = 21*X; A = math.floor(A/65536); X = 13 * X; X = 7+X; X = X % 65536; B = 21*X; B = math.floor(B/65536); X = 13 * X; X = 7+X; X = X % 65536; Y = 100*X; Y = math.floor(Y/65536); X = 13 * X; X = 7+X; X = X % 65536; X = 13 * X; X = 7+X; X = X % 65536; C2 = 100*X; C2 = math.floor(C2/65536); X = 13 * X; X = 7+X; X = X % 65536; C = 21*X; C = math.floor(C/65536); X = 13 * X; X = 7+X; X = X % 65536; D = 21*X; D = math.floor(D/65536); if ((y > miss_rate) and (Y > miss_rate) and ((C1 < crit_rate) or (C2 < crit_rate))) then dhsc[count3] = D7-224; count3 = count3 + 1; end; if ((y > miss_rate) and (Y > miss_rate) and (C1 < crit_rate) and (C2 < crit_rate)) then dhdc[count4] = D7-224; dhdc_dmg[count4] = (math.floor(80+(A+B)/2)+math.floor(80+(C+D)/2))/2; count4 = count4 + 1; end; end; end; end; control = {"Up ", "Down ", "Left ", "Right ", "B ", "C ", "A ", "Start "}; gui.register( function () curr_rng = memory.readwordunsigned(0xff0ec2); for i = 2,#miss,1 do if ((miss[i-1] < curr_rng) and (miss >= curr_rng)) then target = miss; end; end; cnt_in = target - curr_rng; frameup = 0; while (cnt_in > 255) do cnt_in = cnt_in - 255; frameup = frameup + 1; end; precont = curr_rng+frameup*255; new_targ = 256-cnt_in; outs = "Miss: "; if (frameup>0) then outs = outs.."^"..string.format('%d',frameup).." "; end; for x= 1,8,1 do if (new_targ%2) == 1 then outs = outs..control[x]; end; new_targ = math.floor(new_targ/2); end; print(outs); for i = 2,#crits,1 do if ((crits[i-1] < curr_rng) and (crits >= curr_rng)) then target = crits; temp = crit_dmg; end; end; cnt_in = target - curr_rng; frameup = 0; while (cnt_in > 255) do cnt_in = cnt_in - 255; frameup = frameup + 1; end; precont = curr_rng+frameup*255; new_targ = 256-cnt_in; outs = "Crit: "; if (frameup>0) then outs = outs.."^"..string.format('%d',frameup).." "; end; for x= 1,8,1 do if (new_targ%2) == 1 then outs = outs..control[x]; end; new_targ = math.floor(new_targ/2); end; outs = outs.." Dmg:"..string.format('%d',temp); print(outs); target = curr_rng; for i = 2,#dhsc,1 do if ((dhsc[i-1] < curr_rng) and (dhsc > curr_rng)) then target = dhsc; end; end; cnt_in = target - curr_rng; frameup = 0; while (cnt_in > 255) do cnt_in = cnt_in - 255; frameup = frameup + 1; end; precont = curr_rng+frameup*255; new_targ = 256-cnt_in; outs = "DHSC: "; if (frameup>0) then outs = outs.."^"..string.format('%d',frameup).." "; end; for x= 1,8,1 do if (new_targ%2) == 1 then outs = outs..control[x]; end; new_targ = math.floor(new_targ/2); end; print(outs); target = curr_rng; for i = 2,#dhdc,1 do if ((dhdc[i-1] < curr_rng) and (dhdc > curr_rng)) then target = dhdc; temp = dhdc_dmg; end; end; targetsv = target+224; cnt_in = target - curr_rng; frameup = 0; while (cnt_in > 255) do cnt_in = cnt_in - 255; frameup = frameup + 1; end; precont = curr_rng+frameup*255; new_targ = 256-cnt_in; outs = "DHDC: "; if (frameup>0) then outs = outs..string.format('%d',targetsv).." ^"..string.format('%d',frameup).." "; end; for x= 1,8,1 do if (new_targ%2) == 1 then outs = outs..control[x]; end; new_targ = math.floor(new_targ/2); end; outs = outs.." Dmg:"..string.format('%d',temp); print(outs); print(""); end) [/code] Dump Dumps all the current Enemy locations to a file on the C drive called End_Loc.txt. This is a matlab ready copy and paste. Allows for faster optimization of battles, since matlab can be updated quicker with the ending positions of a round. [code lua] start_ag_add = 0xFFA1BB; start_x_add = 0xFFA1B7; start_y_add = 0xFFA1B8; outs = "End_Loc = [" count = 0; done = 0; while (done == 0) do z = memory.readbytesigned(start_ag_add+count*16); if (z == -1) then done = 1; else count = count + 1; end; end; for i = 0,count-1,1 do outs = outs..string.format("%d %d;",memory.readbyte(start_x_add+16*i), memory.readbyte(start_y_add+16*i)); end; outs = outs.."];"; x = io.open("C:\\end_loc.txt", "w"); x:write(outs); x:close(); [/code]
Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
Joined: 3/11/2008
Posts: 583
Location: USA
I...had a strange thought. What does using the other style of controller(6-button?) do in this game- particularly, [how] does it affect RNG update?
Joined: 2/20/2010
Posts: 209
Location: I'm in space
what I have to show for 2 hours of screwing around with savestates; I inflict damage on myself, and also manage to level up in the process: Note HP 0/16 =)
Oh, play it cool. Play it cool. Here come the space cops.
Joined: 3/20/2011
Posts: 4
Found three small glitches, one of which could be useful. -It's possible to queue up a pause if you try to pause just as you walk onto a tile that warps you to a new location (i.e. stairs or teleporter). Maybe this could be used to skip a cutscene that plays on entering a room, or even a battle? -With the right timing, if you try to select an item that is one square to the right or left in a shop while the cursor is still moving, it will select the item two tiles away. -If you de-select a character, you can move the cursor once you've already pressed the button to lock onto the character again if you use the correct timing. Also did a bit of testing with cheats. I'm not totally sure if this information is old, but... The objects on a map don't change. They merely move. This means that the circus tent in battle 7 is on the map beforehand, just in the middle of the sea, recruited party members hang out on the map boundaries, etc. If you go outside the boundaries of a map, you are taken to the world map. Tiles outside the map are walkable. The lowest tile of the passage to the house with Boken in the town before battle 9 is adjacent to a tile that goes to the world map, but it is a loading zone itself. If a way to bypass the loading zone is ever found, we'll be able to skip the Bustoke quarry battle. Getting outside the map on the island while your ship is being fixed lets you sail onward. I found a variant of the shop glitch in the character menu. Hold up or down for 5 input frames, and then hold C and the direction one more frame. You will advance two spaces through the menu instead of one. Like the shop glitch, you don't seem to be able to select out of bounds, but I think further testing is a good idea. My limited experience may be preventing me from seeing something further that could be done with this.
Skilled player (1653)
Joined: 11/15/2004
Posts: 2202
Location: Killjoy
Medibisu wrote:
Found three small glitches, one of which could be useful. -It's possible to queue up a pause if you try to pause just as you walk onto a tile that warps you to a new location (i.e. stairs or teleporter). Maybe this could be used to skip a cutscene that plays on entering a room, or even a battle? -With the right timing, if you try to select an item that is one square to the right or left in a shop while the cursor is still moving, it will select the item two tiles away. -If you de-select a character, you can move the cursor once you've already pressed the button to lock onto the character again if you use the correct timing. Also did a bit of testing with cheats. I'm not totally sure if this information is old, but... The objects on a map don't change. They merely move. This means that the circus tent in battle 7 is on the map beforehand, just in the middle of the sea, recruited party members hang out on the map boundaries, etc. If you go outside the boundaries of a map, you are taken to the world map. Tiles outside the map are walkable. The lowest tile of the passage to the house with Boken in the town before battle 9 is adjacent to a tile that goes to the world map, but it is a loading zone itself. If a way to bypass the loading zone is ever found, we'll be able to skip the Bustoke quarry battle. Getting outside the map on the island while your ship is being fixed lets you sail onward. I found a variant of the shop glitch in the character menu. Hold up or down for 5 input frames, and then hold C and the direction one more frame. You will advance two spaces through the menu instead of one. Like the shop glitch, you don't seem to be able to select out of bounds, but I think further testing is a good idea. My limited experience may be preventing me from seeing something further that could be done with this.
I can't get the pause buffer to work or cursor trick to work. Could you maybe record short movies doing these tricks? Also, the shop/character menu isn't really a glitch. You can press toward a new character every 5 frames. All the 'C' does is 'reset' the control. It would be the same as just pressing down once every 5 frames.
Sage advice from a friend of Jim: So put your tinfoil hat back in the closet, open your eyes to the truth, and realize that the government is in fact causing austismal cancer with it's 9/11 fluoride vaccinations of your water supply.
1 2
6 7