./store_character.lua

  1. STORE_CHARACTER_MALE_GENDER_NAME 				=	"male" 
  2. STORE_CHARACTER_FEMALE_GENDER_NAME				=	"female" 
  3.  
  4. STORE_CHARACTER_DEFAULT_MALE_FIGURE				=	"athletic" 
  5. STORE_CHARACTER_DEFAULT_FEMALE_FIGURE			=	"athletic" 
  6.  
  7. STORE_CHARACTER_CHEEK_MAKEUP_INDEX		 		= 1 
  8. STORE_CHARACTER__ENTIRE_FACE_MAKEUP_INDEX	 	= 3 
  9.  
  10. local Store_newsticker = -1 
  11.  
  12. local COLOR_GOLD = {R=220/255, G=220/255, B=220/255} 
  13.  
  14. local INVALID_STATE						= 0 
  15. local LINEUP_STATE						= 1 
  16. local GALLERY_DOWNLOAD_STATE			= 2 
  17. local CUSTOMIZATION_STATE				= 3 
  18. local GALLERY_FULL_STATE				= 4 
  19. local FINISHED_STATE						= 5 
  20.  
  21. Store_character_current_state = INVALID_STATE 
  22. Store_character_new_state_on_validation = INVALID_STATE 
  23.  
  24. local Online_check_thread = -1 
  25.  
  26. -- Menu Tiers 
  27. local MENU_TIER 			= 1 
  28. local BUILD_TIER 			= 2 
  29. local SKIN_COLOR_TIER	= 3 
  30. local EYE_COLOR_TIER		= 4 
  31. local HAIR_COLOR_TIER	= 5 
  32. local MAKEUP_COLOR_TIER	= 6 
  33. local LINEUP_TIER			= 7 
  34. local Current_tier 		= MENU_TIER 
  35.  
  36. Store_character_doc_handle = -1 
  37.  
  38. -- Used to determine which of three colors player is currently picking, and the index in the color grid is currently chosen. 
  39. local Color_grid_idx			= 1 
  40. local Color_slot_chosen		= 0 
  41.  
  42. Color_grid_data		= {} 
  43.  
  44. local Prev_index = -1 
  45.  
  46. local Original_pitch = 0 
  47.  
  48. local Input_tracker_body_morph_select = nil 
  49. Hint_bar_mouse_input_tracker = -1 
  50. local Triangle_select_button_handle = -1 
  51. local Triangle_select_text_handle = -1 
  52.  
  53. local Susan_mouse_area_img_h 
  54.  
  55. Store_character_in_anim = -1 
  56. Store_character_out_anim = -1 
  57. Player_creation_bg_anim = -1 
  58. Iad_logo_anim = -1 
  59. Iad_bg_anim = -1 
  60.  
  61. -- Hint bar and store header vdo's. 
  62. local Not_popup_grp = -1 
  63. local Reward_image = -1 
  64. local Triangle_select = -1 
  65.  
  66. Lineup_input_tracker = -1 
  67. Lineup_mouse_input_tracker = -1 
  68.  
  69. Store_character_current_preset_gender = -1 
  70. Store_character_current_preset_race	  = -1 
  71. Store_character_current_preset_figure = -1 
  72.  
  73. --Store_character_rand_func 
  74. Store_character_randomizing_morph_set = -1 
  75.  
  76. Store_character_building_morph_set = -1 
  77.  
  78. -- Save current preset settings in case they are needed for a revert. 
  79. Store_character_preset_previous_settings = -1 
  80.  
  81. Store_character_confirm_randomize = true 
  82.  
  83. MAX_FACIAL_FEATURES = 10 
  84.  
  85. -- variable to help control when player customization is actually ready 
  86. Store_lineup_is_loaded = true 
  87.  
  88. -- Compositing data 
  89. -------------------------------------------- 
  90.  
  91. Store_character_composite_slots = { 
  92. 	["facial hair"] 			= {}, 
  93. 	["eyebrows"] 				= {}, 
  94. 	["body mask"]				= {}, 
  95. 	["makeup eyeliner"]		= {}, 
  96. 	["makeup eyeshadow"]		= {}, 
  97. 	["makeup cheeks"]			= {}, 
  98. 	["lips"]						= {}, 
  99. 	["makeup entire face"]	= {},	 
  100. 	["face items"]				= {},	 
  101. 	["face features"]			= {},		 
  102. 	["fingernails"]			= {},			 
  103. } 
  104.  
  105. -- Composite actions; enum must match C code 
  106.  
  107. COMPOSITE_REPLACE = 0 
  108. COMPOSITE_ADD		= 1 
  109. COMPOSITE_REMOVE	= 2 
  110.  
  111. Store_character_current_composite_area = -1 
  112. Store_character_current_composite_item = -1 
  113. Store_character_current_composite_color = -1 
  114. Store_character_current_composite_alpha = -1 
  115. Store_character_allow_multiple_composites = -1 
  116. Store_character_composites_allowed = -1 
  117. Store_character_composites_used = -1 
  118.  
  119. -------------------------------------------- 
  120.  
  121. CHARACTER_COLOR_POOL_TYPE = 0 
  122.  
  123. HAIR_ITEM_SLOT = 1 
  124.  
  125. Store_character_hair_acc_info = { 
  126. 	colors = { [0] = { }, [1] = { }, [2] = { } } 
  127. } 
  128.  
  129. -- Save off current clothing color index if player cancels change 
  130. local Color_prev_color		= 0 
  131.  
  132. Store_character_hair_values = {} 
  133.  
  134. -- Stores skin color selection when the player started, in case they preview new choices but revert. 
  135. Store_character_skin_color_current_setting = -1 
  136.  
  137. Store_character_skin_color_selected = 0 
  138. Store_character_eye_selected = 0 
  139.  
  140. Store_character_movement_anim_grp = -1 
  141.  
  142. -- Save eye color for reverting 
  143. Store_character_orig_eye_color = -1 
  144.  
  145. -- Save off morph values in case player reverts changes 
  146. Store_character_strength = -1 
  147. Store_character_skinny = -1 
  148. Store_character_fat = -1 
  149.  
  150. Store_character_build_cursor_x = -1 
  151. Store_character_build_cursor_y = -1 
  152.  
  153. Store_character_nav_thread = -1 
  154. local Store_character_nav_value = nil 
  155.  
  156. Store_character_preset_update_thread 	= -1 
  157. local Store_character_preset_update_data		= nil 
  158.  
  159. Store_character_preset_new_gender = -1 
  160.  
  161. Store_character_init_camera_moved = false 
  162.  
  163. Store_character_anim_done = true 
  164.  
  165. Store_character_original_anim_id = -1 
  166.  
  167. -- Do we need to display a popup to confirm if the player should cancel? 
  168. Store_character_cancel_confirm_needed = false 
  169.  
  170. -- Save off preset info while waiting for a confirmation of setting it. 
  171. Store_character_tentative_preset_data = -1 
  172.  
  173. local Game_platform = -1 
  174.  
  175. -- Global referencse to the "lazy susan" vdo for the character lineup.  Needed for VDO callbacks. 
  176. Susan_object = -1 
  177.  
  178. -- Number of images in the character lineup 
  179. STORE_CHARACTER_NUM_LINEUP_IMAGES        = 9 
  180. STORE_CHARACTER_NUM_LINEUP_IMAGES_LOADED = 5 
  181.  
  182. -- Table of character lineup preset settings 
  183. Store_character_lineup_presets = { 
  184. 	{ gender = "male",     race = "white",      figure = "athletic" }, 
  185. 	{ gender = "female",   race = "white",      figure = "athletic" }, 
  186. 	{ gender = "male",     race = "black",      figure = "athletic" }, 
  187. 	{ gender = "female",   race = "black",      figure = "athletic" }, 
  188. 	{ gender = "male",     race = "hispanic",   figure = "athletic" }, 
  189. 	{ gender = "female",   race = "hispanic",   figure = "athletic" }, 
  190. 	{ gender = "male",     race = "asian",      figure = "athletic" }, 
  191. 	{ gender = "female",   race = "asian",      figure = "athletic" }, 
  192. } 
  193.  
  194. -- Flag to indicate if we've finished loading/animating in the character lineup. 
  195. Store_character_lineup_init_complete = false 
  196.  
  197. local Store_character_clothing_load_thread = -1 
  198. local Store_character_clothes_on_current = true 
  199. local Store_character_clothes_on_pending = true 
  200.  
  201.  
  202. function store_character_fail_msg(event) 
  203. 	Store_common_popup:nav_enable(false, nil, nil) 
  204. 	game_UI_audio_play("UI_Main_Menu_Select") 
  205. 	Not_popup_grp:set_alpha(1) 
  206. 	Active_list:set_visible(true) 
  207. 	store_character_enable_mouse(true) 
  208. end 
  209.  
  210. -- Player creation utility functions 
  211. -------------------------------------------- 
  212.  
  213. function store_character_change_clothes() 
  214. 	while true do 
  215. 		delay(0.1) 
  216. 		if pcu_is_streaming_done() then 
  217. 			-- Must wait at least a frame for handshake after streaming is done 
  218. 			delay(0.2) 
  219. 			if Store_character_clothes_on_current ~= Store_character_clothes_on_pending then 
  220. 				if Store_character_clothes_on_pending then 
  221. 					pcr_restore_clothing() 
  222. 				else 
  223. 					pcr_strip_clothing() 
  224. 				end 
  225. 				 
  226. 				Store_character_clothes_on_current = Store_character_clothes_on_pending 
  227. 			end 
  228. 			 
  229. 			thread_kill(Store_character_clothing_load_thread) 
  230. 			Store_character_clothing_load_thread = -1 
  231. 			break 
  232. 		end 
  233. 	end 
  234. end 
  235.  
  236. -- This function is used to strip the clothes off the player when they enter submenus from the character creation screen. 
  237. -- 
  238. function store_character_creation_strip_clothes() 
  239. 	if pcr_is_plastic_surgeon() == false then 
  240. 		if Store_character_clothing_load_thread == -1 then 
  241. 			Store_character_clothing_load_thread = thread_new("store_character_change_clothes") 
  242. 		end 
  243. 		Store_character_clothes_on_pending = false 
  244. 	end 
  245. end 
  246.  
  247. -- This function is used to return the clothes on the player when they enter the top menu of the character creation screen. 
  248. -- 
  249. function store_character_creation_add_clothes() 
  250. 	if pcr_is_plastic_surgeon() == false then 
  251. 		if Store_character_clothing_load_thread == -1 then 
  252. 			Store_character_clothing_load_thread = thread_new("store_character_change_clothes") 
  253. 		end 
  254. 		Store_character_clothes_on_pending = true 
  255. 	end 
  256. end 
  257.  
  258. -- Compositing functions --- Possibly move to store_common so tatoos can use them???? 
  259. -------------------------------------------- 
  260.  
  261. -- Save current info on one composite slot 
  262. -- 
  263. function store_character_composite_save_info(slot_name) 
  264.  
  265. 	slot_name = slot_name or Store_character_current_composite_area 
  266.  
  267. 	local index, color, alpha = pcr_get_composite_info(slot_name) 
  268. 	Store_character_composite_slots[slot_name].index = index 
  269. 	Store_character_composite_slots[slot_name].color = color 
  270. 	Store_character_composite_slots[slot_name].alpha = alpha 
  271. end 
  272.  
  273. -- Restore to saved info on one composite slot 
  274. -- 
  275. function store_character_composite_restore_info(slot_name) 
  276.  
  277. 	-- kill update thread if it's still around 
  278. 	if Store_character_nav_thread ~= -1 then 
  279. 		thread_kill(Store_character_nav_thread) 
  280. 		Store_character_nav_thread = -1 
  281. 	end 
  282.  
  283. 	slot_name = slot_name or Store_character_current_composite_area 
  284.  
  285. 	local values = Store_character_composite_slots[slot_name] 
  286. 	pcr_change_composite(slot_name, values.index, values.color, values.alpha) 
  287. end 
  288.  
  289. -- Build a menu based on compositing choices 
  290. -- 
  291. function store_character_composite_menu_build(menu_data) 
  292.  
  293. 	Store_character_current_composite_area = menu_data.composite_area 
  294. 	 
  295. 	-- save off current settings 
  296. 	store_character_composite_save_info() 
  297. 	 
  298. 	if( menu_data.label ~= "CUST_FACIAL_FEATURES" )then -- This facial change has no color associations, skiping it to save memory -Mike Rossi 4/9/2013 
  299. 		-- Get the colors for the palette. 
  300. 		-- We need to do this now, because we need to find and save off the current composite the player has in case they revert. 
  301. 		table_clear(Color_grid_data, true) 
  302. 		vint_force_lua_gc() 
  303. 		Color_grid_idx = 1 
  304. 		pcr_report_composite_colors(Store_character_current_composite_area, true, "store_character_composite_add_color") 
  305. 	end 
  306. 	 
  307. 	-- Initialize the current settings 
  308. 	local values = Store_character_composite_slots[Store_character_current_composite_area] 
  309. 	Store_character_current_composite_item = values.index 
  310. 	Store_character_current_composite_color = values.color 
  311. 	Store_character_current_composite_alpha = values.alpha 
  312. 	 
  313. 	if menu_data.max_selections ~= nil and menu_data.max_selections > 1 then 
  314. 		Store_character_allow_multiple_composites = true 
  315. 		Store_character_composites_used = 0 
  316. 		Store_character_composites_allowed = menu_data.max_selections 
  317. 	else 
  318. 		Store_character_allow_multiple_composites = false	 
  319. 	end 
  320. 		 
  321. 	-- Special case: body mask or menus with multiple selections don't have a "none" choice 
  322. 	if menu_data.composite_area ~= "body mask" and Store_character_allow_multiple_composites == false then 
  323. 		local item = { 
  324. 			label = "CUST_ITEM_NOTHING", type = TYPE_BUTTON, composite_item = -1, on_nav = store_character_composite_item_nav, 
  325. 			on_select = store_character_composite_item_set, on_cancel = store_character_composite_item_revert 
  326. 		}	 
  327. 	 
  328. 		local menu_idx = #Store_common_sub_menu + 1 
  329. 		Store_common_sub_menu[menu_idx] = item 
  330. 	end 
  331. 	 
  332. 	pcr_report_composite_items(Store_character_current_composite_area, "store_character_composite_item_add") 
  333. end 
  334.  
  335. function store_character_composite_color_grid_show(menu_data) 
  336. 	Active_list:set_visible(false) 
  337. 	 
  338. 	Current_tier = MAKEUP_COLOR_TIER 
  339. 	store_character_enable_mouse(false, false) 
  340. 	 
  341. 	-- display the grid 
  342. 	--input_data, current_option, max_width, max_height, button_w, button_h, hint_button_offset, current_category, outline_scale, background_enabled, show_current_button, grid_padding, set_size 
  343. 	Store_common_color_grid:draw_items(Color_grid_data, Color_grid_idx, 5, 5, 53.5, 53.5, 15, nil, 1.1, true, true, -7, true) 
  344. 	Store_common_color_grid:set_visible(true) 
  345. 	Store_common_color_grid:nav_enable(true, "store_character_composite_color_select", "store_character_composite_color_grid_nav")	 
  346. 	Color_grid_data.alpha_select = menu_data.alpha_select 
  347. end 
  348.  
  349. function store_character_composite_color_grid_nav(event, value) 
  350. 	vint_force_lua_gc() --Force Garbage Collection 
  351. 	store_character_grid_nav(event, value) 
  352. 	 
  353. 	-- set the color and preview the item 
  354. 	local idx = Store_common_color_grid:return_selected_index() 
  355. 	if(Color_grid_data[0] ~= nil)then 
  356. 		Store_character_current_composite_color = Color_grid_data[idx-1].index 
  357. 	else 
  358. 		Store_character_current_composite_color = Color_grid_data[idx].index 
  359. 	end 
  360. 	 
  361. 	if Store_character_nav_thread ~= -1 then 
  362. 		thread_kill(Store_character_nav_thread) 
  363. 		Store_character_nav_thread = -1 
  364. 	end 
  365. 	 
  366. 	Store_character_nav_thread = thread_new("store_character_composite_item_delayed_set")	 
  367. end 
  368.  
  369. function store_character_composite_add_color(color_index, label_crc, label_str, red, green, blue, max_colors, is_current, end_of_family) 
  370. 	 
  371. 	local grid_idx = color_index  
  372. 	 
  373. 	Color_grid_data[grid_idx] = { 
  374. 		icon = "ui_menu_veh_pnt_base", 
  375. 		label = "", 
  376. 		label_crc = "", 
  377. 		color = {red = red, green = green, blue = blue}, 
  378. 		index = color_index, 
  379. 		end_of_family = end_of_family 
  380. 	} 
  381. 	 
  382. 	if is_current == true then 
  383. 		Color_grid_idx = grid_idx 
  384. 		Store_character_current_composite_color = Color_grid_data[grid_idx].index 
  385. 	end 
  386. end 
  387.  
  388. function store_character_composite_alpha_done() 
  389. 	game_UI_audio_play("UI_Main_Menu_Select") 
  390. 	store_character_composite_save_info() 
  391. 	store_common_back_menu() 
  392. 	store_common_back_menu()	 
  393. end 
  394.  
  395. function store_character_composite_alpha_revert() 
  396. 	game_UI_audio_play("UI_Main_Menu_Nav_Back") 
  397. end 
  398.  
  399. function store_character_composite_alpha_change(menu_data) 
  400. 	Store_character_current_composite_alpha = menu_data.current_value 
  401. 	store_character_composite_update() 
  402. end 
  403.  
  404. function store_character_composite_show_alpha_menu() 
  405. 	Active_list:set_visible(true) 
  406. 	 
  407. 	-- Get data to populate the megalist 
  408. 	local New_menu_data = { 
  409. 		{ label = "CUST_OPACITY_SLIDER", type = TYPE_SLIDER, on_select = store_character_composite_alpha_done, on_cancel =  store_character_composite_alpha_revert,  
  410. 		  on_value_update = store_character_composite_alpha_change, min = 0, max = 1, step = 0.05, current_value = Store_character_current_composite_alpha },	 
  411. 	} 
  412. 	 
  413. 	store_common_push_menu(New_menu_data) 
  414. end 
  415.  
  416. function store_character_composite_color_select(event) 
  417.  
  418. 	Store_common_color_grid:nav_enable(false, nil, nil) 
  419. 	Store_common_color_grid:cleanup() 
  420. 	Store_common_color_grid:set_visible(false) 
  421. 	Active_list:set_visible(true) 
  422. 	 
  423. 	Current_tier = MENU_TIER 
  424. 	store_character_enable_mouse(true, false) 
  425.  
  426. 	-- Did the player select a color? 
  427. 	if event == "select" or event == "mouse_click" then 
  428. 		game_UI_audio_play("UI_Main_Menu_Select") 
  429. 		if Color_grid_data.alpha_select then 
  430. 			store_character_composite_show_alpha_menu() 
  431. 		else 
  432. 			store_character_composite_save_info() 
  433. 			store_common_back_menu() 
  434. 			table_clear(Color_grid_data, true) 
  435. 		end 
  436. 	else 
  437. 		game_UI_audio_play("UI_Main_Menu_Nav_Back") 
  438. 	end 
  439. end 
  440.  
  441. function store_character_composite_item_set(menu_data) 
  442.  
  443. 	-- Toggle selection if multiple selections allowed 
  444. 	if Store_character_allow_multiple_composites then 
  445. 		Store_character_current_composite_item = menu_data.composite_item		 
  446. 		if menu_data.equipped then 
  447. 			store_character_composite_update(COMPOSITE_REMOVE) 
  448. 		else	 
  449. 			-- Have we hit the maximum number? 
  450. 			if Store_character_composites_used >= Store_character_composites_allowed then 
  451. 				Store_common_popup:populate_list(Ok_choice, 1, STORE_COMMON_LIST_SIZE, 1) 
  452. 				Store_common_popup:set_title("MENU_TITLE_NOTICE") 
  453. 				Store_common_popup:set_text("CUST_MAX_COMPOSITE_WARNING")		 
  454. 				Store_common_popup:nav_enable(true, "store_character_fail_msg", "store_character_popup_nav") 
  455. 				Not_popup_grp:set_alpha(.5)	 
  456. 				Active_list:set_visible(false) 
  457. 				store_character_enable_mouse(false) 
  458. 				return			 
  459. 			else 
  460. 				store_character_composite_update(COMPOSITE_ADD) 
  461. 			end 
  462. 		end 
  463. 		 
  464. 		-- refresh the menu 
  465. 		local index = Active_list:get_selection() 
  466. 		Store_character_composites_used = 0 
  467. 		Store_common_sub_menu = {} 
  468. 		pcr_report_composite_items(Store_character_current_composite_area, "store_character_composite_item_add")		 
  469. 		Menu_data = Store_common_sub_menu 
  470. 		Store_common_sub_menu = {} 
  471. 		 
  472. 		--Rather than reupdate the list we will only reupdate a single item (JMH 9/20/2011) 
  473. 		--store_character_populate_list(Menu_data, index) 
  474. 		Active_list.data = Menu_data 
  475. 		Active_list:refresh_single_item(index) 
  476. 		if Mouse_input_tracker ~= 0 then 
  477. 			Mouse_input_tracker:remove_all() 
  478. 			Active_list:add_mouse_inputs("store_common", Mouse_input_tracker) 
  479. 			Mouse_input_tracker:subscribe(true) 
  480. 		end 
  481. 		 
  482. 		return 
  483. 	end 
  484.  
  485. 	Store_character_current_composite_item = menu_data.composite_item 
  486. 	 
  487. 	if menu_data.composite_item ~= -1 then 
  488. 		-- only some things do we choose color for 
  489. 		if menu_data.colorized then 
  490. 			store_character_composite_color_grid_show(menu_data) 
  491. 		else 
  492. 			if menu_data.alpha_select then 
  493. 				store_character_composite_show_alpha_menu() 
  494. 			else 
  495. 				store_character_composite_save_info() 
  496. 				store_common_back_menu() 
  497. 			end 
  498. 		end 
  499. 	else 
  500. 		store_common_back_menu() 
  501. 	end 
  502. end 
  503.  
  504. -- Player reverted and didn't make a composite change.  Revert previewed composite back to what it was. 
  505. -- 
  506. function store_character_composite_item_revert() 
  507.  
  508. 	-- Don't revert for multiple selections allowed 
  509. 	if Store_character_allow_multiple_composites then 
  510. 		return 
  511. 	end 
  512.  
  513. 	store_character_composite_restore_info() 
  514. end 
  515.  
  516. function store_character_composite_update(optional_action) 
  517.  
  518. 	optional_action = optional_action or COMPOSITE_REPLACE 
  519.  
  520. 	pcr_change_composite(Store_character_current_composite_area, Store_character_current_composite_item, Store_character_current_composite_color, Store_character_current_composite_alpha, optional_action) 
  521.  
  522. 	Store_character_confirm_randomize = true 
  523. end 
  524.  
  525. function store_character_composite_item_delayed_set() 
  526. 	delay(0.4) 
  527. 	store_character_composite_update() 
  528. 	Store_character_nav_thread = -1 
  529. end 
  530.  
  531. function store_character_composite_item_nav(menu_data) 
  532.  
  533. 	-- Don't preview for multiple selections allowed 
  534. 	if Store_character_allow_multiple_composites then 
  535. 		return 
  536. 	end 
  537.  
  538. 	if Store_character_nav_thread ~= -1 then 
  539. 		thread_kill(Store_character_nav_thread) 
  540. 		Store_character_nav_thread = -1 
  541. 	end 
  542. 	 
  543. 	Store_character_current_composite_item = menu_data.composite_item 
  544. 	 
  545. 	-- reset alpha to 1 
  546. 	Store_character_current_composite_alpha = 1 
  547. 	Store_character_nav_thread = thread_new("store_character_composite_item_delayed_set") 
  548. end 
  549.  
  550. function store_character_composite_item_add(composite_index, name_crc, name_str, current, colorized, alpha_select, unused_price, unused_respect) 
  551. 	local item = { 
  552. 		type = TYPE_BUTTON, composite_item = composite_index, label = name_str, label_crc = name_crc, on_nav = store_character_composite_item_nav,  
  553. 		on_select = store_character_composite_item_set, on_cancel = store_character_composite_item_revert, colorized = colorized, alpha_select = alpha_select, 
  554. 	} 
  555.  
  556. 	if Store_character_allow_multiple_composites then 
  557. 		item.equipped = current	 
  558. 		if current then 
  559. 			Store_character_composites_used = Store_character_composites_used + 1 
  560. 		end 
  561. 	end 
  562. 	 
  563. 	local menu_idx = #Store_common_sub_menu + 1 
  564. 	 
  565. 	if current == true then 
  566. 		Store_common_sub_menu.start_index = menu_idx 
  567. 	end 
  568.  
  569. 	Store_common_sub_menu[menu_idx] = item 
  570. end 
  571.  
  572.  
  573.  
  574. -- Preset menus 
  575. -------------------------------------------- 
  576.  
  577. function store_character_preset_enter_main(menu_data) 
  578.  
  579. 	-- Get initial preset values 
  580. 	Store_character_current_preset_gender, Store_character_current_preset_race, Store_character_current_preset_figure = pcr_get_player_preset() 
  581.  
  582. 	if Store_character_preset_update_thread == -1 then 
  583. 		Store_character_preset_update_thread = thread_new("store_character_preset_update_thread") 
  584. 	end 
  585. end 
  586.  
  587. function store_character_preset_cleanup(menu_data) 
  588.  
  589. 	Store_character_preset_update_data = nil 
  590. 	 
  591. 	if Store_character_preset_update_thread ~= -1 then 
  592. 		thread_kill(Store_character_preset_update_thread) 
  593. 		Store_character_preset_update_thread = -1 
  594. 	end 
  595.  
  596. end 
  597.  
  598. function store_character_preset_update_thread() 
  599. 	while true do 
  600.  
  601. 		delay(0.5) 
  602. 		 
  603. 		local update_data = Store_character_preset_update_data 
  604. 		 
  605. 		Store_character_preset_update_data = nil 
  606. 		 
  607. 		if update_data ~= nil then 
  608. 			store_character_apply_preset(update_data) 
  609. 		end 
  610. 		 
  611. 		if Store_character_preset_update_thread == -1 then 
  612. 			break 
  613. 		end 
  614. 	end 
  615. end 
  616.  
  617. -- Player chose a preset - update the character 
  618. -- 
  619. function store_character_preset_nav(menu_data) 
  620. 	Store_character_preset_update_data = menu_data 
  621. end 
  622.  
  623. function store_character_apply_preset(menu_data) 
  624. 	local update_preset = false 
  625. 	local update_regional_preset = false 
  626. 	 
  627. 	-- Age preset updating is handled differently.  So check if this is an age update, and 
  628. 	-- if so, just do that and return. 
  629. 	-- 
  630. 	if menu_data.preset_age ~= nil then 
  631. 		pcr_apply_morph_value("global body", "old", menu_data.preset_age) 
  632. 		pcr_mark_changed() 
  633. 		return 
  634. 	end 
  635. 	 
  636. 	if menu_data.preset_gender ~= nil and menu_data.preset_gender ~= Store_character_current_preset_gender then 
  637. 	 
  638. 		Store_character_preset_new_gender = menu_data.preset_gender 
  639. 	 
  640. 		Store_character_current_preset_gender = menu_data.preset_gender 
  641. 		update_preset = true 
  642. 		if Store_character_current_preset_gender == STORE_CHARACTER_FEMALE_GENDER_NAME then 
  643. 			Store_character_current_preset_figure = STORE_CHARACTER_DEFAULT_FEMALE_FIGURE 
  644. 		else 
  645. 			Store_character_current_preset_figure = STORE_CHARACTER_DEFAULT_MALE_FIGURE 
  646. 		end 
  647. 	end 
  648. 	 
  649. 	if menu_data.preset_race ~= nil and menu_data.preset_race ~= Store_character_current_preset_race then 
  650. 		Store_character_current_preset_race = menu_data.preset_race 
  651. 		update_preset = true 
  652. 	end 
  653. 	 
  654. 	if menu_data.preset_figure ~= nil and menu_data.preset_figure ~= Store_character_current_preset_figure then 
  655. 		Store_character_current_preset_figure = menu_data.preset_figure 
  656. 		update_regional_preset = true; 
  657. 	end 
  658. 		 
  659. 	if update_preset == true then 
  660. 		local preset_name = Store_character_current_preset_gender .. "_" .. Store_character_current_preset_race 
  661. 		local regional_preset_name = Store_character_current_preset_gender .. "_" .. Store_character_current_preset_figure; 
  662. 		pcr_apply_preset(preset_name, "figure", regional_preset_name, true) 
  663. 		pcr_set_triangle_cursor_pos(-1, -1) 
  664. 		pcr_mark_changed() 
  665. 		Store_character_confirm_randomize = true 
  666. 	else 
  667. 		if update_regional_preset == true then 
  668. 			pcr_apply_regional_preset("figure", Store_character_current_preset_gender .. "_" .. Store_character_current_preset_figure) 
  669. 			pcr_set_triangle_cursor_pos(-1, -1)			 
  670. 			pcr_mark_changed() 
  671. 			Store_character_confirm_randomize = true 
  672. 		end 
  673. 	end 
  674. end 
  675.  
  676. -- Player selected a preset with the "select" button.  We need to confirm if they really want to do this first. 
  677. -- 
  678. function store_character_select_preset(menu_data) 
  679.  
  680. 	store_character_enable_mouse(false) 
  681.  
  682. 	Store_common_popup:populate_list(Yes_no_choices, 2, STORE_COMMON_LIST_SIZE, 2)	 
  683. 	Store_common_popup:set_title("MENU_TITLE_WARNING") 
  684. 	Store_common_popup:set_text("PRESET_WARNING_BODY")		 
  685. 	Store_common_popup:nav_enable(true, "store_character_select_preset_final", "store_character_popup_nav") 
  686. 	Not_popup_grp:set_alpha(.5) 
  687. 	Active_list:set_visible(false)	 
  688. 	 
  689. 	Store_character_tentative_preset_data = menu_data 
  690. 	 
  691. 	return true 
  692. end 
  693.  
  694. function store_character_select_preset_final(event) 
  695. 	Store_common_popup:nav_enable(false, nil, nil) 
  696. 	Not_popup_grp:set_alpha(1) 
  697. 	Active_list:set_visible(true) 
  698. 	 
  699. 	-- The user hit the B button and cancelled the change 
  700. 	-- This is redundant to selecting "No" in the list 
  701. 	if event == "back" then 
  702. 		game_UI_audio_play("UI_Main_Menu_Nav_Back") 
  703. 		store_character_enable_mouse(true) 
  704. 		return 
  705. 	end 
  706. 	 
  707. 	game_UI_audio_play("UI_Main_Menu_Select")	 
  708. 	 
  709. 	-- Did we select yes?  This assumes yes is the first item 
  710. 	if Store_common_popup:get_selected_data() ~= 1 then 
  711. 		store_character_enable_mouse(true) 
  712. 		return 
  713. 	end 
  714.  
  715. 	-- Change to the preset 
  716. 	store_character_apply_preset(Store_character_tentative_preset_data) 
  717. 	store_common_back_menu() 
  718. end 
  719.  
  720. -- Player cancelled a preset with the "back" button. 
  721. -- 
  722. function store_character_revert_preset(menu_data) 
  723. 	-- Pass in an previous saved setting to do a revert. 
  724. 	Store_character_preset_update_data = nil 
  725. 	 
  726. 	-- do a revert if we had previous settings 
  727. 	if Store_character_preset_previous_settings ~= nil then 
  728. 		store_character_apply_preset(Store_character_preset_previous_settings) 
  729. 	end 
  730. end 
  731.  
  732. -- Save the current figure setting in case we need to revert. 
  733. -- 
  734. function store_character_preset_save_figure(menu_data) 
  735. 	Store_character_current_preset_gender, Store_character_current_preset_race, Store_character_current_preset_figure = pcr_get_player_preset() 
  736. 	local data = { preset_figure = Store_character_current_preset_figure } 
  737. 	Store_character_preset_previous_settings = data 
  738. end 
  739.  
  740. -- Save the current race setting in case we need to revert. 
  741. -- 
  742. function store_character_preset_save_race(menu_data) 
  743. 	Store_character_current_preset_gender, Store_character_current_preset_race, Store_character_current_preset_figure = pcr_get_player_preset() 
  744. 	local data = { preset_race = Store_character_current_preset_race } 
  745. 	Store_character_preset_previous_settings = data 
  746. end 
  747.  
  748. -- Save the current age setting in case we need to revert. 
  749. -- 
  750. function store_character_preset_save_age(menu_data) 
  751. 	local data = { preset_age = pcr_get_morph_value("Global Body", "old") } 
  752. 	Store_character_preset_previous_settings = data 
  753. end 
  754.  
  755. function store_character_preset_sex_fill(menu_data) 
  756.  
  757. 	local store_character_presets_sex = { 
  758. 		{ label = "PLAYER_CREATION_PRESET_MALE", name = "male", type = TYPE_BUTTON, on_select = store_character_select_preset, on_cancel = store_character_revert_preset, preset_gender = "male" }, 
  759. 		{ label = "PLAYER_CREATION_PRESET_FEMALE", name = "female", type = TYPE_BUTTON, on_select = store_character_select_preset, on_cancel = store_character_revert_preset, preset_gender = "female" }, 
  760. 	} 
  761.  
  762. 	store_character_preset_save_race(menu_data) 
  763. 	Store_common_sub_menu = store_character_presets_sex 
  764. 	for i = 1, #Store_common_sub_menu do 
  765. 		if Store_common_sub_menu[i].name == Store_character_current_preset_gender then 
  766. 			Store_common_sub_menu.start_index = i 
  767. 		end 
  768. 	end 
  769. end 
  770.  
  771.  
  772. function store_character_preset_race_fill(menu_data) 
  773.  
  774. 	local store_character_presets_race = {	 
  775. 		{ label = "RACE_AFRICAN", name = "black", type = TYPE_BUTTON, on_select = store_character_select_preset, on_cancel = store_character_revert_preset, on_nav = store_character_preset_nav, preset_race = "black" }, 
  776. 		{ label = "RACE_ASIAN", name = "asian", type = TYPE_BUTTON, on_select = store_character_select_preset, on_cancel = store_character_revert_preset, on_nav = store_character_preset_nav, preset_race = "asian" }, 
  777. 		{ label = "RACE_CAUCASIAN", name = "white", type = TYPE_BUTTON, on_select = store_character_select_preset, on_cancel = store_character_revert_preset, on_nav = store_character_preset_nav, preset_race = "white" }, 
  778. 		{ label = "RACE_HISPANIC", name = "hispanic", type = TYPE_BUTTON, on_select = store_character_select_preset, on_cancel = store_character_revert_preset, on_nav = store_character_preset_nav, preset_race = "hispanic" }, 
  779. 	} 
  780.  
  781. 	store_character_preset_save_race(menu_data) 
  782. 	Store_common_sub_menu = store_character_presets_race 
  783. 	for i = 1, #Store_common_sub_menu do 
  784. 		if Store_common_sub_menu[i].name == Store_character_current_preset_race then 
  785. 			Store_common_sub_menu.start_index = i 
  786. 		end 
  787. 	end 
  788. end 
  789.  
  790. -- Body menus 
  791. -------------------------------------------- 
  792.  
  793. -- Input constants 
  794. RAW_INPUT_DEAD_ZONE				= 0.1 
  795. LEFT_STICK_PIXELS_PER_FRAME	= 4 
  796.  
  797. Left_stick_current_input_x 	= 0 
  798. Left_stick_current_input_y 	= 0 
  799. Left_stick_input_thread 				= -1 
  800.  
  801. Mouse_x = -1 
  802. Mouse_y = -1 
  803.  
  804. -- Helper function to adjust the raw input based on dead zone and pixel speed 
  805. local function input_from_stick_value_and_speed(value, speed) 
  806. 	if value > RAW_INPUT_DEAD_ZONE then 
  807. 		return (value - RAW_INPUT_DEAD_ZONE) / (1 - RAW_INPUT_DEAD_ZONE) * LEFT_STICK_PIXELS_PER_FRAME 
  808. 	elseif value < -RAW_INPUT_DEAD_ZONE then 
  809. 		return (value + RAW_INPUT_DEAD_ZONE) / (1 - RAW_INPUT_DEAD_ZONE) * LEFT_STICK_PIXELS_PER_FRAME 
  810. 	else 
  811. 		return 0 
  812. 	end 
  813. end 
  814.  
  815. function store_character_move_left_x(event, value) 
  816. 	Left_stick_current_input_x = input_from_stick_value_and_speed(value, LEFT_STICK_PIXELS_PER_FRAME) 
  817. end 
  818.  
  819. function store_character_move_left_y(event, value) 
  820. 	Left_stick_current_input_y = input_from_stick_value_and_speed(value, LEFT_STICK_PIXELS_PER_FRAME) 
  821. end 
  822.  
  823. function store_character_move_left_stick_thread() 
  824. 	local loop_count = 0 
  825. 	local update_needed = false 
  826. 	local new_str, new_skin, new_fat, new_x, new_y 
  827. 	 
  828. 	while true do 
  829. 		if Left_stick_current_input_x ~= 0 or Left_stick_current_input_y ~= 0 then 
  830. 			if Store_common_popup:get_property("visible") ~= true then 
  831. 				local str, skin, fat, x, y = Triangle_select:move_left_stick(Left_stick_current_input_x, Left_stick_current_input_y)	 
  832. 				if str ~= nil then 
  833. 					new_str = str 
  834. 					new_skin = skin 
  835. 					new_fat = fat 
  836. 					new_x = x 
  837. 					new_y = y 
  838. 					update_needed = true 
  839. 				end 
  840. 			end 
  841. 		elseif Mouse_x ~= -1 and Mouse_y ~= -1 then 
  842. 			local str, skin, fat, x, y = Triangle_select:update_mouse(Mouse_x, Mouse_y) 
  843. 			if str ~= nil then 
  844. 				new_str = str 
  845. 				new_skin = skin 
  846. 				new_fat = fat 
  847. 				new_x = x 
  848. 				new_y = y				 
  849. 				update_needed = true 
  850. 			end 
  851. 			 
  852. 			-- Reset mouse values for the mouse event handlers to set in next frame 
  853. 			Mouse_x = -1 
  854. 			Mouse_y = -1 
  855. 		end 
  856. 		 
  857. 		--debug_print("vint", "Thread Running... \n") 
  858. 		delay(1/20) -- Peg to 20 frames/sec 
  859. 		 
  860. 		-- only update the character's body at most every X times through this loop 
  861. 		if loop_count > 0 then 
  862. 			loop_count = 0 
  863. 			if update_needed then 
  864. 				-- actually morph the character 
  865. 				--game_UI_audio_play("UI_Customization_Triangle")				 
  866. 				pcr_apply_morph_value("Global Body", "body muscle", new_str) 
  867. 				pcr_apply_morph_value("Global Body", "body skinny", new_skin) 
  868. 				pcr_apply_morph_value("Global Body", "body fat", new_fat) 
  869. 				pcr_set_triangle_cursor_pos(new_x, new_y)	 
  870. 				 
  871. 				if floor(new_x) ~= floor(Store_character_build_cursor_x) or floor(new_y) ~= floor(Store_character_build_cursor_y) then 
  872. 					Store_character_cancel_confirm_needed = true 
  873. 				end				 
  874. 				 
  875. 				update_needed = false 
  876. 			end 
  877. 		end 
  878. 		loop_count = loop_count + 1 
  879. 		 
  880. 		if Left_stick_input_thread == -1 then 
  881. 			--debug_print("vint", "Die... \n") 
  882. 			break 
  883. 		end 
  884. 	end 
  885. end 
  886.  
  887. -- empty function to take priority over normal input for the store while we're in the triangle selector 
  888. function store_character_null(event, value) 
  889. end 
  890.  
  891. function store_character_load_triangle() 
  892. 	store_unlock_controls() 
  893. 	Store_character_strength = pcr_get_morph_value("Global Body", "body muscle") 
  894. 	Store_character_skinny = pcr_get_morph_value("Global Body", "body skinny") 
  895. 	Store_character_fat = pcr_get_morph_value("Global Body", "body fat") 
  896. 	Store_character_build_cursor_x, Store_character_build_cursor_y = pcr_get_triangle_cursor_pos() 
  897.  
  898. 	Triangle_select:init_morphs(Store_character_strength, Store_character_skinny, Store_character_fat, Store_character_build_cursor_x, Store_character_build_cursor_y) 
  899. 	Triangle_select:set_visible(true) 
  900. 	 
  901. 	local title = nil 
  902. 	local title_crc = nil 
  903. 	title_crc = Menu_data[Active_list:get_selection()].label_crc 
  904. 	if title_crc == nil then 
  905. 		title = Menu_data[Active_list:get_selection()].label 
  906. 	end 
  907. 	Store_header:push_title( title_crc, title ) 
  908. end 
  909.  
  910. function store_character_morph_show(menu_data) 
  911. 	Current_tier = BUILD_TIER 
  912. 	Active_list:set_visible(false) 
  913. 	store_character_enable_mouse(false, false) 
  914. 	 
  915. 	if Input_tracker_body_morph_select == nil then 
  916. 		Input_tracker_body_morph_select = Vdo_input_tracker:new()	 
  917. 		Input_tracker_body_morph_select:add_input("left_joy_x", "store_character_move_left_x", 100, true) 
  918. 		Input_tracker_body_morph_select:add_input("left_joy_y", "store_character_move_left_y", 100, true)	 
  919. 		Input_tracker_body_morph_select:add_input("select", "store_character_morph_select", 100) 
  920. 		Input_tracker_body_morph_select:add_input("back", "store_character_morph_revert_confirm", 100)		 
  921. 		Input_tracker_body_morph_select:add_input("nav_up", "store_character_null", 100) 
  922. 		Input_tracker_body_morph_select:add_input("nav_down", "store_character_null", 100) 
  923. 		Input_tracker_body_morph_select:add_input("nav_left", "store_character_null", 100) 
  924. 		Input_tracker_body_morph_select:add_input("nav_right", "store_character_null", 100) 
  925. 		 
  926. 		if Game_platform == "PC" then 
  927. 			store_character_enable_mouse(false, false) 
  928. 	 
  929. 			-- Add mouse input for the "confirm selection" button 
  930. 			local confirm_handle = vint_object_find("btn_highlight", Triangle_select.handle) 
  931. 			Triangle_select_button_handle = vint_object_find("bg", confirm_handle) 
  932. 			Input_tracker_body_morph_select:add_mouse_input("mouse_click", "store_character_mouse_click", 100, Triangle_select_button_handle) 
  933. 			Input_tracker_body_morph_select:add_mouse_input("mouse_move", "store_character_mouse_move", 100, Triangle_select_button_handle) 
  934. 			 
  935. 			local text_handle = vint_object_find("btn_select", Triangle_select.handle) 
  936. 			Triangle_select_text_handle = vint_object_find("toggle_text", text_handle) 
  937. 			 
  938. 			-- Add mouse input for the build triangle 
  939. 			local triangle_handle = vint_object_find("triangle_base", Triangle_select.handle) 
  940. 			Input_tracker_body_morph_select:add_mouse_input("mouse_click", "store_character_mouse_click", 100, triangle_handle) 
  941. 			Input_tracker_body_morph_select:add_mouse_input("mouse_move", "store_character_mouse_move", 100, triangle_handle) 
  942. 			Input_tracker_body_morph_select:add_mouse_input("mouse_drag", "store_character_mouse_drag", 100, triangle_handle) 
  943. 			Input_tracker_body_morph_select:add_mouse_input("mouse_drag_release", "store_character_mouse_drag_release", 100, triangle_handle) 
  944. 		end 
  945. 	end 
  946. 	 
  947. 	Input_tracker_body_morph_select:subscribe(true) 
  948.  
  949. 	--Load triangle bitmap 
  950. 	game_peg_load_with_cb("store_character_load_triangle", 1, "ui_bms_pcr_tri") 
  951. 	store_lock_controls() 
  952. 	 
  953. 	Left_stick_input_thread = thread_new("store_character_move_left_stick_thread") 
  954. end 
  955.  
  956. function store_character_morph_select() 
  957. 	-- Nuke all button subscriptions 
  958. 	Input_tracker_body_morph_select:subscribe(false) 
  959. 	 
  960. 	game_UI_audio_play("UI_Main_Menu_Select") 
  961. 	 
  962. 	if Left_stick_input_thread ~= -1 then 
  963. 		thread_kill(Left_stick_input_thread) 
  964. 		Left_stick_input_thread = -1 
  965. 	end 
  966. 	 
  967. 	-- Unload triangle bitmap 
  968. 	game_peg_unload("ui_bms_pcr_tri")	 
  969. 		 
  970. 	Triangle_select:set_visible(false) 
  971. 	Active_list:set_visible(true) 
  972. 	 
  973. 	Current_tier = MENU_TIER 
  974. 	store_character_enable_mouse(true, false) 
  975. 	 
  976. 	Store_header:pop_title() 
  977. end 
  978.  
  979. -- If the player made changes to the triangle slider, ask if they want to throw them out. 
  980. -- 
  981. function store_character_morph_revert_confirm() 
  982. 	if Store_character_cancel_confirm_needed == false then 
  983. 		store_character_morph_revert() 
  984. 		return 
  985. 	end	 
  986. 	 
  987. 	store_character_enable_mouse(false) 
  988. 	if Input_tracker_body_morph_select ~= nil then 
  989. 		Input_tracker_body_morph_select:subscribe(false) 
  990. 	end 
  991. 	 
  992. 	Store_common_popup:populate_list(Yes_no_choices, 2, STORE_COMMON_LIST_SIZE, 2)	 
  993. 	Store_common_popup:set_title("MENU_TITLE_WARNING") 
  994. 	Store_common_popup:set_text("CANCEL_WARNING_BODY")		 
  995. 	Store_common_popup:nav_enable(true, "store_character_morph_revert_confirm_final", "store_character_popup_nav") 
  996. 	Not_popup_grp:set_alpha(.5)	 
  997. end 
  998.  
  999. -- Handle response to popup 
  1000. -- 
  1001. function store_character_morph_revert_confirm_final(event) 
  1002. 	Store_common_popup:nav_enable(false, nil, nil) 
  1003. 	Not_popup_grp:set_alpha(1) 
  1004. 	 
  1005. 	-- The user hit the B button and are cancelling the cancel :-) 
  1006. 	-- This is redundant to selecting "No" in the list 
  1007. 	if event == "back" then 
  1008. 		game_UI_audio_play("UI_Main_Menu_Nav_Back") 
  1009. 		--store_character_enable_mouse(true) 
  1010. 		Input_tracker_body_morph_select:subscribe(true) 
  1011. 		if Hint_bar_mouse_input_tracker ~= -1 then 
  1012. 			Hint_bar_mouse_input_tracker:subscribe(true) 
  1013. 		end 
  1014. 		return 
  1015. 	end 
  1016. 	 
  1017. 	game_UI_audio_play("UI_Main_Menu_Select")	 
  1018. 	 
  1019. 	-- Did we select yes?  This assumes yes is the first item 
  1020. 	if Store_common_popup:get_selected_data() ~= 1 then 
  1021. 		--store_character_enable_mouse(true) 
  1022. 		Input_tracker_body_morph_select:subscribe(true) 
  1023. 		if Hint_bar_mouse_input_tracker ~= -1 then 
  1024. 			Hint_bar_mouse_input_tracker:subscribe(true) 
  1025. 		end 
  1026. 		return 
  1027. 	end 
  1028.  
  1029. 	-- Do the cancel 
  1030. 	Store_character_cancel_confirm_needed = false 
  1031. 	store_character_morph_revert() 
  1032. end 
  1033.  
  1034.  
  1035. -- Player reverted changes made in the triangle selector 
  1036. function store_character_morph_revert() 
  1037. 	-- Nuke all button subscriptions 
  1038. 	Input_tracker_body_morph_select:subscribe(false) 
  1039. 	 
  1040. 	if Left_stick_input_thread ~= -1 then 
  1041. 		thread_kill(Left_stick_input_thread) 
  1042. 		Left_stick_input_thread = -1 
  1043. 	end 
  1044. 	 
  1045. 	-- restore previous morph values 
  1046. 	pcr_apply_morph_value("Global Body", "body muscle", Store_character_strength) 
  1047. 	pcr_apply_morph_value("Global Body", "body skinny", Store_character_skinny) 
  1048. 	pcr_apply_morph_value("Global Body", "body fat", Store_character_fat)	 
  1049. 	pcr_set_triangle_cursor_pos(Store_character_build_cursor_x, Store_character_build_cursor_y) 
  1050. 	 
  1051. 	-- Unload triangle bitmap 
  1052. 	game_peg_unload("ui_bms_pcr_tri")	 
  1053. 		 
  1054. 	Triangle_select:set_visible(false) 
  1055. 	Active_list:set_visible(true) 
  1056. 	 
  1057. 	Current_tier = MENU_TIER 
  1058. 	store_character_enable_mouse(true) 
  1059. 	 
  1060. 	Store_header:pop_title()	 
  1061. end 
  1062.  
  1063. -- morph support 
  1064. -- 
  1065. function store_character_morph_change(menu_data)	 
  1066. 	pcr_apply_morph_value(menu_data.morph_set, menu_data.morph_id, menu_data.current_value) 
  1067. 	pcr_mark_changed() 
  1068. 	Store_character_confirm_randomize = true 
  1069. 	Store_character_cancel_confirm_needed = true 
  1070. end 
  1071.  
  1072.  
  1073. function store_character_skin_color_add(id, swatch_crc, label_crc, label_str, current) 
  1074.  
  1075. 	local menu_idx = #Color_grid_data + 1 
  1076.  
  1077. 	local item = { 
  1078. 		index = menu_idx, id = id, icon_crc = swatch_crc, label_crc = label_crc, label = label_str, color = {red = 1, green = 1, blue = 1}, 
  1079. 	} 
  1080.  
  1081. 	Color_grid_data[menu_idx] = item 
  1082.  
  1083. 	if current == true then 
  1084. 		Color_grid_idx = menu_idx 
  1085. 		Store_character_skin_color_current_setting = menu_idx 
  1086. 	end 
  1087. end 
  1088.  
  1089. function store_character_skin_grid_show(menu_data) 
  1090.  
  1091. 	--Store_character_original_values.skin_color = nil 
  1092. 	table_clear(Color_grid_data, true) 
  1093. 	Color_grid_idx = 1 
  1094. 	pcr_report_skin_colors("store_character_skin_color_add") 
  1095.  
  1096. 	-- Load Hair Swatches 
  1097. 	game_peg_load_with_cb("store_character_skin_swatch_loaded",1,"ui_bms_pcr_skin") 
  1098. 	store_lock_controls()	 
  1099.  
  1100. 	store_set_camera_pos("body") 
  1101. end 
  1102.  
  1103. function store_character_skin_color_delayed_set() 
  1104. 	delay(0.4) 
  1105.  
  1106. 	pcr_change_skin_color(Store_character_skin_color_selected) 
  1107. 	Store_character_nav_value = nil 
  1108. 	Store_character_nav_thread = -1 
  1109. end 
  1110.  
  1111. function store_character_skin_color_grid_nav(event, value) 
  1112. 	store_character_grid_nav(event, value) 
  1113. 	 
  1114. 	-- set the color and preview the item 
  1115. 	local idx = Store_common_color_grid:return_selected_index() 
  1116. 	Store_character_skin_color_selected = Color_grid_data[idx].id 
  1117. 	 
  1118. 	if Store_character_nav_thread ~= -1 then 
  1119. 		thread_kill(Store_character_nav_thread) 
  1120. 		Store_character_nav_thread = -1 
  1121. 	end 
  1122. 	 
  1123. 	Store_character_nav_thread = thread_new("store_character_skin_color_delayed_set")	 
  1124. end 
  1125.  
  1126.  
  1127. function store_character_skin_swatch_loaded() 
  1128.  
  1129. 	store_unlock_controls() 
  1130.  
  1131. 	Store_common_color_grid:draw_items(Color_grid_data, Color_grid_idx, 5, 4, 83, 83, 26, nil, 1.1) 
  1132. 	Store_common_color_grid:nav_enable(true, "store_character_skin_color_selected", "store_character_skin_color_grid_nav")		 
  1133. 	Store_common_color_grid:set_visible(true)	 
  1134. 	Active_list:set_visible(false) 
  1135. 	 
  1136. 	Current_tier = SKIN_COLOR_TIER 
  1137. 	store_character_enable_mouse(false, false) 
  1138. 	 
  1139. 	-- set the titles on top 
  1140. 	Store_header:push_title( nil, "CUST_SKIN")	 
  1141. end 
  1142.  
  1143. function store_character_skin_color_selected(event) 
  1144. 	 
  1145. 	-- remove skin color title 
  1146. 	Store_header:pop_title() 
  1147. 	 
  1148. 	-- Did the player select a color? 
  1149. 	if event == "select" or event == "mouse_click" then 
  1150. 		 
  1151. 		game_UI_audio_play("UI_Main_Menu_Select") 
  1152. 		 
  1153. 		local idx = Store_common_color_grid:return_selected_index() 
  1154.  
  1155. 		if idx <= #Color_grid_data then 
  1156. 			pcr_change_skin_color(Color_grid_data[idx].id) 
  1157. 			pcr_mark_changed() 
  1158. 		end 
  1159. 	else 
  1160. 		game_UI_audio_play("UI_Main_Menu_Nav_Back") 
  1161. 		if Store_character_nav_thread > -1 then 
  1162. 			thread_kill(Store_character_nav_thread) 
  1163. 			Store_character_nav_thread = -1 
  1164. 		end 
  1165.  
  1166. 		-- player didn't accept; revert change 
  1167. 		if Store_character_skin_color_current_setting ~= -1 then 
  1168. 			pcr_change_skin_color(Color_grid_data[Store_character_skin_color_current_setting].id) 
  1169. 		end 
  1170. 	end	 
  1171. 	 
  1172. 	game_peg_unload("ui_bms_pcr_skin") 
  1173. 	 
  1174. 	Store_common_color_grid:nav_enable(false, nil, nil) 
  1175. 	Store_common_color_grid:cleanup()	 
  1176. 	Store_common_color_grid:set_visible(false) 
  1177. 	Active_list:set_visible(true) 
  1178. 	table_clear(Color_grid_data, true) 
  1179. 	 
  1180. 	Current_tier = MENU_TIER 
  1181. 	store_character_enable_mouse(true, false) 
  1182. end 
  1183.  
  1184. function store_character_body_menu_return(menu_data)	 
  1185.  
  1186. 	store_character_creation_strip_clothes() 
  1187.  
  1188. 	-- check the current values for age and breast, since a preset will have reset them 
  1189. 	local current_age = pcr_get_morph_value("global body", "old") 
  1190. 	local current_breast = pcr_get_morph_value("global body", "breast")	 
  1191. 	 
  1192. 	menu_data[6].current_value = current_age 
  1193. 	menu_data[7].current_value = current_breast 
  1194. 	 
  1195. 	Store_character_current_preset_gender = pcr_get_player_preset()	 
  1196. 	 
  1197. 	local sex_camera 
  1198. 	if Store_character_current_preset_gender == STORE_CHARACTER_FEMALE_GENDER_NAME then 
  1199. 		sex_camera = "sex female" 
  1200. 	else 
  1201. 		sex_camera = "sex male" 
  1202. 	end	 
  1203. 	 
  1204. 	menu_data[7].camera = sex_camera 
  1205. 	 
  1206. 	-- Redraw the menu to show updated slider values and camera views 
  1207. 	local start_index = store_common_stack_get_index()	 
  1208. 	store_character_populate_list(menu_data, start_index)	 
  1209. end 
  1210.  
  1211. function store_character_camera_on_nav(menu_data) 
  1212. 	if menu_data.camera ~= nil then 
  1213. 		store_set_camera_pos(menu_data.camera) 
  1214. 	end 
  1215. end 
  1216.  
  1217. function store_character_fill_global_menu(menu_data) 
  1218.  
  1219. 	local current_age = pcr_get_morph_value("global body", "old") 
  1220. 	local current_breast = pcr_get_morph_value("global body", "breast") 
  1221.  
  1222. 	Store_character_current_preset_gender = pcr_get_player_preset()	 
  1223.  
  1224. 	local sex_camera 
  1225. 	if Store_character_current_preset_gender == STORE_CHARACTER_FEMALE_GENDER_NAME then 
  1226. 		sex_camera = "sex female" 
  1227. 	else 
  1228. 		sex_camera = "sex male" 
  1229. 	end 
  1230.  
  1231. 	local store_character_global_menu =	{ 
  1232. 		on_enter = store_character_body_menu_return, 
  1233. 		{ label = "CUST_PRESET_SEX",	type = TYPE_BUTTON, on_sub_menu_fill = store_character_preset_sex_fill,			camera = "body",	on_nav = store_character_camera_on_nav }, 
  1234. 		 
  1235. 		{ label = "CUST_PRESET_RACE",	type = TYPE_BUTTON, on_sub_menu_fill = store_character_preset_race_fill,		camera = "body",	on_nav = store_character_camera_on_nav },	 
  1236. 		 
  1237. 		{ label = "STORE_BUILD",		type = TYPE_BUTTON, on_select = store_character_morph_show,							camera = "body",	on_nav = store_character_camera_on_nav }, 
  1238. 		 
  1239. 		{ label = "CUST_SKIN",			type = TYPE_BUTTON, on_select = store_character_skin_grid_show,					camera = "body",	on_nav = store_character_camera_on_nav	},	 
  1240. 		 
  1241. 		{ label = "CUST_BODY_MASK",	type = TYPE_BUTTON, on_sub_menu_fill = store_character_composite_menu_build,	camera = "body",	on_nav = store_character_camera_on_nav,	composite_area = "body mask", }, 
  1242. 		 
  1243. 		{ label = "CUST_PRESET_AGE",	type = TYPE_SLIDER, on_value_update = store_character_morph_change,				camera = "head", on_nav = store_character_camera_on_nav, 
  1244. 		  morph_id = "old",		morph_set = "Global Body",		min = 0,		max = 1,		step = 0.01,		current_value = current_age,  	}, 
  1245. 		   
  1246. 		{ label = "CUST_SEX_APPEAL",	type = TYPE_SLIDER, on_value_update = store_character_morph_change, 				camera = sex_camera, on_nav = store_character_camera_on_nav, 
  1247. 		  morph_id = "breast",	morph_set = "Global Body", 	min = 0,		max = 1,		step = 0.01,		current_value = current_breast,  }, 
  1248. 	} 
  1249. 	 
  1250. 	Store_common_sub_menu = store_character_global_menu 
  1251. end 
  1252.  
  1253.  
  1254. -- Hair menus 
  1255. -------------------------------------------- 
  1256.  
  1257. -- Create the menu of hair style choices. 
  1258. -- 
  1259. function store_character_hair_style_show(menu_data) 
  1260. 	if Store_character_nav_thread > -1 then 
  1261. 		thread_kill(Store_character_nav_thread) 
  1262. 		Store_character_nav_thread = -1 
  1263. 	end 
  1264. 	 
  1265. 	-- save off current hair values 
  1266. 	store_character_hair_item_save()	 
  1267.  
  1268. 	local item = { 
  1269. 		type = TYPE_BUTTON,  
  1270. 		hair_item = -1, 
  1271. 		primary = Store_character_hair_values.primary, 
  1272. 		label = "HAIR_CAT_NONE",  
  1273. 		on_nav = store_character_hair_style_nav,  
  1274. 		on_select = store_character_hair_item_select,  
  1275. 		on_cancel = store_character_hair_item_revert, 
  1276. 	} 
  1277.  
  1278. 	local menu_idx = #Store_common_sub_menu + 1 
  1279. 	Store_common_sub_menu[menu_idx] = item 
  1280. 		 
  1281. 	pcr_report_hair_items(0, "store_character_hair_item_add") 
  1282. end 
  1283.  
  1284. -- Populate hair menus. 
  1285. -- 
  1286. function store_character_hair_item_add(hair_item, label_crc, label_str, is_current, is_dlc) 
  1287. 	local item = { 
  1288. 		type = TYPE_BUTTON,  
  1289. 		hair_item = hair_item, 
  1290. 		primary = Store_character_hair_values.primary, 
  1291. 		label = label_str,  
  1292. 		label_crc = label_crc,  
  1293. 		on_nav = store_character_hair_style_nav,  
  1294. 		on_select = store_character_hair_item_select,  
  1295. 		on_cancel = store_character_hair_item_revert, 
  1296. 		is_dlc = is_dlc, 
  1297. 	} 
  1298. 	 
  1299. 	local menu_idx = #Store_common_sub_menu + 1 
  1300. 	Store_common_sub_menu[menu_idx] = item 
  1301. 	 
  1302. 	if is_current == true then 
  1303. 		Store_common_sub_menu.start_index = menu_idx 
  1304. 	end 
  1305. end 
  1306.  
  1307. -- Update hair preview while player navigates 
  1308. -- 
  1309. function store_character_hair_style_nav(menu_data) 
  1310. 	if Store_character_nav_thread ~= -1 then 
  1311. 		thread_kill(Store_character_nav_thread) 
  1312. 		Store_character_nav_thread = -1 
  1313. 	end 
  1314. 	 
  1315. 	Store_character_nav_value = menu_data 
  1316. 	Store_character_nav_thread = thread_new("store_character_delayed_set_hair_item") 
  1317. end 
  1318.  
  1319. -- Delayed previewing from thread of new hair style while navigating 
  1320. --  
  1321. function store_character_delayed_set_hair_item() 
  1322. 	delay(0.4) 
  1323. 	pcr_change_hair(0, Store_character_nav_value.hair_item, Store_character_nav_value.primary, 0) 
  1324. 	Store_character_nav_thread = -1 
  1325. end 
  1326.  
  1327. -- Player has chosen a hair style and hit accept.  Update, and choose hair colors 
  1328. -- 
  1329. function store_character_hair_item_select(menu_data) 
  1330.  
  1331. 	if Store_character_nav_thread ~= -1 then 
  1332. 		thread_kill(Store_character_nav_thread) 
  1333. 		Store_character_nav_thread = -1 
  1334. 	end 
  1335. 	 
  1336. 	pcr_change_hair(0, menu_data.hair_item, menu_data.primary, 0) 
  1337. 	 
  1338. 	pcr_mark_changed() 
  1339. 	Store_character_confirm_randomize = true 
  1340. 	 
  1341. 	-- Go on to color selection 
  1342. 	if menu_data.hair_item ~= -1 then 
  1343. 		store_character_hair_color_grid_show(menu_data) 
  1344. 	else 
  1345. 		-- Don't choose color if hair choice was "none" 
  1346. 		store_character_hair_item_save() 
  1347. 		store_common_back_menu() 
  1348. 	end 
  1349. end 
  1350.  
  1351. -- Player backed out of hair selection without hitting accept.  Revert to previous hair. 
  1352. -- 
  1353. function store_character_hair_item_revert(menu_data) 
  1354.  
  1355. 	if Store_character_nav_thread ~= -1 then 
  1356. 		thread_kill(Store_character_nav_thread) 
  1357. 		Store_character_nav_thread = -1 
  1358. 	end 
  1359. 	 
  1360. 	-- Do the revert 
  1361. 	pcr_change_hair(0, Store_character_hair_values.style, Store_character_hair_values.primary, 0) 
  1362. end 
  1363.  
  1364. function store_character_hair_item_save(menu_data) 
  1365. 	Store_character_hair_values.style, Store_character_hair_values.primary = pcr_get_hair_info(0) 
  1366. end 
  1367.  
  1368. -- Build the hair color selection grid list.  Start asynchronous load of hair color swatch. 
  1369. -- 
  1370. function store_character_hair_color_grid_show(menu_data)	 
  1371. 	table_clear(Color_grid_data, true) 
  1372. 	 
  1373. 	-- menu_data.hair_item used if we've changed the hair style and directly went to color selection... otherwise used saved value if just picking color 
  1374. 	Color_grid_data.hair_item = menu_data.hair_item or Store_character_hair_values.style 
  1375. 	 
  1376. 	Color_grid_idx = 1 
  1377. 	 
  1378. 	pcr_report_hair_colors("store_character_hair_color_add") 
  1379.  
  1380. 	-- Load Hair Swatches 
  1381. 	game_peg_load_with_cb("store_character_hair_swatch_loaded",1,"ui_bms_pcr_hair") 
  1382. 	store_lock_controls()	 
  1383. end 
  1384.  
  1385. function store_character_hair_color_add(id, swatch_crc, label_crc, label_str, current, swatch_label) 
  1386. 	local menu_idx = #Color_grid_data + 1 
  1387.  
  1388. 	local item = { 
  1389. 		index = menu_idx,  
  1390. 		id = id,  
  1391. 		label_crc = label_crc,  
  1392. 		label = label_str,  
  1393. 		icon_crc = swatch_crc,  
  1394. 		color = {red = 1, green = 1, blue = 1}, 
  1395. 		hair_item = Color_grid_data.hair_item, 
  1396. 		primary = id, 
  1397. 	} 
  1398.  
  1399. 	-- set start index if this is the current hair color 
  1400. 	if current == true then 
  1401. 		Color_grid_idx = menu_idx 
  1402. 	end 
  1403.  
  1404. 	Color_grid_data[menu_idx] = item 
  1405. end	 
  1406.  
  1407. function store_character_hair_swatch_loaded() 
  1408.  
  1409. 	store_unlock_controls() 
  1410.  
  1411. 	Store_common_color_grid:draw_items(Color_grid_data, Color_grid_idx, 5, 4, 83, 83, 26, nil, 1.1) 
  1412. 	 
  1413. 	Store_common_color_grid:nav_enable(true, "store_character_hair_color_selected", "store_character_hair_color_nav")		 
  1414. 	Store_common_color_grid:set_visible(true)	 
  1415. 	Active_list:set_visible(false) 
  1416. 	 
  1417. 	Current_tier = HAIR_COLOR_TIER 
  1418. 	store_character_enable_mouse(false, false) 
  1419. 	 
  1420. 	-- set the titles on top 
  1421. 	Store_header:push_title(nil, "CUST_PRIMARY_COLOR")		 
  1422. end 
  1423.  
  1424. function store_character_hair_color_nav(event, value) 
  1425. 	store_character_grid_nav(event, value) 
  1426. 	 
  1427. 	-- set the color and preview the item 
  1428. 	local idx = Store_common_color_grid:return_selected_index() 
  1429. 	 
  1430. 	Store_character_nav_value = Color_grid_data[idx] 
  1431. 	 
  1432. 	if Store_character_nav_thread ~= -1 then 
  1433. 		thread_kill(Store_character_nav_thread) 
  1434. 		Store_character_nav_thread = -1 
  1435. 	end 
  1436. 	 
  1437. 	Store_character_nav_thread = thread_new("store_character_delayed_set_hair_item") 
  1438. end 
  1439.  
  1440. function store_character_hair_color_selected(event) 
  1441. 	 
  1442. 	-- always make sure to disable inputs, or we'll run out if we start another hair color grid 
  1443. 	Store_common_color_grid:nav_enable(false, nil, nil)	 
  1444. 	 
  1445. 	-- remove hair color title 
  1446. 	Store_header:pop_title() 
  1447. 	 
  1448. 	game_peg_unload("ui_bms_pcr_hair") 
  1449. 	 
  1450. 	Store_common_color_grid:set_visible(false) 
  1451. 	Active_list:set_visible(true)	 
  1452. 	 
  1453. 	Current_tier = MENU_TIER 
  1454. 	store_character_enable_mouse(true, false) 
  1455. 	 
  1456. 	-- Did the player select a color? 
  1457. 	if event == "select" or event == "mouse_click" then 
  1458. 		 
  1459. 		game_UI_audio_play("UI_Main_Menu_Select") 
  1460. 		 
  1461. 		if Store_character_nav_thread > -1 then 
  1462. 			thread_kill(Store_character_nav_thread) 
  1463. 			Store_character_nav_thread = -1 
  1464. 		end 
  1465.  
  1466. 		local idx = Store_common_color_grid:return_selected_index() 
  1467. 		local menu_data = Color_grid_data[idx] 
  1468.  
  1469. 		pcr_change_hair(0, menu_data.hair_item, menu_data.primary, 0)	 
  1470. 		pcr_mark_changed() 
  1471. 		 
  1472. 		store_character_hair_item_save() 
  1473. 		 
  1474. 		store_common_back_menu() 
  1475. 	else 
  1476. 		game_UI_audio_play("UI_Main_Menu_Nav_Back") 
  1477. 		-- reverse the hair color changes since user cancelled, unless they didn't make any changes yet 
  1478. 		if Store_character_nav_value ~= nil then 
  1479. 			pcr_change_hair(0, Store_character_nav_value.hair_item, Store_character_nav_value.primary, 0) 
  1480. 		end 
  1481. 	end 
  1482. 	 
  1483. 	table_clear(Color_grid_data, true)	 
  1484. 	Store_common_color_grid:cleanup()	 
  1485. end 
  1486.  
  1487. function store_character_rebuild_hair_menu(menu_data, animate) 
  1488.  
  1489. 	-- We need to rebuild the menu to update the accessory color choices available 
  1490. 	local menu_data = {} 
  1491. 	store_character_fill_hair_menu(menu_data) 
  1492. 	 
  1493. 	Menu_data = {} 
  1494. 	Menu_data = Store_common_sub_menu 
  1495. 	 
  1496. 	local index = Active_list:get_selection() 
  1497. 	store_character_populate_list(Menu_data, index, animate) --last param to skip animate list 
  1498.  
  1499. 	store_character_creation_strip_clothes() 
  1500. end 
  1501.  
  1502. function store_character_hair_randomize(menu_data) 
  1503. 	-- only head hair uses this now 
  1504. 	pcr_hair_randomize_all() 
  1505. 	 
  1506. 	-- randomize facial hair and eyebrows too 
  1507. 	pcr_set_random_composite("eyebrows") 
  1508. 	 
  1509. 	local preset_gender = pcr_get_player_preset() 
  1510. 	 
  1511. 	-- but don't do facial hair for females 
  1512. 	if preset_gender ~= STORE_CHARACTER_FEMALE_GENDER_NAME then 
  1513. 		pcr_set_random_composite("facial hair") 
  1514. 	end 
  1515. 	 
  1516. 	-- Need to rebuild menu, so that "hair accessory color" is shown if necessary or not 
  1517. 	store_character_rebuild_hair_menu(nil, false) --second param is to skip animating list 
  1518. end 
  1519.  
  1520. -- Callback to get a color option from C and add it to our color grid. 
  1521. -- 
  1522. -- color_index: 	indicates which color this is for 
  1523. -- label_crc:		crc to use for the toggle choice name. nil if string is used. 
  1524. -- label_str:		string to use for the toggle choice name.  nil if crc is used. 
  1525. -- red:				r value. 
  1526. -- green:			g value. 
  1527. -- blue:			b value. 
  1528. -- 
  1529. function store_character_hair_acc_color_add(color_index, label_crc, label_str, red, green, blue) 
  1530. 	local grid_idx = #Color_grid_data + 1 
  1531. 	 
  1532. 	Color_grid_data[grid_idx] = { 
  1533. 		icon = "ui_menu_veh_pnt_base", 
  1534. 		label = label_str, 
  1535. 		label_crc = label_crc, 
  1536. 		color = {red = red, green = green, blue = blue}, 
  1537. 		index = color_index, 
  1538. 	} 
  1539. 	 
  1540. 	if color_index == Store_character_hair_acc_info.colors[Color_slot_chosen].index then 
  1541. 		Color_grid_idx = grid_idx 
  1542. 	end 
  1543. end 
  1544.  
  1545. function store_character_hair_acc_color_selected(event) 
  1546. 	 
  1547. 	--Did the player select a color? 
  1548. 	if event == "select" or event == "mouse_click" then 
  1549. 		game_UI_audio_play("UI_Main_Menu_Select") 
  1550. 		-- We don't have to set the colors here... that was already done in our navigate funcion.				 
  1551. 	else 
  1552. 		game_UI_audio_play("UI_Main_Menu_Nav_Back") 
  1553. 		-- restore previous color 
  1554. 		Store_character_hair_acc_info.colors[Color_slot_chosen].index = Color_grid_data[Color_prev_color].index 
  1555. 		Store_character_hair_acc_info.colors[Color_slot_chosen].red = Color_grid_data[Color_prev_color].color.red 
  1556. 		Store_character_hair_acc_info.colors[Color_slot_chosen].green = Color_grid_data[Color_prev_color].color.green 
  1557. 		Store_character_hair_acc_info.colors[Color_slot_chosen].blue = Color_grid_data[Color_prev_color].color.blue	 
  1558.  
  1559. 		local t = Store_character_hair_acc_info 
  1560. 		pcu_set_slot_info(t.slot_index, t.item_index, t.variant_index, t.colors.num_colors, t.colors[0].index, 
  1561. 		t.colors[1].index, t.colors[2].index, t.wear_option_index, t.logo_index, t.logo_color_index, true, CHARACTER_COLOR_POOL_TYPE) 
  1562. 	end 
  1563. 	 
  1564. 	store_character_populate_list(Menu_data, Active_list:get_selection()) 
  1565. 		 
  1566. 	Store_common_color_grid:nav_enable(false, nil, nil) 
  1567. 	Store_common_color_grid:cleanup()	 
  1568. 	Store_common_color_grid:set_visible(false) 
  1569. 	Store_common_color_grid:cleanup() 
  1570. 	Active_list:set_visible(true) 
  1571. 	table_clear(Color_grid_data, true) 
  1572. 	 
  1573. 	local t = Store_character_hair_acc_info 
  1574. 	 
  1575. 	t.slot_index, t.item_index, t.item_name_crc, t.item_name_str, 
  1576. 	t.num_variants, t.variant_index, t.variant_name_crc, t.variant_name_str, 
  1577. 	t.colors.num_colors, 
  1578. 	t.colors[0].index, t.colors[0].red, t.colors[0].green, t.colors[0].blue, 
  1579. 	t.colors[1].index, t.colors[1].red, t.colors[1].green, t.colors[1].blue, 
  1580. 	t.colors[2].index, t.colors[2].red, t.colors[2].green, t.colors[2].blue, 
  1581. 	t.num_wear_options, t.wear_option_index, t.wear_option_name_crc, t.wear_option_name_str, 
  1582. 	t.num_logos, t.logo_index, t.logo_name_crc, t.logo_name_str, t.logo_color_index, t.logo_color_red, t.logo_color_green, t.logo_color_blue, 
  1583. 	t.item_style, t.item_price, 
  1584. 	t.player_style_level, t.player_style_percent 
  1585. 	= pcu_get_slot_info(HAIR_ITEM_SLOT, CHARACTER_COLOR_POOL_TYPE) 
  1586. 		 
  1587. 	store_character_enable_mouse(true) 
  1588. 	Current_tier = MENU_TIER 
  1589. end 
  1590.  
  1591. function store_character_hair_acc_color_nav(event, value) 
  1592. 	 
  1593. 	if event == "nav_up" then	 
  1594. 		Store_common_color_grid:move_cursor(-2)	 
  1595. 	elseif event == "nav_down" then 
  1596. 		Store_common_color_grid:move_cursor(2) 
  1597. 	elseif event == "nav_left" then 
  1598. 		Store_common_color_grid:move_cursor(-1) 
  1599. 	elseif event == "nav_right" then 
  1600. 		Store_common_color_grid:move_cursor(1) 
  1601. 	 
  1602. 	elseif event == "mouse_move" then 
  1603. 		-- value contains the target_handle in this case 
  1604. 		local new_index = Store_common_color_grid:get_data_index(value) 
  1605. 		if new_index ~= 0 then 
  1606. 			Store_common_color_grid:set_selection(new_index) 
  1607. 			Store_common_color_grid:move_cursor(0, false, true) 
  1608. 		end 
  1609. 		 
  1610. 	else 
  1611. 		--do nothing 
  1612. 	end 
  1613. 	 
  1614. 	-- set the color and preview the item 
  1615. 	local idx = Store_common_color_grid:return_selected_index() 
  1616. 	Store_character_hair_acc_info.colors[Color_slot_chosen].index = Color_grid_data[idx].index 
  1617. 	Store_character_hair_acc_info.colors[Color_slot_chosen].red = Color_grid_data[idx].color.red 
  1618. 	Store_character_hair_acc_info.colors[Color_slot_chosen].green = Color_grid_data[idx].color.green 
  1619. 	Store_character_hair_acc_info.colors[Color_slot_chosen].blue = Color_grid_data[idx].color.blue	 
  1620. 		 
  1621. 	local t = Store_character_hair_acc_info		 
  1622. 	pcu_set_slot_info(t.slot_index, t.item_index, t.variant_index, t.colors.num_colors, t.colors[0].index, 
  1623. 	t.colors[1].index, t.colors[2].index, t.wear_option_index, t.logo_index, t.logo_color_index, true, CHARACTER_COLOR_POOL_TYPE) 
  1624. end 
  1625.  
  1626. function store_character_hair_acc_color_select(menu_data) 
  1627. 	Active_list:set_visible(false) 
  1628. 	 
  1629. 	game_UI_audio_play("UI_Main_Menu_Select") 
  1630. 	 
  1631. 	-- get the colors for the palette 
  1632. 	table_clear(Color_grid_data, true) 
  1633. 	Color_slot_chosen = menu_data.id 
  1634. 	Color_grid_idx = 1 
  1635. 	pcu_report_item_colors("store_character_hair_acc_color_add", 0, CHARACTER_COLOR_POOL_TYPE) 
  1636. 	 
  1637. 	-- display the grid 
  1638. 	Store_common_color_grid:draw_items(Color_grid_data, Color_grid_idx, 5, 7, 53.5, 53.5, 15, nil, 1.1, true, true, -7, true) 
  1639. 	Store_common_color_grid:set_visible(true) 
  1640. 	Store_common_color_grid:nav_enable(true, "store_character_hair_acc_color_selected", "store_character_hair_acc_color_nav")	 
  1641. 	Color_prev_color = Color_grid_idx 
  1642. 	 
  1643. 	if Mouse_input_tracker ~= 0 then 
  1644. 		Mouse_input_tracker:subscribe(false) 
  1645. 	end 
  1646. 	Current_tier = HAIR_COLOR_TIER 
  1647. end 
  1648.  
  1649. function store_character_fill_hair_menu(menu_data) 
  1650.  
  1651. 	local menu = 	{ 
  1652. 		on_enter = store_character_rebuild_hair_menu,	 
  1653. 		{ label = "CUST_CAT_HAIR_HEAD",		type = TYPE_BUTTON, on_sub_menu_fill = store_character_hair_style_show,			rand_func = store_character_hair_randomize,	camera = "head" }, 
  1654. 		{ label = "CUST_CAT_HAIR_FACIAL",	type = TYPE_BUTTON, on_sub_menu_fill = store_character_composite_menu_build,	rand_func = store_character_hair_randomize,	composite_area = "facial hair",					camera = "facial hair"}, 
  1655. 		{ label = "CUST_CAT_HAIR_EYEBROWS",	type = TYPE_BUTTON, on_sub_menu_fill = store_character_composite_menu_build,	rand_func = store_character_hair_randomize,	composite_area = "eyebrows",						camera = "facial hair"}, 
  1656. 	} 
  1657.  
  1658. 	Store_common_sub_menu = menu 
  1659. 	 
  1660. 	local t = Store_character_hair_acc_info 
  1661. 	 
  1662. 	t.slot_index, t.item_index, t.item_name_crc, t.item_name_str, 
  1663. 	t.num_variants, t.variant_index, t.variant_name_crc, t.variant_name_str, 
  1664. 	t.colors.num_colors, 
  1665. 	t.colors[0].index, t.colors[0].red, t.colors[0].green, t.colors[0].blue, 
  1666. 	t.colors[1].index, t.colors[1].red, t.colors[1].green, t.colors[1].blue, 
  1667. 	t.colors[2].index, t.colors[2].red, t.colors[2].green, t.colors[2].blue, 
  1668. 	t.num_wear_options, t.wear_option_index, t.wear_option_name_crc, t.wear_option_name_str, 
  1669. 	t.num_logos, t.logo_index, t.logo_name_crc, t.logo_name_str, t.logo_color_index, t.logo_color_red, t.logo_color_green, t.logo_color_blue, 
  1670. 	t.item_style, t.item_price, 
  1671. 	t.player_style_level, t.player_style_percent 
  1672. 	= pcu_get_slot_info(HAIR_ITEM_SLOT, CHARACTER_COLOR_POOL_TYPE) 
  1673. 	 
  1674. 	local menu_idx = #Store_common_sub_menu + 1 
  1675. 	 
  1676. 	-- color selections 
  1677. 	if t.colors.num_colors ~= nil and t.colors.num_colors > 0 then 
  1678. 		Store_common_sub_menu[menu_idx] = { label = "CUST_HAIR_ACCESSORY_COLOR",		type = TYPE_BUTTON, on_sub_menu_fill = store_character_hair_acc_color_menu_fill,	rand_func = store_character_hair_randomize,	camera = "head" } 
  1679. 	end 
  1680. 	 
  1681. end	 
  1682.  
  1683. function store_character_hair_acc_color_menu_fill(menu_data) 
  1684.  
  1685. 	local menu_idx = #Store_common_sub_menu 
  1686. 	 
  1687. 	local t = Store_character_hair_acc_info	 
  1688. 	 
  1689. 	-- color selections 
  1690. 	if t.colors.num_colors ~= nil and t.colors.num_colors > 0 then 
  1691. 		local c = t.colors 
  1692. 		 
  1693. 		for i = 0, c.num_colors - 1 do 
  1694. 			local color_label 
  1695. 			if i == 0 then 
  1696. 				color_label = "STORE_PRIMARY_COLOR" 
  1697. 			elseif i == 1 then 
  1698. 				color_label = "STORE_SECONDARY_COLOR" 
  1699. 			elseif i == 2 then 
  1700. 				color_label = "STORE_TERTIARY_COLOR" 
  1701. 			else 
  1702. 				color_label = "STORE_DETAIL_COLOR" 
  1703. 			end 
  1704. 			 
  1705. 			menu_idx = menu_idx + 1 
  1706. 			local new_item = { 
  1707. 				type = TYPE_TOGGLE_COLOR, 
  1708. 				id = i, 
  1709. 				label = color_label, 
  1710. 				label_crc = nil, 
  1711. 				color = c[i], 
  1712. 				on_select = store_character_hair_acc_color_select, 
  1713. 			}	 
  1714. 			Store_common_sub_menu[menu_idx] = new_item	 
  1715. 		end 
  1716. 	end 
  1717. end 
  1718.  
  1719. -- Makeup menus 
  1720. -------------------------------------------- 
  1721.  
  1722. function store_character_makeup_randomize(menu_data) 
  1723.  
  1724. 	-- randomize from the makeup selections 
  1725. 	local areas = {"makeup eyeliner", "makeup eyeshadow", "makeup cheeks", "makeup entire face", "fingernails", "face items"} 
  1726. 	 
  1727. 	for index, composite_area in pairs(areas) do 
  1728. 		pcr_set_random_composite(composite_area) 
  1729. 	end	 
  1730. 	 
  1731. 	pcr_lips_randomize() 
  1732. end 
  1733.  
  1734. function store_character_makeup_enter_menu() 
  1735.  
  1736. 	store_character_creation_strip_clothes() 
  1737. 	store_set_camera_pos("head") 
  1738. end 
  1739.  
  1740. -- Face menus 
  1741. -------------------------------------------- 
  1742.  
  1743. function store_character_randomize_one_morph(id, name_crc, name_str, value, gender, step_rate, rand_range) 
  1744. 	pcr_apply_morph_value(Store_character_randomizing_morph_set, id, rand_float(0.5 - rand_range, 0.5 + rand_range)) 
  1745. 	pcr_mark_changed() 
  1746. end 
  1747.  
  1748. function store_character_randomize_all_morphs(menu_data) 
  1749.  
  1750. 	local morph_sets = {"Brow", "Crown", "Forehead", "Eyes", "Nose", "Cheekbones", "Ears", "Chin", "Mouth", "Jaw"} 
  1751. 	 
  1752. 	for index, morph_set_id in pairs(morph_sets) do 
  1753. 		Store_character_randomizing_morph_set = morph_set_id 
  1754. 		pcr_report_avail_morphs(morph_set_id, "store_character_randomize_one_morph") 
  1755. 	end 
  1756. 	 
  1757. 	pcr_randomize_eye_colors() 
  1758. 	 
  1759. 	Store_character_randomizing_morph_set = -1 
  1760. 	 
  1761. 	-- Now remove all facial features, then pick random one(s) 
  1762. 	pcr_report_composite_items("face features", "store_character_composite_face_features_remove")	 
  1763. 	 
  1764. 	-- super easy algorithm to pick feature, but favor less features over more. 
  1765. 	local one_more_chance = 0.6 -- tweak this value to lower or raise expected number of features 
  1766. 	local random_features = 0 
  1767. 	 
  1768. 	while random_features < MAX_FACIAL_FEATURES do 
  1769. 		if rand_float(0.0, 1.0) > one_more_chance then 
  1770. 			-- we're done! 
  1771. 			random_features = MAX_FACIAL_FEATURES 
  1772. 		else 
  1773. 			pcr_set_random_composite("face features", true) 
  1774. 			random_features = random_features + 1 
  1775. 		end 
  1776. 	end 
  1777. end 
  1778.  
  1779. function store_character_composite_face_features_remove(composite_index, name_crc, name_str, current, colorized, alpha_select, unused_price, unused_respect) 
  1780. 	-- only remove if it's set 
  1781. 	if current then 
  1782. 		pcr_change_composite("face features", composite_index, -1, -1, COMPOSITE_REMOVE) 
  1783. 	end 
  1784. end 
  1785.  
  1786. function store_character_randomize_morph_set(menu_data) 
  1787. 	for i = 1, #Menu_data do 
  1788. 		local curr_item = Menu_data[i] 
  1789. 		local v = rand_float(0.5 - curr_item.rand_range, 0.5 + curr_item.rand_range) 
  1790. 		curr_item.current_value = v 
  1791. 		pcr_apply_morph_value(curr_item.morph_set, curr_item.morph_id, v) 
  1792. 	end 
  1793. 	 
  1794. 	-- redraw the sliders with new values 
  1795. 	local current_index = Active_list:get_selection()	 
  1796. 	store_character_populate_list(Menu_data, current_index)	 
  1797. 	 
  1798. 	pcr_mark_changed() 
  1799. end 
  1800.  
  1801. -- Player accepted morph changes on slider menu 
  1802. -- 
  1803. function store_character_morph_accept() 
  1804. 	game_UI_audio_play("UI_Main_Menu_Select") 
  1805. 	store_common_back_menu() 
  1806. end 
  1807.  
  1808. -- Player hit cancel on slider menu 
  1809. -- 
  1810. function store_character_morph_cancel() 
  1811. 	 
  1812. 	-- restore all to original values 
  1813. 	for i = 1, #Menu_data do 
  1814. 		local curr_item = Menu_data[i] 
  1815. 		pcr_apply_morph_value(curr_item.morph_set, curr_item.morph_id, curr_item.orig_value) 
  1816. 	end	 
  1817. end 
  1818.  
  1819. -- Player hit cancel on slider menu - check if we need to confirm with player before proceeding. 
  1820. -- Return true if a confirm is needed, false if we can proceed. 
  1821. -- 
  1822. function store_character_morph_cancel_confirm() 
  1823. 	if Store_character_cancel_confirm_needed == false then 
  1824. 		return false 
  1825. 	end	 
  1826. 	 
  1827. 	store_character_enable_mouse(false) 
  1828.  
  1829. 	Store_common_popup:populate_list(Yes_no_choices, 2, STORE_COMMON_LIST_SIZE, 2)	 
  1830. 	Store_common_popup:set_title("MENU_TITLE_WARNING") 
  1831. 	Store_common_popup:set_text("CANCEL_WARNING_BODY")		 
  1832. 	Store_common_popup:nav_enable(true, "store_character_morph_cancel_final", "store_character_popup_nav") 
  1833. 	Not_popup_grp:set_alpha(.5)	 
  1834. 	Active_list:set_visible(false) 
  1835. 	 
  1836. 	return true 
  1837. end 
  1838.  
  1839. function store_character_morph_cancel_final(event) 
  1840. 	Store_common_popup:nav_enable(false, nil, nil) 
  1841. 	Not_popup_grp:set_alpha(1) 
  1842. 	Active_list:set_visible(true) 
  1843. 	 
  1844. 	-- The user hit the B button and are cancelling the cancel :-) 
  1845. 	-- This is redundant to selecting "No" in the list 
  1846. 	if event == "back" then 
  1847. 		game_UI_audio_play("UI_Main_Menu_Nav_Back") 
  1848. 		store_character_enable_mouse(true) 
  1849. 		return 
  1850. 	end 
  1851. 	 
  1852. 	game_UI_audio_play("UI_Main_Menu_Select")	 
  1853. 	 
  1854. 	-- Did we select yes?  This assumes yes is the first item 
  1855. 	if Store_common_popup:get_selected_data() ~= 1 then 
  1856. 		store_character_enable_mouse(true) 
  1857. 		return 
  1858. 	end 
  1859.  
  1860. 	-- Do the cancel 
  1861. 	Store_character_cancel_confirm_needed = false 
  1862.  
  1863. 	store_common_button_b() 
  1864. end 
  1865.  
  1866. function store_character_morph_add(id, name_crc, name_str, value, gender, step_value, rand_range) 
  1867. 	local item = { 
  1868. 		type = TYPE_SLIDER, morph_id = id, morph_set = Store_character_building_morph_set, rand_func = store_character_randomize_morph_set, 
  1869. 		is_gender = gender, on_value_update = store_character_morph_change, label_crc = name_crc, label = name_str, 
  1870. 		orig_value = value, current_value = value, min = 0, max = 1, step = step_value, rand_range = rand_range, 
  1871. 		on_select = store_character_morph_accept, on_cancel = store_character_morph_cancel, on_cancel_confirm = store_character_morph_cancel_confirm 
  1872. 	} 
  1873.  
  1874. 	local menu_idx = #Store_common_sub_menu + 1 
  1875. 	Store_common_sub_menu[menu_idx] = item 
  1876. end 
  1877.  
  1878. function store_character_morph_menu_build(menu_data) 
  1879.  
  1880. 	Store_character_building_morph_set = {} 
  1881. 	Store_character_building_morph_set = menu_data.morph_set 
  1882. 	 
  1883. 	pcr_report_avail_morphs(menu_data.morph_set, "store_character_morph_add") 
  1884.  
  1885. 	Store_character_cancel_confirm_needed = false 
  1886. 	 
  1887. 	if menu_data.camera ~= nil then 
  1888. 		store_set_camera_pos(menu_data.camera) 
  1889. 	end 
  1890. end 
  1891.  
  1892. function store_character_eye_color_add(id, swatch_crc, label_crc, label_str, current) 
  1893.  
  1894. 	local menu_idx = #Color_grid_data + 1 
  1895.  
  1896. 	local item = { 
  1897. 		index = menu_idx, id = id, icon_crc = swatch_crc, label_crc = label_crc, label = label_str, color = {red = 1, green = 1, blue = 1}, 
  1898. 	} 
  1899.  
  1900. 	Color_grid_data[menu_idx] = item 
  1901.  
  1902. 	if current == true then 
  1903. 		Color_grid_idx = menu_idx 
  1904. 		Store_character_orig_eye_color = id 
  1905. 	end 
  1906. end 
  1907.  
  1908. function store_character_eye_grid_show(menu_data) 
  1909. 	-- Disable mouse input for hint buttons 
  1910. 	if Hint_bar_mouse_input_tracker ~= -1 then 
  1911. 		Hint_bar_mouse_input_tracker:remove_all() 
  1912. 	end 
  1913.  
  1914. 	--Store_character_original_values.eyes_color = nil 
  1915. 	 
  1916. 	table_clear(Color_grid_data, true) 
  1917. 	Color_grid_idx = 1 
  1918. 	pcr_report_eye_colors("store_character_eye_color_add") 
  1919.  
  1920. 	-- Load Hair Swatches 
  1921. 	game_peg_load_with_cb("store_character_eye_swatch_loaded",1,"ui_bms_pcr_eyes") 
  1922. 	store_lock_controls()		 
  1923.  
  1924. 	store_set_camera_pos("eyes") 
  1925. 	 
  1926. 	-- take randomize choice out of hints 
  1927. 	local hint_data = { {CTRL_MENU_BUTTON_B, "MENU_BACK"} } 
  1928. 	Store_common_hint_bar:set_hints(hint_data) 
  1929. 	 
  1930. 	-- Re-enable mouse input for hint buttons 
  1931. 	if Hint_bar_mouse_input_tracker ~= -1 then 
  1932. 		Store_common_hint_bar:add_mouse_inputs("store_character", Hint_bar_mouse_input_tracker) 
  1933. 		Hint_bar_mouse_input_tracker:subscribe(true) 
  1934. 	end 
  1935. end 
  1936.  
  1937. -- Leaving head/face submenu. Currently just makes sure we reposition the camera. 
  1938. -- 
  1939. function store_character_face_menu_back(menu_data) 
  1940. 	table_clear(Color_grid_data, true) 
  1941.  
  1942. 	store_set_camera_pos("head") 
  1943. 	 
  1944. 	store_character_creation_strip_clothes()	 
  1945. end 
  1946.  
  1947. function store_character_eye_delayed_set() 
  1948. 	delay(0.4) 
  1949.  
  1950. 	pcr_change_eye_color(Store_character_eye_selected) 
  1951. 	Store_character_nav_value = nil 
  1952. 	Store_character_nav_thread = -1 
  1953. end 
  1954.  
  1955. function store_character_eye_grid_nav(event, value) 
  1956. 	store_character_grid_nav(event, value) 
  1957. 	 
  1958. 	-- set the color and preview the item 
  1959. 	local idx = Store_common_color_grid:return_selected_index() 
  1960. 	Store_character_eye_selected = Color_grid_data[idx].id 
  1961. 	 
  1962. 	if Store_character_nav_thread ~= -1 then 
  1963. 		thread_kill(Store_character_nav_thread) 
  1964. 		Store_character_nav_thread = -1 
  1965. 	end 
  1966. 	 
  1967. 	Store_character_nav_thread = thread_new("store_character_eye_delayed_set")	 
  1968. end 
  1969.  
  1970.  
  1971. function store_character_eye_swatch_loaded() 
  1972.  
  1973. 	store_unlock_controls() 
  1974.  
  1975. 	Store_common_color_grid:draw_items(Color_grid_data, Color_grid_idx, 7, 2, 59, 64, 25) 
  1976. 	Store_common_color_grid:nav_enable(true, "store_character_eye_color_selected", "store_character_eye_grid_nav")		 
  1977. 	Store_common_color_grid:set_visible(true)	 
  1978. 	Active_list:set_visible(false) 
  1979. 	 
  1980. 	Current_tier = EYE_COLOR_TIER 
  1981. 	store_character_enable_mouse(false, false) 
  1982. 	 
  1983. 	-- set the titles on top 
  1984. 	Store_header:push_title(nil, "CUST_EYE_COLOR")		 
  1985. end 
  1986.  
  1987. function store_character_eye_color_selected(event) 
  1988. 	 
  1989. 	-- remove hair color title 
  1990. 	Store_header:pop_title()	 
  1991. 	 
  1992. 	-- Did the player select a color? 
  1993. 	if event == "select" or event == "mouse_click" then 
  1994. 	 
  1995. 		game_UI_audio_play("UI_Main_Menu_Select") 
  1996. 		 
  1997. 		local idx = Store_common_color_grid:return_selected_index() 
  1998.  
  1999. 		if idx <= #Color_grid_data then 
  2000. 			pcr_change_eye_color(Color_grid_data[idx].id) 
  2001. 			pcr_mark_changed() 
  2002. 		end 
  2003. 	else 
  2004. 		if Store_character_nav_thread > -1 then 
  2005. 			thread_kill(Store_character_nav_thread) 
  2006. 			Store_character_nav_thread = -1 
  2007. 		end 
  2008. 		 
  2009. 		pcr_change_eye_color(Store_character_orig_eye_color) 
  2010. 	end	 
  2011. 	 
  2012. 	game_peg_unload("ui_bms_pcr_eyes") 
  2013. 	 
  2014. 	Store_common_color_grid:nav_enable(false, nil, nil) 
  2015. 	Store_common_color_grid:cleanup()	 
  2016. 	Store_common_color_grid:set_visible(false) 
  2017. 	Active_list:set_visible(true) 
  2018. 	table_clear(Color_grid_data, true) 
  2019. 	 
  2020. 	Current_tier = MENU_TIER 
  2021. 	store_character_enable_mouse(true, false) 
  2022.  
  2023. 	-- restore camera back to head position 
  2024. 	store_character_face_menu_back()	 
  2025. 	 
  2026. 	-- repopulate menu to restore hints 
  2027. 	store_character_populate_list(Menu_data, Active_list:get_selection()) 
  2028. end 
  2029.  
  2030.  
  2031. -- Personality menus 
  2032. -------------------------------------------- 
  2033.  
  2034. -- voice 
  2035. function store_character_set_voice(menu_data) 
  2036. 	pcr_set_voice(menu_data.voice, false) 
  2037. 	pcr_mark_changed() 
  2038. end 
  2039.  
  2040. function store_character_set_pitch(menu_data) 
  2041. 	local pitch = menu_data.current_value/100 
  2042. 	pcr_set_voice_pitch(pitch)  
  2043. end 
  2044.  
  2045. function store_character_confirm_pitch(menu_data) 
  2046. 	Original_pitch = pcr_get_voice_pitch() 
  2047. 	store_common_back_menu() 
  2048. 	store_common_back_menu() 
  2049. end 
  2050.  
  2051. function store_character_revert_pitch(menu_data) 
  2052. 	pcr_set_voice_pitch(Original_pitch) 
  2053. end 
  2054.  
  2055.  
  2056. function store_character_preview_voice(menu_data) 
  2057. 	pcr_set_voice(menu_data.voice, true) 
  2058. end 
  2059.  
  2060. function store_character_movement_select(menu_data) 
  2061. 	pcr_set_anim(menu_data.anim_grp, menu_data.anim_id) 
  2062. 	store_common_back_menu() 
  2063. end 
  2064.  
  2065. function store_character_movement_revert(menu_data) 
  2066. 	pcr_set_anim(menu_data.anim_grp, Store_character_original_anim_id) 
  2067. end 
  2068.  
  2069. function store_character_movement_stop() 
  2070. 	pcr_preview_anim(nil) 
  2071. end 
  2072.  
  2073. function store_character_movement_nav(menu_data) 
  2074. 	pcr_preview_anim(menu_data.anim_grp) 
  2075. 	pcr_set_anim(menu_data.anim_grp, menu_data.anim_id) 
  2076. end 
  2077.  
  2078. function store_character_movement_add_item(display_name, id, current) 
  2079.  
  2080. 	local menu_idx = #Store_common_sub_menu + 1 
  2081.  
  2082. 	local item = { label = display_name, type = TYPE_BUTTON, anim_id = id, anim_grp = Store_character_movement_anim_grp,  
  2083. 		on_nav = store_character_movement_nav, on_select = store_character_movement_select, on_cancel = store_character_movement_revert, 
  2084. 	} 
  2085. 	 
  2086. 	if current == true then 
  2087. 		Store_character_original_anim_id = id 
  2088. 		Store_common_sub_menu.start_index = menu_idx 
  2089. 	end 
  2090. 	 
  2091. 	Store_common_sub_menu[menu_idx] = item 
  2092. end 
  2093.  
  2094. function store_character_movement_show(menu_data) 
  2095. 	Store_common_sub_menu.start_index = 1 
  2096. 	Store_character_movement_anim_grp = menu_data.anim_group 
  2097. 	pcr_report_anims(menu_data.anim_group, "store_character_movement_add_item") 
  2098. 	if #Store_common_sub_menu == 0 then 
  2099. 		Store_common_sub_menu[1] = { label = "NO_OPTIONS_RIGHT_NOW", type = TYPE_BUTTON, anim_grp = -1, anim_id = -1 } 
  2100. 	else		 
  2101. 		store_character_movement_nav(Store_common_sub_menu[Store_common_sub_menu.start_index]) 
  2102. 	end 
  2103. end 
  2104.  
  2105. function store_character_pitch_menu_fill(menu_data) 
  2106. 	Original_pitch = pcr_get_voice_pitch() 
  2107. 	local store_character_pitch_menu = { 
  2108. 		{ label = "CUST_VOICE_PITCH",		type = TYPE_SLIDER,  on_value_update = store_character_set_pitch, on_select = store_character_confirm_pitch, on_cancel = store_character_revert_pitch, min = -100, max = 100, step = 10, s_snap = 5, s_value = 50, current_value = floor(Original_pitch*100)}, 
  2109. 	} 
  2110. 	Store_common_sub_menu = store_character_pitch_menu 
  2111. end 
  2112.  
  2113. function store_character_voice_menu_fill(menu_data) 
  2114.  
  2115. 	local store_character_presets_voice_menu = { 
  2116. 		{ label = "CUST_VOICE_MALE_WHITE",		type = TYPE_BUTTON, on_nav = store_character_preview_voice, on_select = store_character_set_voice, voice = "MALE_WHITE" , on_sub_menu_fill = store_character_pitch_menu_fill}, 
  2117. 		{ label = "CUST_VOICE_MALE_BLACK", 		type = TYPE_BUTTON, on_nav = store_character_preview_voice, on_select = store_character_set_voice, voice = "MALE_BLACK" , on_sub_menu_fill = store_character_pitch_menu_fill}, 
  2118. 		{ label = "CUST_VOICE_MALE_LATINO", 	type = TYPE_BUTTON, on_nav = store_character_preview_voice, on_select = store_character_set_voice, voice = "MALE_WHITE_ACCENT" , on_sub_menu_fill = store_character_pitch_menu_fill}, 
  2119. 		{ label = "CUST_VOICE_FEMALE_WHITE",	type = TYPE_BUTTON, on_nav = store_character_preview_voice, on_select = store_character_set_voice, voice = "FEMALE_WHITE" , on_sub_menu_fill = store_character_pitch_menu_fill}, 
  2120. 		{ label = "CUST_VOICE_FEMALE_BLACK", 	type = TYPE_BUTTON, on_nav = store_character_preview_voice, on_select = store_character_set_voice, voice = "FEMALE_BLACK" , on_sub_menu_fill = store_character_pitch_menu_fill}, 
  2121. 		{ label = "CUST_VOICE_FEMALE_LATINO", 	type = TYPE_BUTTON, on_nav = store_character_preview_voice, on_select = store_character_set_voice, voice = "FEMALE_LATINO" , on_sub_menu_fill = store_character_pitch_menu_fill}, 
  2122. 		{ label = "CUST_VOICE_ZOMBIE", 			type = TYPE_BUTTON, on_nav = store_character_preview_voice, on_select = store_character_set_voice, voice = "ZOMBIE" , on_sub_menu_fill = store_character_pitch_menu_fill},	 
  2123. 	} 
  2124.  
  2125. 	Store_common_sub_menu = store_character_presets_voice_menu 
  2126. 	 
  2127. 	-- get index of current voice setting; add 1 because lua menu starts at index 1 instead of 0 
  2128. 	local selected_voice = pcr_get_voice() + 1 
  2129. 	 
  2130. 	-- check for valid range 
  2131. 	if selected_voice >= 1 and selected_voice <= #store_character_presets_voice_menu then 
  2132. 		-- set as highlighted option 
  2133. 		Store_common_sub_menu.start_index = selected_voice 
  2134. 		 
  2135. 		-- and play a preview of it 
  2136. 		store_character_preview_voice(store_character_presets_voice_menu[selected_voice]) 
  2137. 	end 
  2138. end 
  2139.  
  2140. -- Main menu 
  2141. -------------------------------------------- 
  2142.  
  2143. function store_character_exit_final(event, value) 
  2144. 	Store_common_popup:nav_enable(false, nil, nil) 
  2145. 	 
  2146. 	-- The user hit the B button and is exiting 
  2147. 	-- This is redundant to selecting "No" in the list 
  2148. 	 
  2149. 	 
  2150. 	 
  2151. 	if event == "back" then 
  2152. 		game_UI_audio_play("UI_Main_Menu_Nav_Back")	 
  2153. 		Not_popup_grp:set_alpha(1) 
  2154. 		Active_list:set_visible(true) 
  2155. 		store_character_enable_mouse(true) 
  2156. 		return 
  2157. 	end 
  2158. 	 
  2159. 	game_UI_audio_play("UI_Main_Menu_Select") 
  2160. 	 
  2161. 	-- Make sure the popup is set to the correct selection when the user clicks on a button 
  2162. 	if event == "mouse_click" then 
  2163. 		local new_index = Store_common_popup.list:get_button_index(value) 
  2164. 		if new_index ~= 0 then 
  2165. 			Store_common_popup.list:set_selection(new_index) 
  2166. 		end 
  2167. 	end 
  2168. 	 
  2169. 	-- Did we select yes?  This assumes yes is the first item 
  2170. 	if Store_common_popup:get_selected_data() ~= 1 then 
  2171. 		Not_popup_grp:set_alpha(1) 
  2172. 		Active_list:set_visible(true) 
  2173. 		store_character_enable_mouse(true) 
  2174. 		return 
  2175. 	end 
  2176. 	 
  2177. 	store_lock_controls() 
  2178. 	 
  2179. 	Not_popup_grp:set_alpha(0) 
  2180. 	 
  2181. 	-- exit the interface.  for police lineup, we need to wait for both players in co-op 
  2182. 	if pcr_is_plastic_surgeon() == true then 
  2183. 		pop_screen() 
  2184. 	else 
  2185. 		pcr_creation_complete() 
  2186. 		--local anim = Vdo_anim_object:new("player_creation_fade_out_anim", 0, Store_character_doc_handle) 
  2187. 		--anim:play() 
  2188. 	end 
  2189. 	 
  2190. 	vint_set_property(vint_object_find("player_creation_grp"), "background", false) 
  2191. 	 
  2192. end 
  2193.  
  2194. -- Player has requested to leave the store.  Get confirmation before doing so. 
  2195. -- 
  2196. function store_character_exit(menu_data) 
  2197.  
  2198. 	local body 
  2199. 	local heading = "MENU_TITLE_WARNING" 
  2200. 	 
  2201. 	-- Not allowed to leave store until streaming of character assets is done 
  2202. 	if pcu_is_streaming_done() == false then 
  2203. 		return 
  2204. 	end 
  2205. 	 
  2206. 	if pcr_is_plastic_surgeon() == true then 
  2207. 		body = "SURGEON_FINISHED_FULL" 
  2208. 	else 
  2209. 		body = "CUST_EXIT_WARNING_BODY" 
  2210. 	end 
  2211. 	 
  2212. 	store_character_enable_mouse(false) 
  2213. 	 
  2214. 	Store_common_popup:populate_list(Yes_no_choices, 2, STORE_COMMON_LIST_SIZE, 2)	 
  2215. 	Store_common_popup:set_title(heading) 
  2216. 	Store_common_popup:set_text(body)		 
  2217. 	Store_common_popup:nav_enable(true, "store_character_exit_final", "store_character_popup_nav") 
  2218. 	Not_popup_grp:set_alpha(.5)	 
  2219. 	Active_list:set_visible(false) 
  2220. end 
  2221.  
  2222. -- We have returned to the top level menu.  Currently restores camera position and 
  2223. -- makes sure the thread for preset updates is killed.  Also returns clothes on the player in creation. 
  2224. -- 
  2225. function store_character_return_main(menu_data) 
  2226. 	store_character_preset_cleanup() 
  2227. 	store_set_camera_pos("body")	 
  2228. 	store_character_creation_add_clothes()	 
  2229. 	 
  2230. 	Color_grid_idx			= 1 
  2231. 	Color_slot_chosen		= 0 
  2232. 	table_clear(Color_grid_data, true) 
  2233. 	Prev_index = -1 
  2234. 	Store_character_randomizing_morph_set = -1 
  2235. 	Store_character_building_morph_set = -1 
  2236. 	Store_character_preset_previous_settings = -1 
  2237. 	Store_character_current_composite_area = -1 
  2238. 	Store_character_current_composite_item = -1 
  2239. 	Store_character_current_composite_color = -1 
  2240. 	Store_character_current_composite_alpha = -1 
  2241. 	Store_character_allow_multiple_composites = -1 
  2242. 	Store_character_composites_allowed = -1 
  2243. 	Store_character_composites_used = -1 
  2244. 	Store_character_hair_acc_info = { 
  2245. 		colors = { [0] = { }, [1] = { }, [2] = { } } 
  2246. 	} 
  2247. 	Color_prev_color		= 0 
  2248. 	Store_character_hair_values = {} 
  2249. 	Store_character_skin_color_current_setting = -1 
  2250. 	Store_character_skin_color_selected = 0 
  2251. 	Store_character_eye_selected = 0 
  2252. 	Store_character_movement_anim_grp = -1 
  2253. 	Store_character_orig_eye_color = -1 
  2254. 	Store_character_strength = -1 
  2255. 	Store_character_skinny = -1 
  2256. 	Store_character_fat = -1 
  2257. 	Store_character_tentative_preset_data = -1 
  2258. 	 
  2259. 	-- kill update thread if it's still around 
  2260. 	if Store_character_nav_thread ~= -1 then 
  2261. 		thread_kill(Store_character_nav_thread) 
  2262. 		Store_character_nav_thread = -1 
  2263. 	end	 
  2264. end 
  2265.  
  2266. function store_character_set_start_camera() 
  2267. 	if Store_character_init_camera_moved == false then 
  2268. 		store_set_camera_pos("body")	 
  2269. 		store_start_lighting_change() 
  2270. 		Store_character_init_camera_moved = true 
  2271. 	end 
  2272. end 
  2273.  
  2274. -- Load the online character gallery. 
  2275. -- 
  2276. function store_character_load_gallery() 
  2277. 	Store_character_new_state_on_validation = GALLERY_FULL_STATE 
  2278. 	Online_check_thread = thread_new("store_character_check_online_for_gallery") 
  2279. end 
  2280.  
  2281. function store_character_check_online_for_gallery() 
  2282. 	store_set_camera_pos("body") 
  2283. 	 
  2284. 	-- Unsubscribe from lineup input if in lineup so user can't move left and right while validating online connection	 
  2285. 	if Lineup_input_tracker ~= -1 and Store_character_current_state == LINEUP_STATE then 
  2286. 		Lineup_input_tracker:subscribe(false) 
  2287. 		if game_get_platform() == "PC" then	 
  2288. 			Lineup_mouse_input_tracker:subscribe(false)			 
  2289. 		end 
  2290. 	end 
  2291. 	 
  2292. 	-- Unsubscribe from hint bar inputs on pc while validating online connection 
  2293. 	if game_get_platform() == "PC" then	 
  2294. 		Hint_bar_mouse_input_tracker:subscribe(false) 
  2295. 	end 
  2296. 	 
  2297. 	store_common_input_disable() 
  2298. 	store_lock_controls() 
  2299. 	 
  2300. 	online_and_privilege_validator_begin(false, true, true, true, true, true)	-- Check we're signed in and we have content permissions 
  2301. 	while Online_validator_result == ONLINE_VALIDATOR_IN_PROGRESS do 
  2302. 		thread_yield() 
  2303. 	end 
  2304. 	 
  2305. 	-- Resubscribe to lineup inputs if in lineup now that online check is done 
  2306. 	if Lineup_input_tracker  ~= -1 and Store_character_current_state == LINEUP_STATE then 
  2307. 		Lineup_input_tracker:subscribe(true) 
  2308. 		if game_get_platform() == "PC" then	 
  2309. 			Lineup_mouse_input_tracker:subscribe(true) 
  2310. 		end 
  2311. 	end 
  2312. 	 
  2313. 	-- Resubscribe to hint bar inputs now that online check is done 
  2314. 	if game_get_platform() == "PC" then	 
  2315. 		Hint_bar_mouse_input_tracker:subscribe(true) 
  2316. 	end 
  2317. 	 
  2318. 	store_common_input_enable() 
  2319. 	store_unlock_controls() 
  2320. 	 
  2321. 	if game_get_platform() == "XBOX360" or (game_get_platform() == "XBOX3") then 
  2322. 		if main_menu_xbox_get_age_group() ~= "adult" then 
  2323. 			dialog_box_message( "MENU_TITLE_NOTICE", "PLATFORM_XBOX_COMMUNITY_AGE_RESTRICTED" ) 
  2324. 			return 
  2325. 		end 
  2326. 	end 
  2327. 	 
  2328. 	if Online_validator_result ~= ONLINE_VALIDATOR_PASSED then 
  2329. 		return 
  2330. 	end 
  2331.  
  2332. 	if main_menu_check_user_content() == false then 
  2333. 		dialog_box_message("MENU_TITLE_WARNING", "USER_CONTENT_PRIV_DENIED") 
  2334. 		return 
  2335. 	end 
  2336. 	 
  2337. 	pcr_restore_clothing() 
  2338.  
  2339. 	-- proceed to the character gallery (could be full menu or download only, based on where we're coming from) 
  2340. 	store_character_change_state(Store_character_new_state_on_validation) 
  2341. 	 
  2342. 	-- Entering the character gallery, disable the input for the store character 
  2343. 	if Lineup_input_tracker  ~= -1 then 
  2344. 		Lineup_input_tracker:subscribe(false) 
  2345. 		if game_get_platform() == "PC" then	 
  2346. 			Lineup_mouse_input_tracker:subscribe(false) 
  2347. 			Hint_bar_mouse_input_tracker:subscribe(false) 
  2348. 		end 
  2349. 	end 
  2350. 	store_common_input_disable() 
  2351. 	store_lock_controls() 
  2352. 	-- Make the news ticker no longer visible 
  2353. 	if pcr_is_plastic_surgeon() == false then 
  2354. 		local ticker_grp_h = vint_object_find("ticker_grp", 0, Store_character_doc_handle) 
  2355. 		vint_set_property(ticker_grp_h, "visible", false) 
  2356. 	end 
  2357.  
  2358. 	Online_check_thread = -1 
  2359. 	 
  2360. 	--Glitch the screen 
  2361. 	glitch_cell() 
  2362. end 
  2363.  
  2364. function store_character_face_menu_fill() 
  2365.  
  2366. 	local face_menu = { 
  2367. 		on_enter = store_character_face_menu_back, 
  2368. 		{ label = "CUST_FACIAL_FEATURES",		type = TYPE_BUTTON, on_sub_menu_fill = store_character_composite_menu_build, 	rand_func = store_character_randomize_all_morphs, 	composite_area = "face features", 						max_selections = MAX_FACIAL_FEATURES,			camera = "eyes",},	 
  2369. 		{ label = "cust_morph_cat_crown",		type = TYPE_BUTTON, on_sub_menu_fill = store_character_morph_menu_build, 		rand_func = store_character_randomize_all_morphs, 	morph_set = "crown", 		camera = "crown",}, 
  2370. 		{ label = "cust_morph_cat_forehead",	type = TYPE_BUTTON, on_sub_menu_fill = store_character_morph_menu_build, 		rand_func = store_character_randomize_all_morphs, 	morph_set = "forehead", 	camera = "forehead",}, 
  2371. 		{ label = "cust_morph_cat_brow",			type = TYPE_BUTTON, on_sub_menu_fill = store_character_morph_menu_build, 		rand_func = store_character_randomize_all_morphs, 	morph_set = "brow", 			camera = "brow",}, 
  2372. 		{ label = "cust_morph_cat_eyes",			type = TYPE_BUTTON, on_sub_menu_fill = store_character_morph_menu_build, 		rand_func = store_character_randomize_all_morphs, 	morph_set = "eyes", 			camera = "eyes",}, 
  2373. 		{ label = "CUST_EYE_COLOR",				type = TYPE_BUTTON, on_select = store_character_eye_grid_show, 					rand_func = store_character_randomize_all_morphs, 	on_back = store_character_face_menu_back,													camera = "eyes",}, 
  2374. 		{ label = "cust_morph_cat_ears",			type = TYPE_BUTTON, on_sub_menu_fill = store_character_morph_menu_build, 		rand_func = store_character_randomize_all_morphs, 	morph_set = "ears", 			camera = "ears",}, 
  2375. 		{ label = "cust_morph_cat_cheekbones", type = TYPE_BUTTON, on_sub_menu_fill = store_character_morph_menu_build, 		rand_func = store_character_randomize_all_morphs, 	morph_set = "cheekbones",	camera = "cheekbones",}, 
  2376. 		{ label = "cust_morph_cat_nose",			type = TYPE_BUTTON, on_sub_menu_fill = store_character_morph_menu_build, 		rand_func = store_character_randomize_all_morphs, 	morph_set = "nose", 			camera = "nose",}, 
  2377. 		{ label = "cust_morph_cat_mouth",		type = TYPE_BUTTON, on_sub_menu_fill = store_character_morph_menu_build, 		rand_func = store_character_randomize_all_morphs, 	morph_set = "mouth", 		camera = "mouth",}, 
  2378. 		{ label = "cust_morph_cat_chin",			type = TYPE_BUTTON, on_sub_menu_fill = store_character_morph_menu_build, 		rand_func = store_character_randomize_all_morphs, 	morph_set = "chin", 			camera = "chin",}, 
  2379. 		{ label = "cust_morph_cat_jaw",			type = TYPE_BUTTON, on_sub_menu_fill = store_character_morph_menu_build, 		rand_func = store_character_randomize_all_morphs, 	morph_set = "jaw", 			camera = "jaw",}, 
  2380. 	} 
  2381.  
  2382. 	Store_common_sub_menu = face_menu 
  2383. end 
  2384.  
  2385. function store_character_makeup_menu_fill() 
  2386.  
  2387. 	local makeup_menu = { 
  2388. 		on_enter = store_character_makeup_enter_menu, 
  2389. 		{ label = "CUST_EYELINER",						type = TYPE_BUTTON, on_sub_menu_fill = store_character_composite_menu_build, rand_func = store_character_makeup_randomize, composite_area = "makeup eyeliner",		camera = "eyes", }, 
  2390. 		{ label = "CUST_EYESHADOW", 					type = TYPE_BUTTON, on_sub_menu_fill = store_character_composite_menu_build, rand_func = store_character_makeup_randomize, composite_area = "makeup eyeshadow",	camera = "eyes", }, 
  2391. 		{ label = "CUST_CAT_MAKEUP_CHEEKS", 		type = TYPE_BUTTON, on_sub_menu_fill = store_character_composite_menu_build, rand_func = store_character_makeup_randomize, composite_area = "makeup cheeks",		camera = "head", }, 
  2392. 		{ label = "CUST_CAT_MAKEUP_MOUTH",			type = TYPE_BUTTON, on_sub_menu_fill = store_character_composite_menu_build, rand_func = store_character_makeup_randomize, composite_area = "lips", 					camera = "head" }, 
  2393. 		{ label = "CUST_CAT_MAKEUP_ENTIRE_FACE",	type = TYPE_BUTTON, on_sub_menu_fill = store_character_composite_menu_build, rand_func = store_character_makeup_randomize, composite_area = "makeup entire face", camera = "head", }, 
  2394. 		{ label = "CUST_FACIAL_ITEMS", 				type = TYPE_BUTTON, on_sub_menu_fill = store_character_composite_menu_build, rand_func = store_character_makeup_randomize, composite_area = "face items", 			camera = "entire face", },	 
  2395. 		{ label = "CUST_CAT_FINGERNAILS",			type = TYPE_BUTTON, on_sub_menu_fill = store_character_composite_menu_build, rand_func = store_character_makeup_randomize, composite_area = "fingernails", 			camera = "hands", }, 
  2396. 	} 
  2397.  
  2398. 	Store_common_sub_menu = makeup_menu 
  2399. end 
  2400.  
  2401. function store_character_personality_menu_fill() 
  2402.  
  2403. 	local personality_menu = { 
  2404. 		on_enter = 	store_character_movement_stop, 
  2405. 		{ label = "CUST_VOICE",						type = TYPE_BUTTON, on_sub_menu_fill = store_character_voice_menu_fill }, 
  2406. 		{ label = "CUST_MOVEMENT_COMPLIMENT", 	type = TYPE_BUTTON, on_sub_menu_fill = store_character_movement_show, anim_group = "compliment_style",  }, 
  2407. 		{ label = "CUST_MOVEMENT_TAUNT", 		type = TYPE_BUTTON, on_sub_menu_fill = store_character_movement_show, anim_group = "taunt_style", }, 
  2408. 	} 
  2409.  
  2410. 	Store_common_sub_menu = personality_menu 
  2411. end 
  2412.  
  2413. function store_character_main_menu_fill() 
  2414.  
  2415. 	local main_menu = { 
  2416. 		on_enter = store_character_return_main, 
  2417. 		{ label = "CUST_MENU_GLOBAL", 			type = TYPE_BUTTON, id = 2, on_sub_menu_fill = store_character_fill_global_menu, 		camera = "body", }, 
  2418. 		{ label = "CUST_MENU_FINE_TUNING", 		type = TYPE_BUTTON, id = 3, on_sub_menu_fill = store_character_face_menu_fill, 			camera = "head", }, 
  2419. 		{ label = "CUST_MENU_HAIR", 				type = TYPE_BUTTON, id = 4, on_sub_menu_fill = store_character_fill_hair_menu, 			camera = "head", }, 
  2420. 		{ label = "CUST_MENU_MAKEUP", 			type = TYPE_BUTTON, id = 5, on_sub_menu_fill = store_character_makeup_menu_fill, 		camera = "head", }, 
  2421. 		{ label = "CUST_MENU_MOVEMENT", 			type = TYPE_BUTTON, id = 6, on_sub_menu_fill = store_character_personality_menu_fill,	camera = "body", }, 
  2422. 		{ label = "STORE_CHARACTER_GALLERY", 	type = TYPE_BUTTON, 			 on_select = store_character_load_gallery, 										  	  }, 
  2423. 		{ label = "STORE_EXIT", 					type = TYPE_BUTTON, id = 7, on_select = store_character_exit 													  	  } 
  2424. 	} 
  2425. 	 
  2426. 	Menu_data = main_menu 
  2427. end 
  2428.  
  2429.  
  2430.  
  2431. ---------------------------------------------------------------------------  
  2432. -- Initialize Character Store 
  2433. --------------------------------------------------------------------------- 
  2434. function store_character_init() 
  2435. 	--Hide screen while loading 
  2436. 	local screen_grp_h = vint_object_find("screen_grp") 
  2437. 	vint_set_property(screen_grp_h, "visible", false) 
  2438. 	 
  2439. 	 
  2440. 	if pcr_is_plastic_surgeon() then 
  2441. 		Store_common_current_highlight_color = COLOR_STORE_CHARACTER_PRIMARY 
  2442. 	else 
  2443. 		Store_common_current_highlight_color = COLOR_GOLD 
  2444. 	end 
  2445. 	 
  2446. 	Game_platform = game_get_platform() 
  2447. 	 
  2448. 	thread_new( "store_character_map_dump" ) 
  2449. end 
  2450.  
  2451. function store_character_map_dump() 
  2452. 	-- unload the full screen map to pillage memory 
  2453. 	pause_map_dump( true ) 
  2454. 	 
  2455. 	-- Find doc handle 
  2456. 	Store_character_doc_handle = vint_document_find("store_character") 
  2457.  
  2458. 	-- Set up some callbacks for the common store script 
  2459. 	Store_common_allow_input_cb	= store_character_allow_input 
  2460. 	Store_common_populate_list_cb = store_character_populate_list 
  2461. 	Store_common_exit_cb				= store_character_exit 
  2462.  
  2463. 	-- Subscribe to the button presses we need, Input_tracker is created in store_common.lua 
  2464. 	Input_tracker:add_input("alt_select", "store_character_confirm_randomize", 50)	 
  2465. 	store_lock_controls() 
  2466. 	 
  2467. 	if Game_platform == "PC" then 
  2468. 		Hint_bar_mouse_input_tracker = Vdo_input_tracker:new() 
  2469. 	end 
  2470. 	 
  2471. 	--Setup Button Hints 
  2472. 	local hint_data = { 
  2473. 		{CTRL_MENU_BUTTON_B, "MENU_BACK"}, 
  2474. 	} 
  2475. 	Store_common_hint_bar:set_hints(hint_data)  
  2476. 	Store_common_hint_bar:set_visible(true)	 
  2477. 	 
  2478. 	if game_is_active_input_gamepad() then 
  2479. 		local hint_rotate_data = { 
  2480. 			{CTRL_BUTTON_RS, "STORE_ZOOM_ROTATE"}, 
  2481. 		} 
  2482. 		Store_common_rotate_hint:set_hints(hint_rotate_data) 	 
  2483. 		Store_common_rotate_hint:enable_text_shadow(true) 
  2484. 		if game_get_platform() ~= "PC" then 
  2485. 			Store_common_rotate_hint:set_visible(true) 
  2486. 		end 
  2487. 	end 
  2488. 	 
  2489. 	Store_header:set_visible(true)		 
  2490. 		 
  2491. 	-- Everything that is not in the popup so we can fade it when the popup is active 
  2492. 	Not_popup_grp = Vdo_base_object:new("not_popup_grp", 0, Store_common_doc_handle) 
  2493.  
  2494. 	-- Setup purchase popup 
  2495. 	Store_common_popup:set_visible(false) 
  2496. 	Store_common_popup:set_size(STORE_COMMON_LIST_SIZE, (LIST_BUTTON_HEIGHT * 5) + (LIST_BUTTON_SPACE * 5)) 
  2497. 	 
  2498. 	-- Setup Color grid 
  2499. 	Store_common_color_grid:set_visible(false) 
  2500. 	Store_common_color_grid:set_ui_screen("store_character") 
  2501. 	 
  2502. 	-- Setup Triangle Select 
  2503. 	Triangle_select = Vdo_triangle_select:new("store_character_triangle", 0, Store_character_doc_handle) 
  2504. 	Triangle_select:set_visible(false) 
  2505. 	 
  2506. 	-- Populate the areas and draw the first menu 
  2507. 	store_character_main_menu_fill() 
  2508. 	 
  2509. 	local is_plastic_surgeon = pcr_is_plastic_surgeon()		 
  2510. 	 
  2511. 	Store_character_confirm_randomize = is_plastic_surgeon 
  2512. 	 
  2513. 	-- If we're in the character lineup, change the text on the "exit" choice 
  2514. 	if is_plastic_surgeon == false then 
  2515. 		Menu_data[#Menu_data].label = "CUST_MENU_EXIT" 
  2516. 		Menu_data[#Menu_data].is_new = true	 
  2517. 	end 
  2518. 	 
  2519. 	--Set the highlight color here, if you don't it breaks 
  2520. 	Active_list:set_highlight_color(Store_common_current_highlight_color, COLOR_PLAYER_CREATION_SECONDARY, COLOR_PLAYER_CREATION_TERTIARY)		 
  2521. 	 
  2522. 	-- Pass the table data to the megalist vdo. 
  2523. 	store_character_populate_list(Menu_data, 1) 
  2524. 	 
  2525. 	-- Hide background animations 
  2526. 	local player_creation_grp = Vdo_base_object:new("player_creation_grp", 0, Store_character_doc_handle) 
  2527. 	local player_creation_top_grp = Vdo_base_object:new("player_creation_top_grp", 0, Store_character_doc_handle) 
  2528. 	local iad_bg_grp = Vdo_base_object:new("iad_bg_grp", 0, Store_character_doc_handle) 
  2529. 	local ticker_grp_h = vint_object_find("ticker_grp", 0, Store_character_doc_handle) 
  2530. 	local lines_grp_h = vint_object_find("lines_grp", 0, Store_character_doc_handle) 
  2531. 	local customize_grp_h = vint_object_find("customize_grp", 0, Store_character_doc_handle) 
  2532. 	player_creation_top_grp:set_visible(false)	 
  2533. 	player_creation_grp:set_property("background", false) 
  2534. 	vint_set_property(ticker_grp_h, "alpha", 0) 
  2535. 	vint_set_property(lines_grp_h, "alpha", 0) 
  2536. 	vint_set_property(customize_grp_h, "alpha", 0) 
  2537. 	iad_bg_grp:set_visible(false) 
  2538.  
  2539. 	local color_primary, color_secondary, color_tertiary	 
  2540. 	 
  2541. 	--setup common anims and tweens to both stores 
  2542. 	Store_character_in_anim = Vdo_anim_object:new("store_common_in_anim", 0, Store_common_doc_handle) 
  2543. 	local list_x, list_y = Active_list:get_anchor() 
  2544. 	local grid_x, grid_y = Store_common_color_grid:get_anchor() 
  2545. 	Active_list:set_anchor(list_x, STORE_COMMON_LIST_NO_PRICE_Y) 
  2546. 	Store_common_color_grid:set_anchor(grid_x, STORE_COMMON_GRID_NO_PRICE_Y) 
  2547. 	 
  2548. 	-- reset this variable since we might be coming from IAD 
  2549. 	Store_lineup_is_loaded = true 
  2550. 	 
  2551. 	-- What store are we in? 
  2552. 	if is_plastic_surgeon == false then 
  2553. 	 
  2554. 		Store_character_current_state = LINEUP_STATE 
  2555. 	 
  2556. 		--Handle input for character line-up component 
  2557. 			 
  2558. 		-- Gets rid of the repsect meter in player creation 
  2559. 		Store_header:reformat_and_resize(true,435) 
  2560. 		 
  2561. 		-- Change colors for player creation 
  2562. 		color_primary = COLOR_GOLD --COLOR_SAINTS_PURPLE 
  2563. 		--color_primary = COLOR_PLAYER_CREATION_PRIMARY 
  2564. 		color_secondary = COLOR_PLAYER_CREATION_SECONDARY 
  2565. 		color_tertiary = COLOR_PLAYER_CREATION_TERTIARY		 
  2566.  
  2567. 		-- Set background animations  
  2568. 		Store_character_out_anim = Vdo_anim_object:new("store_common_anim_out", 0, Store_common_doc_handle)			 
  2569. 		Player_creation_bg_anim = Vdo_anim_object:new("player_creation_bg_anim", 0, Store_character_doc_handle)	 
  2570. 		local player_creation_start_anim_h = vint_object_find("player_creation_start_anim", 0, Store_character_doc_handle) 
  2571. 		vint_apply_start_values(Store_character_in_anim.handle) 
  2572. 		vint_apply_start_values(Player_creation_bg_anim.handle)		 
  2573. 		vint_apply_start_values(player_creation_start_anim_h) 
  2574. 		 
  2575. 		--Newsticker 
  2576. 		 
  2577. 		local newsticker_h = vint_object_find("newsticker") 
  2578. 		Store_newsticker = Vdo_newsticker:new("newsticker", 0, 0, "store_character.lua", "Store_newsticker") 
  2579. 		 
  2580. 		local twn_h = vint_object_find("new_tween1", Player_creation_bg_anim.handle) 
  2581. 		vint_set_property(twn_h, "end_event", "store_character_bg_anim_done") 
  2582. 		 
  2583. 		Player_creation_bg_anim:play() 
  2584. 		lua_play_anim(player_creation_start_anim_h) 
  2585. 		 
  2586. 		-- MWA - make call to unload the city loading bitmaps - there is weird case where 
  2587. 		-- we enter customization screen right as city is done loading and we need to unload them 
  2588. 		-- Honnigford fixed this, but they were unloading too early.  I'm moving the unload to 
  2589. 		-- be immediately before we need screen. 
  2590. 		--local city_load_doc_h = vint_document_find( "city_load" ) 
  2591. 		--if city_load_doc_h ~= 0 then 
  2592. 		--	city_load_hide_images( ) 
  2593. 		--end 
  2594. 		 
  2595. 		game_peg_load_with_cb("store_character_line_up_is_loaded", 1, "ui_bms_store_line_up") 
  2596. 		--store_character_line_up_is_loaded() 
  2597. 		Store_lineup_is_loaded = false 
  2598. 		 
  2599. 		Active_list:set_visible(false) 
  2600. 		Store_header:set_visible(false) 
  2601. 		Store_common_rotate_hint:set_visible(false) 
  2602. 		 
  2603. 		--vint_set_property(vint_object_find("police_logo"), "visible", false)		 
  2604. 		vint_set_property(vint_object_find( "title_grp", 0, Store_character_doc_handle ), "alpha", 0 ) 
  2605. 		 
  2606. 		-- Change the top level exit callback so that we go back to the character lineup instead of the game. 
  2607. 		Store_common_exit_cb = store_character_lineup_return_confirm 
  2608. 		 
  2609. 		-- Change hint text 
  2610. 		local hint_data = { 
  2611. 			{CTRL_MENU_BUTTON_A, "CUST_CHOOSE_CHARACTER"}, 
  2612. 		} 
  2613. 		Store_common_hint_bar:set_hints(hint_data)  
  2614. 		--Store_common_hint_bar:set_visible(false) 
  2615. 		 
  2616. 		character_enable_mouse_drag(false) 
  2617. 		 
  2618. 	else	 
  2619. 	 
  2620. 		Store_character_current_state = CUSTOMIZATION_STATE 
  2621. 		 
  2622. 		--store_character_select_hide_screen() 
  2623. 		 
  2624. 		-- Change colors for store character 
  2625. 		color_primary = COLOR_STORE_CHARACTER_PRIMARY 
  2626. 		color_secondary = COLOR_STORE_CHARACTER_SECONDARY 
  2627. 		color_tertiary = COLOR_STORE_CHARACTER_TERTIARY	 
  2628. 		 
  2629. 		-- Set animations  
  2630. 		Iad_bg_anim = Vdo_anim_object:new("iad_bg_anim", 0, Store_character_doc_handle)	 
  2631. 		Iad_logo_anim = Vdo_anim_object:new("iad_logo_anim", 0, Store_character_doc_handle)	 
  2632. 		 
  2633. 		-- Set tweens 
  2634. 		local end_event_twn = Vdo_tween_object:new("end_event_twn", Store_character_in_anim.handle) 
  2635. 		end_event_twn:set_end_event("store_unlock_controls") 
  2636. 		 
  2637. 		local iad_end_event_twn = Vdo_tween_object:new("iad_bg_end_event",Iad_bg_anim.handle,Store_character_doc_handle) 
  2638. 		iad_end_event_twn:set_end_event("store_loop_bg_anims") 
  2639. 		 
  2640. 		local twn_h = vint_object_find("new_tween23", Iad_bg_anim.handle) 
  2641. 		vint_set_property(twn_h, "end_event", "store_character_bg_anim_done") 
  2642. 	 
  2643. 		vint_apply_start_values(Iad_bg_anim.handle) 
  2644. 		vint_apply_start_values(Store_character_in_anim.handle) 
  2645. 		vint_apply_start_values(Iad_logo_anim.handle) 
  2646. 		 
  2647. 		ui_audio_post_event("enter_image_as_designed") 
  2648. 		 
  2649. 		-- Stream store graphic then play animation in callback 
  2650. 		game_peg_load_with_cb("store_character_bg_is_loaded", 1, "ui_bms_store_iad") 
  2651. 		 
  2652. 		character_enable_mouse_drag(true) 
  2653. 	end 
  2654. 	 
  2655. 	-- Set colors 
  2656. 	Store_header:set_color(color_primary, color_secondary, color_tertiary)		 
  2657. 	Active_list:set_highlight_color(color_primary, color_secondary, color_tertiary)		 
  2658. 	Store_common_color_grid:set_highlight_color(color_primary, color_secondary, color_tertiary)		 
  2659. 	Triangle_select:set_highlight_color(color_primary, color_secondary, color_tertiary)	 
  2660. 	Store_common_popup:set_color(color_primary, color_secondary, color_tertiary)	 
  2661. 	 
  2662. 	-- Set initial titles 
  2663. 	if pcr_is_plastic_surgeon() == false then 
  2664. 		Store_header:push_title(nil, "STORE_CHOOSE_A_CATEGORY") 
  2665. 	else 
  2666. 		Store_header:set_title() 
  2667. 	end 
  2668. 	 
  2669. end 
  2670.  
  2671. function store_lock_controls()  
  2672. 	Input_tracker:subscribe(false) 
  2673. 	store_character_enable_mouse(false) 
  2674. 	if Input_tracker_body_morph_select ~= nil then 
  2675. 		Input_tracker_body_morph_select:subscribe(false) 
  2676. 	end 
  2677. end 
  2678.  
  2679. function store_unlock_controls() 
  2680. 	Input_tracker:subscribe(true) 
  2681. 	 
  2682. 	if Current_tier == BUILD_TIER then 
  2683. 		if Input_tracker_body_morph_select ~= nil then 
  2684. 			Input_tracker_body_morph_select:subscribe(true) 
  2685. 		end 
  2686. 		if Hint_bar_mouse_input_tracker ~= -1 then 
  2687. 			Hint_bar_mouse_input_tracker:subscribe(true) 
  2688. 		end 
  2689. 	else 
  2690. 		store_character_enable_mouse(true) 
  2691. 	end 
  2692. end 
  2693.  
  2694. function store_loop_bg_anims(tween_handle) 
  2695. 	local animation = vint_object_parent(tween_handle) 
  2696. 	 
  2697. 	-- Loop bg anim starting at frame 40 
  2698. 	lua_play_anim(animation, -1) 
  2699. end 
  2700.  
  2701. -- Callback for when background and related images for lineup are loaded. 
  2702. -- 
  2703. function store_character_line_up_is_loaded() 
  2704.  
  2705. 	local player_creation_top_grp = Vdo_base_object:new("player_creation_top_grp", 0, Store_character_doc_handle) 
  2706. 	player_creation_top_grp:set_visible(true) 
  2707. 	 
  2708. 	image_streamer_add_image("ui_store_lineup_mugshot_04") 
  2709. 	image_streamer_add_image("ui_store_lineup_mugshot_05") 
  2710. 	image_streamer_add_image("ui_store_lineup_mugshot_02") 
  2711. 	image_streamer_add_image("ui_store_lineup_mugshot_03") 
  2712. 	image_streamer_add_image("ui_store_lineup_mugshot_07") 
  2713. 	image_streamer_add_image("ui_store_lineup_mugshot_01") 
  2714. 	image_streamer_add_image("ui_store_lineup_mugshot_08") 
  2715. 	image_streamer_add_image("ui_store_lineup_mugshot_06") 
  2716. 	image_streamer_add_image("ui_store_lineup_mugshot_09")		 
  2717.  
  2718. 	local susan = Vdo_susan:new("susan", 0, Store_character_doc_handle, "store_character.lua", "Susan_object") 
  2719. 	Susan_object = susan 
  2720. 	 
  2721. 	Susan_object:set_visible(false) 
  2722.  
  2723. 	image_streamer_start_streaming(STORE_CHARACTER_NUM_LINEUP_IMAGES - 1, STORE_CHARACTER_NUM_LINEUP_IMAGES_LOADED, store_character_lineup_images_loaded) 
  2724. 	 
  2725. 	 
  2726. 	--store_character_lineup_images_loaded() 
  2727. 	 
  2728. 	-- Turn off customization inputs 
  2729. 	store_lock_controls() 
  2730. 	 
  2731. 	-- subscribe to inputs for the character lineup 
  2732. 	Lineup_input_tracker = Vdo_input_tracker:new() 
  2733. 	Lineup_input_tracker:add_input("nav_left", "store_character_lineup_nav", 50) 
  2734. 	Lineup_input_tracker:add_input("nav_right", "store_character_lineup_nav", 50)	 
  2735. 	Lineup_input_tracker:add_input("select", "store_character_lineup_select", 50)		 
  2736. 	Lineup_input_tracker:subscribe(true) 
  2737. 	 
  2738. 	Susan_mouse_area_img_h = vint_object_find("susan_mouse_area_img", 0 ,Store_character_doc_handle) 
  2739. 	 
  2740. 	if game_get_platform() == "PC" then		 
  2741. 		Lineup_mouse_input_tracker = Vdo_input_tracker:new()		 
  2742. 		Lineup_mouse_input_tracker:add_mouse_input("mouse_click", "store_character_mouse_click", 25, Susan_mouse_area_img_h) 
  2743. 		Lineup_mouse_input_tracker:add_mouse_input("mouse_click", "store_character_mouse_click", 50, Susan_object.arrow_left.handle) 
  2744. 		Lineup_mouse_input_tracker:add_mouse_input("mouse_click", "store_character_mouse_click", 50, Susan_object.arrow_right.handle) 
  2745. 		Lineup_mouse_input_tracker:add_mouse_input("mouse_move", "store_character_mouse_move", 50, Susan_object.arrow_left.handle) 
  2746. 		Lineup_mouse_input_tracker:add_mouse_input("mouse_move", "store_character_mouse_move", 50, Susan_object.arrow_right.handle) 
  2747. 		Lineup_mouse_input_tracker:subscribe(true) 
  2748. 	end 
  2749. 	store_character_enable_mouse_split(false, true, true) 
  2750. 	Current_tier = LINEUP_TIER 
  2751.  
  2752. 	Store_lineup_is_loaded = true 
  2753. 	 
  2754. 	--Show Screen 
  2755. 	local screen_grp_h = vint_object_find("screen_grp") 
  2756. 	vint_set_property(screen_grp_h, "visible", true) 
  2757. 	 
  2758. end 
  2759.  
  2760. -- Callback for when lineup images are done loading. 
  2761. -- 
  2762. function store_character_lineup_images_loaded() 
  2763. 	if Store_character_lineup_init_complete == false then 
  2764. 		Store_character_in_anim:play(0) 
  2765. 		Player_creation_bg_anim:play(0) 
  2766. 		 
  2767. 		Susan_object:set_images(image_streamer_get_images())		 
  2768. 		Susan_object:play_intro() 
  2769. 		Susan_object:set_visible(true) 
  2770.  
  2771. 		Store_character_lineup_init_complete = true 
  2772. 		 
  2773. 		store_character_lineup_loaded() 
  2774. 	end 
  2775. end 
  2776.  
  2777. function store_character_is_lineup_loaded() 
  2778. 	return Store_lineup_is_loaded 
  2779. end 
  2780.  
  2781. function store_character_bg_is_loaded() 
  2782. 	Store_character_in_anim:play(0) 
  2783. 	Iad_bg_anim:play(0) 
  2784. 	Iad_logo_anim:play(0) 
  2785. 	 
  2786. 	-- Unhide background  
  2787. 	local iad_bg_grp = Vdo_base_object:new("iad_bg_grp", 0, Store_character_doc_handle) 
  2788. 	iad_bg_grp:set_visible(true) 
  2789. 	 
  2790. 	--Show Screen 
  2791. 	local screen_grp_h = vint_object_find("screen_grp") 
  2792. 	vint_set_property(screen_grp_h, "visible", true) 
  2793. 	 
  2794. end 
  2795.  
  2796. ---------------------------------------------------------------------------  
  2797. -- Cleanup Character Store 
  2798. --------------------------------------------------------------------------- 
  2799. function store_character_cleanup() 
  2800.  
  2801. 	-- we needed to add a second temporary persona to the player in pcr_set_voice.  This needs to be cleared out on exit 
  2802. 	pcr_cleanup_player_voice() 
  2803.  
  2804. 	-- Nuke all button subscriptions 
  2805. 	store_lock_controls() 
  2806. 	 
  2807. 	game_peg_unload("ui_bms_pcr_tri")	 
  2808. 	game_peg_unload("ui_bms_pcr_skin")	 
  2809. 	game_peg_unload("ui_bms_pcr_eyes")	 
  2810. 	game_peg_unload("ui_bms_pcr_hair")	 
  2811. 	game_peg_unload("ui_bms_store_iad")		 
  2812. 	game_peg_unload("ui_bms_store_line_up") 
  2813. 	 
  2814. 	-- Remove any images from the character lineup 
  2815. 	image_streamer_end_streaming() 
  2816. 	image_streamer_remove_all_images()	 
  2817. 	 
  2818. 	-- reload the full screen map 
  2819. 	pause_map_restore() 
  2820. 	 
  2821. 	character_enable_mouse_drag(false) 
  2822. 	 
  2823. 	-- Some things need to be cleaned up right away when a store doc is unloading, particular disabled inputs which have 
  2824. 	-- callbacks to the script that is unloading. 
  2825. 	store_common_cleanup_current_store()	 
  2826. 	 
  2827. 	if Online_check_thread ~= -1 then 
  2828. 		thread_kill(Online_check_thread) 
  2829. 	end		 
  2830. 	 
  2831. 	if Store_character_clothing_load_thread ~= -1 then 
  2832. 		thread_kill(Store_character_clothing_load_thread) 
  2833. 	end		 
  2834. end 
  2835.  
  2836. -- Populate the active megalist menu, and hide the previous menu 
  2837. -- 
  2838. -- list_data: 		this table contains the data to populate the megalist 
  2839. -- current_index: 	the current index in the menu that's selected 
  2840. -- 
  2841. function store_character_populate_list(list_data, current_index, animate) 
  2842. 	 
  2843. 	Active_list:draw_items(list_data, current_index, STORE_COMMON_LIST_SIZE, 10, LIST_FONT_SCALE, nil, animate) 
  2844. 	Active_list:set_visible(true) 
  2845. 	 
  2846. 	-- Update the hint bar 
  2847. 	 
  2848. 	-- Are we on the main screen? 
  2849. 	local back_hint 
  2850. 	if store_common_stack_get_menu() ~= nil then 
  2851. 		back_hint = {CTRL_MENU_BUTTON_B, "MENU_BACK"} 
  2852. 	else 
  2853. 		-- Are we in plastic surgeon or character creation? 
  2854. 		if pcr_is_plastic_surgeon() then 
  2855. 			back_hint = {CTRL_MENU_BUTTON_B, "STORE_EXIT"}		 
  2856. 		else 
  2857. 			back_hint = {CTRL_MENU_BUTTON_B, "MENU_BACK"} 
  2858. 		end 
  2859. 	end 
  2860. 	 
  2861. 	-- build hint data 
  2862. 	local hint_data = {} 
  2863. 	local hint_count = 0 
  2864. 	 
  2865. 	-- If all the items in the menu are sliders (no submenus) then add an "accept" hint 
  2866. 	-- restore all to original values 
  2867. 	local has_buttons = false 
  2868. 	for i = 1, #list_data do 
  2869. 		if list_data[i].type == TYPE_BUTTON or list_data[i].type == TYPE_TOGGLE_COLOR then 
  2870. 			has_buttons = true 
  2871. 		end 
  2872. 	end 
  2873. 	 
  2874. 	if has_buttons == false then 
  2875. 		hint_count = hint_count + 1 
  2876. 		hint_data[hint_count] = {CTRL_MENU_BUTTON_A, "PAUSE_MENU_ACCEPT"} 
  2877. 	end 
  2878. 	 
  2879. 	-- add back choice 
  2880. 	hint_count = hint_count + 1 
  2881. 	hint_data[hint_count] = back_hint 
  2882. 	 
  2883. 	-- Is there a randomize function? 
  2884. 	if list_data[1].rand_func ~= nil then 
  2885. 		hint_count = hint_count + 1 
  2886. 		hint_data[hint_count] = {CTRL_BUTTON_X, "PLAYER_CREATION_RANDOMIZE"}  
  2887. 	end 
  2888. 	 
  2889. 	Store_common_hint_bar:set_hints(hint_data) 
  2890. 	 
  2891. 	if Game_platform == "PC" then 
  2892. 		Mouse_input_tracker:remove_all() 
  2893. 		Hint_bar_mouse_input_tracker:remove_all() 
  2894. 		 
  2895. 		Active_list:set_store("store_character") 
  2896. 		Active_list:add_mouse_inputs("store_common", Mouse_input_tracker) 
  2897. 		Store_common_hint_bar:add_mouse_inputs("store_character", Hint_bar_mouse_input_tracker) 
  2898. 		store_character_enable_mouse(true) 
  2899. 	end 
  2900. end 
  2901.  
  2902. -- Callback that's called when asynchronous image loading is complete 
  2903. -- 
  2904. function store_character_set_logo() 
  2905. 	-- TODO 
  2906. end 
  2907.  
  2908. -- Handle navigating grid 
  2909. function store_character_grid_nav(event, value) 
  2910.  
  2911. 	if event == "nav_up" then	 
  2912. 		Store_common_color_grid:move_cursor(-2)	 
  2913. 	elseif event == "nav_down" then 
  2914. 		Store_common_color_grid:move_cursor(2) 
  2915. 	elseif event == "nav_left" then 
  2916. 		Store_common_color_grid:move_cursor(-1) 
  2917. 	elseif event == "nav_right" then 
  2918. 		Store_common_color_grid:move_cursor(1) 
  2919. 	elseif event == "mouse_move" then 
  2920. 		-- value contains the target_handle in this case 
  2921. 		local new_index = Store_common_color_grid:get_data_index(value) 
  2922. 		if new_index ~= 0 then 
  2923. 			Store_common_color_grid:set_selection(new_index) 
  2924. 			Store_common_color_grid:move_cursor(0, false, true) 
  2925. 		end 
  2926. 	 
  2927. 	else 
  2928. 		--do nothing 
  2929. 	end 
  2930. end 
  2931.  
  2932. function store_character_confirm_randomize() 
  2933.  
  2934. 	-- Is the active list visible? 
  2935. 	if Active_list:get_visible() == false then 
  2936. 		return 
  2937. 	end 
  2938.  
  2939. 	-- Does a randomization function exist for this data? 
  2940. 	local current_index = Active_list:get_selection() 
  2941.  
  2942. 	if Menu_data[current_index].rand_func == nil then 
  2943. 		return 
  2944. 	end 
  2945.  
  2946. 	-- if we don't need to warn the player first, just randomize 
  2947. 	if Store_character_confirm_randomize == false then 
  2948. 		 
  2949. 		game_UI_audio_play("UI_Main_Menu_Select") 
  2950. 		 
  2951. 		-- Do the randomization 
  2952. 		local current_index = Active_list:get_selection() 
  2953. 		Menu_data[current_index].rand_func(Menu_data[current_index]) 
  2954. 		return 
  2955. 	end 
  2956. 	 
  2957. 	store_character_enable_mouse(false) 
  2958. 	 
  2959. 	Store_common_popup:populate_list(Yes_no_choices, 2, STORE_COMMON_LIST_SIZE, 2)	 
  2960. 	Store_common_popup:set_title("RANDOM_WARNING_HEADING") 
  2961. 	Store_common_popup:set_text("RANDOM_WARNING_BODY")		 
  2962. 	Store_common_popup:nav_enable(true, "store_character_randomize_final", "store_character_popup_nav") 
  2963. 	Not_popup_grp:set_alpha(.5)	 
  2964. 	Active_list:set_visible(false) 
  2965. 	 
  2966. end 
  2967.  
  2968. function store_character_randomize_final(event) 
  2969. 	Store_common_popup:nav_enable(false, nil, nil) 
  2970. 	Not_popup_grp:set_alpha(1) 
  2971. 	Active_list:set_visible(true) 
  2972. 	 
  2973. 	-- The user hit the B button and are cancelling the purchase 
  2974. 	-- This is redundant to selecting "No" in the list 
  2975. 	if event == "back" then 
  2976. 		game_UI_audio_play("UI_Main_Menu_Nav_Back") 
  2977. 		store_character_enable_mouse(true) 
  2978. 		return 
  2979. 	end 
  2980. 	 
  2981. 	game_UI_audio_play("UI_Main_Menu_Select")	 
  2982. 	 
  2983. 	-- Did we select yes?  This assumes yes is the first item 
  2984. 	if Store_common_popup:get_selected_data() ~= 1 then 
  2985. 		store_character_enable_mouse(true) 
  2986. 		return 
  2987. 	end 
  2988.  
  2989. 	-- Do the randomization 
  2990. 	Store_character_confirm_randomize = false 
  2991. 	local current_index = Active_list:get_selection() 
  2992. 	Menu_data[current_index].rand_func(Menu_data[current_index]) 
  2993. 	store_character_enable_mouse(true) 
  2994. 	 
  2995. 	-- We'll now need to confirm if they want to throw the changes out 
  2996. 	Store_character_cancel_confirm_needed = true 
  2997. end 
  2998.  
  2999. function store_character_popup_nav(event, value) 
  3000. 	 
  3001. 	if event == "mouse_move" then 
  3002. 		vint_set_mouse_cursor("") 
  3003. 	end 
  3004. 	 
  3005. 	if event == "nav_up" then	 
  3006. 		Store_common_popup.list:move_cursor(-1)	 
  3007. 	elseif event == "nav_down" then 
  3008. 		Store_common_popup.list:move_cursor(1) 
  3009. 	elseif event == "mouse_move" then 
  3010. 		-- value contains the target_handle in this case 
  3011. 		local new_index = Store_common_popup.list:get_button_index(value) 
  3012. 		if new_index ~= 0 then 
  3013. 			Store_common_popup.list:set_selection(new_index) 
  3014. 			Store_common_popup.list:move_cursor(0, true) 
  3015. 		end 
  3016. 		 
  3017. 	else 
  3018. 		--do nothing 
  3019. 	end 
  3020. 		 
  3021. end 
  3022.  
  3023. function store_character_play_exit_anim() 
  3024. 	 
  3025. 	ui_audio_post_event("UI_Store_Exit") 
  3026. 	 
  3027. 	local anim_out = Vdo_anim_object:new("iad_anim_out", 0, Store_character_doc_handle) 
  3028. 	local end_event_twn = Vdo_tween_object:new("iad_end_event", anim_out.handle) 
  3029. 	 
  3030. 	end_event_twn:set_end_event("store_unload_doc") 
  3031. 	 
  3032. 	if Iad_bg_anim ~= -1 and Iad_bg_anim ~= nil then 
  3033. 		Iad_bg_anim:stop(0) 
  3034. 	end 
  3035. 	anim_out:play(0) 
  3036. 	store_common_play_anim_out() 
  3037.  
  3038. end 
  3039.  
  3040. function store_unload_doc() 
  3041.  
  3042. 	vint_document_unload() 
  3043. 	 
  3044. end 
  3045.  
  3046.  
  3047. -- ===================================== 
  3048. --       Mouse Specific Functions 
  3049. -- ===================================== 
  3050.  
  3051. -- Subscribes or removes subscriptions to all mouse input trackers 
  3052. -- 
  3053. function store_character_enable_mouse(enable, set_hint_bar) 
  3054. 	if Game_platform == "PC" and enable ~= nil then 
  3055. 		if Mouse_input_tracker ~= 0 then 
  3056. 			Mouse_input_tracker:subscribe(enable) 
  3057. 		end 
  3058. 		 
  3059. 		Active_list:enable_toggle_input(enable) 
  3060. 		 
  3061. 		-- The hint bar is defaulted to be subscribed with the other input trackers unless specified 
  3062. 		if set_hint_bar == nil then 
  3063. 			set_hint_bar = true 
  3064. 		end 
  3065. 		if Hint_bar_mouse_input_tracker ~= -1 and set_hint_bar then 
  3066. 			Hint_bar_mouse_input_tracker:subscribe(enable) 
  3067. 		end 
  3068. 	end 
  3069. end 
  3070.  
  3071. -- Subscribes or removes subscriptions to specific mouse input trackers 
  3072. -- 
  3073. function store_character_enable_mouse_split(enable_active_list, enable_hint_bar, enable_lineup) 
  3074. 	if Game_platform == "PC" then 
  3075. 		if Mouse_input_tracker ~= nil then 
  3076. 			Mouse_input_tracker:subscribe(enable_active_list) 
  3077. 		end 
  3078. 		if Hint_bar_mouse_input_tracker ~= -1 then 
  3079. 			Hint_bar_mouse_input_tracker:subscribe(enable_hint_bar) 
  3080. 		end 
  3081. 		if Lineup_mouse_input_tracker ~= nil then 
  3082. 			Lineup_mouse_input_tracker:subscribe(enable_lineup) 
  3083. 		end 
  3084. 	end 
  3085. end 
  3086.  
  3087. function store_character_mouse_click(event, target_handle, mouse_x, mouse_y) 
  3088. 	-- Check if the user clicked on the hint bar 
  3089. 	local hint_index = Store_common_hint_bar:get_hint_index(target_handle) 
  3090. 	if hint_index ~= 0 then 
  3091. 		-- Depending on the current tier, clicking on the "Back" button on the hint bar needs 
  3092. 		-- to call different functions 
  3093. 		if Store_common_hint_bar.hint_data[hint_index][1] == CTRL_BUTTON_X then 
  3094. 			store_character_confirm_randomize() 
  3095. 		elseif Current_tier == LINEUP_TIER and Store_character_current_state == LINEUP_STATE then 
  3096. 			store_character_lineup_select(event) 
  3097. 		elseif Store_common_hint_bar.hint_data[hint_index][1] == CTRL_MENU_BUTTON_B then 
  3098. 			if Current_tier == BUILD_TIER then 
  3099. 				store_character_morph_revert_confirm() 
  3100. 			elseif Current_tier == SKIN_COLOR_TIER then 
  3101. 				store_character_skin_color_selected("back") 
  3102. 			elseif Current_tier == EYE_COLOR_TIER then 
  3103. 				store_character_eye_color_selected("back") 
  3104. 			elseif Current_tier == HAIR_COLOR_TIER then 
  3105. 				store_character_hair_color_selected("back") 
  3106. 			elseif Current_tier == MAKEUP_COLOR_TIER then 
  3107. 				store_character_composite_color_select("back") 
  3108. 			else --Current_tier == MENU_TIER then 
  3109. 				store_common_button_b() 
  3110. 			end 
  3111. 		elseif Store_common_hint_bar.hint_data[hint_index][1] == CTRL_MENU_BUTTON_A then 
  3112. 			store_common_button_a() 
  3113. 		end 
  3114. 		return 
  3115. 	end 
  3116. 	 
  3117. 	-- Check if the user clicked on a susan arrow 
  3118. 	if Susan_object ~= nil and Susan_object ~= -1 then 
  3119. 		if target_handle == Susan_object.arrow_left.handle then 
  3120. 			-- Navigate left 
  3121. 			store_character_lineup_nav("nav_left") 
  3122. 		elseif target_handle == Susan_object.arrow_right.handle then 
  3123. 			-- Navigate right 
  3124. 			store_character_lineup_nav("nav_right") 
  3125. 		elseif target_handle == Susan_mouse_area_img_h then 
  3126. 			-- Select character from lineup 
  3127. 			if Current_tier == LINEUP_TIER then 
  3128. 				store_character_lineup_select(event)	 
  3129. 			end 
  3130. 		end 
  3131. 	end 
  3132. 	 
  3133. 	-- Check if the user clicked on the confirm button or triangle on the build screen 
  3134. 	if Left_stick_input_thread ~= -1 and Triangle_select_button_handle == target_handle then 
  3135. 		store_character_morph_select() 
  3136. 	end 
  3137. 	 
  3138. 	local triangle_handle = vint_object_find("triangle_base", Triangle_select.handle) 
  3139. 	if Left_stick_input_thread ~= -1 and triangle_handle == target_handle then 
  3140. 		Mouse_x = mouse_x 
  3141. 		Mouse_y = mouse_y 
  3142. 	end 
  3143. end 
  3144.  
  3145. function store_character_mouse_move(event, target_handle) 
  3146. 	 
  3147. 	vint_set_mouse_cursor("") 
  3148. 	store_common_mouse_zoom(0.0) 
  3149.  
  3150. 	-- Reset highlights 
  3151. 	Store_common_hint_bar:set_highlight(0) 
  3152. 	Active_list:highlight_left_arrow(false) 
  3153. 	Active_list:highlight_right_arrow(false) 
  3154. 	 
  3155. 	-- Check if the user is over the hint bar 
  3156. 	local hint_index = Store_common_hint_bar:get_hint_index(target_handle) 
  3157. 	if hint_index ~= 0 then 
  3158. 		Store_common_hint_bar:set_highlight(hint_index, Store_common_current_highlight_color) 
  3159. 		return 
  3160. 	end 
  3161. 	 
  3162. 	-- Check if the user is over a button on the list 
  3163. 	local old_index = Active_list:get_selection() 
  3164. 	local new_index = Active_list:get_button_index(target_handle) 
  3165. 	if new_index ~= 0 and new_index ~= old_index then 
  3166. 		Active_list:set_selection(new_index) 
  3167. 		Active_list:move_cursor(0, true) 
  3168. 		 
  3169. 		-- If the item has a callback for navigation, do it (such as putting clothes on) 
  3170. 		local data_item = Active_list:return_selected_data() 
  3171. 		if data_item.on_nav ~= nil then 
  3172. 			data_item.on_nav(data_item) 
  3173. 		end 
  3174. 	end 
  3175. 	 
  3176. 	-- Check if the user is over the toggle/slider arrows 
  3177. 	local current_selection = Active_list:return_selected_data() 
  3178. 	if current_selection.type == TYPE_SLIDER then 
  3179. 		if Active_list:is_left_arrow(target_handle) then 
  3180. 			Active_list:highlight_left_arrow(true) 
  3181. 		elseif Active_list:is_right_arrow(target_handle) then 
  3182. 			Active_list:highlight_right_arrow(true) 
  3183. 		end 
  3184. 	end 
  3185. 	 
  3186. 	-- Custom highlighting for the select build button 
  3187. 	vint_set_property(Triangle_select_text_handle, "alpha", 1, 1, 1) 
  3188. 	if Left_stick_input_thread ~= -1 and Triangle_select_button_handle == target_handle then 
  3189. 		vint_set_property(Triangle_select_text_handle, "alpha", .5,.5,.5) 
  3190. 	end 
  3191. 	 
  3192. 	local SUSAN_ARROW_SCALE = 1.5 
  3193. 	-- Custom highlighting for the lineup arrows 
  3194. 	if Susan_object ~= nil and Susan_object ~= -1 then 
  3195. 		Susan_object.arrow_left:set_scale(SUSAN_ARROW_SCALE, SUSAN_ARROW_SCALE) 
  3196. 		Susan_object.arrow_right:set_scale(SUSAN_ARROW_SCALE, SUSAN_ARROW_SCALE) 
  3197. 		if target_handle == Susan_object.arrow_left.handle then 
  3198. 			Susan_object.arrow_left:set_scale(SUSAN_ARROW_SCALE * 1.15, SUSAN_ARROW_SCALE * 1.15) 
  3199. 		elseif target_handle == Susan_object.arrow_right.handle then 
  3200. 			Susan_object.arrow_right:set_scale(SUSAN_ARROW_SCALE * 1.15, SUSAN_ARROW_SCALE * 1.15) 
  3201. 		end 
  3202. 	end 
  3203. end 
  3204.  
  3205. function store_character_mouse_scroll(event, target_handle, mouse_x, mouse_y, scroll_lines) 
  3206. 	if scroll_lines ~= 0 then 
  3207. 		if Store_common_color_grid.bg.handle == target_handle then 
  3208. 			Store_common_color_grid:scroll_list(scroll_lines * -1) 
  3209. 		end 
  3210. 	end 
  3211. end 
  3212.  
  3213. function store_character_mouse_drag(event, target_handle, mouse_x, mouse_y) 
  3214. 	if Store_common_color_grid.scrollbar.tab_grp.handle == target_handle then 
  3215. 		local new_start_index = Store_common_color_grid.scrollbar:drag_scrolltab(mouse_y, Store_common_color_grid.rows - (Store_common_color_grid.max_height - 1)) 
  3216. 		Store_common_color_grid:scroll_list(0, new_start_index) 
  3217. 		return 
  3218. 	end 
  3219. 	 
  3220. 	-- Set the mouse's position to start the update 
  3221. 	local triangle_handle = vint_object_find("triangle_base", Triangle_select.handle) 
  3222. 	if Left_stick_input_thread ~= -1 and triangle_handle == target_handle then 
  3223. 		Mouse_x = mouse_x 
  3224. 		Mouse_y = mouse_y 
  3225. 	end 
  3226. end 
  3227.  
  3228. function store_character_mouse_drag_release(event, target_handle, mouse_x, mouse_y) 
  3229. 	-- Rebuild the mouse tracker and snap the scrolltab to the index's notch 
  3230. 	if Store_common_color_grid.scrollbar.tab_grp.handle == target_handle then 
  3231. 		local start_row = Store_common_color_grid:get_visible_rows() 
  3232. 		Store_common_color_grid.scrollbar:release_scrolltab(start_row, Store_common_color_grid.rows - (Store_common_color_grid.max_height - 1)) 
  3233. 		Store_common_color_grid:update_mouse_inputs() 
  3234. 		return 
  3235. 	end 
  3236. 	 
  3237. 	-- Reset the mouse's tracked position, so the build screen doesn't constantly update 
  3238. 	local triangle_handle = vint_object_find("triangle_base", Triangle_select.handle) 
  3239. 	if triangle_handle == target_handle then 
  3240. 		Mouse_x = -1 
  3241. 		Mouse_y = -1 
  3242. 	end 
  3243. end 
  3244.  
  3245. -- Navigate left and right events are handled for the character lineup here. 
  3246. -- 
  3247. -- event: only accepts left and right navs. 
  3248. -- 
  3249. function store_character_lineup_nav(event) 
  3250. 	if event == "nav_left" then 
  3251. 		if not image_streamer_is_stream_in_progress() and not Susan_object:is_in_progress() and Susan_object:get_index() > 1 then 
  3252. 			Susan_object:move_right() 
  3253. 			game_UI_audio_play("UI_Main_Menu_Nav_Page_Right") 
  3254. 			if image_streamer_nav_index(-1) == false then 
  3255. 				assert_msg(false, "nav_left failed") 
  3256. 			end 
  3257. 		end 
  3258. 	elseif event == "nav_right" then 
  3259. 		if not image_streamer_is_stream_in_progress() and not Susan_object:is_in_progress() and Susan_object:get_index() < STORE_CHARACTER_NUM_LINEUP_IMAGES then	 
  3260. 			Susan_object:move_left() 
  3261. 			game_UI_audio_play("UI_Main_Menu_Nav_Page_Right") 
  3262. 			if image_streamer_nav_index(1) == false then 
  3263. 				assert_msg(false, "nav_right failed") 
  3264. 			end 
  3265. 		end 
  3266. 	else 
  3267. 		--do nothing 
  3268. 	end 
  3269. 	 
  3270. 	local index = Susan_object:get_index() 
  3271. 	 
  3272. 	if index == STORE_CHARACTER_NUM_LINEUP_IMAGES then 
  3273. 		if index ~= Prev_index then 
  3274. 			--store_character_select_show_text( "LINEUP_DOWNLOAD_CHARACTER", "LINEUP_DOWNLOAD_CHARACTER_DESC", true ) 
  3275. 			Susan_object:show_text("LINEUP_DOWNLOAD_CHARACTER", "LINEUP_DOWNLOAD_CHARACTER_DESC", true) 
  3276. 		end 
  3277. 	else 
  3278. 		--store_character_select_show_text( nil, nil, false ) 
  3279. 		Susan_object:show_text(nil, nil, false) 
  3280. 	end 
  3281. 	 
  3282. 	Prev_index = index 
  3283. 	 
  3284. end 
  3285.  
  3286. -- The player has selected a picture from the character lineup, and this function will take us to the character customization screen. 
  3287. -- 
  3288. function store_character_lineup_select(event) 
  3289. 	local new_state 
  3290. 	local index = Susan_object:get_index() 
  3291. 	 
  3292. 	Store_character_current_state = LINEUP_STATE	 
  3293. 	 
  3294. 	-- Special case: the last choice is for the Agora character gallery choice 
  3295. 	if index == STORE_CHARACTER_NUM_LINEUP_IMAGES then 
  3296. 		Store_character_new_state_on_validation = GALLERY_DOWNLOAD_STATE 
  3297. 		Online_check_thread = thread_new("store_character_check_online_for_gallery") 
  3298. 	else 
  3299. 		store_character_change_state(CUSTOMIZATION_STATE) 
  3300. 	end 
  3301. end 
  3302.  
  3303. -- Player selected a preset with the "select" button.  We need to confirm if they really want to do this first. 
  3304. -- 
  3305. function store_character_lineup_return_confirm() 
  3306.  
  3307. 	store_character_enable_mouse(false) 
  3308.  
  3309. 	Store_common_popup:populate_list(Yes_no_choices, 2, STORE_COMMON_LIST_SIZE, 2)	 
  3310. 	Store_common_popup:set_title("MENU_TITLE_WARNING") 
  3311. 	Store_common_popup:set_text("LINEUP_WARNING_BODY")		 
  3312. 	Store_common_popup:nav_enable(true, "store_character_lineup_return_confirm2", "store_character_popup_nav") 
  3313. 	Not_popup_grp:set_alpha(.5) 
  3314. 	Active_list:set_visible(false) 
  3315. 	 
  3316. 	return true 
  3317. end 
  3318.  
  3319. function store_character_lineup_return_confirm2(event) 
  3320. 	Store_common_popup:nav_enable(false, nil, nil) 
  3321. 	Not_popup_grp:set_alpha(1) 
  3322. 	Active_list:set_visible(true) 
  3323. 	 
  3324. 	-- The user hit the B button and cancelled the change 
  3325. 	-- This is redundant to selecting "No" in the list 
  3326. 	if event == "back" then 
  3327. 		game_UI_audio_play("UI_Main_Menu_Nav_Back") 
  3328. 		store_character_enable_mouse(true) 
  3329. 		return 
  3330. 	end 
  3331. 	 
  3332. 	game_UI_audio_play("UI_Main_Menu_Select")	 
  3333. 	 
  3334. 	-- Did we select yes?  This assumes yes is the first item 
  3335. 	if Store_common_popup:get_selected_data() ~= 1 then 
  3336. 		store_character_enable_mouse(true) 
  3337. 		return 
  3338. 	end 
  3339.  
  3340. 	-- return to the lineup 
  3341. 	store_character_change_state(LINEUP_STATE) 
  3342. end 
  3343.  
  3344.  
  3345. function store_character_lineup_susan_in_done() 
  3346. 	Store_character_anim_done = true 
  3347. 	Lineup_input_tracker:subscribe(true) --store_character_select_unlock_input() 
  3348. 	 
  3349. 	store_character_enable_mouse_split(false, true, true) 
  3350. 	Current_tier = LINEUP_TIER 
  3351. 	 
  3352. 	--debug_print("vint","store_character_lineup_susan_in_done \n") 
  3353. end 
  3354.  
  3355. function store_character_lineup_susan_out_done() 
  3356. 	Store_character_anim_done = true 
  3357. 	Input_tracker:subscribe(true) 
  3358. 	 
  3359. 	store_character_enable_mouse_split(true, true, false) 
  3360. 	Current_tier = MENU_TIER 
  3361. 	 
  3362. 	image_streamer_end_streaming() 
  3363. 	--debug_print("vint","store_character_lineup_susan_out_done \n") 
  3364.  
  3365. end 
  3366.  
  3367. function store_character_allow_input() 
  3368. 	return Store_character_anim_done 
  3369. 	--[[if pcr_is_plastic_surgeon() then 
  3370. 		return Store_character_anim_done 
  3371. 	else 
  3372. 		return Store_character_select_anim_done 
  3373. 	end]] 
  3374. end 
  3375.  
  3376. -- Called when this interface becomes the top one on the stack again. 
  3377. -- 
  3378. function store_character_gained_focus() 
  3379. 	bg_saints_show(false) 
  3380. 	local is_plastic_surgeon = pcr_is_plastic_surgeon() 
  3381.  
  3382. 	local new_state 
  3383. 	 
  3384. 	if Store_character_current_state == GALLERY_DOWNLOAD_STATE and Store_common_gallery_cancel then 
  3385. 		new_state = LINEUP_STATE 
  3386. 	else 
  3387. 		new_state = CUSTOMIZATION_STATE 
  3388. 		character_enable_mouse_drag(true) 
  3389. 	end 
  3390.  
  3391. 	Store_common_gallery_cancel = false 
  3392. 	store_character_change_state(new_state) 
  3393. 	 
  3394. 	if is_plastic_surgeon == false and Store_common_gallery_download_only == true then 
  3395. 		--vint_set_property(vint_object_find("police_logo"), "visible", true)		 
  3396. 	end 
  3397.  
  3398. 	if Hint_bar_mouse_input_tracker ~= -1 then 
  3399. 		Hint_bar_mouse_input_tracker:subscribe(true) 
  3400. 	end 
  3401. 	 
  3402. end 
  3403.  
  3404. function store_character_lost_focus() 
  3405.  
  3406. 	if Hint_bar_mouse_input_tracker ~= -1 then 
  3407. 		Hint_bar_mouse_input_tracker:subscribe(false) 
  3408. 	end 
  3409.  
  3410. end 
  3411.  
  3412. function store_character_bg_anim_done() 
  3413. 	store_common_bg_anim_complete() 
  3414. end 
  3415.  
  3416.  
  3417. --******************************* State transition functions ******************************************************* 
  3418.  
  3419. function store_character_lineup_to_gallery_download() 
  3420. 	if push_screen("store_gallery") == true then 
  3421. 		 
  3422. 		if Lineup_input_tracker  ~= -1 then 
  3423. 			Lineup_input_tracker:subscribe(false) 
  3424. 			if game_get_platform() == "PC" then	 
  3425. 				Lineup_mouse_input_tracker:subscribe(false) 
  3426. 				Hint_bar_mouse_input_tracker:subscribe(false) 
  3427. 			end 
  3428. 		end 
  3429. 		Input_tracker:subscribe(false) 
  3430. 		store_character_enable_mouse(false) 
  3431. 		if Input_tracker_body_morph_select ~= nil then 
  3432. 			Input_tracker_body_morph_select:subscribe(false) 
  3433. 		end 
  3434. 		 
  3435. 		Store_common_gallery_download_only = true	 
  3436. 		 
  3437. 		Lineup_input_tracker:subscribe(false) 
  3438. 		store_character_enable_mouse_split(false, false, false) 
  3439. 		 
  3440. 		--store_character_creation_add_clothes() 
  3441. 		 
  3442. 		--store_character_select_play_outro() 
  3443. 		 
  3444. 		--Set UI color to purple for gallery 
  3445. 		Active_list:set_highlight_color(COLOR_SAINTS_PURPLE)	 
  3446. 		Store_header:set_color(COLOR_SAINTS_PURPLE, COLOR_STORE_CLOTHING_SECONDARY, COLOR_STORE_CLOTHING_TERTIARY) 
  3447. 		 
  3448. 	else 
  3449.  
  3450. 		Store_character_current_state = LINEUP_STATE 
  3451.  
  3452. 	end 
  3453.  
  3454. end 
  3455.  
  3456.  
  3457. function store_character_lineup_to_customization() 
  3458.  
  3459. 	-- reset callbacks 
  3460. 	Store_common_populate_list_cb = store_character_populate_list 
  3461. 	Store_common_exit_cb				= store_character_lineup_return_confirm 
  3462.  
  3463. 	vint_apply_start_values(Store_character_in_anim.handle) 
  3464. 	vint_apply_start_values(Player_creation_bg_anim.handle) 
  3465. 		 
  3466. 	-- Get the index of the picture the player picked 
  3467. 	local index = Susan_object:get_index() 
  3468. 	--debug_print("vint","CHARACTER SELECT INDEX = "..var_to_string(index).."\n") 
  3469. 	local info = Store_character_lineup_presets[index] 
  3470.  
  3471. 	-- switch input from lineup to customization 
  3472. 	Lineup_input_tracker:subscribe(false) 
  3473. 	store_character_enable_mouse_split(false, false, false) 
  3474. 	 
  3475. 	-- load in our preset character 
  3476. 	local preset_name = info.gender .. "_" .. info.race 
  3477. 	local regional_preset_name = info.gender .. "_" .. info.figure 
  3478. 	pcr_apply_preset(preset_name, "figure", regional_preset_name, false) 
  3479. 	pcr_mark_changed() 
  3480. 	 
  3481. 	-- We want the character to have clothes on at the top menu, and we need to change to preset clothing 
  3482. 	pcr_add_default_clothing() 
  3483. 	 
  3484. 	-- transition to customization interface 
  3485. 	Store_character_anim_done = false 
  3486. 	 
  3487. 	ui_audio_post_event("Police_Lineup") 
  3488. 	 
  3489. 	local pcr_anim_in = Vdo_anim_object:new("player_creation_fade_in_anim", 0, Store_character_doc_handle) 
  3490. 	local end_tween = Vdo_anim_object:new("susan_anchor_out_twn", pcr_anim_in.handle)	 
  3491. 	 
  3492. 	end_tween:set_property("end_event","store_character_lineup_susan_out_done") 
  3493. 	 
  3494. 	--store_character_select_play_outro() 
  3495. 	 
  3496. 	vint_set_property(vint_object_find("player_creation_grp"), "background", true) 
  3497. 	 
  3498. 	game_UI_audio_play("UI_Main_Menu_Select") 
  3499. 	 
  3500. 	Active_list:set_visible(true) 
  3501. 	Store_header:set_visible(true) 
  3502. 	if game_get_platform() ~= "PC" then 
  3503. 		Store_common_rotate_hint:set_visible(true) 
  3504. 	end 
  3505. 	 
  3506. 	--vint_set_property(vint_object_find("police_logo"), "visible", true) 
  3507. 	vint_set_property(vint_object_find("title_grp", 0, Store_character_doc_handle), "alpha", 1.0) 
  3508. 	 
  3509. 	pcr_anim_in:play()	 
  3510. 	Store_character_in_anim:play(0) 
  3511. 	Player_creation_bg_anim:play(0)	 
  3512. 	 
  3513. 	--store_character_select_hide_screen() 
  3514.  
  3515. 	-- Change hint buttons 
  3516. 	local hint_data = { 
  3517. 		{CTRL_MENU_BUTTON_B, "MENU_BACK"}, 
  3518. 	} 
  3519. 	Store_common_hint_bar:set_hints(hint_data)  
  3520. 	--Store_common_hint_bar:set_visible(true) 
  3521. 	 
  3522. 	character_enable_mouse_drag(true) 
  3523. end 
  3524.  
  3525.  
  3526. function store_character_gallery_download_to_lineup() 
  3527.  
  3528. 	--restore the ui color to store specific 
  3529. 	Active_list:set_highlight_color(Store_common_current_highlight_color)	 
  3530. 	Store_header:set_color(Store_common_current_highlight_color, COLOR_STORE_CLOTHING_SECONDARY, COLOR_STORE_CLOTHING_TERTIARY)	 
  3531. 	 
  3532. 	-- reset callbacks 
  3533. 	Store_common_populate_list_cb = store_character_populate_list 
  3534. 	Store_common_exit_cb				= store_character_lineup_return_confirm	 
  3535. 	 
  3536. 	vint_apply_start_values(Store_character_in_anim.handle) 
  3537. 	vint_apply_start_values(Player_creation_bg_anim.handle) 
  3538.  
  3539. 	store_character_populate_list(Menu_data, Active_list:get_selection())	 
  3540. 	Active_list:set_visible(false) 
  3541. 	Store_header:set_visible(false) 
  3542. 	Store_common_rotate_hint:set_visible(false) 
  3543.  
  3544. 	--vint_set_property(vint_object_find("police_logo"), "visible", false)			 
  3545. 	 
  3546. 	Store_character_in_anim:play(0) 
  3547. 	Player_creation_bg_anim:play(0) 
  3548. 	 
  3549. 	local anim = Vdo_anim_object:new("player_creation_fade_out_anim", 0, Store_character_doc_handle) 
  3550. 	anim:play(-10) --we don't want to see the title pop, so start this anim after its complete 
  3551.  
  3552. 	Susan_object:play_intro() 
  3553. 	vint_set_property(vint_object_find("player_creation_grp"), "background", false) 
  3554. 	 
  3555. 	Store_character_anim_done = false 
  3556. 	 
  3557. 	local end_tween = Vdo_anim_object:new("gradient_alpha_in_twn") 
  3558. 	end_tween:set_property("end_event","store_character_lineup_susan_in_done") 
  3559. 	 
  3560. 	-- start streaming images again 
  3561. 	-- Get the index of the picture the player picked 
  3562. 	local index = Susan_object:get_index() 
  3563. 	 
  3564. 	-- Decrement the index to load the images before current highlight 
  3565. 	index = index - 2 
  3566. 	if index < 1 then 
  3567. 		index = index + STORE_CHARACTER_NUM_LINEUP_IMAGES 
  3568. 	end 
  3569. 	 
  3570. 	image_streamer_start_streaming(index, STORE_CHARACTER_NUM_LINEUP_IMAGES_LOADED) 
  3571. 	 
  3572. 	-- switch inputs back to lineup mode 
  3573. 	Input_tracker:subscribe(false) 
  3574. 	store_character_enable_mouse_split(false, false, true) 
  3575. 	 
  3576. 	-- Change hint buttons 
  3577. 	local hint_data = { 
  3578. 		{CTRL_MENU_BUTTON_A, "CUST_CHOOSE_CHARACTER"}, 
  3579. 	} 
  3580. 	Store_common_hint_bar:set_hints(hint_data) 	 
  3581. 	Store_common_hint_bar:set_visible(true) 
  3582. 	 
  3583. 	character_enable_mouse_drag(false)	 
  3584. 	 
  3585. 	Store_common_gallery_download_only = false	 
  3586. 	 
  3587. 	Store_header:clear_titles()	 
  3588. 	Store_header:push_title(nil, "STORE_CHOOSE_A_CATEGORY")	 
  3589. 	 
  3590. 	vint_set_property(vint_object_find("player_creation_grp", 0, Store_character_doc_handle), "background", false) 
  3591. 	Lineup_input_tracker:subscribe(true) 
  3592. 	bg_saints_set_background(false)	 
  3593. end 
  3594.  
  3595.  
  3596. function store_character_gallery_download_to_customization() 
  3597.  
  3598. 	--restore the ui color to store specific 
  3599. 	Active_list:set_highlight_color(Store_common_current_highlight_color)	 
  3600. 	Store_header:set_color(Store_common_current_highlight_color, COLOR_STORE_CLOTHING_SECONDARY, COLOR_STORE_CLOTHING_TERTIARY) 
  3601.  
  3602. 	-- Unload police lineup images 
  3603. 	image_streamer_end_streaming() 
  3604. 	 
  3605. 	-- reset callbacks 
  3606. 	Store_common_populate_list_cb = store_character_populate_list 
  3607. 	Store_common_exit_cb				= store_character_lineup_return_confirm 
  3608.  
  3609. 	vint_apply_start_values(Store_character_in_anim.handle) 
  3610. 	 
  3611. 	--vint_set_property(vint_object_find("police_logo"), "visible", true)		 
  3612. 	 
  3613. 	local pcr_anim_in = Vdo_anim_object:new("player_creation_fade_in_anim", 0, Store_character_doc_handle) 
  3614. 	 
  3615. 	Store_common_gallery_download_only = false 
  3616. 	Store_header:set_visible(true) 
  3617. 	Active_list:set_visible(true) 
  3618. 	if game_get_platform() ~= "PC" then 
  3619. 		Store_common_rotate_hint:set_visible(true) 
  3620. 	end 
  3621. 	 
  3622. 	Susan_object:set_visible(false)	 
  3623. 	pcr_anim_in:play(0)	 
  3624. 	Store_character_in_anim:play(0) 
  3625. 	 
  3626. 	store_unlock_controls() 
  3627. 	 
  3628. 	Store_header:clear_titles()	 
  3629. 	Store_header:push_title(nil, "STORE_CHOOSE_A_CATEGORY")	 
  3630.  
  3631. 	store_character_populate_list(Menu_data, Active_list:get_selection()) 
  3632. 	 
  3633. 	-- Cleans up images in the image streamer for lineup 
  3634. 	store_character_lineup_susan_out_done()	 
  3635. end 
  3636.  
  3637.  
  3638. function store_character_customization_to_lineup() 
  3639. 	vint_apply_start_values(Store_character_in_anim.handle) 
  3640. 	vint_apply_start_values(Player_creation_bg_anim.handle) 
  3641.  
  3642. 	Active_list:set_visible(false) 
  3643. 	Store_header:set_visible(false) 
  3644. 	Store_common_rotate_hint:set_visible(false) 
  3645.  
  3646. 	--vint_set_property(vint_object_find("police_logo"), "visible", false)			 
  3647. 	 
  3648. 	Store_character_in_anim:play(0) 
  3649. 	Player_creation_bg_anim:play(0) 
  3650. 	 
  3651. 	local anim = Vdo_anim_object:new("player_creation_fade_out_anim", 0, Store_character_doc_handle) 
  3652. 	anim:play() 
  3653.  
  3654. 	Susan_object:play_intro() 
  3655. 	 
  3656. 	vint_set_property(vint_object_find("player_creation_grp"), "background", false) 
  3657. 	 
  3658. 	Store_character_anim_done = false 
  3659. 	 
  3660. 	local end_tween = Vdo_anim_object:new("gradient_alpha_in_twn") 
  3661. 	end_tween:set_property("end_event","store_character_lineup_susan_in_done") 
  3662. 	 
  3663. 	-- start streaming images again 
  3664. 	-- Get the index of the picture the player picked 
  3665. 	local index = Susan_object:get_index() 
  3666. 	 
  3667. 	-- Decrement the index to load the images before current highlight 
  3668. 	index = index - 2 
  3669. 	if index < 1 then 
  3670. 		index = index + STORE_CHARACTER_NUM_LINEUP_IMAGES 
  3671. 	end 
  3672. 		 
  3673. 	image_streamer_start_streaming(index, STORE_CHARACTER_NUM_LINEUP_IMAGES_LOADED) 
  3674. 	 
  3675. 	-- switch inputs back to lineup mode 
  3676. 	Input_tracker:subscribe(false) 
  3677. 	store_character_enable_mouse_split(false, false, false) 
  3678. 	 
  3679. 	-- Change hint buttons 
  3680. 	local hint_data = { 
  3681. 		{CTRL_MENU_BUTTON_A, "CUST_CHOOSE_CHARACTER"}, 
  3682. 	} 
  3683. 	Store_common_hint_bar:set_hints(hint_data)  
  3684. 	--Store_common_hint_bar:set_visible(false)	 
  3685. 	 
  3686. 	character_enable_mouse_drag(false) 
  3687. 	Susan_object:set_visible(true) 
  3688. end 
  3689.  
  3690.  
  3691. function store_character_customization_to_gallery_full() 
  3692. 	if (push_screen("store_gallery") ~= true) then 
  3693. 		Store_character_current_state = CUSTOMIZATION_STATE 
  3694. 	else 
  3695. 		--Set UI color to purple for gallery 
  3696. 		Active_list:set_highlight_color(COLOR_SAINTS_PURPLE)	 
  3697. 		Store_header:set_color(COLOR_SAINTS_PURPLE, COLOR_STORE_CLOTHING_SECONDARY, COLOR_STORE_CLOTHING_TERTIARY) 
  3698. 	end 
  3699. end 
  3700.  
  3701.  
  3702. function store_character_customization_to_finished() 
  3703.  
  3704. end 
  3705.  
  3706.  
  3707. function store_character_gallery_full_to_customization() 
  3708. 	--restore the ui color to store specific 
  3709. 	Active_list:set_highlight_color(Store_common_current_highlight_color)	 
  3710. 	Store_header:set_color(Store_common_current_highlight_color, COLOR_STORE_CLOTHING_SECONDARY, COLOR_STORE_CLOTHING_TERTIARY) 
  3711. 	 
  3712. 	Store_common_gallery_download_only = false 
  3713. 	 
  3714. 	if pcr_is_plastic_surgeon() == true then 
  3715. 		pcr_strip_clothing() 
  3716. 	end 
  3717.  
  3718. 	store_unlock_controls() 
  3719. 	 
  3720. 	-- reset our store stacks 
  3721. 	store_common_stack_clear_menu() 
  3722. 	store_common_stack_clear_id() 
  3723. 	store_common_stack_clear_index()	 
  3724. 	 
  3725. 	-- Populate the areas and draw the first menu 
  3726. 	store_character_main_menu_fill()	 
  3727. 	 
  3728. 	-- If we're in the character lineup, change the text on the "exit" choice, and what happens on back 
  3729. 	local is_plastic_surgeon = pcr_is_plastic_surgeon() 
  3730. 	if is_plastic_surgeon == false then 
  3731. 		Menu_data[#Menu_data].label = "CUST_MENU_EXIT" 
  3732. 		Menu_data[#Menu_data].is_new 	= true 
  3733. 		Store_common_exit_cb	= store_character_lineup_return_confirm					 
  3734. 	else		 
  3735. 		Store_common_exit_cb	= store_character_exit			 
  3736. 	end 
  3737. 	 
  3738. 	if game_get_platform() ~= "PC" then 
  3739. 		Store_common_rotate_hint:set_visible(true) 
  3740. 	end 
  3741. 	 
  3742. 	-- Pass the table data to the megalist vdo. 
  3743. 	store_character_populate_list(Menu_data, 1) 
  3744. 	 
  3745. 	-- Set up some callbacks for the common store script 
  3746. 	Store_common_populate_list_cb = store_character_populate_list 
  3747. 	 
  3748. 	-- Bring the News ticker back 
  3749. 	if pcr_is_plastic_surgeon() == false then 
  3750. 		local ticker_grp_h = vint_object_find("ticker_grp", 0, Store_character_doc_handle) 
  3751. 		vint_set_property(ticker_grp_h, "visible", true) 
  3752. 	end 
  3753. 	 
  3754. 	--Glitch the screen 
  3755. 	glitch_cell() 
  3756. end 
  3757.  
  3758. local Creation_state_transitions = { 
  3759. 	[LINEUP_STATE] = { 
  3760. 		[GALLERY_DOWNLOAD_STATE]		= store_character_lineup_to_gallery_download, 
  3761. 		[CUSTOMIZATION_STATE]			= store_character_lineup_to_customization, 
  3762. 	}, 
  3763. 	 
  3764. 	[GALLERY_DOWNLOAD_STATE] = { 
  3765. 		[LINEUP_STATE]						= store_character_gallery_download_to_lineup, 
  3766. 		[CUSTOMIZATION_STATE]			= store_character_gallery_download_to_customization, 
  3767. 	}, 
  3768.  
  3769. 	[CUSTOMIZATION_STATE] = { 
  3770. 		[LINEUP_STATE]						= store_character_customization_to_lineup, 
  3771. 		[GALLERY_FULL_STATE]				= store_character_customization_to_gallery_full, 
  3772. 		[FINISHED_STATE]					= store_character_customization_to_finished, 
  3773. 	}, 
  3774. 	 
  3775. 	[GALLERY_FULL_STATE] = { 
  3776. 		[CUSTOMIZATION_STATE]			= store_character_gallery_full_to_customization, 
  3777. 	}, 
  3778. } 
  3779.  
  3780. function store_character_change_state(new_state) 
  3781.  
  3782. 	local state_change_func = Creation_state_transitions[Store_character_current_state][new_state] 
  3783.  
  3784. 	-- don't do anything on an invalid state change 
  3785. 	if state_change_func ~= nil then 
  3786. 		Store_character_current_state = new_state 
  3787. 		state_change_func() 
  3788. 	end 
  3789. end 
  3790.