1{ 2id: "menu_selector_load_game", 3ignore_collide: true, 4zorder: 20, 5is_human: true, 6 7editor_info: { 8 category: "playable", 9 }, 10 11vars: { 12 currently_selected: null, 13 }, 14 15consts: { 16 offset: [-18,0], 17 }, 18 19properties: { 20 item_chars: "filter(level.chars, value.consts.is_menu_item)", 21 22 closest_item: "choose(item_chars, -distance(value, {midpoint_x: midpoint_x - consts.offset[0], midpoint_y: midpoint_y - consts.offset[1]}))", 23 click_item: "def(x,y) choose(item_chars, -distance(value, {midpoint_x: x, midpoint_y: y}))", 24 25 first_item: "closest_item.default_in_group", 26 27 select: "def(item) if(item, [ 28 set(xy, list_add(item.xy, consts.offset)), 29 set(currently_selected, item), 30 fire_event(item, 'selected'), 31 fire_event(currently_selected, 'deselected'), 32 currently_selected.show_selector, 33 item.hide_selector, 34 fire_event(item, 'activate'), 35 if(level.cycle > 10, sound('MenuCursorMove.ogg')), 36 ],[ 37 fire_event('failed_select'), 38 ])", 39 40 // debug_fn([value.msg, decimal(x-value.x)/decimal(y-value.y)], true)) 41 next_item: "def(direction) //as on a number pad 42 choose( 43 filter(item_chars, 44 switch(direction, 45 2, value.y > y2 and abs(decimal(x2-value.x)/decimal(y2-value.y)) <= 1, 46 4, value.x < x2 and abs(decimal(x2-value.x)/decimal(y2-value.y)) >= 1, // The below is a strange workaround for a bug involving infinite math. the abs() is returning the absolute of -inf8, which is one more than inf7, so it wraps back around to -inf8. However, -1/0 is inverting inf7, coming out with -inf7, which is one more than -inf8… as far as I can tell. 47 6, value.x > x2 and abs(decimal(x2-value.x)/decimal(y2-value.y)) >= 1, 48 8, value.y < y2 and abs(decimal(x2-value.x)/decimal(y2-value.y)) <= 1, 49 // Who do we appreciate? 50 )), 51 -distance(value, {midpoint_x: midpoint_x - consts.offset[0], midpoint_y: midpoint_y - consts.offset[1]})) 52 where x2 = x - self.consts.offset[0] 53 where y2 = y - self.consts.offset[1]", 54 55 screen_scale_factor: "if(DOUBLE_SCALE, 1, 2)", 56}, 57 58on_start_level: "[ 59 select(first_item), 60 set(alpha,0), 61 spawn(me.type+'.arrow',mid_x,mid_y,facing, [set(child.parent,me)]) 62 ]", 63 64on_ctrl_down: "select(next_item(2))", 65on_ctrl_up: "select(next_item(8))", 66on_ctrl_left: "select(next_item(4).selector.targeting)", 67on_ctrl_right:"select(next_item(6).selector.targeting)", 68 69"on_mouse_down*": "if(mouse_button in [1,3], select(click_item(mouse_x*screen_scale_factor, (mouse_y+8)*screen_scale_factor )))", 70 71on_ctrl_tongue: "fire_event('finish_menu')", 72on_ctrl_attack: "fire_event('ctrl_tongue')", 73on_ctrl_jump: "fire_event('ctrl_tongue')", 74 75//on_finish_menu: "", //TODO virtual, would be defined in level, except : need to know how to assign event handlers in spawn(), because on the titlescreen we have to spawn our playable object, we can't put stuff in the instance of the playable object that's on the actual level, because we obliterate that when we transfer to the level. 76 "on_enter_level": "[ 77 map(filter(level.chars, value.group=0), 'slot_obj', [ 78 if(level_data['no save data'], remove_object(slot_obj), 79 map(keys(level_data), 'ld_key', 80 spawn('text_controller', slot_obj.mid_x+20, slot_obj.mid_y+(index+1)*25, 1, child.set_text('${ld_key}: ${level_data[ld_key]}')), 81 )), 82 set(slot_obj.vars.save_slot_index, index), 83 ] where level_data = (if(sd.version, { 84 ~level~: translate(sd.title), 85 ~coins~: player.vars.coins, 86 ~visited levels~: size(player.vars.levels_visited), 87 // can't do this'hp': '${player.hitpoints}/${player.max_hitpoints}', 88 ~hp~: str(player.hitpoints/2 or player_default_hitpoints)+'/'+str(player.max_hitpoints/2 or player_default_hitpoints), 89 } where player_default_hitpoints = object(player.type or 'frogatto_playable').hitpoints/2 90 where player = find(sd.character, 'character', character.is_human), 91 {'no save data': true}) 92 where sd = get_save_document(index)) 93 ), 94 ]", 95 96 "on_finish_menu": "if(cycle > 30, [ 97 swallow_event(), 98 set(control_lock, []), 99 screen_flash([255,255,255,0], [0,0,0,5], 52), 100 schedule(50, 101 [set(control_lock, null), 102 load_game('instant', currently_selected.vars.save_slot_index),] 103 ) 104 ])", 105 106on_process:" 107 if(13 in ctrl_keys or ' ' in ctrl_keys, 108 fire_event('finish_menu') 109 )", 110 111animation: { 112 id: "normal", 113 image: "characters/stand_in_selector.png", 114 rect: [0,0,15,15], 115}, 116 117object_type: [ 118 { 119 id: "arrow", 120 ignore_collide: true, 121 zorder: 30, 122 123 on_end_anim: "set(animation,animation)", 124 on_process: "[set(relative_x, -50 + 4*sin(cycle*10)),set(relative_y, 2 - img_h/2)]", 125 on_create: "set(rotate,-90)", 126 127 animation: { 128 id: "normal", 129 image: "gui/arrow-menu-cursor.png", 130 rect: [0,0,23,23], 131 frames: 8, 132 frames_per_row: 4, 133 duration: 3, 134 }, 135 }, 136 { 137 id: "arrow_selected", 138 ignore_collide: true, 139 zorder: 25, 140 141 on_end_anim: "set(animation,animation)", 142 on_create: "set(rotate,-90)", 143 144 animation: { 145 id: "normal", 146 image: "gui/arrow-menu-selected.png", 147 rect: [0,0,23,23], 148 frames: 1, 149 duration: 100, 150 }, 151 }], 152 153} 154