./cell_cheats.lua

  1. local	CELL_CHEATS_POPULATE_CATEGORIES 	= 0 
  2. local	CELL_CHEATS_POPULATE_CHEATS		= 1 
  3.  
  4. local ID_CHEAT	= -1 
  5.  
  6. local Category_menu = { } 
  7. local Num_category_items = 1 
  8. local Category_selected_idx = 1 
  9. local Sub_menu = { } 
  10. local Num_submenu_items = 0 
  11. local Unlocked_cheat 
  12. local Cheat_just_unlocked = false 
  13. local Sub_menu_category = 1 
  14.  
  15. local Add_cheat_button = { label = "ADD_CHEAT", 	type = TYPE_BUTTON, id = ID_CHEAT		} 
  16.  
  17. local Sub_menu_is_active = false 
  18.  
  19. local Input_tracker 
  20. local Mouse_input_tracker 
  21. local Hint_bar 
  22. local Continue_hint_bar 
  23.  
  24. Cheats_list		 = -1				--This must be global because the megalist needs it to be for callback (JMH 4/4/2011) 
  25.  
  26. local Cell_cheats_doc_handle = -1 
  27. local CHEATS_LIST_WIDTH = 400 
  28. local CHEATS_LIST_NUM_OPTIONS = 10 
  29. local CHEATS_LIST_TITLE_OFFSET = 30		--Offset to accomodate for header on submenus. 
  30.  
  31. local Cheat_being_entered = false 
  32.  
  33. --Base position for cheatslist... 
  34. local Cheats_list_start_x, Cheats_list_start_y 
  35.  
  36. function cell_cheats_init() 
  37. 	Cell_cheats_doc_handle = vint_document_find("cell_cheats") 
  38.  
  39. 	-- Subscribe to the button presses we need 
  40. 	Input_tracker = Vdo_input_tracker:new() 
  41. 	Input_tracker:add_input("nav_up", "cell_cheats_nav_up", 50) 
  42. 	Input_tracker:add_input("nav_down", "cell_cheats_nav_down", 50)	 
  43. 	Input_tracker:add_input("back", "cell_cheats_button_b", 50) 
  44. 	Input_tracker:add_input("select", "cell_cheats_button_a", 50) 
  45. 	Input_tracker:add_input("map", "cell_cheats_button_map", 50) 
  46.  
  47. 	local grp_h = vint_object_find("new_cheat_grp", 0, Cell_cheats_doc_handle) 
  48. 	vint_set_property(grp_h, "visible", false) 
  49.  
  50. 	--Set up title 
  51. 	local cell_title_h = Vdo_cell_title:new("cell_title", 0, Cell_cheats_doc_handle) 
  52. 	cell_title_h:set_text("HELP_TEXT_CHEATS_TITLE") 
  53. 	cell_title_h:set_icon("ui_cell_icon_cheats") 
  54. 	cell_title_h:play_dots_anim() 
  55. 	 
  56. 	local data = { 
  57. 		{CTRL_MENU_BUTTON_A, "MAINMENU_CONTINUE"}, 
  58. 	} 
  59. 	Continue_hint_bar = Vdo_hint_bar:new("cheat_btn_hint_bar", grp_h) 
  60. 	Continue_hint_bar:set_hints(data) 
  61. 	 
  62. 	Cheats_list = Vdo_mega_list:new("cheats_list", 0, Cell_cheats_doc_handle, "cell_cheats.lua", "Cheats_list") 
  63. 	Cheats_list:set_highlight_color(COLOR_CHEATS_PRIMARY, COLOR_CHEATS_SECONDARY)	 
  64. 	 
  65. 	--Get base position for cheatslist... 
  66. 	Cheats_list_start_x, Cheats_list_start_y = vint_get_property(Cheats_list.handle, "anchor") 
  67. 	 
  68. 	cell_cheats_enter_category_menu() 
  69. 	 
  70. 	--Transition the screen in... 
  71. 	cell_transition_screen(CELL_STATE_PORTRAIT, CELL_SCREEN_CHEATS, CELL_SCREEN_EXTRAS, cell_cheats_unlock_controls) 
  72. 	-- Setup Button Hints 
  73. 	Hint_bar = Vdo_hint_bar:new("hint_bar", 0, Cell_cheats_doc_handle) 
  74. 	local hint_data = { 
  75. 		{CTRL_MENU_BUTTON_B, "MENU_BACK"}, 
  76. 	} 
  77. 	Hint_bar:set_hints(hint_data)  
  78. 	Hint_bar:set_visible(true)	 
  79. 	if game_get_platform() == "PC" then 
  80. 		 
  81. 		Hint_bar:set_highlight(0) 
  82. 		Continue_hint_bar:set_highlight(1, COLOR_CHEATS_SECONDARY) 
  83. 		vint_dataitem_add_subscription("cell_cheats_text", "update", "cell_cheats_text_update") 
  84. 	 
  85. 		Mouse_input_tracker = Vdo_input_tracker:new() 
  86. 		-- Inputs also updated in cell_cheats_mouse_update 
  87. 		Cheats_list:add_mouse_inputs("cell_cheats", Mouse_input_tracker) 
  88. 		Hint_bar:add_mouse_inputs("cell_cheats", Mouse_input_tracker) 
  89. 		Mouse_input_tracker:subscribe(false) 
  90. 	end 
  91. 	--glitch 
  92. 	--glitch_cell() 
  93. end 
  94.  
  95. function cell_cheats_cleanup() 
  96. 	-- Nuke all button subscriptions 
  97. 	Input_tracker:subscribe(false) 
  98. 	 
  99. 	if Mouse_input_tracker ~= nil then 
  100. 		Mouse_input_tracker:subscribe(false) 
  101. 	end 
  102. end 
  103.  
  104. function cell_cheats_enter_category_menu() 
  105.  
  106. 	local subtitle_h = vint_object_find("subtitle", 0, Cell_cheats_doc_handle) 
  107. 	local description_grp_h = vint_object_find("description_grp", 0, Cell_cheats_doc_handle) 
  108. 	 
  109. 	-- set description text invisble 
  110. 	Cheats_list:set_anchor(Cheats_list_start_x, Cheats_list_start_y) 
  111. 	vint_set_property(description_grp_h, "visible", false) 
  112. 	vint_set_property(subtitle_h, "visible", false) 
  113.  
  114. 	Sub_menu_is_active = false 
  115.  
  116. 	Category_menu = {  
  117. 		[1] = Add_cheat_button, 
  118. 	} 
  119. 	Num_category_items = 1 
  120. 	vint_dataresponder_request("cell_cheats_populate", "cell_cheats_populate_categories", 0, CELL_CHEATS_POPULATE_CATEGORIES) 
  121. 	Cheats_list:draw_items(Category_menu, Category_selected_idx, CHEATS_LIST_WIDTH, CHEATS_LIST_NUM_OPTIONS, LIST_FONT_SCALE, true, true) 
  122. 	 
  123. 	--if Hint_bar ~= nil then 
  124. 	--	Hint_bar:set_anchor(-166, 244) 
  125. 	--end 
  126. 	 
  127. 	cell_cheats_mouse_update() 
  128. end 
  129.  
  130. function cell_cheats_mouse_update() 
  131. 	if Mouse_input_tracker ~= nil then 
  132. 		Mouse_input_tracker:remove_all() 
  133. 		Cheats_list:add_mouse_inputs("cell_cheats", Mouse_input_tracker) 
  134. 		Hint_bar:add_mouse_inputs("cell_cheats", Mouse_input_tracker) 
  135. 		Mouse_input_tracker:subscribe(true) 
  136. 	end 
  137. end 
  138.  
  139. function cell_cheats_populate_categories(display_name, id) 
  140. 	Num_category_items = Num_category_items + 1 
  141. 	Category_menu[Num_category_items] = { label = display_name, type = TYPE_BUTTON, id = id } 
  142. end 
  143.  
  144. function cell_cheats_enter_submenu(category_id) 
  145. 	local cheats_list_h = vint_object_find("cheats_list", 0, Cell_cheats_doc_handle) 
  146. 	local description_grp_h = vint_object_find("description_grp", 0, Cell_cheats_doc_handle) 
  147. 	local subtitle_h = vint_object_find("subtitle", 0, Cell_cheats_doc_handle) 
  148. 	 
  149. 	-- Use category name for this 
  150. 	local category_tag = nil 
  151. 	 
  152. 	for idx, category in pairs(Category_menu) do 
  153. 		if category.id == category_id then 
  154. 			category_tag = category.label 
  155. 		end 
  156. 	end 
  157. 	 
  158. 	Num_submenu_items = 0 
  159. 	Sub_menu = { } 
  160. 	vint_dataresponder_request("cell_cheats_populate", "cell_cheats_populate_cheats", 0, CELL_CHEATS_POPULATE_CHEATS, category_id) 
  161. 	Cheats_list:draw_items(Sub_menu, 1, CHEATS_LIST_WIDTH, CHEATS_LIST_NUM_OPTIONS, LIST_FONT_SCALE, true, true) 
  162. 	Sub_menu_is_active = true 
  163. 	Sub_menu_category = category_id 
  164. 		 
  165. 	--Move megalist to accomodate for header... 
  166. 	vint_set_property(Cheats_list.handle, "anchor", Cheats_list_start_x, Cheats_list_start_y + CHEATS_LIST_TITLE_OFFSET) 
  167. 	vint_set_property(description_grp_h, "visible", true) 
  168. 	vint_set_property(subtitle_h, "text_tag", category_tag) 
  169. 	vint_set_property(subtitle_h, "visible", true) 
  170. 	 
  171. 	--if Hint_bar ~= nil then 
  172. 	--	Hint_bar:set_anchor(-166, 130) 
  173. 	--end 
  174. 	 
  175. 	cell_cheats_set_description() 
  176. 	cell_cheats_mouse_update() 
  177. end 
  178.  
  179. function cell_cheats_populate_cheats(display_name, description, cheat_is_active, cheat_index, toggleable) 
  180. 	Num_submenu_items = Num_submenu_items + 1 
  181. 	Sub_menu[Num_submenu_items] = { 	label = display_name,	type = TYPE_BUTTON, description = description, cheat_index = cheat_index } 
  182. 	if toggleable == "true" then 
  183. 		Sub_menu[Num_submenu_items].equipped = cheat_is_active 
  184. 		Sub_menu[Num_submenu_items].owned = true 
  185. 	elseif toggleable == "once" then 
  186. 		Sub_menu[Num_submenu_items].cheats_equipped = cheat_is_active 
  187. 		Sub_menu[Num_submenu_items].owned = true 
  188. 	elseif toggleable == "false" then 
  189. 		Sub_menu[Num_submenu_items].equipped = false 
  190. 		Sub_menu[Num_submenu_items].owned = false 
  191. 	end 
  192. end 
  193.  
  194. function cell_cheats_set_description() 
  195. 	local selection = Cheats_list:get_selection() 
  196. 	local description = Sub_menu[selection].description 
  197. 	local label = Sub_menu[selection].label 
  198. 	 
  199. 	local description_grp_h = vint_object_find("description_grp", 0, Cell_cheats_doc_handle) 
  200. 	vint_set_property(description_grp_h, "visible", true) 
  201. 	 
  202. 	local description_text_h = vint_object_find("cheats_description", description_grp_h) 
  203. 	vint_set_property(description_text_h, "text_tag", description) 
  204. 	 
  205. 	local desc_header_h = vint_object_find("desc_header", description_grp_h) 
  206. 	vint_set_property(desc_header_h, "text_tag", label) 
  207. 	resize_text_element(desc_header_h, 380) 
  208. end 
  209.  
  210. function cell_cheats_cheat_unlocked(cheat_index, display_name, description, category_id) 
  211. 	Cheat_just_unlocked = true 
  212. 	 
  213. 	local unlocked_header 
  214. 	local unlocked_text 
  215. 	if cheat_index == - 1 then 
  216. 		Unlocked_cheat = nil 
  217. 		unlocked_header = "CHEAT_NOT_FOUND" 
  218. 		unlocked_text = "CHEAT_NOT_FOUND_DESC" 
  219. 	else 
  220. 		Unlocked_cheat = { cheat_index = cheat_index, category_id = category_id	} 
  221. 		unlocked_header = display_name 
  222. 		unlocked_text = description 
  223. 		game_UI_audio_play("UI_Cell_Cheat_Unlocked") 
  224. 	end 
  225. 	 
  226. 	Cheats_list:set_visible(false) 
  227. 	local grp_h = vint_object_find("new_cheat_grp") 
  228. 	vint_set_property(grp_h, "visible", true) 
  229. 	 
  230. 	local title_h = vint_object_find("new_cheat_title", grp_h) 
  231. 	local desc_h = vint_object_find("new_cheat_description", grp_h) 
  232. 	 
  233. 	vint_set_property(title_h, "text_tag", unlocked_header) 
  234. 	vint_set_property(desc_h, "text_tag", unlocked_text) 
  235. 	 
  236. 	--Align all elements... 
  237. 	--Align web info... 
  238. 	local data = { 
  239. 		{h = title_h, 	type = VINT_OBJECT_TEXT, space = 0}, 
  240. 		{h = desc_h, 	type = VINT_OBJECT_TEXT, space = 0}, 
  241. 		{h = Continue_hint_bar.handle,	type = VINT_OBJECT_INVALID, space = 25}, 
  242. 	} 
  243. 	local width, height = vint_align_elements(data, true) 
  244. 	 
  245. 	--Hide back button... 
  246. 	if Hint_bar ~= nil then 
  247. 		Hint_bar:set_visible(false) 
  248. 	end 
  249. 			 
  250. 	if Mouse_input_tracker ~= nil then 
  251. 		Mouse_input_tracker:remove_all() 
  252. 		Continue_hint_bar:add_mouse_inputs("cell_cheats", Mouse_input_tracker) 
  253. 		Mouse_input_tracker:subscribe(true) 
  254. 	end 
  255. end 
  256.  
  257. function cell_cheats_cheat_activated(Cheat_index, is_active) 
  258. 	for idx, Cheat  in pairs(Sub_menu) do 
  259. 		if Cheat.cheat_index == Cheat_index then 
  260. 			if Cheat.owned == true then 
  261. 				Cheat.equipped = is_active 
  262. 				Cheat.cheats_equipped = is_active 
  263. 			end 
  264. 			 
  265. 			-- repopulate the list 
  266. 			Num_submenu_items = 0 
  267. 			Sub_menu = { } 
  268. 			vint_dataresponder_request("cell_cheats_populate", "cell_cheats_populate_cheats", 0, CELL_CHEATS_POPULATE_CHEATS, Sub_menu_category) 
  269. 			Cheats_list:draw_items(Sub_menu, idx, CHEATS_LIST_WIDTH, CHEATS_LIST_NUM_OPTIONS, LIST_FONT_SCALE, true, false) 
  270. 		end 
  271. 	end 
  272. 	cell_cheats_mouse_update() 
  273. end 
  274.  
  275. function cell_cheats_nav_up(event, acceleration) 
  276. 	if Cheat_just_unlocked == true then 
  277. 		return 
  278. 	end 
  279. 	Cheats_list:move_cursor(-1) 
  280.  
  281. 	if Sub_menu_is_active then 
  282. 		cell_cheats_set_description() 
  283. 	end 
  284. end 
  285.  
  286. function cell_cheats_nav_down(event, acceleration) 
  287. 	if Cheat_just_unlocked == true then 
  288. 		return 
  289. 	end 
  290. 	Cheats_list:move_cursor(1) 
  291. 	 
  292. 	if Sub_menu_is_active then 
  293. 		cell_cheats_set_description() 
  294. 	end 
  295. end 
  296.  
  297. function cell_cheats_button_map(event, acceleration) 
  298. 	if Cheat_just_unlocked == true then 
  299. 		return 
  300. 	end 
  301. 	ui_audio_post_event("UI_Hub_Menu_Back") 
  302. 	cell_transition_screen(CELL_STATE_OUT, CELL_SCREEN_NONE, CELL_SCREEN_CHEATS, cell_cheats_exit_to_game) 
  303. end 
  304.  
  305. function cell_cheats_button_b(event, acceleration) 
  306.  
  307. 	if Cheat_being_entered == false then 
  308. 		if Cheat_just_unlocked == false then 
  309. 			if Sub_menu_is_active == false then 
  310. 				--Transition the screen out to extras... 
  311. 				cell_cheats_lock_controls() 
  312. 				cell_transition_screen(CELL_STATE_PORTRAIT, CELL_SCREEN_EXTRAS, CELL_SCREEN_CHEATS, cell_cheats_exit_to_extras) 
  313. 			else  
  314. 				cell_cheats_enter_category_menu() 
  315. 			end 
  316. 			ui_audio_post_event("UI_Hub_Menu_Back") 
  317. 		end 
  318. 	elseif game_get_platform() == "PC" then 
  319. 		cell_cheats_cancel_cheat() 
  320. 	end 
  321. end 
  322.  
  323. function cheat_add_cb(success) 
  324.  
  325. 	if success then 
  326. 		cell_cheats_unlock_cheat("VKEYBOARD_RESULTS") 
  327. 	end 
  328.  
  329. end 
  330.  
  331. function cell_cheats_button_a(event, acceleration) 
  332. 	if Cheats_list:list_is_playing() == false then 
  333. 		if Cheat_being_entered == false then 
  334. 			if Cheat_just_unlocked == true then 
  335. 				Cheat_just_unlocked = false 
  336. 				if Unlocked_cheat == nil then 
  337. 					cell_cheats_enter_category_menu() 
  338. 				else 
  339. 					-- Update the category menu so we can get the display name for the submenu header. 
  340. 					Category_menu = {  
  341. 						[1] = Add_cheat_button, 
  342. 					} 
  343. 					Num_category_items = 1 
  344. 					vint_dataresponder_request("cell_cheats_populate", "cell_cheats_populate_categories", 0, CELL_CHEATS_POPULATE_CATEGORIES) 
  345. 					cell_cheats_enter_submenu(Unlocked_cheat.category_id) 
  346. 					 
  347. 					for idx, Cheat  in pairs(Sub_menu) do 
  348. 						if Cheat.cheat_index == Unlocked_cheat.cheat_index then 
  349. 							Cheats_list:draw_items(Sub_menu, idx, CHEATS_LIST_WIDTH, CHEATS_LIST_NUM_OPTIONS, LIST_FONT_SCALE, true, true) 
  350. 							cell_cheats_set_description() 
  351. 						end 
  352. 					end 
  353. 					 
  354. 					cell_cheats_mouse_update() 
  355. 				end 
  356. 				local grp_h = vint_object_find("new_cheat_grp", 0, Cell_cheats_doc_handle) 
  357. 				vint_set_property(grp_h, "visible", false) 
  358. 				Cheats_list:set_visible(true) 
  359. 				 
  360. 				--show back button... 
  361. 				if Hint_bar ~= nil then 
  362. 					Hint_bar:set_visible(true) 
  363. 				end 
  364. 				 
  365. 			elseif Sub_menu_is_active == false then 
  366. 				local id = Cheats_list:get_id() 
  367. 				Category_selected_idx = Cheats_list:get_selection() 
  368. 				-- Selection made in Category menu 
  369. 				if id == ID_CHEAT then 
  370. 					-- add cheat was selected 
  371. 					game_vkeyboard_input("CHEAT_ENTRY_SHORT", "CHEAT_ENTRY_LONG", 32, "", "cheat_add_cb", true) 
  372. 				else 
  373. 					 
  374. 					-- entering a sub menu 
  375. 					cell_cheats_enter_submenu(id) 
  376. 				end 
  377. 			else 
  378. 				-- Selection made in Sub menu 
  379. 				local selection = Cheats_list:get_selection() 
  380. 				cell_cheats_activate_cheat(Sub_menu[selection].cheat_index) 
  381. 			end 
  382. 			 
  383. 			ui_audio_post_event("UI_Hub_Menu_Forward") 
  384. 		elseif game_get_platform() == "PC" then 
  385. 			cell_cheats_confirm_cheat() 
  386. 		end 
  387. 	end 
  388. end 
  389.  
  390. function cell_cheats_lock_controls() 
  391. 	Input_tracker:subscribe(false) 
  392. 	if Mouse_input_tracker ~= nil then 
  393. 		Mouse_input_tracker:subscribe(false) 
  394. 	end 
  395. end 
  396.  
  397. function cell_cheats_unlock_controls() 
  398. 	Input_tracker:subscribe(true) 
  399. 	if Mouse_input_tracker ~= nil then 
  400. 		Mouse_input_tracker:subscribe(true) 
  401. 	end 
  402. end 
  403.  
  404. function cell_cheats_exit_to_extras() 
  405. 	pop_screen() 
  406. end 
  407.  
  408. function cell_cheats_exit_to_game() 
  409. 	pop_screen() 
  410. 	pop_screen() 
  411. 	pop_screen() 
  412. 	pop_screen() 
  413. end 
  414.  
  415. function cell_cheats_mouse_click(event, target_handle) 
  416. 	local hint_index = Hint_bar:get_hint_index(target_handle) 
  417. 	if hint_index == 1 then 
  418. 		cell_cheats_button_b() 
  419. 	end 
  420. 	 
  421. 	local hint_index = Continue_hint_bar:get_hint_index(target_handle) 
  422. 	if hint_index == 1 then 
  423. 		cell_cheats_button_a() 
  424. 	end 
  425.  
  426. 	-- If the target_handle matches a button, activate it 
  427. 	local new_index = Cheats_list:get_button_index(target_handle) 
  428. 	if new_index ~= 0 then 
  429. 		-- Enter an option if the target_handle is in the List 
  430. 		Cheats_list:set_selection(new_index) 
  431. 		cell_cheats_button_a() 
  432. 	end 
  433. end 
  434.  
  435. function cell_cheats_mouse_move(event, target_handle) 
  436. 	Hint_bar:set_highlight(0) 
  437. 	Continue_hint_bar:set_highlight(0) 
  438. 	local hint_index = Hint_bar:get_hint_index(target_handle) 
  439. 	if hint_index ~= 0 then 
  440. 		Hint_bar:set_highlight(hint_index) 
  441. 	end 
  442. 	 
  443. 	local hint_index = Continue_hint_bar:get_hint_index(target_handle)	 
  444. 	if hint_index == 1 then 
  445. 		Continue_hint_bar:set_highlight(1, COLOR_CHEATS_PRIMARY) 
  446. 	end 
  447. 	 
  448. 	local new_index = Cheats_list:get_button_index(target_handle) 
  449. 	if new_index ~= 0 then 
  450. 		-- Set the button as the new selected highlight 
  451. 		Cheats_list:set_selection(new_index) 
  452. 		Cheats_list:move_cursor(0, true) 
  453. 		if Sub_menu_is_active then 
  454. 			cell_cheats_set_description() 
  455. 		end 
  456. 	end 
  457. end 
  458.  
  459. function cell_cheats_mouse_scroll(event, target_handle, mouse_x, mouse_y, scroll_lines)	 
  460. 	if Cheats_list:list_is_playing() == false then 
  461. 		if scroll_lines ~= 0 then 
  462. 			Cheats_list:scroll_list(scroll_lines * -1) 
  463. 			cell_cheats_mouse_update() 
  464. 		end 
  465. 	end 
  466. end 
  467.  
  468. function cell_cheats_mouse_drag(event, target_handle, mouse_x, mouse_y) 
  469. 	if Cheats_list:list_is_playing() == false then 
  470. 		if Cheats_list.scrollbar.tab_grp.handle == target_handle then 
  471. 			local new_start_index = Cheats_list.scrollbar:drag_scrolltab(mouse_y, Cheats_list.num_buttons - (Cheats_list.max_buttons - 1)) 
  472. 			Cheats_list:scroll_list(0, new_start_index) 
  473. 		end 
  474. 	end 
  475. end 
  476.  
  477. function cell_cheats_mouse_drag_release(event, target_handle, mouse_x, mouse_y) 
  478. 	if Cheats_list:list_is_playing() == false then 
  479. 		if Cheats_list.scrollbar.tab_grp.handle == target_handle then 
  480. 			local start_index = Cheats_list:get_visible_indices() 
  481. 			Cheats_list.scrollbar:release_scrolltab(start_index, Cheats_list.num_buttons - (Cheats_list.max_buttons - 1)) 
  482. 			cell_cheats_mouse_update() 
  483. 		end 
  484. 	end 
  485. end 
  486.  
  487. function cell_cheats_text_update(di_h, event_name) 
  488. 	local override, cheat_text = vint_dataitem_get(di_h) 
  489. 	 
  490. 	Cheat_being_entered = override; 
  491. 	 
  492. 	if override == true then 
  493. 		Add_cheat_button.label = cheat_text 
  494. 	else 
  495. 		Add_cheat_button.label = "ADD_CHEAT" 
  496. 	end 
  497. 	 
  498. 	Cheats_list:draw_items(Category_menu, 1, CHEATS_LIST_WIDTH, CHEATS_LIST_NUM_OPTIONS, LIST_FONT_SCALE, true, true) 
  499. end 
  500.