Ryyz Posted January 19, 2018 Share Posted January 19, 2018 (edited) Okay, I'm making a witcher alchemy mod complete with a toxicity system. I want to be able to stop potion magic effects from applying when the toxicity reaches 100%. I'd like to make it where the potion itself becomes unusable but idk if thats possible. Anyway, this is the script I came up with: ScriptName WA_ToxicityScript Extends ActiveMagicEffect ;GlobalVariable that disallows potion. 0 is disallow. 1 is allow. disallow once toxicity is at 100. allow when below GlobalVariable Property DisallowPotion Auto ;Toxicity level integer. default 0. max 100. Int ToxicityLevel Event OnEffectStart (Actor akTarget, Actor akCaster) ;Check if toxicity level is less than 100. If it is add 25 to toxicityamount. If (ToxicityLevel < 100) DisallowPotion.SetValue(1) ToxicityLevel += 25 Debug.Notification("You drink the potion. Toxicity is now "+ToxicityLevel) EndIf ;Check is toxicitylevel is 100. if it is set globalvariable to 0. If (ToxicityLevel == 100) DisallowPotion.SetValue(0) Debug.Notification("Your toxicity amount is too high. Drinking another potion would kill you.") EndIf If (ToxicityLevel == 0) Else Utility.Wait(90) ToxicityLevel -= 25 Debug.Notification("Your toxicity amount is now "+ToxicityLevel) EndIf EndEvent Here's the problem I'm having. I drink the potion, script runs, applies 25 toxicity like it should. I drink another, but the toxicity doesn't increase and it stays at 25. Basically it only adds toxicity once. I can't test the global since it never reaches 100, it goes to 25 every potion consumption. I also tested the removing toxicity, it worked fine. It removes it properly. I originally had "Int ToxicityLevel = 0" I thought that's what was cuasing it so I removed the "= 0" since integers start at 0. Anyone have any ideas? I'm stumped. Also, if there's a way to stop the potion from being consumed at all, I'd like some info on that. If not, just helping me work through this problem would be fine. Edited January 19, 2018 by Ryyz Link to comment Share on other sites More sharing options...
JonathanOstrus Posted January 19, 2018 Share Posted January 19, 2018 First issue is that your Toxicity counter is a local script variable. Since the script is instanced once per effect firing it would not increment. You would probably want to change that to a GlobalVariable property just like your disallow flag. Of course your code for checking and changing the value would then need slight modifications as well. Also your usage of the Utility.Wait(90) scares me. While probably functional there could be implications that could cause other game play things to fail. Using a game timer to call back and decrement your toxicity would be a preferred method. Link to comment Share on other sites More sharing options...
TangerineDog Posted January 19, 2018 Share Posted January 19, 2018 What you're trying to do sounds a hell of a lot like a Hunger script I made with the kind help of folks around here. Modified to suit your needs, the effect would be this: Your toxicity level is raised by 25 with every potion you drink 'til it reaches a max, but it declines with time until it's back at the minimal level.If it is at the maximum level or the next potion would raise it to or beyond that level, you can't drink it. But since doing your own stuff is more fun: the problem I see with your script is that ToxicityLevel is not a global.Every potion sees a copy the same script, but for every potion it starts at 0 and goes to 25.Make it a global. That'll do it. Link to comment Share on other sites More sharing options...
Ryyz Posted January 19, 2018 Author Share Posted January 19, 2018 (edited) That completely slipped my mind. But in order to actually compare the global variable I'd need to cast it as an integer. How exactly is that done with globals? Or is there another way to check the value without doing that? Edit: Never mind the above. How would I check for the global? Doesn't work the same as local integers. First issue is that your Toxicity counter is a local script variable. Since the script is instanced once per effect firing it would not increment. You would probably want to change that to a GlobalVariable property just like your disallow flag. Of course your code for checking and changing the value would then need slight modifications as well. Also your usage of the Utility.Wait(90) scares me. While probably functional there could be implications that could cause other game play things to fail. Using a game timer to call back and decrement your toxicity would be a preferred method. Edited January 20, 2018 by Ryyz Link to comment Share on other sites More sharing options...
Ryyz Posted January 20, 2018 Author Share Posted January 20, 2018 So, I thought the script should go like Int ToxicityLevelInt = (ToxicityLevelGlobal.GetValue() as Int) If (ToxicityLevelInt < 100) but it didn't work. Theres no compiler errors. When I test in game I still have the same problem. I also changed all the math to ToxicityLevelInt. I've never worked with globals like this so I'm kinda lost. Link to comment Share on other sites More sharing options...
JonathanOstrus Posted January 20, 2018 Share Posted January 20, 2018 (edited) I didn't test this in actual use but this should do it provided you make and fill the global property. ScriptName WA_ToxicityScript Extends ActiveMagicEffect ;GlobalVariable that disallows potion. 0 is disallow. 1 is allow. disallow once toxicity is at 100. allow when below GlobalVariable Property DisallowPotion Auto ;Toxicity level integer. default 0. max 100. GlobalVariable Property ToxicityLevel Auto Event OnEffectStart (Actor akTarget, Actor akCaster) ;Check if toxicity level is less than 100. If it is add 25 to toxicityamount. If (ToxicityLevel.Value < 100) DisallowPotion.Value = 1 ToxicityLevel.Value += 25 Debug.Notification("You drink the potion. Toxicity is now "+ToxicityLevel) EndIf ;Check is toxicitylevel is 100. if it is set globalvariable to 0. If (ToxicityLevel.Value == 100) DisallowPotion.Value = 0 Debug.Notification("Your toxicity amount is too high. Drinking another potion would kill you.") EndIf If (ToxicityLevel.Value == 0) Else Utility.Wait(90) ToxicityLevel.Value -= 25 Debug.Notification("Your toxicity amount is now "+ToxicityLevel) EndIf EndEvent If you need to actually test against int change the .Value properties to .GetValueInt(). That will get and return pre-cast as int. This should work as is though if memory serves. It's been a while since I actually made mod content aside from concept coding. Edit: The only thing that should be left is dealing with the ugly 90sec wait timer. I believe in actual use if you were to pop 4 of these consumables at once it would lockup the papyrus engine so no other scripts would fire until one of yours finished the wait and completed. Edited January 20, 2018 by BigAndFlabby Link to comment Share on other sites More sharing options...
Ryyz Posted January 20, 2018 Author Share Posted January 20, 2018 I didn't test this in actual use but this should do it provided you make and fill the global property. ScriptName WA_ToxicityScript Extends ActiveMagicEffect ;GlobalVariable that disallows potion. 0 is disallow. 1 is allow. disallow once toxicity is at 100. allow when below GlobalVariable Property DisallowPotion Auto ;Toxicity level integer. default 0. max 100. GlobalVariable Property ToxicityLevel Auto Event OnEffectStart (Actor akTarget, Actor akCaster) ;Check if toxicity level is less than 100. If it is add 25 to toxicityamount. If (ToxicityLevel.Value < 100) DisallowPotion.Value = 1 ToxicityLevel.Value += 25 Debug.Notification("You drink the potion. Toxicity is now "+ToxicityLevel) EndIf ;Check is toxicitylevel is 100. if it is set globalvariable to 0. If (ToxicityLevel.Value == 100) DisallowPotion.Value = 0 Debug.Notification("Your toxicity amount is too high. Drinking another potion would kill you.") EndIf If (ToxicityLevel.Value == 0) Else Utility.Wait(90) ToxicityLevel.Value -= 25 Debug.Notification("Your toxicity amount is now "+ToxicityLevel) EndIf EndEvent If you need to actually test against int change the .Value properties to .GetValueInt(). That will get and return pre-cast as int. This should work as is though if memory serves. It's been a while since I actually made mod content aside from concept coding.Ooooh. Thanks for the info. I didn't realize you could use .Value like that. Thanks! Link to comment Share on other sites More sharing options...
JonathanOstrus Posted January 20, 2018 Share Posted January 20, 2018 Yup. Might be worth skimming over https://www.creationkit.com/fallout4/index.php?title=GlobalVariable_Script If you use globals more often you might have use for the Mod() function. Link to comment Share on other sites More sharing options...
IsharaMeradin Posted January 20, 2018 Share Posted January 20, 2018 Beat to the punch... Tho I'll post what I came up with. I suggest changing your magic effect (the one your script is attached) to have a duration of 90 seconds. Thus you can use the OnEffectFinish event to drop the global value by 25. Other changes are that I kept it as float, I didn't see where it needed to be used as an integer. Also, I used Mod. In theory, Mod is more thread safe but mileage may vary... ScriptName WA_ToxicityScript Extends ActiveMagicEffect ;GlobalVariable that disallows potion. 0 is disallow. 1 is allow. disallow once toxicity is at 100. allow when below GlobalVariable Property DisallowPotion Auto ;Toxicity level integer. default 0. max 100. GlobalVariable Property ToxicityLevel Auto Event OnEffectStart (Actor akTarget, Actor akCaster) ;Check if toxicity level is less than 100. If it is add 25 to toxicityamount. If (ToxicityLevel.GetValue() < 100.0) DisallowPotion.SetValue(1) ToxicityLevel.Mod(25.0) Debug.Notification("You drink the potion. Toxicity is now "+ToxicityLevel.GetValue()) EndIf ;Check is toxicitylevel is 100. if it is set globalvariable to 0. If (ToxicityLevel.GetValue() == 100.0) DisallowPotion.SetValue(0) Debug.Notification("Your toxicity amount is too high. Drinking another potion would kill you.") EndIf EndEvent Event OnEffectFinish(Actor akTarget, Actor akCaster) If ToxicityLevel.GetValue() != 0 ToxicityLevel.Mod(-25.0) Debug.Notification("Your toxicity amount is now "+ToxicityLevel.GetValue()) EndIf EndEvent Link to comment Share on other sites More sharing options...
JonathanOstrus Posted January 20, 2018 Share Posted January 20, 2018 (edited) Beat to the punch... Tho I'll post what I came up with. I suggest changing your magic effect (the one your script is attached) to have a duration of 90 seconds. Thus you can use the OnEffectFinish event to drop the global value by 25. Other changes are that I kept it as float, I didn't see where it needed to be used as an integer. Also, I used Mod. In theory, Mod is more thread safe but mileage may vary... ScriptName WA_ToxicityScript Extends ActiveMagicEffect ;GlobalVariable that disallows potion. 0 is disallow. 1 is allow. disallow once toxicity is at 100. allow when below GlobalVariable Property DisallowPotion Auto ;Toxicity level integer. default 0. max 100. GlobalVariable Property ToxicityLevel Auto Event OnEffectStart (Actor akTarget, Actor akCaster) ;Check if toxicity level is less than 100. If it is add 25 to toxicityamount. If (ToxicityLevel.GetValue() < 100.0) DisallowPotion.SetValue(1) ToxicityLevel.Mod(25.0) Debug.Notification("You drink the potion. Toxicity is now "+ToxicityLevel.GetValue()) EndIf ;Check is toxicitylevel is 100. if it is set globalvariable to 0. If (ToxicityLevel.GetValue() == 100.0) DisallowPotion.SetValue(0) Debug.Notification("Your toxicity amount is too high. Drinking another potion would kill you.") EndIf EndEvent Event OnEffectFinish(Actor akTarget, Actor akCaster) If ToxicityLevel.GetValue() != 0 ToxicityLevel.Mod(-25.0) Debug.Notification("Your toxicity amount is now "+ToxicityLevel.GetValue()) EndIf EndEvent Oooh yes, yes. Much better method (use built in effect duration). [facepalm] Knew that in the back of my mind, but as previously stated it's been a hot minute since I actually made a mod beyond concept stuff. Edit: Might also be worth noting for OP that if you plan to publish the mod and have the messages displayed to the user, you would want to convert the Debug.Notification to a Message.Show() style command. Edited January 20, 2018 by BigAndFlabby Link to comment Share on other sites More sharing options...
Recommended Posts