BigBizkit Posted February 20, 2015 Share Posted February 20, 2015 Hi, I have a script X attached to an object in the game. It uses some integer properties set to specific values. Now, I go into the game and run the script (it's OnActivate) and everything works fine. And I save the game. Now, I go into the CK and change some values of the integers, maybe add lines etc. Basically, I edit the script and save. Now, when I load the previous savegame, the script does not seem to be updated. It still treats the integer values as they were set when the savegame "first saw" the mod. Is there a way of forcing such scripts to update without having to uninstall and reinstall the mod? I am asking this in relation to my Pirates mod that I am on the verge of updating. I GUESS if there is no other way, I could copy paste the script and objects in question, essentially creating new instances of them. Thanks Link to comment Share on other sites More sharing options...
cdcooley Posted February 20, 2015 Share Posted February 20, 2015 There's a page about that on the CK Wiki, but here's one option for dealing with the problem. Assume you started with this script.ScriptName SampleScript extends ObjectReference MiscObject Property RewardObject Auto ; Object given to player as a reward int ActivationCount = 0 Event OnActivate(ObjectReference akActionRef) if akActionRef == Game.GetPlayer() ActivationCount += 1 if ActivationCount >= 6 ActivationCount = 0 Debug.Notification("You are persistent, here's your reward.") Game.GetPlayer().AddItem(RewardObject, 1) endif endif EndEvent If you later wanted to give a different reward item then just changing the RewardObject property wouldn't work but changing the code would. You can also change other things defined inside the events and functions (like rewarding after 8 activates instead of 6). ScriptName SampleScript extends ObjectReference MiscObject Property RewardObject Auto ; old unused property (removing generates warnings in log) MiscObject Property NewRewardObject Auto ; Object given to player as a reward int ActivationCount = 0 Event OnActivate(ObjectReference akActionRef) if akActionRef == Game.GetPlayer() ActivationCount += 1 if ActivationCount >= 8 ActivationCount = 0 Debug.Notification("You are persistent, here's your reward.") Game.GetPlayer().AddItem(NewRewardObject, 1) endif endif EndEvent New properties will get filled and the code inside functions and events can be changed, but existing properties won't get updated. If you want more detailed advice, you'll have to post actual scripts and describe the changes you want to make. Link to comment Share on other sites More sharing options...
BigBizkit Posted February 20, 2015 Author Share Posted February 20, 2015 (edited) Alright, this is my messy yet functional script that generates the encounters at sea. Scriptname aaTelescope extends ObjectReference Message Property aaTelescopeMSGTraders Auto Message Property aaTelescopeMSGNothing Auto Message Property aaTelescopeMSGRndPirates Auto Message Property aaTelescopeMSGIMPERIAL Auto Message Property aaTelescopeMSGStormcloaks Auto Message Property aaTelescopeMSGKatariah1 Auto Message Property aaTelescopeMSGSEASNAKE Auto Message Property aaTelescopeMSGNoShips Auto GlobalVariable property aaNavalBattleStarted auto GlobalVariable property aaRerollTimes auto Objectreference Property XMarkerTraders Auto Objectreference Property XMarkerTradersRUM Auto Objectreference Property XMarkerTradersGOLD Auto Objectreference Property XMarkerTradersCARPETS Auto Objectreference Property XMarkerTradersFOOD Auto Objectreference Property XMarkerRNDPirates Auto Objectreference Property XMarkerRNDPirateGOLD Auto actor Property Nalcaryo Auto faction property ShipCrewFaction auto Objectreference Property XMarkerIMPERIAL Auto Objectreference Property XMarkerIMPERIALGOLD Auto Objectreference Property XMarkerStormcloaks Auto Objectreference Property XMarkerStormcloaksFUR Auto Objectreference Property XMarkerStormcloaksHEALTH Auto Objectreference Property aaXKatariah1 Auto Objectreference Property aaXKatariah1LL Auto Objectreference Property aaXKatariah1rl Auto objectreference property aaXKatariah1MainTreasureMarker auto Objectreference Property aaXKatariah1TrDiamond auto Objectreference Property aaXKatariah1TrRAVEN Auto Objectreference Property aaXKatariah1TrCROWNfull auto Objectreference Property aaXKatariah1TrCROWNhalf Auto Objectreference Property aaXKatariah1TrMOON auto Objectreference Property aaXKatariah1TrMajCUP Auto Objectreference Property aaXKatariah1TrMajGoblet Auto Objectreference Property aaXSeaSnakeMarker Auto actor Property Dudecomb Auto ImageSpaceModifier Property FadeToBlackImod Auto ImageSpaceModifier Property FadeToBlackHoldImod Auto ImageSpaceModifier Property FadeToBlackBackImod Auto int property SeeNOTHINGchance auto int property SeeTRADERSchance auto int property SeeRNDPIRATESchance auto int property SeeIMPERIALchance auto int property SeeSTORMCLOAKSchance auto int property SeeKatariah1chance auto int property SeeSEASNAKEchance auto referencealias[] property CrewAlias auto faction property aaShipCrewFRONTrowFaction auto objectreference[] property aaXFrontRowMarker auto Objectreference Property XCaptain Auto Objectreference Property XPlayer Auto objectreference property aaDoorLower auto objectreference property aaDoorUpper auto objectreference property aaDoorBack auto objectreference property aaDoorCaptain auto Event OnActivate(ObjectReference akActionRef) if aaRerollTimes.GetValue() <= 0 aaTelescopeMSGNoShips.Show() else if aaNavalBattleStarted.GetValueInt() == 0 int EnemyShip = Utility.RandomINT(0, 100) if EnemyShip >= (100 - SeeNothingCHANCE) aaTelescopeMSGNothing.Show() ; ------------> you see nothing 25% aaRerollTimes.SetValue(aaRerollTimes.GetValue() - 1) elseif EnemyShip >= (100 - SeeNothingCHANCE - SeeTRADERSchance) ;-----------> you see traders 25% int Option = aaTelescopeMSGTraders.Show() if Option == 0 ;-------> attack traders ; FadeOut () XMarkerTraders.ENable() int TraderLoot = Utility.RandomINT(0, 100) if TraderLoot >= 75 XMarkerTradersRUM.ENable() ; they have RUM 25% elseif TraderLoot >= 50 ; they have CARPETS 25% XMarkerTradersCARPETS.ENable() elseif TraderLoot >= 15 ; they have FOOD 35% XMarkerTradersFOOD.ENable() elseif TraderLoot < 15 ; they have GOLD 15% XMarkerTradersGOLD.ENable() endif BoardingCrew () ; FadeIn () ; Utility.Wait(3.5) ; FadeToBlackHoldImod.PopTo(FadeToBlackBackImod) ; FadeToBlackHoldImod.Remove() elseif Option == 1 aaRerollTimes.SetValue(aaRerollTimes.GetValue() - 1) endif elseif EnemyShip >= (100 - SeeNothingCHANCE - SeeTRADERSchance - SeeRNDPIRATESchance) ;-----------> you see RND-Pirates 50% int Option = aaTelescopeMSGRndPirates.Show() if Option == 0 ;-------> attack them ; FadeOut () XMarkerRNDPirates.ENable() XMarkerRNDPIrateGold.ENable() int NalcaryoChance = Utility.RandomINT(0, 100) if NalcaryoChance >= 50 && Nalcaryo.IsInFaction(ShipCrewFaction) == 0 ; enable Nalcaryo 50% and only if not in crew, if he is crew, he won't get disabled anyway Nalcaryo.ENable() endif BoardingCrew () ; FadeIn () ; Utility.Wait(3.5) ; FadeToBlackHoldImod.PopTo(FadeToBlackBackImod) ; FadeToBlackHoldImod.Remove() elseif Option == 1 aaRerollTimes.SetValue(aaRerollTimes.GetValue() - 1) endif elseif EnemyShip >= (100 - SeeNothingCHANCE - SeeTRADERSchance - SeeRNDPIRATESchance - SeeImperialchance) ;-----------> you see IMPERIALS int Option = aaTelescopeMSGIMPERIAL.Show() if Option == 0 ;-------> attack them ; FadeOut () XMarkerIMPERIAL.ENable() XMarkerIMPERIALGold.ENable() BoardingCrew () ; FadeIn () ; Utility.Wait(3.5) ; FadeToBlackHoldImod.PopTo(FadeToBlackBackImod) ; FadeToBlackHoldImod.Remove() elseif Option == 1 aaRerollTimes.SetValue(aaRerollTimes.GetValue() - 1) endif ;---------------------------------------------------------STORMCLOAKS--------------------------------------------------------- elseif EnemyShip >= (100 - SeeNothingCHANCE - SeeTRADERSchance - SeeRNDPIRATESchance - SeeImperialchance - SeeStormCloaksChance) ;-----------> you see STORMCLOAKS int Option = aaTelescopeMSGStormcloaks.Show() if Option == 0 ;-------> attack them ; FadeOut () XMarkerSTORMCLOAKS.ENable() int StormCloakLOOT = Utility.RandomINT(0, 100) if StormCloakLOOT >= 50 XMarkerStormcloaksFUR.ENable() elseif StormCloakLOOT < 50 XMarkerStormcloaksHEALTH.ENable() endif BoardingCrew () ; FadeIn () ; Utility.Wait(3.5) ; FadeToBlackHoldImod.PopTo(FadeToBlackBackImod) ; FadeToBlackHoldImod.Remove() elseif Option == 1 aaRerollTimes.SetValue(aaRerollTimes.GetValue() - 1) endif ;---------------------------------------------------------KATARIAH1--------------------------------------------------------- elseif EnemyShip >= (100 - SeeNothingCHANCE - SeeTRADERSchance - SeeRNDPIRATESchance - SeeImperialchance - SeeStormCloaksChance - SeeKatariah1Chance) ;-----------> you see IMPERIALS int Option = aaTelescopeMSGKatariah1.Show() if Option == 0 ;-------> attack them ; FadeOut () aaXKatariah1.ENable() aaXKatariah1LL.ENable() ;-----------base loot right and left aaXKatariah1rL.ENable() aaXKatariah1MainTreasureMarker.ENable() Utility.Wait(0.1) aaXKatariah1MainTreasureMarker.ENable() Utility.Wait(0.1) aaXKatariah1MainTreasureMarker.ENable() int Katariah1 = Utility.RandomINT(1, 6) if Katariah1 == 1 aaXKatariah1TrDiamond.ENable() elseif Katariah1 == 2 aaXKatariah1TrRAVEN.ENable() elseif Katariah1 == 3 aaXKatariah1TrCROWNfull.ENable() elseif Katariah1 == 4 aaXKatariah1TrCROWNhalf.ENable() elseif Katariah1 == 5 aaXKatariah1TrMOON.ENable() elseif Katariah1 == 6 aaXKatariah1TrMajCUP.ENable() elseif Katariah1 == 7 aaXKatariah1TrMajGoblet.ENable() endif BoardingCrew () ; FadeIn () ; Utility.Wait(3.5) ; FadeToBlackHoldImod.PopTo(FadeToBlackBackImod) ; FadeToBlackHoldImod.Remove() elseif Option == 1 aaRerollTimes.SetValue(aaRerollTimes.GetValue() - 1) endif ;---------------------------------------------------------SEASNAKE--------------------------------------------------------- elseif EnemyShip >= (100 - SeeNothingCHANCE - SeeTRADERSchance - SeeRNDPIRATESchance - SeeImperialchance - SeeStormCloaksChance - SeeKatariah1Chance - SeeSeaSnakeChance) ;-----------> you see IMPERIALS int Option = aaTelescopeMSGSeaSnake.Show() if Option == 0 ;-------> attack them aaXSeaSnakeMarker.ENable() int DudecombChance = Utility.RandomINT(0, 100) if DudecombChance >= 50 && Dudecomb.IsInFaction(ShipCrewFaction) == 0 ; enable Dudecomb 50% and only if not in crew, if he is crew, he won't get disabled anyway Dudecomb.ENable() endif BoardingCrew () elseif Option == 1 ; there is no other option but ok aaRerollTimes.SetValue(aaRerollTimes.GetValue() - 1) endif endif ;-------------> EnemyShip-check else ;----------Naval Battle Started aaTelescopeMSGNoShips.Show() endif endif ; --------> Reroll EndEvent Function BoardingCrew () Game.GetPlayer().MoveTo(XCaptain) Game.GetPlayer().MoveTo(XPlayer) aaNavalBattleStarted.SetValue(1) aaDoorLower.Lock() aaDoorUpper.Lock() aaDoorBack.Lock() aaDoorCaptain.Lock() if XMarkerTraders.IsDisabled() == 0 ; if TRADERS int index = 0 while index < 9 if CrewAlias[index].GetActorRef().ISInFaction(aaShipCrewFRONTrowFaction) CrewAlias[index].GetActorRef().MoveTo(aaXFrontRowMarker[index]) endif index += 1 endwhile elseif XMarkerRNDPirates.IsDisabled() == 0 ; if PIRATE int index = 0 while index < 9 if CrewAlias[index].GetActorRef().ISInFaction(aaShipCrewFRONTrowFaction) CrewAlias[index].GetActorRef().MoveTo(aaXFrontRowMarker[index+8]) endif index += 1 endwhile elseif XMarkerIMPERIAL.IsDisabled() == 0 ; if IMPERIAL int index = 0 while index < 9 if CrewAlias[index].GetActorRef().ISInFaction(aaShipCrewFRONTrowFaction) CrewAlias[index].GetActorRef().MoveTo(aaXFrontRowMarker[index+16]) endif index += 1 endwhile elseif XMarkerStormcloaks.IsDisabled() == 0 ; if STORMCLOAKS int index = 0 while index < 9 if CrewAlias[index].GetActorRef().ISInFaction(aaShipCrewFRONTrowFaction) CrewAlias[index].GetActorRef().MoveTo(aaXFrontRowMarker[index+24]) endif index += 1 endwhile elseif aaXKatariah1.IsDisabled() == 0 ; if KATARIAH1 int index = 0 while index < 9 if CrewAlias[index].GetActorRef().ISInFaction(aaShipCrewFRONTrowFaction) CrewAlias[index].GetActorRef().MoveTo(aaXFrontRowMarker[index+32]) endif index += 1 endwhile elseif aaXSeaSnakeMarker.IsDisabled() == 0 ; if SEASNAKE int index = 0 while index < 9 if CrewAlias[index].GetActorRef().ISInFaction(aaShipCrewFRONTrowFaction) CrewAlias[index].GetActorRef().MoveTo(aaXFrontRowMarker[index+24]) ; same as for STORMCLOAKS endif index += 1 endwhile endif EndFunction Function FadeOut () aaNavalBattleStarted.SetValue(1) FadeToBlackImod.Apply() Utility.Wait(1.5) FadeToBlackImod.PopTo(FadeToBlackHoldImod) EndFunction Function FadeIn () Utility.Wait(2.5) FadeToBlackHoldImod.PopTo(FadeToBlackBackImod) FadeToBlackHoldImod.Remove() EndFunction The annotations about the percentages are outdated, I assure you I have set the "chances" to values that add up to 100. OK let me explain a bit. The EnemyShip roll determines what ship you "see" through the telescope. I use the SeeSOMETHINGChance integer properties there so I could easily adjusts the probabilities by setting the integer properties. The Seasnake encounter is new, every property with Seasnake in it and the part from : ;-----------------------------------------------------SEASNAKE---------------------------------------------------------elseif EnemyShip >= (100 - SeeNothingCHANCE - SeeTRADERSchance - SeeRNDPIRATESchance - SeeImperialchance - SeeStormCloaksChance - SeeKatariah1Chance - SeeSeaSnakeChance) ..........to the end of the check is newly added. The problem so to speak is, that the savegame remembers the SeeSomethingChance integers as they were set before. All available encounter (SeeSomethingChances) chances in summation are always = 100. When I added the SEASNAKE encounter, I lowered all the other "chances" by 10, and set the new SeasnakeChance to 60 (and it works that way in a "new" savegame). Since the "old" savegame "remembers" the integer properties to be set to the values from before, the condition for the SeaSnake encounter can never be true because the one above will always fire before it. What you said would mean that I could easily circumvent this problem by replacing the SeeSomethingChances with actual numbers. That would mean I had to set them every time I add an encounter manually. That being said, I am pretty sure there is a smarter way to achieve what I was going for (that being x% chance for A, y% chance for b, z% chance for c and x+y+z = 100), edit: I guess if I just use Global Variables instead of the integers, there would not be a problem. That way, users could set them to values they like. Is there a way to prevent that the values in summation become bigger than 100 though? I can only think of a solution pertaining to limiting users to certain presets for the probabilities, rather than them setting the values as they want. Edited February 21, 2015 by BigBizkit Link to comment Share on other sites More sharing options...
cdcooley Posted February 21, 2015 Share Posted February 21, 2015 The value of global variables are also stored in the save game file, so that wouldn't help at all. And player's can change script properties from the console so globals really don't have any advantage here. If it's just a matter of getting those values updated, the easy way would be to write a function to change all of those properties to a set of new values when some trigger condition holds true. From that point on you would be making any changes in that function instead of the CK, but the changes would still all be in one easy to find location. You could also use that function as a sanity check to make sure they really do add up to 100 (in case the player changed them through the console) and set them to something sensible. So with these properties I would do something like this: ... Function CheckTheEncounterChances() ; ensure the chances get new values after the update if (SeeSEASNAKEchance == 0) ; see if the new one is unset SeeNOTHINGchance = 10 SeeTRADERSchance = 6 SeeRNDPIRATESchance = 6 SeeIMPERIALchance = = 6 SeeSTORMCLOAKSchance = 6 SeeKatariah1chance = 6 SeeSEASNAKEchance = 60 ; that's pretty often endif ; now make sure everything is set up as a percentage int total = SeeNOTHINGchance + SeeTRADERSchance + SeeRNDPIRATESchance + SeeIMPERIALchance + SeeSTORMCLOAKSchance + SeeKatariah1chance + SeeSEASNAKEchance if total != 100 ; someone messed up so space them out proportionally SeeSEASNAKEchance = 100 * SeeSEASNAKEchance / 100 SeeTRADERSchance = 100 * SeeTRADERSchance / 100 SeeRNDPIRATESchance = 100 * SeeRNDPIRATESchance / 100 SeeIMPERIALchance = 100 * SeeIMPERIALchance / 100 SeeSTORMCLOAKSchance = 100 * SeeSTORMCLOAKSchance / 100 SeeKatariah1chance = 100 * SeeKatariah1chance / 100 SeeNOTHINGchance = 100 - SeeSEASNAKEchance - SeeTRADERSchance - SeeRNDPIRATESchance - SeeIMPERIALchance - SeeSTORMCLOAKSchance - SeeKatariah1chance ; the last one gets everything left to avoid rounding error problems endif EndFunction ... Event OnActivate(ObjectReference akActionRef) if aaRerollTimes.GetValue() <= 0 aaTelescopeMSGNoShips.Show() else if aaNavalBattleStarted.GetValueInt() == 0 int EnemyShip = Utility.RandomINT(0, 100) CheckTheEncounterChances() ;;;;;; This make sure the chances are updated and valid each time if EnemyShip >= (100 - SeeNothingCHANCE) aaTelescopeMSGNothing.Show() ; ------------> you see nothing 25% aaRerollTimes.SetValue(aaRerollTimes.GetValue() - 1) ... Leave the new SeaSnake property unfilled in the CK (or set it to 0) and let the script make the changes when the player next tries to use the telescope. When you decide to add a new variable or change things again it's as easy as adding a new variable that you can check and updating the chances in that section of the code. With the code to scale things to 100 you could even just set the probabilities relative to each other without working out the math. So 1, 1, 1, 2, 2, 3, 5 would be perfectly valid for the 7 changes and get converted to 6, 6, 6, 13, 13, 20, 36. I put the scaling of the Nothing chance last so it could absorb the rounding errors and in this example it would be 3% more likely than it should be but sometimes it could be less likely depending on the combination of numbers used. Link to comment Share on other sites More sharing options...
BigBizkit Posted February 21, 2015 Author Share Posted February 21, 2015 (edited) That is some great advice there. Thank you for your efforts. 1. So the (start) value for a global I set in the ck is also baked into the save for ever (unless changed via console/script I mean)? Ok.2. I did not know you could access properties in a script via console. I always used globals for something like that. Good to know.3. The CheckEncounter Function, especially the first if block is basically my solution for updating. Great. 4. Maybe it is because I am tired, but I really don't get the "spacing them out proportionally part". Let's say someone messes up and sets them all to 60, except for the Nothing which they set to 0. The check you are suggesting would still leave all the values at 60, and "nothing" would get set to a negative value. I honestly don't get why you would do 100 * x and then / 100. Doesn't it just cancel itself out(?). Could you elaborate on the spacing out / scaling or rephrase it. I don't get it. You make it out to be the sort of auto-adjusting to each other I am looking for but I fail to understand it yet. bonus question: if properties that were once set in a savegame remain that way, and they are not something that you could fill with code such as integers or globals, that means the property is "doomed"? Like in your first post: if I updated several times and always changed the reward to some other item I'd always have to use a new property? (this does not happen in my mod just asking). Would deleting such old but in the savegame already filled properties (which are not used anymore) cause issues other than warnings? Edited February 21, 2015 by BigBizkit Link to comment Share on other sites More sharing options...
cdcooley Posted February 21, 2015 Share Posted February 21, 2015 Sorry, it was late and I mistyped.Those lines should be dividing by total instead SeeSEASNAKEchance = 100 * SeeSEASNAKEchance / totalsince obviously the way I wrote it did absolutely nothing. :blush: You can remove old properties without doing any real harm, but it generates a one-time warning/error message and some people watch their logs and freak out when they see even that. Link to comment Share on other sites More sharing options...
BigBizkit Posted February 22, 2015 Author Share Posted February 22, 2015 (edited) Arrr, much better! Thank you very much for your help. I will make sure to implement the function in the next update. You wouldn't know why apparently for some people sometimes not all the statics linked to a X Marker get enabled. I am 500% sure they are all linked properly and the enable fires. But for some markers it won't enable one particular static or sometimes more than one. It happens e.g. for a vanilla static (ApoStand01 or sth, a static from dragonborn). It works fine for me but I've seen it in both video reviews about the mod so it seems to be an issue. Edited February 22, 2015 by BigBizkit Link to comment Share on other sites More sharing options...
Recommended Posts