dizietemblesssma Posted September 30, 2020 Share Posted September 30, 2020 In my new mod, where I am scratching an itch for outfit changing - I know it already exists! - I'm concerned that adding more features will make a mod with poor performance.It seems to be basically working but I have little experience of what would constitute a 'heavy' script, I wonder if someone could comment on the following MCM menu script, there's a lot of formlist declaring? and filling: Scriptname dz_outfits_mcm_menu Extends SKI_ConfigBase Actor Property PlayerRef Auto ;fast way to refer to the player ;MagicEffect Property dz_outfits_ability_effect Auto Spell Property dz_outfits_grant_ability_spell Auto Spell Property dz_outfits_ability_spell Auto ;Spell Property dz_outfits_dummy_spell Auto Bool[] Property activate_toggle Auto ;keep track of spells applied Actor[] Property teammate_ref_slot Auto ;keep track of actor for the page FormList[] Property default_outfits Auto ;define the arrays of formlists to store outfits in FormList[] Property playerh_outfits Auto FormList[] Property dwelling_outfits Auto FormList[] Property city_outfits Auto FormList[] Property pleasant_outfits Auto FormList[] Property rainy_outfits Auto FormList[] Property snowy_outfits Auto FormList[] Property swim_outfits Auto Bool Property notification_show_toggle Auto ;show notifications of outfit change Bool Property weather_show_toggle Auto ;show weather change notifications Bool Property combat_override_toggle Auto ;does combat change outfit Bool Property weapons_include_toggle Auto ;replace weaons and spells with outfit change Bool Property player_activate_toggle Auto ;turn player changing off for quests that require staying in dress Bool Property undress_toggle Auto ;non-functional stripping toggle Bool Property head_toggle Auto ;remove headgear Bool Property debug_toggle Auto ;enable debug messages ;;;we need to store variables here that get lost as abilities are stopped/started by conditions;;; String[] Property curr_env Auto ;used to see if environment has changed String[] Property curr_outfit_type Auto ;used to see if identified outfit type has changed ;Bool[] activate_toggle ;is this NPC activated Bool[] Property all_outfit_toggle Auto ;is the page being reset? Bool[] Property default_outfit_toggle Auto ;array to store default outfit toggles Bool[] Property player_house_outfit_toggle Auto ;array to store playerh outfit toggles Bool[] Property dwelling_outfit_toggle Auto ;array to store indoors outfit toggles Bool[] Property city_outfit_toggle Auto ;array to store town/city outfit toggles Bool[] Property pleasant_outfit_toggle Auto ;array to store pleasant outfit toggles Bool[] Property rainy_outfit_toggle Auto ;array to store rainy outfit toggles Bool[] Property snowy_outfit_toggle Auto ;array to store snowy outfit toggles Bool[] Property swim_outfit_toggle Auto ;array to store swim outfit toggles ;Bool[] in_use ;is this page being used? Int hotkey ;this is the key for adding NPCs Int combat_hotkey ;this is the key to toggle combat changing on and off Int player_activate_key ;this is the key to toggle player auto-changing on and off Int undress_key ;this is the key to toggle undressed on or off Int Property index Auto String NPC_name ;we will need the name of the NPC later ;;;these are dummy objects that act as placeholders in the formlists Form Property dz_dummylweapon Auto Form Property dz_dummyrweapon Auto Form Property dz_dummylspell Auto Form Property dz_dummyrspell Auto Form Property dz_dummybspell Auto Form Property dz_dummyispell Auto ;;;here are all the formlists predefined in the Creation Kit;;; FormList Property dz_auto_outfits_playerh_formlist00 Auto FormList Property dz_auto_outfits_playerh_formlist01 Auto FormList Property dz_auto_outfits_playerh_formlist02 Auto FormList Property dz_auto_outfits_playerh_formlist03 Auto FormList Property dz_auto_outfits_playerh_formlist04 Auto FormList Property dz_auto_outfits_playerh_formlist05 Auto FormList Property dz_auto_outfits_playerh_formlist06 Auto FormList Property dz_auto_outfits_playerh_formlist07 Auto FormList Property dz_auto_outfits_playerh_formlist08 Auto FormList Property dz_auto_outfits_playerh_formlist09 Auto FormList Property dz_auto_outfits_playerh_formlist10 Auto FormList Property dz_auto_outfits_dwelling_formlist00 Auto FormList Property dz_auto_outfits_dwelling_formlist01 Auto FormList Property dz_auto_outfits_dwelling_formlist02 Auto FormList Property dz_auto_outfits_dwelling_formlist03 Auto FormList Property dz_auto_outfits_dwelling_formlist04 Auto FormList Property dz_auto_outfits_dwelling_formlist05 Auto FormList Property dz_auto_outfits_dwelling_formlist06 Auto FormList Property dz_auto_outfits_dwelling_formlist07 Auto FormList Property dz_auto_outfits_dwelling_formlist08 Auto FormList Property dz_auto_outfits_dwelling_formlist09 Auto FormList Property dz_auto_outfits_dwelling_formlist10 Auto FormList Property dz_auto_outfits_city_formlist00 Auto FormList Property dz_auto_outfits_city_formlist01 Auto FormList Property dz_auto_outfits_city_formlist02 Auto FormList Property dz_auto_outfits_city_formlist03 Auto FormList Property dz_auto_outfits_city_formlist04 Auto FormList Property dz_auto_outfits_city_formlist05 Auto FormList Property dz_auto_outfits_city_formlist06 Auto FormList Property dz_auto_outfits_city_formlist07 Auto FormList Property dz_auto_outfits_city_formlist08 Auto FormList Property dz_auto_outfits_city_formlist09 Auto FormList Property dz_auto_outfits_city_formlist10 Auto FormList Property dz_auto_outfits_default_formlist00 Auto FormList Property dz_auto_outfits_default_formlist01 Auto FormList Property dz_auto_outfits_default_formlist02 Auto FormList Property dz_auto_outfits_default_formlist03 Auto FormList Property dz_auto_outfits_default_formlist04 Auto FormList Property dz_auto_outfits_default_formlist05 Auto FormList Property dz_auto_outfits_default_formlist06 Auto FormList Property dz_auto_outfits_default_formlist07 Auto FormList Property dz_auto_outfits_default_formlist08 Auto FormList Property dz_auto_outfits_default_formlist09 Auto FormList Property dz_auto_outfits_default_formlist10 Auto FormList Property dz_auto_outfits_pleasant_formlist00 Auto FormList Property dz_auto_outfits_pleasant_formlist01 Auto FormList Property dz_auto_outfits_pleasant_formlist02 Auto FormList Property dz_auto_outfits_pleasant_formlist03 Auto FormList Property dz_auto_outfits_pleasant_formlist04 Auto FormList Property dz_auto_outfits_pleasant_formlist05 Auto FormList Property dz_auto_outfits_pleasant_formlist06 Auto FormList Property dz_auto_outfits_pleasant_formlist07 Auto FormList Property dz_auto_outfits_pleasant_formlist08 Auto FormList Property dz_auto_outfits_pleasant_formlist09 Auto FormList Property dz_auto_outfits_pleasant_formlist10 Auto FormList Property dz_auto_outfits_rainy_formlist00 Auto FormList Property dz_auto_outfits_rainy_formlist01 Auto FormList Property dz_auto_outfits_rainy_formlist02 Auto FormList Property dz_auto_outfits_rainy_formlist03 Auto FormList Property dz_auto_outfits_rainy_formlist04 Auto FormList Property dz_auto_outfits_rainy_formlist05 Auto FormList Property dz_auto_outfits_rainy_formlist06 Auto FormList Property dz_auto_outfits_rainy_formlist07 Auto FormList Property dz_auto_outfits_rainy_formlist08 Auto FormList Property dz_auto_outfits_rainy_formlist09 Auto FormList Property dz_auto_outfits_rainy_formlist10 Auto FormList Property dz_auto_outfits_snowy_formlist00 Auto FormList Property dz_auto_outfits_snowy_formlist01 Auto FormList Property dz_auto_outfits_snowy_formlist02 Auto FormList Property dz_auto_outfits_snowy_formlist03 Auto FormList Property dz_auto_outfits_snowy_formlist04 Auto FormList Property dz_auto_outfits_snowy_formlist05 Auto FormList Property dz_auto_outfits_snowy_formlist06 Auto FormList Property dz_auto_outfits_snowy_formlist07 Auto FormList Property dz_auto_outfits_snowy_formlist08 Auto FormList Property dz_auto_outfits_snowy_formlist09 Auto FormList Property dz_auto_outfits_snowy_formlist10 Auto FormList Property dz_auto_outfits_swim_formlist00 Auto FormList Property dz_auto_outfits_swim_formlist01 Auto FormList Property dz_auto_outfits_swim_formlist02 Auto FormList Property dz_auto_outfits_swim_formlist03 Auto FormList Property dz_auto_outfits_swim_formlist04 Auto FormList Property dz_auto_outfits_swim_formlist05 Auto FormList Property dz_auto_outfits_swim_formlist06 Auto FormList Property dz_auto_outfits_swim_formlist07 Auto FormList Property dz_auto_outfits_swim_formlist08 Auto FormList Property dz_auto_outfits_swim_formlist09 Auto FormList Property dz_auto_outfits_swim_formlist10 Auto Int Function GetVersion() ;version function Return 1 ; Default version EndFunction Event OnConfigInit() ;when the mod is first installed Pages = New String[12] ;fill the array of page names once on mod install Pages[0] = "$Configuration_text" Pages[1] = PlayerRef.GetBaseObject().Getname() Pages[2] = "$empty_text" Pages[3] = "$empty_text" Pages[4] = "$empty_text" Pages[5] = "$empty_text" Pages[6] = "$empty_text" Pages[7] = "$empty_text" Pages[8] = "$empty_text" Pages[9] = "$empty_text" Pages[10] = "$empty_text" Pages[11] = "$empty_text" hotkey = 27 ;this is the "]" key, default for adding NPCs registerForKey(hotkey) combat_hotkey = 26 ;this is the "[" key, default for toggling combat changing registerForKey(combat_hotkey) player_activate_key = 40 ;this is "'" key, default for toggling off player auto-changing registerForKey(player_activate_key) undress_key = 39 registerForKey(undress_key) ;this is the ";" key, default for toggling undressed on or off teammate_ref_slot = New Actor[12] ;create the array for slots teammate_ref_slot[1] = PlayerRef ;fill the player's slot ;in_use = New Bool[12] ;in_use[1] = True default_outfit_toggle = New Bool[11] ;fill array player_house_outfit_toggle = New Bool[11] ;fill array dwelling_outfit_toggle = New Bool[11] ;fill array city_outfit_toggle = New Bool[11] ;fill array pleasant_outfit_toggle = New Bool[11] ;fill array rainy_outfit_toggle = New Bool[11] ;fill array snowy_outfit_toggle = New Bool[11] ;fill array swim_outfit_toggle = New Bool[11] ;fill array activate_toggle = New Bool[11] ;fill array playerh_outfits = New FormList[11] ;fill array default_outfits = New FormList[11] ;fill array dwelling_outfits = New FormList[11] ;fill array city_outfits = New FormList[11] ;fill array pleasant_outfits = New FormList[11] ;fill array rainy_outfits = New FormList[11] ;fill array snowy_outfits = New FormList[11] ;fill array swim_outfits = New FormList[11] ;fill array curr_env = New String[11] ;fill array curr_outfit_type = New String[11] ;fill array dz_fill_arrays() ;fill arrays with formlists EndEvent Event OnConfigClose() RegisterForSingleUpdate(0.1) EndEvent Event OnUpdate() Int j j = 0 While j < pages.Length If activate_toggle[j] == True dz_activate_changing(True,j) EndIf j = j + 1 EndWhile EndEvent Event OnPageReset(String a_page) ;debug.messagebox("resetting page") ;debug.messagebox("default_outfits[1] is"+default_outfits[1]) If a_page == "" ;exit if page is "" ;ShowMessage("a_page = \"\" Returning",False) Return EndIf ;;what is the index of this page? index = dz_find_page_index(a_page) NPC_name = a_page If a_page == pages[0] ;is this the configuration page? ;;;left side of menu;;; SetCursorFillMode(TOP_TO_BOTTOM) SetCursorPosition(0) AddHeaderOption("$Changing_Options") AddToggleOptionST("state_notification_option","$outfit_change_notifications?",notification_show_toggle) AddEmptyOption() AddToggleOptionST("state_combat_option","$combat_override?",combat_override_toggle) AddEmptyOption() AddToggleOptionST("state_head_option","$head_override?",head_toggle) AddEmptyOption() AddToggleOptionST("state_weapons_option","$include_weapons?",weapons_include_toggle) AddEmptyOption() AddHeaderOption("$Warning_text") AddToggleOptionST("info_text","","") ;;;right hand side of menu;;; SetCursorFillMode(TOP_TO_BOTTOM) ;fill the page with toggles etc. SetCursorPosition(1) AddHeaderOption("$Select_Key") AddKeyMapOptionST("state_hotkey","$Set_hotkey",hotkey) AddEmptyOption() AddHeaderOption("$Select_combat_Key") AddKeyMapOptionST("state_combat_hotkey","$Set_combat_hotkey",combat_hotkey) AddEmptyOption() AddHeaderOption("$select_activate_key") AddKeyMapOptionST("state_player_activate_key","$Set_player_activate_key",player_activate_key) AddEmptyOption() AddHeaderOption("$select_undress_key") AddKeyMapOptionST("state_undress_key","$Set_undress_key",undress_key) AddEmptyOption() AddEmptyOption() AddToggleOptionST("debug_option","$display_debug_messages?",debug_toggle) Else ;/ int i i = 1 While i < pages.Length /; ;;;fill left hand side toggles SetCursorFillMode(TOP_TO_BOTTOM) ;fill the page with toggles etc. SetCursorPosition(0) AddHeaderOption("$Reset_text") ;show the toggle for reseting the outfits and page name AddToggleOptionST("reset_page","$Reset_this_page?", all_outfit_toggle[index]) AddEmptyOption() AddEmptyOption() AddHeaderOption("$Default_Combat_text") ;show the toggle to setting/unsetting the default outfit AddToggleOptionST("default","$Default_Outfit_set?", default_outfit_toggle[index]) AddEmptyOption() AddHeaderOption("$swimming_text") AddToggleOptionST("swim","$swimming_outfit_set?", swim_outfit_toggle[index]) AddEmptyOption() AddHeaderOption("$Activate_text") ;show the toggle to activate/deactivate auto changing for the NPC (uses a spell) AddToggleOptionST("toggle_activate_on","$Activate_auto_changing_for_this_character?", activate_toggle[index]) ;;;do the right hand side toggles SetCursorPosition(1) AddHeaderOption("$Location_text") ;show the toggles to setting/unsetting the location based outfits AddEmptyOption() AddToggleOptionST("city","$City_Outfit_set?", city_outfit_toggle[index]) AddToggleOptionST("playerh","$House_Outfit_set?", player_house_outfit_toggle[index]) AddToggleOptionST("indoors","$indoors_outfit_set?", dwelling_outfit_toggle[index]) AddEmptyOption() AddHeaderOption("$Weather_text") ;show the toggles to setting/unsetting the weather based outfits AddEmptyOption() AddToggleOptionST("pleasant","$Pleasant_Outfit_set?", pleasant_outfit_toggle[index]) AddToggleOptionST("rainy","$Cloudy_Rainy_outfit_set?", rainy_outfit_toggle[index]) AddToggleOptionST("snowy","$Snowy_outfit_set?", snowy_outfit_toggle[index]) ;debug.messagebox("index = "+index+" page name = "+pages[index]) ;/ SetCursorPosition(17) AddHeaderOption("$swim/Wading") SetCursorPosition(19) iswim = Adpleasant_outfit_toggleOption("swim outfit set", _toggle_swim) /; ;/ i = i +1 EndWhile /; EndIf EndEvent State info_text Event OnSelectST() String wall_of_text wall_of_text = "$wall_of_text" ShowMessage(wall_of_text,False) ;SetTextOptionValueST(wall_of_text) EndEvent Event OnHighlightST() SetInfoText("$Click_here_to_read_important_information") EndEvent EndState State reset_page Event OnSelectST() dz_reset_toggles() EndEvent Event OnDefaultST() all_outfit_toggle[index] = False SetToggleOptionValueST(all_outfit_toggle[index]) EndEvent Event OnHighlightST() SetInfoText("$Reset_the_outfits_and_clear_the_page?") EndEvent EndState State toggle_activate_on Event OnSelectST() ;debug.messagebox("toggle is "+activate_toggle[index]) activate_toggle[index] = !activate_toggle[index] ;debug.messagebox("toggle is now "+activate_toggle[index]) If activate_toggle[index] == True ;debug.messagebox("toggle should be true, it is "+activate_toggle[index]) String msg msg = "$Do_you_wish_to_activate_auto_changing_for{ "+NPC_name+"}" If ShowMessage(msg,True) ;dz_activate_changing(True,index) ;call the activation function player_activate_toggle = True ;set the default value for the player toggle If debug_toggle debug.messagebox("answer = yes to turn on, toggle ="+activate_toggle[index]) EndIf ForcePageReset() ;Return Else activate_toggle[index] = False SetToggleOptionValueST(activate_toggle[index]) ;debug.messagebox("answer = no to turn on, toggle ="+activate_toggle[index]) ForcePageReset() ;Return EndIf Else ;debug.messagebox("toggle should be false, it is "+activate_toggle[index]) String msg msg = "$Do_you_wish_to_deactivate_auto_changing_for{ "+NPC_name+"}" If ShowMessage(msg,True) dz_activate_changing(False,index) If debug_toggle debug.messagebox("answer = yes to turn off, toggle ="+activate_toggle[index]) EndIf SetToggleOptionValueST(activate_toggle[index]) ;debug.messagebox("toggle is now "+activate_toggle[index]) ForcePageReset() ;Return Else activate_toggle[index] = True SetToggleOptionValueST(activate_toggle[index]) ;debug.messagebox("answer = no to turn off, toggle ="+activate_toggle[index]) ForcePageReset() ;Return EndIf EndIf EndEvent Event OnDefaultST() activate_toggle[index] = False SetToggleOptionValueST(activate_toggle[index]) dz_activate_changing(False,index) EndEvent Event OnHighlightST() SetInfoText("$Activate_the_auto_changing_option") EndEvent EndState State default Event OnSelectST() ;debug.messagebox("default_outfits[1] is "+default_outfits[1]) ;(default_outfits[1] as formlist).addform(00063b47) bool b b = dz_toggle_outfit(default_outfit_toggle[index],"$Set_the_Default_Outfit_for{","$Remove_the Default_Outfit_for{",default_outfits[index],"default") default_outfit_toggle[index] = b EndEvent Event OnDefaultST() default_outfit_toggle[index] = False SetToggleOptionValueST(default_outfit_toggle[index]) EndEvent Event OnHighlightST() SetInfoText("$Set_the_default_outfit") EndEvent EndState State playerh Event OnSelectST() bool b b = dz_toggle_outfit(player_house_outfit_toggle[index],"$Set_PlayerHouse_Outfit_for{","$Remove_the_PlayerHouse_Outfit_for{",playerh_outfits[index],"playerh") player_house_outfit_toggle[index] = b EndEvent Event OnDefaultST() player_house_outfit_toggle[index] = False SetToggleOptionValueST(player_house_outfit_toggle[index]) EndEvent Event OnHighlightST() SetInfoText("$Set_the_outfit_for_inside_the_playerhouse") EndEvent EndState State indoors Event OnSelectST() bool b b = dz_toggle_outfit(dwelling_outfit_toggle[index],"$Set_the_indoors_outift_for{","$Remove_the_indoors_out_for{",city_outfits[index],"dwelling") dwelling_outfit_toggle[index] = b EndEvent Event OnDefaultST() dwelling_outfit_toggle[index] = False SetToggleOptionValueST(dwelling_outfit_toggle[index]) EndEvent Event OnHighlightST() SetInfoText("$Set_the_outfit_for_indoors_not_Player_Home") EndEvent EndState State city Event OnSelectST() bool b b = dz_toggle_outfit(city_outfit_toggle[index],"$Set_the_city_outfit_for{","$Remove_the_city_outfit_for{",city_outfits[index],"city") city_outfit_toggle[index] = b EndEvent Event OnDefaultST() city_outfit_toggle[index] = False SetToggleOptionValueST(city_outfit_toggle[index]) EndEvent Event OnHighlightST() SetInfoText("$Set_the_city_outfit_for_the_5_major_cities") EndEvent EndState State pleasant Event OnSelectST() bool b b = dz_toggle_outfit(pleasant_outfit_toggle[index],"$Set_Pleasant_Weather_Outfit_for{","$Remove_the_Pleasant_Weather_Outfit_for{",pleasant_outfits[index],"pleasant") pleasant_outfit_toggle[index] = b EndEvent Event OnDefaultST() pleasant_outfit_toggle[index] = False SetToggleOptionValueST(pleasant_outfit_toggle[index]) EndEvent Event OnHighlightST() SetInfoText("$Set_the_outfit_for_pleasant_weather") EndEvent EndState State rainy Event OnSelectST() bool b b = dz_toggle_outfit(rainy_outfit_toggle[index],"$Set_The Rainy_Weather_Outfit_for{","$Remove_the_Rainy_Weather_Outfit_for{",rainy_outfits[index],"rainy") rainy_outfit_toggle[index] = b EndEvent Event OnDefaultST() rainy_outfit_toggle[index] = False SetToggleOptionValueST(rainy_outfit_toggle[index]) EndEvent Event OnHighlightST() SetInfoText("$Set_the_outfit_for_cloudy_or_rainy_weather") EndEvent EndState State snowy Event OnSelectST() bool b b = dz_toggle_outfit(snowy_outfit_toggle[index],"$Set_the_Snowy_Weather_Outfit_for{","$Remove_the_Snowy_Weather_Outfit_for{",snowy_outfits[index],"snowy") snowy_outfit_toggle[index] = b EndEvent Event OnDefaultST() snowy_outfit_toggle[index] = False SetToggleOptionValueST(snowy_outfit_toggle[index]) EndEvent Event OnHighlightST() SetInfoText("$Set_the_outfit_for_snowy_weather") EndEvent EndState State swim Event OnSelectST() bool b b = dz_toggle_outfit(swim_outfit_toggle[index],"$Set_the_swim_outfit_for{","$Remove_the_swim_outfit_for{",swim_outfits[index],"swim") swim_outfit_toggle[index] = b EndEvent Event OnDefaultST() swim_outfit_toggle[index] = False SetToggleOptionValueST(swim_outfit_toggle[index]) EndEvent Event OnHighlightST() SetInfoText("$Set_the_outfit_for_swimming") EndEvent EndState State state_notification_option Event OnSelectST() notification_show_toggle = !notification_show_toggle SetToggleOptionValueST(notification_show_toggle) If notification_show_toggle == True ShowMessage("$show_outfit_notifications_on",False) ElseIf notification_show_toggle == False ShowMessage("$show_outfit_notifications_off",False) EndIf EndEvent Event OnDefaultST() notification_show_toggle = False EndEvent Event OnHighlightST() SetInfoText("$receive_notifications_when_outfit_changes") EndEvent EndState ;/ State state_weather_option Event OnSelectST() weather_show_toggle = !weather_show_toggle SetToggleOptionValueST(weather_show_toggle) If weather_show_toggle == True ShowMessage("$weather_show_notifications_on",False) ElseIf weather_show_toggle == False ShowMessage("$weather_show_notifications_off",False) EndIf EndEvent Event OnDefaultST() weather_show_toggle = False EndEvent Event OnHighlightST() SetInfoText("$receive_notifications_when_new_location_has_different_weather") EndEvent EndState /; State state_combat_option Event OnSelectST() combat_override_toggle = !combat_override_toggle SetToggleOptionValueST(combat_override_toggle) If combat_override_toggle == True ShowMessage("$combat_on",False) ElseIf combat_override_toggle == False ShowMessage("$combat_off",False) EndIf EndEvent Event OnDefaultST() combat_override_toggle = False EndEvent Event OnHighlightST() SetInfoText("$auto_change_when in_combat") EndEvent EndState State state_hotkey Event OnKeyMapChangeST(int keyCode, string conflictControl, string conflictName) Bool continue = True If (conflictControl != "") string msg If (conflictName != "") msg = "$KeyMapConflict{" + conflictControl + "}{" + conflictName + "}" Else msg = "$KeyMapConflict{" + conflictControl + "}" EndIf continue = ShowMessage(msg, True, "$Yes_text", "$No_text") EndIf If (continue) hotkey = keyCode SetKeyMapOptionValueST(keyCode) EndIf RegisterForKey(keyCode) EndEvent Event OnDefaultST() ;what is the default setting for this toggle SetKeyMapOptionValueST(27) ;this is the ']' key EndEvent Event OnHighlightST() ;text shown on mouse hover over this toggle SetInfoText("$This_is_the_hotkey_to_add_NPCs_to_the_list") EndEvent EndState State state_combat_hotkey Event OnKeyMapChangeST(int keyCode, string conflictControl, string conflictName) Bool continue = True If (conflictControl != "") string msg If (conflictName != "") msg = "$KeyMapConflict{" + conflictControl + "}{" + conflictName + "}" Else msg = "$KeyMapConflict{" + conflictControl + "}" EndIf continue = ShowMessage(msg, True, "$Yes_text", "$No_text") EndIf If (continue) combat_hotkey = keyCode SetKeyMapOptionValueST(keyCode) EndIf RegisterForKey(keyCode) EndEvent Event OnDefaultST() ;what is the default setting for this toggle SetKeyMapOptionValueST(26) ;this is the ']' key EndEvent Event OnHighlightST() ;text shown on mouse hover over this toggle SetInfoText("$This_is_the_hotkey_to_toggle_combat_changing") EndEvent EndState State state_player_activate_key Event OnKeyMapChangeST(int keyCode, string conflictControl, string conflictName) Bool continue = True If (conflictControl != "") string msg If (conflictName != "") msg = "$KeyMapConflict{" + conflictControl + "}{" + conflictName + "}" Else msg = "$KeyMapConflict{" + conflictControl + "}" EndIf continue = ShowMessage(msg, True, "$Yes_text", "$No_text") EndIf If (continue) player_activate_key = keyCode SetKeyMapOptionValueST(keyCode) EndIf RegisterForKey(keyCode) EndEvent Event OnDefaultST() ;what is the default setting for this toggle SetKeyMapOptionValueST(40) ;this is the ']' key EndEvent Event OnHighlightST() ;text shown on mouse hover over this toggle SetInfoText("$This_is_the_hotkey_to_toggle_player_auto_changing") EndEvent EndState State state_undress_key Event OnHighlightST() SetInfoText("$highlight_state_undress_key") EndEvent EndState State state_weapons_option Event OnSelectST() weapons_include_toggle = !weapons_include_toggle SetToggleOptionValueST(weapons_include_toggle) If weapons_include_toggle == True ShowMessage("$weapons_and_spells_will_be_appllied",False) ElseIf weapons_include_toggle == False ShowMessage("$weapons_and_spells_will_not_be_appllied",False) EndIf EndEvent Event OnDefaultST() weapons_include_toggle = False EndEvent Event OnHighlightST() SetInfoText("$store_weapons_and_spells?") EndEvent EndState State state_head_option Event OnSelectST() head_toggle = !head_toggle SetToggleOptionValueST(head_toggle) If head_toggle == True ShowMessage("$Headgear_will_be_removed_in_dwellings",False) ElseIf head_toggle == False ShowMessage("$Headgear_will_remain_equipped_in_dwellings",False) EndIf EndEvent Event OnDefaultST() head_toggle = False EndEvent Event OnHighlightST() SetInfoText("$remove_headgear?") EndEvent EndState State debug_option Event OnSelectST() debug_toggle = !debug_toggle SetToggleOptionValueST(debug_toggle) If debug_toggle == True ShowMessage("$debug_messages_will_be_shown") ElseIf debug_toggle == False ShowMessage("$debug_messages_will_not_be_shown") EndIf EndEvent Event OnDefaultST() debug_toggle = False EndEvent Event OnHighlightST() SetInfoText("$show_debug_messages_when_scripts_fire") EndEvent EndState Function dz_reset_toggles() all_outfit_toggle[index] = True ;SetToggleOptionValueST(all_outfit_toggle[index]) If index !=0 && index !=1 If ShowMessage("$Reset_the_outfits_and_clear_the_NPC_name?",True) all_outfit_toggle[index] = False SetToggleOptionValueST(all_outfit_toggle[index]) ForcePagereset() dz_delete_outfits() EndIf ElseIf index == 1 String msg msg = "$Reset_the_outfits_for{" + Pages[1] + "}" If ShowMessage(msg,True) ;If ShowMessage("$Reset_the_outfits_for",True) all_outfit_toggle[index] = False SetToggleOptionValueST(all_outfit_toggle[index]) ForcePagereset() dz_delete_outfits() ;ForcePageReset() EndIf Else all_outfit_toggle[index] = False SetToggleOptionValueST(all_outfit_toggle[index]) ForcePagereset() EndIf SetToggleOptionValueST(all_outfit_toggle[index]) EndFunction Function dz_delete_outfits() If NPC_name != teammate_ref_slot[index].GetBaseObject().Getname() ShowMessage("$do_not_match.",False) Return EndIf Formlist a Actor[] b default_outfits[index] = a default_outfit_toggle[index] = False SetToggleOptionValueST(default_outfit_toggle) ;debug.messagebox("dz_delete_outfits debug, index = "+index) playerh_outfits[index] = a player_house_outfit_toggle[index] = False SetToggleOptionValueST(player_house_outfit_toggle) city_outfits[index] = a city_outfit_toggle[index] = False SetToggleOptionValueST(city_outfit_toggle) dwelling_outfits[index] = a dwelling_outfit_toggle[index] = False SetToggleOptionValueST(dwelling_outfit_toggle) pleasant_outfits[index] = a pleasant_outfit_toggle[index] = False SetToggleOptionValueST(pleasant_outfit_toggle) rainy_outfits[index] = a rainy_outfit_toggle[index] = False SetToggleOptionValueST(rainy_outfit_toggle) snowy_outfits[index] = a snowy_outfit_toggle[index] = False SetToggleOptionValueST(snowy_outfit_toggle) swim_outfits[index] = a swim_outfit_toggle[index] = False SetToggleOptionValueST(swim_outfit_toggle) If index != 0 && index !=1 Pages[index] = "$empty_text" teammate_ref_slot[index] = b[index] SetTitletext("$empty_text") EndIf ShowMessage("$Done_text",False) ;all_outfit_toggle[index] = False ;SetToggleOptionValueST(all_outfit_toggle[index]) ;ForcePageReset() EndFunction Function dz_activate_changing(Bool var,Int indx) spell my_spell my_spell = dz_outfits_grant_ability_spell If var == True my_spell.cast(PlayerRef,teammate_ref_slot[indx]) EndIf EndFunction string Function GetCustomControl(int keyCode) If (keyCode == hotkey) Return "$hotkey_name" ElseIf (keycode == combat_hotkey) Return "$combat_hotkey_name" ElseIf (keycode == player_activate_key) Return "$activate_key_name" Else Return "" EndIf EndFunction Event OnKeyDown(int code) If code == hotkey && !Utility.IsInMenuMode() Actor teammate_ref ;get the reference for the NPC under the crosshair teammate_ref = Game.GetCurrentCrosshairRef() as Actor If !teammate_ref ;debug.messagebox("$There_is_no_NPC_under_the_crosshair") debug.messagebox("There is no NPC under the crosshair") Return EndIf String teammate_name ;get the name of the NPC under the crosshair teammate_name = teammate_ref.GetBaseObject().Getname() int i i = 0 While i < pages.length If pages[i] == teammate_name String msg ;msg = "$already_has_a_slot_assigned{"+teammate_name+"}" msg = teammate_name+" already uses a menu page" debug.messagebox(msg) Return EndIf i = i + 1 EndWhile i = 0 While i < pages.length If pages[i] == "$empty_text" pages[i] = teammate_name teammate_ref_slot[i] = teammate_ref ;in_use[index] = True Return EndIf i = i + 1 EndWhile ;debug.messagebox("$There_are_no_free_slots_Enter_the_MCM_menu_to_free_up_a_slot_first") debug.messagebox("There are no free menu pages. Enter the MCM menu to free up a page first.") ElseIf code == combat_hotkey && !Utility.IsInMenuMode() combat_override_toggle = !combat_override_toggle If combat_override_toggle == True ;debug.notification("$combat_outfit_auto_changing_turned_on") debug.notification("Combat auto changing turned on") Int k k = 0 While k < teammate_ref_slot.Length If teammate_ref_slot[k].IsIncombat() dz_outfits_ability_spell.cast(teammate_ref_slot[k],teammate_ref_slot[k]) EndIf k = k + 1 EndWhile Else ;debug.notification("$combat_outfit_auto_changing_turned_off") debug.notification("Combat auto changing turned off") EndIf ElseIf code == player_activate_key && !Utility.IsInMenuMode() If activate_toggle[1] == False Return EndIf player_activate_toggle = !player_activate_toggle If player_activate_toggle == True && curr_env[1] != "playerh" debug.notification("Player auto-changing turned on") dz_outfits_ability_spell.cast(PlayerRef,PlayerRef) Else debug.notification("Player auto-changing turned off") EndIf ElseIf code == undress_key && !Utility.IsInMenuMode() undress_toggle = !undress_toggle If undress_toggle == True ;do stuff EndIf EndIf EndEvent Int Function dz_find_page_index(String a_page) ;debug.messagebox("dz_find_index debug, a_page ="+a_page) Int i i = 0 While i < Pages.Length If Pages[i] == a_page ;debug.messagebox("dz_find_index debug, pages[i] = "+pages[i]+" index is "+i) Return i ElseIf teammate_ref_slot[i].GetBaseObject().GetName() == a_page ;debug.messagebox("dz_find_index debug, teammate = "+teammate_ref_slot[i].GetBaseObject().GetName()+" index is "+i) Return i EndIf i = i + 1 EndWhile EndFunction ;;;this function fills the passed in outfits array element with a formlist of the equipped items;;; ;;;worn by the NPC of the selected page at the appropriate index;;; Bool Function dz_toggle_outfit(Bool z_toggle,String set_message,String remove_message,FormList outfits_array_element, String outfit_type) If NPC_name != teammate_ref_slot[index].GetBaseObject().Getname() ShowMessage("$The_stored_outfits_and_page_name_do_not_match,_try_exiting_and_opening_the_menu_again",False) Return z_toggle EndIf If z_toggle == False String msg msg = set_message+NPC_name+"}" If ShowMessage(msg,True) z_toggle = True SetToggleOptionValueST(z_toggle) String msg2 msg2 = "$Getting_outfit_for{"+NPC_name+"}" ShowMessage(msg2,False) dz_get_kit(teammate_ref_slot[index],outfits_array_element,outfit_type) Return z_toggle EndIf ElseIf z_toggle == True String msg msg = remove_message+NPC_name+"}" If ShowMessage(msg,True) z_toggle = False SetToggleOptionValueST(z_toggle) String msg2 msg2 = "$Forgetting_outfit_for{"+NPC_name+"}" ShowMessage(msg2,False) Formlist a outfits_array_element = a ForcePageReset() Return z_toggle EndIf EndIf EndFunction Function dz_get_kit(Actor aRef,FormList list,String outfit_type) list.revert() If aRef.GetEquippedWeapon(True) list.AddForm(aRef.GetEquippedWeapon(True)) Else list.AddForm(dz_dummylweapon) EndIf If aRef.GetEquippedWeapon() list.AddForm(aRef.GetEquippedWeapon()) Else list.AddForm(dz_dummyrweapon) EndIf If aRef.GetEquippedSpell(0) list.AddForm(aRef.GetEquippedSpell(0)) Else list.AddForm(dz_dummylspell) EndIf If aRef.GetEquippedSpell(1) list.AddForm(aRef.GetEquippedSpell(1)) Else list.AddForm(dz_dummyrspell) EndIf If aRef.GetEquippedSpell(2) list.AddForm(aRef.GetEquippedSpell(2)) Else list.AddForm(dz_dummybspell) EndIf If aRef.GetEquippedSpell(3) list.AddForm(aRef.GetEquippedSpell(3)) Else list.AddForm(dz_dummyispell) EndIf Form[] Items ;temporary array Items = PO3_SKSEFunctions.AddAllEquippedItemsToArray(aRef) ;fill array with equipped items list.AddForms(Items as Form[]) ;add temp array items to formlist ;/ Int i i = 0 While i < Items.Length If Items[i] As Ammo debug.messagebox("ammo is "+Items[i]) EndIf i = i + 1 EndWhile /; Return EndFunction ;;;this function is for debugging;;; String Function dz_formlist_item_names(Formlist list) int j j = list.GetSize() string names int i i = 0 While i < j ;names = names + list.GetAt(i) as String names = names + list.GetAt(i).GetName() names = names + ", " i = i + 1 EndWhile Return names as string EndFunction ;/ Function dz_copy_formlist(Formlist form_source,FormList form_dest) Int k k = 0 While k < form_source.GetSize() debug.messagebox("source formlist element ("+k+") is "+form_source.GetAt(k)) form_dest.addform(form_source.GetAt(k) as Form) debug.messagebox("destination formlist element ("+k+") is "+form_dest.GetAt(k)) k = k + 1 EndWhile EndFunction /; ;/ Function dz_add_equip_to_list(Actor aRef) Formlist akList ;;;PO3_SKSEFunctions.AddAllItemsToList(aRef,akList,noEquipped = False, noFavourited = True, noQuestItem = True) PO3_SKSEFunctions.AddAllItemsToList(aRef,akList,False,True,True) debug.messagebox("equipped list is "+dz_form_array_item_names(akList)) EndFunction /; Function dz_fill_arrays() playerh_outfits[0] = dz_auto_outfits_playerh_formlist00 playerh_outfits[1] = dz_auto_outfits_playerh_formlist01 playerh_outfits[2] = dz_auto_outfits_playerh_formlist02 playerh_outfits[3] = dz_auto_outfits_playerh_formlist03 playerh_outfits[4] = dz_auto_outfits_playerh_formlist04 playerh_outfits[5] = dz_auto_outfits_playerh_formlist05 playerh_outfits[6] = dz_auto_outfits_playerh_formlist06 playerh_outfits[7] = dz_auto_outfits_playerh_formlist07 playerh_outfits[8] = dz_auto_outfits_playerh_formlist08 playerh_outfits[9] = dz_auto_outfits_playerh_formlist09 playerh_outfits[10] = dz_auto_outfits_playerh_formlist10 default_outfits[0] = dz_auto_outfits_default_formlist00 default_outfits[1] = dz_auto_outfits_default_formlist01 default_outfits[2] = dz_auto_outfits_default_formlist02 default_outfits[3] = dz_auto_outfits_default_formlist03 default_outfits[4] = dz_auto_outfits_default_formlist04 default_outfits[5] = dz_auto_outfits_default_formlist05 default_outfits[6] = dz_auto_outfits_default_formlist06 default_outfits[7] = dz_auto_outfits_default_formlist07 default_outfits[8] = dz_auto_outfits_default_formlist08 default_outfits[9] = dz_auto_outfits_default_formlist09 default_outfits[10] = dz_auto_outfits_default_formlist10 dwelling_outfits[0] = dz_auto_outfits_dwelling_formlist00 dwelling_outfits[1] = dz_auto_outfits_dwelling_formlist01 dwelling_outfits[2] = dz_auto_outfits_dwelling_formlist02 dwelling_outfits[3] = dz_auto_outfits_dwelling_formlist03 dwelling_outfits[4] = dz_auto_outfits_dwelling_formlist04 dwelling_outfits[5] = dz_auto_outfits_dwelling_formlist05 dwelling_outfits[6] = dz_auto_outfits_dwelling_formlist06 dwelling_outfits[7] = dz_auto_outfits_dwelling_formlist07 dwelling_outfits[8] = dz_auto_outfits_dwelling_formlist08 dwelling_outfits[9] = dz_auto_outfits_dwelling_formlist09 dwelling_outfits[10] = dz_auto_outfits_dwelling_formlist10 city_outfits[0] = dz_auto_outfits_city_formlist00 city_outfits[1] = dz_auto_outfits_city_formlist01 city_outfits[2] = dz_auto_outfits_city_formlist02 city_outfits[3] = dz_auto_outfits_city_formlist03 city_outfits[4] = dz_auto_outfits_city_formlist04 city_outfits[5] = dz_auto_outfits_city_formlist05 city_outfits[6] = dz_auto_outfits_city_formlist06 city_outfits[7] = dz_auto_outfits_city_formlist07 city_outfits[8] = dz_auto_outfits_city_formlist08 city_outfits[9] = dz_auto_outfits_city_formlist09 city_outfits[10] = dz_auto_outfits_city_formlist10 pleasant_outfits[0] = dz_auto_outfits_pleasant_formlist00 pleasant_outfits[1] = dz_auto_outfits_pleasant_formlist01 pleasant_outfits[2] = dz_auto_outfits_pleasant_formlist02 pleasant_outfits[3] = dz_auto_outfits_pleasant_formlist03 pleasant_outfits[4] = dz_auto_outfits_pleasant_formlist04 pleasant_outfits[5] = dz_auto_outfits_pleasant_formlist05 pleasant_outfits[6] = dz_auto_outfits_pleasant_formlist06 pleasant_outfits[7] = dz_auto_outfits_pleasant_formlist07 pleasant_outfits[8] = dz_auto_outfits_pleasant_formlist08 pleasant_outfits[9] = dz_auto_outfits_pleasant_formlist09 pleasant_outfits[10] = dz_auto_outfits_pleasant_formlist10 rainy_outfits[0] = dz_auto_outfits_rainy_formlist00 rainy_outfits[1] = dz_auto_outfits_rainy_formlist01 rainy_outfits[2] = dz_auto_outfits_rainy_formlist02 rainy_outfits[3] = dz_auto_outfits_rainy_formlist03 rainy_outfits[4] = dz_auto_outfits_rainy_formlist04 rainy_outfits[5] = dz_auto_outfits_rainy_formlist05 rainy_outfits[6] = dz_auto_outfits_rainy_formlist06 rainy_outfits[7] = dz_auto_outfits_rainy_formlist07 rainy_outfits[8] = dz_auto_outfits_rainy_formlist08 rainy_outfits[9] = dz_auto_outfits_rainy_formlist09 rainy_outfits[10] = dz_auto_outfits_rainy_formlist10 snowy_outfits[0] = dz_auto_outfits_snowy_formlist00 snowy_outfits[1] = dz_auto_outfits_snowy_formlist01 snowy_outfits[2] = dz_auto_outfits_snowy_formlist02 snowy_outfits[3] = dz_auto_outfits_snowy_formlist03 snowy_outfits[4] = dz_auto_outfits_snowy_formlist04 snowy_outfits[5] = dz_auto_outfits_snowy_formlist05 snowy_outfits[6] = dz_auto_outfits_snowy_formlist06 snowy_outfits[7] = dz_auto_outfits_snowy_formlist07 snowy_outfits[8] = dz_auto_outfits_snowy_formlist08 snowy_outfits[9] = dz_auto_outfits_snowy_formlist09 snowy_outfits[10] = dz_auto_outfits_snowy_formlist10 swim_outfits[0] = dz_auto_outfits_swim_formlist00 swim_outfits[1] = dz_auto_outfits_swim_formlist01 swim_outfits[2] = dz_auto_outfits_swim_formlist02 swim_outfits[3] = dz_auto_outfits_swim_formlist03 swim_outfits[4] = dz_auto_outfits_swim_formlist04 swim_outfits[5] = dz_auto_outfits_swim_formlist05 swim_outfits[6] = dz_auto_outfits_swim_formlist06 swim_outfits[7] = dz_auto_outfits_swim_formlist07 swim_outfits[8] = dz_auto_outfits_swim_formlist08 swim_outfits[9] = dz_auto_outfits_swim_formlist09 swim_outfits[10] = dz_auto_outfits_swim_formlist10 EndFunction adding features will mean adding even more formlists and I don't know if that is wise or not? diziet Link to comment Share on other sites More sharing options...
maxarturo Posted September 30, 2020 Share Posted September 30, 2020 'FormLists' are the slowests function that papyrus / game engine has, and as a 'FormList' grows the more slower it becomes. I personally don't use them at all, i try to avoid them as much as i can, as the matter of fact i have removed them all from my mod. The same goes for 'Global Variables', they are so unreliable when they are used on heavy scripted scenes, but unfortunately some things can only be done through 'Global Variables', and a bunch of 'Fail Safes' needs to be applied to ensure reliability and consistency. Link to comment Share on other sites More sharing options...
Evangela Posted October 1, 2020 Share Posted October 1, 2020 (edited) An array of Formlists is definitely performance killing. There's a bit of redundant assigning, and assigning does take time. Instead of this: Int i i = 0 You can do this int i Because all unassigned declared variables will have their default values assigned to them automatically(Default initialization). Integers in this case is 0. Instead of this i = i + 1 You can do this i += 1 For loops, if you know the size of the formlist will never change, you can keep that assigned to a variable and not have the loop continuously call Getsize(). Edited October 1, 2020 by Rasikko Link to comment Share on other sites More sharing options...
maxarturo Posted October 1, 2020 Share Posted October 1, 2020 (edited) @ Rasikko I assume that this: i = i + 1 TO i += 1 also applies to help "Count" functions to execute faster. Example: HitToleranceCount += 1 I just finished working on a "Combat Ability" script for a unique constractable droid, the script has like a 1000 lines, and although it's working flawlessly, for the next couple of days i intend to spent some time trying to make it even more faster and optimize it even more, as much as it can possibly be optimized of course... Thank you very much. Edited October 1, 2020 by maxarturo Link to comment Share on other sites More sharing options...
Evangela Posted October 1, 2020 Share Posted October 1, 2020 I try to aim for at least 2 seconds, anything more and I'm doing something wrong. I never written a 1,000 line code though but I can get crazy with function calls which will start to create quite a big queue. Link to comment Share on other sites More sharing options...
dizietemblesssma Posted October 1, 2020 Author Share Posted October 1, 2020 An array of Formlists is definitely performance killing. There's a bit of redundant assigning, and assigning does take time. i += 1 For loops, if you know the size of the formlist will never change, you can keep that assigned to a variable and not have the loop continuously call Getsize().Cool I shall go through and replace the i = i + 1 s:)If instead of arrays of formlists I had a massively long script that used arrays instead of formlists, and as you can't have arrays of arrays, had separate states for each array (instead of constructng the states using while loops) would that be a lot quicker?Bearing in mind that the script posted is for the MCM menu, during gameplay the main script is: Scriptname dz_outfits_ability_effect_script Extends ActiveMagicEffect ;;;we need access to the mcm menu variables dz_outfits_mcm_menu Property dz_mcm Auto ;set mcm menu as property Keyword Property LocTypePlayerHouse Auto ;set player home location keyword Keyword Property LocTypeDwelling Auto ;set indoors location keyword Keyword Property ArmorHelmet Auto ;set helmet keyword Keyword Property ClothingHead Auto ;set the non-armour headgaear keyword WorldSpace Property WhiterunWorld Auto ;set the whiterun worldspace variable WorldSpace Property RiftenWorld Auto ;set the riften worldspace variable WorldSpace Property SolitudeWorld Auto ;set the solitude worldspace variable WorldSpace Property MarkarthWorld Auto ;set the markarth worldspace variable WorldSpace Property WindhelmWorld Auto ;set the windhelm worldspace variable MagicEffect dz_outfits_ability_effect ;magic effect name variable for checking later on Spell Property dz_outfits_meta_ability_spell Auto ;the spell that controls the other spells Actor Property PlayerRef Auto ;fast reference to the player String outfit_type ;to be used to reference stored outfits later Int slot_index ;what index in the mcm menu does this actor use String env ;local variable for weather or playerhome environment Bool dbg ;variable to indicate debug messages on/off Event OnEffectStart(Actor Target, Actor Caster) dbg = dz_mcm.debug_toggle ;are debug messages on? ;;;if this is the player and player changing is turned off then exit;;; If Target == PlayerRef && dz_mcm.player_activate_toggle == False ;is this the player and is the player changing turned off Return ;if so, get the hell out of Dodge! EndIf ;;;due to the effect of stopping and starting due to conditions on the spell;;; ;;;we need to refresh variables specific to this actor;;; Int i ;declare internal variable i = 0 ;set variable While i < dz_mcm.Pages.Length ;while loop through all menu slot indexes If dz_mcm.teammate_ref_slot[i] == Target ;find the menu page index for this actor slot_index = i ;set local index variable EndIf i = i + 1 EndWhile If dbg debug.notification("Outfit ability spell effect starting") EndIf ;;;if auto-changing status has changed to off;;; If dz_mcm.activate_toggle[slot_index] == False ;check to see if mcm menu toggle for ability has been deactivated If dbg debug.notification("Dispelling outfit ability spell") EndIf Target.dispelspell(dz_outfits_meta_ability_spell) self.dispel() ;dispel the ability Return ;and return, no more to be done EndIf ;;;what is the current environment - city,indoors, other?;;; Location kcurrentloc = Target.GetCurrentLocation() If kcurrentloc.HasKeyword(LocTypePlayerHouse) == True ;is current location a player home env = "playerh" ;set the environment to playerh If dbg debug.notification("Environment is player home") EndIf ElseIf kcurrentloc.HasKeyword(LocTypeDwelling) == True ;is the current location a dwelling env = "dwelling" ;set the environment to dwelling If dbg debug.notification("Environment is dwelling") EndIf ElseIf dz_check_worldspace(Target) ;is the current location a city worldspace env ="city" ;set the location to city If dbg debug.notification("Environment is major city worldspace") EndIf Else env = "none" ;otherwise environment is none If dbg debug.notification("Environment is none") EndIf EndIf ;;;what is the current weather?;;; ;;;https://www.creationkit.com/index.php?title=GetClassification_-_Weather gives the codes for weather classifiaction;;; Weather currentWeather = Weather.GetCurrentWeather() If dbg debug.notification("Getting current weather") EndIf If currentWeather.GetClassification() == -1 outfit_type = "default" If dbg debug.notification("Default outfit weather") EndIf ElseIf currentWeather.GetClassification() == 0 outfit_type = "pleasant" If dbg debug.notification("Pleasant outfit weather") EndIf ElseIf currentWeather.GetClassification() == 1 outfit_type = "rainy" If dbg debug.notification("Rainy outfit weather") EndIf ElseIf currentWeather.GetClassification() == 2 outfit_type = "rainy" If dbg debug.notification("Rainy outfit weather") EndIf ElseIf currentWeather.GetClassification() == 3 outfit_type = "snowy" If dbg debug.notification("Snowy outfit weather") EndIf EndIf ;;;if swimming, override outfit type;;; If Target.IsSwimming() If dbg debug.notification("Target is swimming") EndIf outfit_type = "swim" EndIf If dbg debug.notification("Current outfit type is "+dz_mcm.curr_outfit_type[slot_index]) debug.notification("Current environment is "+dz_mcm.curr_env[slot_index]) EndIf ;;;compare detected environment abd outfit with stored ones;;; If dz_mcm.curr_env[slot_index] == env && dz_mcm.curr_outfit_type[slot_index] == outfit_type If dbg debug.notification("Environment and outfit type unchanged - returning") EndIf Return Else If dbg debug.notification("Detected outfit type is "+outfit_type) debug.notification("Detected environment type is "+env) EndIf dz_fill_teammate(Target) ;change the outfit EndIf EndEvent Event OnEffectFinish(Actor Target, Actor Caster) EndEvent ;;;functions for filling outfits;;; ;;;this function decides waht outfit to equip and calls the function to dress that outfit;;; Function dz_fill_teammate(Actor NPCRef) String this_npc_name this_npc_name = NPCRef.GetDisplayName() ;get the actor's name If dbg debug.messagebox("Checking outfit type for "+this_npc_name) EndIf ;;;swimming overrides all;;; ;;;first make sure we are not indoors(to avoid conflict with auto-stripping in player home mods) and that we have a swimming outfit;;; If outfit_type == "swim" && dz_mcm.swim_outfit_toggle[slot_index] == True && env != "dwelling" && env != "playerh" If dz_mcm.curr_outfit_type[slot_index] != "swim" dz_fill_outfit(NPCRef,dz_mcm.swim_outfits[slot_index]) ;dress in swimming outift dz_mcm.curr_outfit_type[slot_index] = "swim" If dz_mcm.notification_show_toggle == True debug.notification(this_npc_name+" changed to swimming outfit") EndIf EndIf ;;;if not swimming then check for combat;;; ElseIf dz_mcm.combat_override_toggle == True && NPCRef.IsInCombat() && dz_mcm.default_outfit_toggle[slot_index] == True If dz_mcm.curr_outfit_type[slot_index] != "default" dz_fill_outfit(NPCRef,dz_mcm.default_outfits[slot_index]) ;dress in default/combat outfit dz_mcm.curr_outfit_type[slot_index] = "default" If dz_mcm.notification_show_toggle == True debug.notification(this_npc_name+" changed to combat outfit") EndIf EndIf ;;;if not in combat (or swimming) then check for in player home;;; ElseIf env == "playerh" && dz_mcm.player_house_outfit_toggle[slot_index] == True ;inside the player home, only this outfit is needed, so check first dz_mcm.curr_env[slot_index] = "playerh" If dz_mcm.curr_outfit_type[slot_index] != "playerh" ;dress in player home outfit dz_fill_outfit(NPCRef,dz_mcm.playerh_outfits[slot_index]) dz_mcm.curr_outfit_type[slot_index] = "playerh" If dz_mcm.notification_show_toggle == True debug.notification(this_npc_name+" changed to player home outfit") EndIf EndIf ;;;if swimming, in combat, or in player home, check for in a dwelling;;; ElseIf env == "dwelling" && dz_mcm.dwelling_outfit_toggle[slot_index] == True dz_mcm.curr_env[slot_index] = "dwelling" If dz_mcm.curr_outfit_type[slot_index] != "dwelling" dz_fill_outfit(NPCRef,dz_mcm.dwelling_outfits[slot_index]) ;dress in indoors outfit dz_mcm.curr_outfit_type[slot_index] = "dwelling" If dz_mcm.notification_show_toggle == True debug.notification(this_npc_name+" changed to dwelling outfit") EndIf EndIf ;;;check for being one of the major worldspaces;;; ElseIf env == "city" && dz_mcm.city_outfit_toggle[slot_index] == True ;dress in city outfit... dz_mcm.curr_env[slot_index] = "city" If outfit_type == "snowy" ;...unless the the weather is snowy!... If dz_mcm.snowy_outfit_toggle[slot_index] == True && dz_mcm.curr_outfit_type[slot_index] != "snowy" dz_fill_outfit(NPCRef,dz_mcm.snowy_outfits[slot_index]) ;dress in snowy outfit dz_mcm.curr_outfit_type[slot_index] = "snowy" If dz_mcm.notification_show_toggle == True debug.notification(this_npc_name+" changed to snowy weather outfit") EndIf EndIf ElseIf outfit_type == "rainy" ;...or the weather is rainy... If dz_mcm.rainy_outfit_toggle[slot_index] == True && dz_mcm.curr_outfit_type[slot_index] != "rainy" dz_fill_outfit(NPCRef,dz_mcm.rainy_outfits[slot_index]) ;dress in rainy outfit dz_mcm.curr_outfit_type[slot_index] = "rainy" If dz_mcm.notification_show_toggle == True debug.notification(this_npc_name+" changed to rainy weather outfit") EndIf EndIf ElseIf dz_mcm.city_outfit_toggle[slot_index] == True && dz_mcm.curr_outfit_type[slot_index] != "city" dz_fill_outfit(NPCRef,dz_mcm.city_outfits[slot_index]) ;...otherwise dress in city outfit dz_mcm.curr_outfit_type[slot_index] = "city" If dz_mcm.notification_show_toggle == True debug.notification(this_npc_name+" changed to city outfit") EndIf EndIf ;;;if not swimming, in combat, in a player home or in a city, check for weather;;; ElseIf outfit_type == "snowy" && dz_mcm.snowy_outfit_toggle[slot_index] == True ;snowing and have snowy outfit If dz_mcm.curr_outfit_type[slot_index] != "snowy" dz_fill_outfit(NPCRef,dz_mcm.snowy_outfits[slot_index]) ;dress for snowy weather dz_mcm.curr_outfit_type[slot_index] = "snowy" If dz_mcm.notification_show_toggle == True debug.notification(this_npc_name+" changed to snowy weather outfit") EndIf EndIf ElseIf outfit_type == "rainy" && dz_mcm.rainy_outfit_toggle[slot_index] == True ;raining and have rainy outfit If dz_mcm.curr_outfit_type[slot_index] != "rainy" dz_fill_outfit(NPCRef,dz_mcm.rainy_outfits[slot_index]) ;dress for cloudy or rainy weather dz_mcm.curr_outfit_type[slot_index] = "rainy" If dz_mcm.notification_show_toggle == True debug.notification(this_npc_name+" changed to rainy weather outfit") EndIf EndIf ElseIf outfit_type == "pleasant" && dz_mcm.pleasant_outfit_toggle[slot_index] == True ;pleasant and have pleasant outfit If dz_mcm.curr_outfit_type[slot_index] != "pleasant" dz_fill_outfit(NPCRef,dz_mcm.pleasant_outfits[slot_index]) ;dress for pleasant weather dz_mcm.curr_outfit_type[slot_index] = "pleasant" If dz_mcm.notification_show_toggle == True debug.notification(this_npc_name+" changed to pleasant weather outfit") EndIf EndIf ;;;if nothing applies, check for default outfit;;; ElseIf outfit_type == "default" && dz_mcm.default_outfit_toggle[slot_index] == True ;default and have default/combat outfit If dz_mcm.curr_outfit_type[slot_index] != "default" dz_fill_outfit(NPCRef,dz_mcm.default_outfits[slot_index]) ;otherwise dress in default/combat outfit dz_mcm.curr_outfit_type[slot_index] = "default" If dz_mcm.notification_show_toggle == True debug.notification(this_npc_name+" changed to default outfit") EndIf EndIf ;;;if no outfit is being applied;;; Else If dbg debug.notification("Check for helmet removal...") EndIf If dz_mcm.head_toggle == True ;do we reomve headgear indoors If dbg debug.notification("Remove helmet function") EndIf dz_remove_helmet(NPCRef) ;remove headgear EndIf EndIf EndFunction ;;;this function does the actual dressng of the actor;;; Function dz_fill_outfit(Actor the_npc, Formlist outfit_formlist) If dbg debug.messagebox("beginning fill outfit for "+the_npc.GetDisplayName()) EndIf Form[] Items ;temporary array Items = outfit_formlist.ToArray() ;place stored outift in temporary array If dbg debug.messagebox("stored outfit for "+the_npc.GetDisplayName()+" is "+dz_array_item_names(Items)) EndIf int i ;define this variable for use in arrays i = 0 ;this_npc.UnEquipAll() While i < Items.Length ;loop through the stored items If Items[i] As Armor ;|| Items[i] As Ammo || Items[i] As Light ;if stored items are armour the_npc.EquipItemEx(Items[i],0,False,True) ;re-equip them EndIf i = i + 1 EndWhile Form[] current_items ;another temporary array current_items = PO3_SKSEFunctions.AddAllEquippedItemsToArray(the_npc) ;place final dressed items in the other temporary array int j j = 0 While j < current_items.Length ;for each item that now equipped... int k k = 0 Bool keep = False While k < Items.Length If current_items[j] == Items[k] ;...see if it was in the stored outfit... keep = True ;...then we want to keep it... EndIf k = k + 1 EndWhile If dz_mcm.weapons_include_toggle == True ;...if the config says to re-equip weapons... If keep == False ;...unequip the item that was not stored the_npc.UnEquipItem(current_items[j]) EndIf ;otherwise unequip the item that was not stored unless it is a weapon, spell or ammo ElseIf keep == False && !current_items[j] As Weapon && !current_items[j] As Spell && !current_items[j] As Ammo the_npc.UnEquipItem(current_items[j]) EndIf j = j + 1 ;now check the next item that is currently equipped against the stored list EndWhile ;;;re-equip weapons etc;;; If dz_mcm.weapons_include_toggle == True ;if this is true we need to replace the current weapons with stored weapons If (outfit_formlist.GetAt(0) as Weapon) ;is there a stored left hand weapon) the_npc.EquipItemEx(outfit_formlist.GetAt(0) As Weapon,2,False,True) ;if so replace it ElseIf the_npc.GetEquippedWeapon(True) As Weapon ;otherwise is there an existing lefthand weapon the_npc.UnEquipItem(the_npc.GetEquippedWeapon(True)) ;remove existing lefthand weapon EndIf If (outfit_formlist.GetAt(1) as Weapon) ;is there a stored right hand weapon the_npc.EquipItemEx(outfit_formlist.GetAt(1) As Weapon,1,False,True) ;if so replace it ElseIf the_npc.GetEquippedWeapon() As Weapon ;otherwise is there an existing righthand weapon the_npc.UnEquipItem(the_npc.GetEquippedWeapon()) ;remove existing righthand weapon EndIf If (outfit_formlist.GetAt(2) as Spell) ;is there a stored left hand spell the_npc.EquipSpell(outfit_formlist.GetAt(2) As Spell,0) ;if so replace it EndIf If (outfit_formlist.GetAt(3) as Spell) ;is there a stored righthand spell the_npc.EquipSpell(outfit_formlist.GetAt(3) As Spell,1) ;if so replace it EndIf If (outfit_formlist.GetAt(4) as Spell) ;is there a stored both hands spell the_npc.EquipSpell(outfit_formlist.GetAt(4) As Spell,2) ;if so replace it EndIf Int k k = 0 While k < Items.Length ;loop through the stored items If Items[k] As Ammo || Items[k] As Light ;is there stored ammo or torch the_npc.EquipItemEx(Items[k],0,False,True) ;if so re-equip them EndIf k = k + 1 EndWhile EndIf ;;;finally if we are to remove headgear indoors;;; ;/ If dz_mcm.head_toggle == True && !the_npc.IsInCombat() && env == "dwelling" || env == "playerh" ;if we are indoors and not in combat Int m m = 0 While m < Items.Length ;search for headgear in the stored items... If Items[m].HasKeyword(ArmorHelmet) || Items[m].HasKeyword(ClothingHead) the_npc.UnEquipItem(Items[m]) ;...and unequip it EndIf m = m + 1 EndWhile EndIf /; ;;;try the separate function;;; dz_remove_helmet(the_npc) EndFunction ;;;this function helps remove headgear elsewhere in the script;;; Function dz_remove_helmet(Actor aRef) If dz_mcm.head_toggle == True && !aRef.IsInCombat() && env == "dwelling" || env == "playerh" Form[] worn_items ;temporary array worn_items = PO3_SKSEFunctions.AddAllEquippedItemsToArray(aRef) ;store worn items in temporary array Int m m = 0 While m < worn_items.Length ;find headgear in array If worn_items[m].HasKeyword(ArmorHelmet) || worn_items[m].HasKeyword(ClothingHead) aRef.UnEquipItem(worn_items[m]) ;unequip it EndIf m = m + 1 EndWhile EndIf EndFunction ;;;this function checks to see if we are in one of the five major cities that have their own worldspace;;; Bool Function dz_check_worldspace(Actor aRef) ;;;is the actor in whiterun,markarth,solitude,riften,windhelm If aRef.GetWorldSpace() == WhiterunWorld || aRef.GetWorldSpace() == MarkarthWorld || aRef.GetWorldSpace() == SolitudeWorld \ || aRef.GetWorldSpace() == RiftenWorld || aRef.GetWorldSpace() == WindhelmWorld Return True EndIf EndFunction ;;;this function is for debugging;;; String Function dz_formlist_item_names(Formlist list) ;obtain names of formlist entries int j j = list.GetSize() string names int i i = 0 While i < j ;names = names + list.GetAt(i) as String names = names + list.GetAt(i).GetName() names = names + ", " i = i + 1 EndWhile Return names as string EndFunction ;;;and so is this function;;; String Function dz_array_item_names(Form[] array) ;obtain names of array items string names int j j = 0 While j < array.Length names = names + array[j].GetName() names = names + ", " j = j + 1 EndWhile Return names as string EndFunction diziet Link to comment Share on other sites More sharing options...
maxarturo Posted October 1, 2020 Share Posted October 1, 2020 "If instead of arrays of formlists I had a massively long script that used arrays instead of formlists" Yes, it would be faster, but this would have a massive impact on the 'Save File' size, and from what i can remember from one of your previous post, you have a bunch of 'FormList' with a bunch of 'References' in each of them. The bigger the 'Save File' becomes, the more time the game needs to load it, as a results a lot of players like myself will never install your mod, or if it was to be installed, after the realization of the 'Save File' growth the mod would immediately be uninstalled !. Have a happy modding. Link to comment Share on other sites More sharing options...
dizietemblesssma Posted October 1, 2020 Author Share Posted October 1, 2020 "If instead of arrays of formlists I had a massively long script that used arrays instead of formlists"Yes, it would be faster, but this would have a massive impact on the 'Save File' size, and from what i can remember from one of your previous post, you have a bunch of 'FormList' with a bunch of 'References' in each of them. A bigger save file size with eg: 7 arrays of 10 formlists each, than with 70 arrays?The formlists are created in the CK, but no items placed in them till the MCM menu runs and the user toggles states or not, for most users of this mod I can see most formlists being empty (if that's the right word). diziet Link to comment Share on other sites More sharing options...
maxarturo Posted October 1, 2020 Share Posted October 1, 2020 Keep in mind that scripts are stored in save files, what i posted before is just a tip / advice. "7 arrays of 10 formlists each, than with 70 arrays" Calculate this: Each 'FormList' has 25 items, now put all of those items from all of the formlists in a container, go in game and open / remove / add items to it. You will see a massive behavior fluctuation comparing it to a container that has a logical number of items, ike 100. You can see what is going to happen if and once those formlists are filled, and especially if they are filled with a large amount of references. Unfortunately Skyrim engine has some major flaws, and you need to adapt to them in order to be able to construct a safe mod free from issues. Innovation is the key... don't think outside the box... but built a new one instead. Link to comment Share on other sites More sharing options...
dizietemblesssma Posted October 4, 2020 Author Share Posted October 4, 2020 How much slower would using something like the StorageUtil that comes with Papyrus Util SE - https://www.nexusmods.com/skyrimspecialedition/mods/13048 be? Storing items in files instead of formlists? I assume this would keep savegame file size down?, and the performance question would only apply while the MCM menu was open not during gameplay, as far as I can see. diziet Link to comment Share on other sites More sharing options...
Recommended Posts