antstubell Posted August 7, 2019 Share Posted August 7, 2019 I'm running around in circles with this. So far I haven't even bothered compiling because script just looks wrong. Again, I forget how to do this correctly.So far...Player pushes lever - I have a script attached that sets a global to 1 when lever is in the "Pushed" position. If player activates the lever again 'pulls it', the lever is in the "Pulled Position" and the global is set to 0. Default is 0Lever is pushed, global set to 1 - stuff happens visually (this is already done) - now the whole reason for this lever is to charge a battery. Battery takes, for now, 12hrs to charge, I intend to use an Int Property so I can input the number of hours and therefore reuse the script for other things.Player will get a message saying something like "Battery Charging". This where I need 12hrs, or whatever I input into the Int property to pass and after that a message appears saying "Check battery" wherever the player is.Now if player decides to pull the lever - activate it again - before the allotted time expires I want it to pause the charging process. Then player can restart the charging by activating the lever again and the time will continue from where it left off. Another option is that if player turns off the charging then all progress is lost and timer is reset - this not really realistic but plan B.The lever script already sets the global...Pull Position - 0 Not Charging (default)Push Position = 1 Charging.. so the timer script can use that value as a check.I hope I have made myself clear and thank you all. Link to comment Share on other sites More sharing options...
IsharaMeradin Posted August 7, 2019 Share Posted August 7, 2019 I would add the timer stuff to your lever script. Declare your Integer property:Int Property myTimer Auto Where you want to start the timer use:RegisterForUpdateGameTime(myTimer) When you want the timer to end:Event OnUpdateGameTime() ; do stuffEndEvent When you want to stop the timer mid-count:UnRegisterForUpdateGameTime() That gets you the "plan B" Your "plan A" is more complicated as you have to get the current game time when registering for the update and store it in a variable. Then when wanting to pause the timer, get the new current game time, subtract the old from the new and then subtract that from the original timer value and finally register for update time with that value when the player decides to restart the timer. It is possible to do, just a bit of effort. Link to comment Share on other sites More sharing options...
antstubell Posted August 8, 2019 Author Share Posted August 8, 2019 Shouldn't I use...UnRegisterForUpdateGameTime()… when the script has done what I want, i.e. finished - as well as pausing it? Link to comment Share on other sites More sharing options...
antstubell Posted August 8, 2019 Author Share Posted August 8, 2019 This is what I have so far. It looks correct to me but as you see in the video it is hit and miss. GlobalVariable Property LPos AutoInt Property PassTime AutoEvent OnActivate(ObjectReference akActionRef)If LPos.GetValue() == 1; the lever is ONUnRegisterForUpdateGameTime()debug.notification("Battery Charging Aborted. All Charge Lost")EndIfIf LPos.GetValue() == 0; the lever default starting position OFFRegisterForUpdateGameTime(PassTime)debug.notification("Batteries Charging")EndIfEndEventEvent OnUpdateGameTime()debug.notification("Batteries Fully Charged")EndEvent https://onedrive.live.com/?cid=B60C11D037429D8E&id=B60C11D037429D8E%2134448&parId=B60C11D037429D8E%21191&o=OneUp Link to comment Share on other sites More sharing options...
IsharaMeradin Posted August 8, 2019 Share Posted August 8, 2019 You can use a separate bool variable as the toggle status.Example (adapting your code): GlobalVariable Property LPos Auto Int Property PassTime Auto Bool isToggled = False Event OnActivate(ObjectReference akActionRef) If isToggled == False isToggled = True ; lever turned on If LPos.GetValue() == 1; the lever is ON UnRegisterForUpdateGameTime() debug.notification("Battery Charging Aborted. All Charge Lost") EndIf Else isToggled = False ; lever turned off If LPos.GetValue() == 0; the lever default starting position OFF RegisterForSingleUpdateGameTime(PassTime) debug.notification("Batteries Charging") EndIf EndIf EndEvent Event OnUpdateGameTime() debug.notification("Batteries Fully Charged") EndEvent Switched to RegisterForSingleUpdateGameTime as you don't need it to automatically re-register but rather register only when the player pulls the lever. The global variable LPos should do what the bool variable is doing but there is a delay in updating the value since that is handled elsewhere instead of within this script. You can change the script to update LPos instead of updating it elsewhere. That may speed up recognition of the change in value. You can also utilize states if you so choose to keep each pull separated so that there is no crossing of processing as the lever is pulled. Link to comment Share on other sites More sharing options...
cdcooley Posted August 9, 2019 Share Posted August 9, 2019 Here's a script (with two different implementations of the OnActivate logic) that should accomplish your Plan A. ScriptName BatteryCharger extends ObjectReference GlobalVariable Property LPos Auto float Property ChargeHoursRequired = 12.0 Auto ; these two variables keep track of any partial charge state float ChargeStartHour = 0.0 float ChargeHoursCompleted = 0.0 Event OnUpdateGameTime() Debug.Notification("Batteries Fully Charged") EndEvent State Busy Event OnActivate(ObjectReference akActionRef) ; prevent double activation EndEvent EndState State Draining Event OnActivate(ObjectReference akActionRef) ; prevent activation after batteries have been fully charged and are now being used EndEvent EndState ; lever action logic based on the global variable Event OnActivate(ObjectReference akActionRef) GoToState("Busy") if LPos.GetValue() == 0; the lever is OFF (default starting position) if ChargeHoursCompleted >= ChargeHoursRequired Debug.Notification("Batteries are already fully charged!") ; This probably shouldn't be possible but just in case it's worth checking ; Do whatever is appropriate for full charge else ; start charging ChargeStartHour = Utility.GetCurrentGameTime() * 24.0 ; game time in hours float HoursNeeded = ChargeHoursRequired - ChargeHoursCompleted RegisterForSingleUpdate(HoursNeeded) Debug.Notification("Batteries Charging: " + (HoursNeeded) + " hours needed" ) LPos.SetValue(1) ; Any other actions required to start charging process endif else ; the lever is ON (and charging may or may not be complete) UnregisterForUpdateGameTime() ChargeHoursCompleted = Utility.GetCurrentGameTime() * 24.0 - ChargeStartHour LPos.SetValue(0) if ChargeHoursCompleted >= ChargeHoursRequired Debug.Notification("Batteries are fully charged!") ; This is the expected outcome take any additional actions needed GoToState("Draining") else ; incomplete charge float HoursNeeded = ChargeHoursRequired - ChargeHoursCompleted Debug.Notification("Battery Charging Aborted: " + HoursNeeded + " more hours needed for full charge") GoToState("") endif endif EndEvent ; My alternate version of the charging/pausing/final activation logic for the lever Event OnActivate(ObjectReference akActionRef) GoToState("Busy") UnregisterForUpdateGameTime() if ChargeStartHour == 0.0 ; Not currently charging, so record the start time ChargeStartHour = Utility.GetCurrentGameTime() * 24.0 ; game time in hours else ; Has been charging and now won't be ChargeHoursCompleted += Utility.GetCurrentGameTime() * 24.0 - ChargeStartHour ChargeStartHour = 0.0 endif float HoursNeeded = ChargeHoursRequired - ChargeHoursCompleted if HoursNeeded <= 0.0 ; Full Charge Debug.Notification("Batteries are fully charged!") ; Do whatever is needed (visual effects, setting globals, etc.) when the batteries are ready ; If the batteries need to be recharged later you can transition this script back to the "" state GoToState("Draining") elseif ChargeStartHour > 0.0 ; Starting (or restarting) the charging process RegisterForSingleUpdate(HoursNeeded) Debug.Notification("Batteries Charging: " + (HoursNeeded) + " hours needed" ) ; Do whatever is needed (visual effects, setting globals, etc.) when the batteries start to charge GoToState("") else ; Charging was paused by pulling the lever too soon Debug.Notification("Battery Charging Aborted: " + HoursNeeded + " more hours needed for full charge") ; Take any other action needed (visual effects, setting globals, etc.) when battery charging is interrupted GoToState("") endif EndEvent The important part is the use of the "Busy" state to prevent double activation of the lever. Technically the best version of this would use a lever that doesn't have the NorLever01SCRIPT or other default lever scripts and implements their logic to make sure the lever always appears in the correct push or pull state. My version of the OnActivate event ignores the lever's position and keeps track of the what action to take based on the amount of charge already completed and whether there's a current charging start time. With it the activator could just as easily be a simple button with no memory of on and off. Link to comment Share on other sites More sharing options...
antstubell Posted August 9, 2019 Author Share Posted August 9, 2019 @cdcooleyI just tried you 2nd/alternative script (I tend to believe if there is an alternative it is usually better than the previous - could be wrong) and it works fine with 1 issue. The NorLever01 script is obviously important as it contains the animation for the lever, I see how a button would be a simpler choice but for aesthetics in this case a lever looks better as there are mechanical things happening too when the lever is activated.I inputted 1 into ChargeHoursRequired for testing purposes and after 1 hour, using 'Wait' , I don't get a message informing me of the battery being fully charged. Examining the script I don't see why this doesn't appear. Upon activating the lever after 1 hour I do get the message that the battery is fully charged.Can you say why this is so? Link to comment Share on other sites More sharing options...
antstubell Posted August 9, 2019 Author Share Posted August 9, 2019 To elaborate on my previous post, once the battery is fully charged a lever activation is required to 'turn on' all the necessary sfx and fx. Is it possible to have these turn on automatically when the charge is full. See video,The small switch to the right on the 'battery pack' is allowing the current to be fed along power cables to other devices - all this is already done.https://onedrive.live.com/?cid=B60C11D037429D8E&id=B60C11D037429D8E%2134449&parId=B60C11D037429D8E%21191&o=OneUp Link to comment Share on other sites More sharing options...
maxarturo Posted August 9, 2019 Share Posted August 9, 2019 " The NorLever01 script is obviously important as it contains the animation for the lever " Just put on cdcooley Script the " Lever's Animation ". " Is it possible to have these turn on automatically when the charge is full " Just add a " Function " to when battery is fully charged. Link to comment Share on other sites More sharing options...
antstubell Posted August 9, 2019 Author Share Posted August 9, 2019 (edited) Isn't that what this part of the script should do... if HoursNeeded <= 0.0 ; Full ChargeDebug.Notification("Batteries Are Fully Charged"); Do whatever is needed (visual effects, setting globals, etc.) when the batteries are ready; If the batteries need to be recharged later you can transition this script back to the "" stateBattSwitch.Enable(); turns on sfx and fxGoToState("Draining") BattSwitch being an xmarker which enables all the 'stuff' but script, somehow, requires the lever to be activated again for the 'stuff' to happen. Edited August 9, 2019 by antstubell Link to comment Share on other sites More sharing options...
Recommended Posts