"""Approach an observed map event through normal game controls; no saves.""" from nav import * from locate import locate,capture_ready mid,eid=int(sys.argv[1]),int(sys.argv[2]);kind=sys.argv[3] if len(sys.argv)>3 else 'talk' a,sx,sy=locate(mid) if a!=mid:raise SystemExit(f'Wrong map: observed {a}, expected {mid}') v=json.loads(subprocess.check_output(['ruby',str(ROOT/'scripts/route_map.rb'),str(mid),str(sx),str(sy)],stderr=subprocess.DEVNULL)) e=v['events'][str(eid)];x,y=e['x'],e['y'];opts=[] if kind=='enter' and not any(c['code']==201 for c in e['list'] or []):raise SystemExit('Entry event has no transfer; no input sent') def transfer_arrived(): capture_ready();act('wait:2') actual=locate() destinations={tuple(c['parameters'][1:4]) for c in e['list'] or [] if c['code']==201 and c['parameters'][0]==0} if actual in destinations: print('TRANSFER VERIFIED AFTER INTERRUPTION',actual,flush=True);return True return False if not any(c['code'] not in [0,108,408] for c in (e['list'] or [])):raise SystemExit('Inactive event; no interaction') required={c['parameters'][2] for c in e['list'] if c['code']==111 and len(c['parameters'])>=3 and c['parameters'][:2]==[6,-1]} if kind in ['item','enter'] else set() meaningful=[c for c in e['list'] if c['code'] not in [0,108,408]] if kind=='talk' and meaningful and meaningful[0]['code']==111 and meaningful[0]['parameters'][:2]==[6,-1]: direction=meaningful[0]['parameters'][2] # Some crystals deliberately do nothing from one side; their actions are in ELSE. required=({2,4,6,8}-{direction}) if len(meaningful)>1 and meaningful[1]['code']==411 else {direction} # An immediate Exit Event Processing means this facing is forbidden, not required. forbidden=set() cmds=e['list'] or [] for i,c in enumerate(cmds[:-1]): if c['code']==111 and c['parameters'][:2]==[6,-1] and cmds[i+1]['code']==115: forbidden.add(c['parameters'][2]) if forbidden:required={2,4,6,8}-forbidden for dx,dy,k in [(0,1,'up'),(0,-1,'down'),(1,0,'left'),(-1,0,'right')]: if required and {'down':2,'left':4,'right':6,'up':8}[k] not in required:continue try: p=(x+dx,y+dy) if p!=(sx,sy) and any((ee['x'],ee['y'])==p and any(cc['code']==201 for cc in (ee['list'] or [])) for ee in v['events'].values()):continue opts.append((len(route(v,p)),p,k)) except ValueError:pass if not opts and kind=='talk': # RPG XP counters permit action-button interaction from two tiles away. # Check the installed tile flag, rather than guessing a booth's open side. w,h=v['width'],v['height'] for dx,dy,k in [(0,1,'up'),(0,-1,'down'),(1,0,'left'),(-1,0,'right')]: cx,cy=x+dx,y+dy if not (0<=cx