RatB0Y68 Posted June 5, 2022 Share Posted June 5, 2022 I've made more progress with the new version of my follower mod. I decided to make a follower for my follower. I've done this in one of my skyrim follower mods & it worked well.She isn't a proper companion though, she can't interact with the player, trade items etc. I could set her up to be one but my actual companion was such a monumental undertaking I never want to repeat that.This presents a certain challenge. I want this npc to wear multiple outfits, but change between them each day. I know Deacon already does something like this when he enters new locations. I've had a look and I can't find anything that indicates how this is done. Can this be done by AI packages? Or is it controlled by a quest? Any advice would be appreciated. Link to comment Share on other sites More sharing options...
SKKmods Posted June 5, 2022 Share Posted June 5, 2022 You would need a script to set the outfit. If the actor is unique to you then attaching a script to the lvlActor form would be the most straightforward. Could look something like this (written cold, my contain errors) : Scriptname MyActorScript extends Actor Outfit Property pMyOutfitA Auto Const Mandatory Outfit Property pMyOutfitB Auto Const Mandatory Outfit Property pMyOutfitC Auto Const Mandatory GlobalVariable Property pGameDay Auto Const Mandatory Float fLastDayChange Outfit LastOutfit Event OnInit() Self.SetOutfit(pMyOutfitA) LastOutfit = pMyOutfitA fLastDayChange = pGameDay.GetValue() EndEvent Event OnLocationChange(Location akOldLoc, Location akNewLoc) ; or any event that happens every day but not too often. If (pGameDay.GetValue() > fLastDayChange) If (LastOutfit == pMyOutfitA) LastOutfit = pMyOutfitB ElseIf (LastOutfit == pMyOutfitB) LastOutfit = pMyOutfitC ElseIf (LastOutfit == pMyOutfitC) LastOutfit = pMyOutfitA Endif Self.SetOutfit(LastOutfit) fLastDayChange = pGameDay.GetValue() EndIf EndEvent Link to comment Share on other sites More sharing options...
RatB0Y68 Posted June 5, 2022 Author Share Posted June 5, 2022 Interesting. That looks very complex. Is it possible to have more than 3 Outfit Properties? Perhaps one for each day? I'm assuming that the blue text represents properties I'll have to create. For the akOldLoc & akNewLoc entries, will I have to fill them with specific locations? Or is there some way to make them represent any location change? Thanks for your assistance with this. Link to comment Share on other sites More sharing options...
niston Posted June 5, 2022 Share Posted June 5, 2022 Just make an array:Outfit[] Property MyOutfits Auto Const Mandatory You can populate it in CK and access each element by number from script:MyOutfits[0], MyOutfits[1], ... MyOutfits[n] The number can be a variable (such as n), so you could increment it by one each time and reset it to 0 after the last element (MyOutfits.Length - 1) has been reached. akOldLoc / akNewLoc will be filled by the game when it fires the LocationChange event.But if you'd rather have things on a timetable, I recommend the scheduler in F4MS. Link to comment Share on other sites More sharing options...
RatB0Y68 Posted June 12, 2022 Author Share Posted June 12, 2022 Just coming back to say you are both epic human beings & I appreciate you for helping me. The script is a success, the outfit changes are flawless. I have an additional request for help. I've noticed that, while you can set an npc to have a sleep outfit & make packages that trigger the use of that outfit, the new outfit change script seems to overrule that feature (or maybe sleep outfits don't work in FO4). If I wanted to make my npc equip their sleep outfit when their doing their sleep packages, how would I go about doing this? Thanks again. Link to comment Share on other sites More sharing options...
AndyTheSaurus Posted September 6 Share Posted September 6 I'm new to modding Fallout4. I'vs modded a lot for Morrowind, Oblivion and Fallout3 ( I think I released my TenpennyTowerMakeover, transforming all the goons there into prohibition era gangsters).Skyrim was a pain - I lost intrest as Ice ands Snow does nort appeal to me. Fallout4 is very difficult because the programming interface has to be set up by the user, and so much has changed. I tend to look for stuff I can copy. So far I cannot manage dialogues - dont understand the new scene based dialogue system. Anyway, I was always doing clothing changes, and your script seems ideal for my Doc Hoff changing his vintage clothing Mod outfit during the night, with changes : Scriptname Fallout3DocHoffClothingScript extends Actor Outfit Property Fallout3DocHoffDayBlackTieTailsOutfitNoHat Auto Const Mandatory Outfit Property Fallout3DocHoffEveningWhiteTieTailsOutfitNoHat Auto Const Mandatory Outfit Property Fallout3DocHoffDayBlackTieTailsOutfitNoHatSC Auto Const Mandatory Outfit Property Fallout3DocHoffEveningWhiteTieTailsOutfitNoHatSC Auto Const Mandatory GlobalVariable Property pGameHour Auto Const Mandatory Outfit LastOutfit int myTimerID = 10 ; Give our timer an ID we can remember float myTimerDuration = 5.0 ; 5 seconds Event OnInit() Self.SetOutfit(Fallout3DocHoffDayBlackTieTailsOutfitNoHat ) LastOutfit = Fallout3DocHoffDayBlackTieTailsOutfitNoHat StartTimer(myTimerDuration , myTimerID ) EndEvent Event OnTimer(int aiTimerID) If aiTimerID == myTimerID ; The five second timer we started just expired CheckOutfit() StartTimer(myTimerDuration , myTimerID) EndIf EndEvent Function CheckOutfit() If (pGameHour.GetValue() < 6 ) || (pGameHour.GetValue() >= 18 ) If (LastOutfit != Fallout3DocHoffEveningWhiteTieTailsOutfitNoHat ) LastOutfit = Fallout3DocHoffEveningWhiteTieTailsOutfitNoHat Self.SetOutfit(LastOutfit) endif else If (LastOutfit != Fallout3DocHoffDayBlackTieTailsOutfitNoHat ) LastOutfit = Fallout3DocHoffDayBlackTieTailsOutfitNoHat Self.SetOutfit(LastOutfit) endif endif EndFunction Link to comment Share on other sites More sharing options...
Sars99 Posted September 6 Share Posted September 6 Probably a touch overkill but I wanted to have a little dabble in your eveningwear idea. Spoiler Scriptname Fallout3DocHoffClothingScript extends Actor Struct OutfitStruct Outfit theOutfit bool IsEveningWear = True EndStruct ;A struct array of all the possible outfits with an ability to 'tag' them as evening wear. Could have new outfits added to it via other scripts OutfitStruct[] Property actorOutfits Auto Const Float Property FirstChange = 6.0 Auto Const {The first time of day (in hours) that the actor will change} Float Property SecondChange = 18.0 Auto Const {The second time of day (in hours) that the actor will change} int LastOutfit = -1 int myTimerID = 10 ; Give our timer an ID we can remember float myTimerDuration = 3.0 ; 3 in-game hours, less intensive than every five seconds. The game time doesn't change that quickly. Could even set this to one hour. Event OnLoad() ;Use OnLoad so that the event fires everytime the player loads the cell with Doc Hoff in it CheckOutfit(IsEvening()) StartTimerGameTime(myTimerDuration, myTimerID ) EndEvent Event OnUnload() CancelTimerGameTime(myTimerID) EndEvent Event OnTimerGameTime(int aiTimerID) If aiTimerID == myTimerID CheckOutfit(IsEvening()) StartTimerGameTime(myTimerDuration , myTimerID) EndIf EndEvent Function CheckOutfit(bool inTimeCheck) ;start at the last outfit to cycle through them int index = LastOutfit While index < actorOutfits.Length ;check here to ensure that it loops round and doesn't try to call indexes outside of the arrays range If index >= actorOutfits.Length index = 0 EndIf If actorOutfits[index].IsEveningWear == inTimeCheck && index != LastOutfit LastOutfit = index SetOutfit(actorOutfits[index].theOutfit) index += 999 EndIf index += 1 EndWhile EndFunction Float Function GetTimeOfDay() ;GetCurrentGameTime gives the current game time in terms of "game days passed". Subtracting the floor of this value gives the time of day as a decimal (i.e. the difference) Float fDayHoursDecimal = Utility.GetCurrentGameTime() - math.Floor(Utility.GetCurrentGameTime()) Float fHourOfDay = math.Floor(fDayHoursDecimal * 24) return fHourOfDay EndFunction bool Function IsEvening() ;Just a handy function in case you want to expand the script or call it from elsewhere Float currentHour = GetTimeOfDay() return currentHour < FirstChange || currentHour >= SecondChange EndFunction Link to comment Share on other sites More sharing options...
AndyTheSaurus Posted September 7 Share Posted September 7 15 hours ago, Sars99 said: Probably a touch overkill but I wanted to have a little dabble in your eveningwear idexxxx Hide contents Scriptname Fallout3DocHoffClothingScript extends Actor Struct OutfitStruct Outfit theOutfit bool IsEveningWear = True EndStruct ;A struct array of all the possible outfits with an ability to 'tag' them as evening wear. Could have new outfits added to it via other scripts OutfitStruct[] Property actorOutfits Auto Const Float Property FirstChange = 6.0 Auto Const {The first time of day (in hours) that the actor will change} Float Property SecondChange = 18.0 Auto Const {The second time of day (in hours) that the actor will change} int LastOutfit = -1 int myTimerID = 10 ; Give our timer an ID we can remember float myTimerDuration = 3.0 ; 3 in-game hours, less intensive than every five seconds. The game time doesn't change that quickly. Could even set this to one hour. Event OnLoad() ;Use OnLoad so that the event fires everytime the player loads the cell with Doc Hoff in it CheckOutfit(IsEvening()) StartTimerGameTime(myTimerDuration, myTimerID ) EndEvent Event OnUnload() CancelTimerGameTime(myTimerID) EndEvent Event OnTimerGameTime(int aiTimerID) If aiTimerID == myTimerID CheckOutfit(IsEvening()) StartTimerGameTime(myTimerDuration , myTimerID) EndIf EndEvent Function CheckOutfit(bool inTimeCheck) ;start at the last outfit to cycle through them int index = LastOutfit While index < actorOutfits.Length ;check here to ensure that it loops round and doesn't try to call indexes outside of the arrays range If index >= actorOutfits.Length index = 0 EndIf If actorOutfits[index].IsEveningWear == inTimeCheck && index != LastOutfit LastOutfit = index SetOutfit(actorOutfits[index].theOutfit) index += 999 EndIf index += 1 EndWhile EndFunction Float Function GetTimeOfDay() ;GetCurrentGameTime gives the current game time in terms of "game days passed". Subtracting the floor of this value gives the time of day as a decimal (i.e. the difference) Float fDayHoursDecimal = Utility.GetCurrentGameTime() - math.Floor(Utility.GetCurrentGameTime()) Float fHourOfDay = math.Floor(fDayHoursDecimal * 24) return fHourOfDay EndFunction bool Function IsEvening() ;Just a handy function in case you want to expand the script or call it from elsewhere Float currentHour = GetTimeOfDay() return currentHour < FirstChange || currentHour >= SecondChange EndFunction Your code is a bit beyond me - but I'm saving it for future use. So far what I have written is for STANDARD Formal wear rules - just change the formal wear to the correct version unless the player is wearing something else. I'm anticipating that there may be cells where STRICT formal wear Rules ( Day wear only, Evening wear only, or STRICT stadard rlues in use) may be in use - they override any else being worn. I've just put in dummy code as I've no idea where vthat might apply - probably the Sanctuary and in Doc Hoffs precence at the Red Racket Petrol Stop. It's unfortunate that it seems no longer possible to detect being in a Named Exterior Cell by using a dummy interior cell name. Have to use distance from standard markers. If want to control players wear in Doc Hoffs presence its a different problem - he's in a different plugin. Fortunately there is a way to pass messages between plugins. Link to comment Share on other sites More sharing options...
AndyTheSaurus Posted September 7 Share Posted September 7 (edited) Anyone know how to access a reference in a script i.e. via the name of a X Marker or a Map Marker ref, so that I can use it in the GetDistance function????? if ( PlayerREF.GetDistance ( PlayerHomeMarkerREF) < 5000 ) ............ endif Edited September 7 by AndyTheSaurus Link to comment Share on other sites More sharing options...
Recommended Posts