SUBSIM Radio Room Forums



SUBSIM: The Web's #1 resource for all submarine & naval simulations since 1997

Go Back   SUBSIM Radio Room Forums > Silent Hunter 3 - 4 - 5 > SH5 Mods Workshop
Forget password? Reset here

Reply
 
Thread Tools Display Modes
Old 05-04-10, 03:23 PM   #1
reaper7
sim2reality
 
Join Date: Jun 2007
Location: AM 82
Posts: 2,280
Downloads: 258
Uploads: 30
Default [TEC] Need Help with a script

I need some help with a script. I require to monitor the period of time in the Day eg Dawn, Dusk Day or Night (Well really I only need the Night).
I have got that part of the code working (Tested it by linking the code to a button so when pressed it checked the time and activated the item respectively).

But I can't get the game to update the item by its self. I have looked through the Dev's and TheDarkWraiths scripts at the timer code but can't seem to get it to work (The script editor doesn't throw up any errors).

Following ip the relevant timer section from my script, can anyone tell me why this part does not seem to be reached;
d = Game.CurrentGameDateTime
if d.Hour in [ 22,23,0,1,2,3,4,5, ]:
ScriptManagerManaged.ShowPythonError("Night Time")
Pageobsperiscope_ObsGraticule.Visible = True

else:
ScriptManagerManaged.ShowPythonError("Not Night Time")
Pageobsperiscope_ObsGraticule.Visible = False
Like I said if I use the above attached to a button it works, but in the timer code when I enter a station it does not seem to ever go into that part of the code:

Code:
#Page obs periscope.py
 
TimerID_CheckTime = 299000001
RefreshTimerDuration = 0.5
 
from menu import *
from game import Game
 
def InitializeScript():
  pass
 
def Menu_PageActivated( page ):
ScriptManagerManaged.ShowPythonError("Page Activated")
if page == Pageobsperiscope:
 Pageobsperiscope.AnimationStopped += Pageobsperiscope_AnimationStopped
 Pageobsperiscope.StopAnimationsOfType( MenuItemWrapper.AnimationTypes.Timer )
 Pageobsperiscope.StartAnimation( MenuItemWrapper.AnimationTypes.Timer, 1, RefreshTimerDuration ).ID = TimerID_CheckTime
 
def Pageobsperiscope_AnimationStopped( Animation ):
ScriptManagerManaged.ShowPythonError("AnimationStopped")
if animation.ID != TimerID_CheckTime:
 Pageobsperiscope.StartAnimation( MenuItemWrapper.AnimationTypes.Timer, 1, RefreshTimerDuration ).ID = TimerID_CheckTime
if not Menu.IsInMission:
return
 d = Game.CurrentGameDateTime
if d.Hour in [ 22,23,0,1,2,3,4,5, ]:
  ScriptManagerManaged.ShowPythonError("Night Time") 
 Pageobsperiscope_ObsGraticule.Visible = True
 
else:
  ScriptManagerManaged.ShowPythonError("Not Night Time")
 Pageobsperiscope_ObsGraticule.Visible = False

 
def StartGame():
 pass
 
 
def Menu_PageDeactivated( page ):
ScriptManagerManaged.ShowPythonError("Page Deactivated")
if page == Pageobsperiscope:
 Pageobsperiscope.StopAnimationsOfType( MenuItemWrapper.AnimationTypes.Timer )
 Pageobsperiscope.AnimationStopped -= Pageobsperiscope_AnimationStopped
 
def EndGame():
 pass
 
def UnloadScript():
 pass
 

Here is the full script in case it makes more sence:

Code:
#Page obs periscope.py
TimerID_CheckTime = 299000001
RefreshTimerDuration = 0.6
from menu import *
from game import Game
# Globals
AttackDiscShown = True
RAOBFShown = True
 
def InitializeScript():
ScriptManagerManaged.ShowPythonError("InitalizeScript")
Pageobsperiscope_ShipContext_LockButton.Visible = False
Pageobsperiscope_ShipContext_UpArrow.Visible = False
Pageobsperiscope_ShipContext_DownArrow.Visible = False
Pageobsperiscope_LockToggle.Clicked += LockToggle
Pageobsperiscope_RAOBFToggle.Visible = True
#Pageobsperiscope_RAOBFToggle.ToolTip = "Range & Angle on Bow Finder"
Pageobsperiscope_RAOBFToggle.Clicked += RAOBFToggle
Pageobsperiscope_AttackDiscToggle.Visible = True
#Pageobsperiscope_AttackDiscToggle.ToolTip = "Attack Disc"
Pageobsperiscope_AttackDiscToggle.Clicked += AttackDiscToggle
 
RAOBFToggle( None ) 
AttackDiscToggle( None )
LockToggle( None )
 
def Menu_PageActivated( page ):
ScriptManagerManaged.ShowPythonError("Page Activated")
if page == Pageobsperiscope:
Pageobsperiscope.AnimationStopped += Pageobsperiscope_AnimationStopped
Pageobsperiscope.StopAnimationsOfType( MenuItemWrapper.AnimationTypes.Timer )
# start the polling
Pageobsperiscope.StartAnimation( MenuItemWrapper.AnimationTypes.Timer, 1, RefreshTimerDuration ).ID = TimerID_CheckTime
 
def Pageobsperiscope_AnimationStopped( Animation ):
ScriptManagerManaged.ShowPythonError("AnimationStopped")
if animation.ID != TimerID_CheckTime:
Pageobsperiscope.StartAnimation( MenuItemWrapper.AnimationTypes.Timer, 1, RefreshTimerDuration ).ID = TimerID_CheckTime
if not Menu.IsInMission:
return
d = Game.CurrentGameDateTime
if d.Hour in [ 22,23,0,1,2,3,4,5, ]:
Pageobsperiscope_ObsGraticule.Visible = True
ScriptManagerManaged.ShowPythonError("NightTime") 
else:
Pageobsperiscope_ObsGraticule.Visible = False
ScriptManagerManaged.ShowPythonError("DayTime")
 
 
def StartGame():
ScriptManagerManaged.ShowPythonError("StartGame")
Pageobsperiscope_RAOBF.Visible = False
Pageobsperiscope_AttackDisc.Visible = False
pass
 
 
def LockToggle( sender ):
ScriptManagerManaged.ShowPythonError("lockToggle")
Game.SubmarineCommands.ExecuteCommand( "Toggle_lock_target" )
 
 
def RAOBFToggle( sender ):
ScriptManagerManaged.ShowPythonError("RAOBFToggle")
global RAOBFShown
RAOBFShown = not RAOBFShown
Pageobsperiscope_RAOBF.Visible = RAOBFShown
#Pageobsperiscope_RAOBFGraticule.Visible = RAOBFShown
#Pageobsperiscope_RAOBFGraticuleBkg.Visible = RAOBFShown
 
#This is the part were it works as tied to a button
d = Game.CurrentGameDateTime
if d.Hour in [ 22,23,0,1,2,3,4,5, ]:
ScriptManagerManaged.ShowPythonError("NightTime") 
Pageobsperiscope_RAOBFGraticuleBkg.Visible = RAOBFShown
Pageobsperiscope_RAOBFGraticule.Visible = RAOBFShown
else: 
ScriptManagerManaged.ShowPythonError("DayTime")
Pageobsperiscope_RAOBFGraticuleBkg.Visible = RAOBFShown
 
 
def AttackDiscToggle( sender ):
ScriptManagerManaged.ShowPythonError("AttackDiscToggle")
global AttackDiscShown
AttackDiscShown = not AttackDiscShown
Pageobsperiscope_AttackDisc.Visible = not AttackDiscShown
 
 
def Menu_PageDeactivated( page ):
ScriptManagerManaged.ShowPythonError("Page Deactivated")
if page == Pageobsperiscope:
Pageobsperiscope.StopAnimationsOfType( MenuItemWrapper.AnimationTypes.Timer )
Pageobsperiscope.AnimationStopped -= Pageobsperiscope_AnimationStopped
 
 
def EndGame():
pass
 
 
def UnloadScript():
Pageobsperiscope_LockToggle.Clicked -= LockToggle
Pageobsperiscope_RAOBFToggle.Clicked -= RAOBFToggle
Pageobsperiscope_AttackDiscToggle.Clicked -= AttackDiscToggle
pass
 
Any suggestions.
reaper7 is offline   Reply With Quote
Old 05-04-10, 03:38 PM   #2
TheDarkWraith
Black Magic
 
Join Date: Jun 2007
Posts: 11,962
Downloads: 147
Uploads: 5


Default

there are multiple things wrong with this code (just stating a fact that's all not busting your chops). First, your animation timer will never be reset because you told it not to:

def Pageobsperiscope_AnimationStopped( Animation ):
ScriptManagerManaged.ShowPythonError("AnimationSto pped")
if animation.ID != TimerID_CheckTime:
Pageobsperiscope.StartAnimation( MenuItemWrapper.AnimationTypes.Timer, 1, RefreshTimerDuration ).ID = TimerID_CheckTime
if not Menu.IsInMission:
return
UpdateGraticules ( )

that function should be coded as follows:

def Pageobsperiscope_AnimationStopped( Animation ):
ScriptManagerManaged.ShowPythonError("AnimationSto pped")
if not Menu.IsInMission:
return
if animation.ID == TimerID_CheckTime:
Pageobsperiscope.StartAnimation( MenuItemWrapper.AnimationTypes.Timer, 1, RefreshTimerDuration ).ID = TimerID_CheckTime
UpdateGraticules ( )


Second you keep writing the same code over and over. You should define a function and return a value back from it everywhere you have this code. And that stay comma after the 5 would've given you a nasty python error also:

d = Game.CurrentGameDateTime
if d.Hour in [ 22,23,0,1,2,3,4,5, ]:
ScriptManagerManaged.ShowPythonError("Night Time")

it should be replaced with a function call:

def GetCurrentGameDateTime():
d = Game.CurrentGameDateTime
if d.Hour in [ 22, 23, 0, 1, 2, 3, 4, 5 ]:
ScriptManagerManaged.ShowPythonError( "Night Time" )
return True
else:
return False

then everything that needs to access that function would look like this:

Pageobsperiscope_ObsGraticule.Visible = GetCurrentGameDateTime()


The problem with writing the same code over and over instead of practicing code reuse is if you change one then you have to ensure you change them ALL. By localizing it all in one place you never have to worry about that ever happening

Last edited by TheDarkWraith; 05-04-10 at 04:02 PM.
TheDarkWraith is offline   Reply With Quote
Old 05-04-10, 04:02 PM   #3
reaper7
sim2reality
 
Join Date: Jun 2007
Location: AM 82
Posts: 2,280
Downloads: 258
Uploads: 30
Default

Quote:
Originally Posted by TheDarkWraith View Post
there are multiple things wrong with this code. First, your animation timer will never be reset because you told it not to:

The problem with writing the same code over and over instead of practicing code reuse is if you change one then you have to ensure you change them ALL. By localizing it all in one place you never have to worry about that ever happening

Thanks TheDarkWraith for your quick reply. Wastn't sure about the != part above as I copied that from the stock default Hud script had noticed you had == in your attack periscope script.

Yes, the fuction call is good practice - I had it called that way originally but when it didn't work. I did the Frankeinstein on it had chopped and pasted everywhere just to test the Night Time part of the code. Bad Practice

Thanks will give it another crack. And congrats with your new V2.1.0 its the biz.
reaper7 is offline   Reply With Quote
Old 05-04-10, 05:02 PM   #4
reaper7
sim2reality
 
Join Date: Jun 2007
Location: AM 82
Posts: 2,280
Downloads: 258
Uploads: 30
Default

Ok Changed the Code to the following (Alot cleaner now ): No errors, but still only the part thats codded to change to a button press responds.

Have Coloured the lines in Red that activate the controls that are made visible/hidden depending on the timecheck. This one Pageobsperiscope_ObsGraticule.Visible = GetCurrentGameDateTime() needs to update itself without user action (Timer can be every minute - doesn't need to be every second would that be RefreshTimerDuration = 60.0)

The other instance works on a button press: Timecheck = GetCurrentGameDateTime()
if Timecheck == True:
Pageobsperiscope_RAOBFGraticuleBkg.Visible = RAOBFShown
Pageobsperiscope_RAOBFGraticule.Visible = RAOBFShown
and this works perfectly but only if the user presses the button.

How can I set an action to initiate a function once the timer is reached
e.g call the GetCurrentGameDateTime() every minute while Page is open.


Code:
#Page obs periscope.py
 
# Globals
AttackDiscShown = True
RAOBFShown = True
 
TimerID_CheckTime = 299000001
RefreshTimerDuration = 1.0
 
from menu import *
from game import Game
 
def InitializeScript():
 Pageobsperiscope_ShipContext_LockButton.Visible = False
 Pageobsperiscope_LockToggle.Clicked += LockToggle
 Pageobsperiscope_RAOBFToggle.Visible = True
 Pageobsperiscope_RAOBFToggle.Clicked += RAOBFToggle
 Pageobsperiscope_AttackDiscToggle.Visible = True
 Pageobsperiscope_AttackDiscToggle.Clicked += AttackDiscToggle
 Pageobsperiscope_ObsGraticule.Visible = GetCurrentGameDateTime()
 
 RAOBFToggle( None ) 
 AttackDiscToggle( None )
 LockToggle( None )
 
 
def Menu_PageActivated( page ):
if page == Pageobsperiscope:
 Pageobsperiscope.AnimationStopped += Pageobsperiscope_AnimationStopped
 Pageobsperiscope.StopAnimationsOfType( MenuItemWrapper.AnimationTypes.Timer )
 Pageobsperiscope.StartAnimation( MenuItemWrapper.AnimationTypes.Timer, 1, RefreshTimerDuration ).ID = TimerID_CheckTime
 Pageobsperiscope_ObsGraticule.Visible = GetCurrentGameDateTime()

 
def Pageobsperiscope_AnimationStopped( Animation ):
if not Menu.IsInMission:
 return
if animation.ID == TimerID_CheckTime:
 Pageobsperiscope.StartAnimation( MenuItemWrapper.AnimationTypes.Timer, 1, RefreshTimerDuration ).ID = TimerID_CheckTime
 
 
def StartGame():
 Pageobsperiscope_RAOBF.Visible = False
 Pageobsperiscope_AttackDisc.Visible = False
 pass
 
 
def GetCurrentGameDateTime():
d = Game.CurrentGameDateTime
if d.Hour in [ 22,23,0,1,2,3,4,5, ]:
 return True
else:
 return False
 
 
def LockToggle( sender ):
 Game.SubmarineCommands.ExecuteCommand(  "Toggle_lock_target" )
 
 
def RAOBFToggle( sender ):
 global RAOBFShown
 RAOBFShown = not RAOBFShown
 Pageobsperiscope_RAOBF.Visible = RAOBFShown
Timecheck = GetCurrentGameDateTime()
if Timecheck == True:
  Pageobsperiscope_RAOBFGraticuleBkg.Visible = RAOBFShown
 Pageobsperiscope_RAOBFGraticule.Visible = RAOBFShown
else: 
 Pageobsperiscope_RAOBFGraticuleBkg.Visible = RAOBFShown
 
 
def AttackDiscToggle( sender ):
 global AttackDiscShown
 AttackDiscShown = not AttackDiscShown
 Pageobsperiscope_AttackDisc.Visible = not AttackDiscShown
 
 
def Menu_PageDeactivated( page ):
if page == Pageobsperiscope:
 Pageobsperiscope.StopAnimationsOfType( MenuItemWrapper.AnimationTypes.Timer )
 Pageobsperiscope.AnimationStopped -= Pageobsperiscope_AnimationStopped
 
 
def EndGame():
 pass
 
 
def UnloadScript():
Pageobsperiscope_LockToggle.Clicked -= LockToggle
Pageobsperiscope_RAOBFToggle.Clicked -= RAOBFToggle
Pageobsperiscope_AttackDiscToggle.Clicked -= AttackDiscToggle
pass
Thanks for all your help DW, hope all my questions on scripting aren't taking you away from your own work. But its great that we have Code Geniuses to help us noobes .
reaper7 is offline   Reply With Quote
Old 05-04-10, 09:11 PM   #5
TheDarkWraith
Black Magic
 
Join Date: Jun 2007
Posts: 11,962
Downloads: 147
Uploads: 5


Default

anything you want updated when the timer expires needs to be placed in the Pageobsperiscope_AnimationStopped function. You told the timer to start....it times out....you told the page that when animation is stopped to call Pageobsperiscope_AnimationStopped. In that same function you told the timer to start timing again (recursive).

The timer is in seconds so 1.0 would be 1 second

Now the method you are using is called polling (for the event). This is highly inefficient when the game exposes an event way of doing things. Instead of checking every second for something to happen you could just set an event and when that event happens it calls the event handler (function) for that event. I figured out how to do this.....after digging and analyzing and experimenting. I'll leave that up to you to discover how to do.

Before v2.1.0 of the UIs mod I used the same method, polling. Everyone says v2.1.0 runs much smoother....and I can believe it because I'm not polling for multiple events to happen anymore. The game just sits back and waits for an event to happen and then it calls the associated function to handle it. Makes things much smoother and doesn't waste CPU cycles
TheDarkWraith is offline   Reply With Quote
Old 05-05-10, 05:18 AM   #6
reaper7
sim2reality
 
Join Date: Jun 2007
Location: AM 82
Posts: 2,280
Downloads: 258
Uploads: 30
Default

Ah... So I'm starting the timer and exiting the function without doing anything and then looping (Ok that makes sence now).
Its like learning to speak English all over again.
I think it may be time to invest in a Pyton Book or two.

Thanks DW for your assistance. Hope you don't mind but I'm sure I'll be looking for help with more script probs.

EDIT: Still no go. Placed ScriptManagerManaged.ShowPythonError messages everywhere just to trace the script, and its as if the script never calls the timer function ie the ShowPythonError I placed in the Pageobsperiscope_AnimationStopped function never shows up.

Tried the same with the PageDefaulHud script placing a ShowPythonError in its Pageobsperiscope_AnimationStopped function and that keeps throwing up the Popup error (Got stuck in an infinite loop as soon as I closed the popup the script had cycled again and threw upa new popup). So that shows my Timer function is not getting called or running.
Will Investigate to see what calls the Pageobsperiscope_AnimationStopped function in the DefaultHud script and see if I can get this working.

Last edited by reaper7; 05-05-10 at 07:49 AM.
reaper7 is offline   Reply With Quote
Old 05-05-10, 08:26 AM   #7
TheDarkWraith
Black Magic
 
Join Date: Jun 2007
Posts: 11,962
Downloads: 147
Uploads: 5


Default

what's the popup error it keeps giving you?
TheDarkWraith is offline   Reply With Quote
Old 05-05-10, 09:15 AM   #8
reaper7
sim2reality
 
Join Date: Jun 2007
Location: AM 82
Posts: 2,280
Downloads: 258
Uploads: 30
Default

Quote:
Originally Posted by TheDarkWraith View Post
what's the popup error it keeps giving you?

The Popup error was the one I created using ScriptManagerManaged.ShowPythonError for feedback.
I just did that to prove if the Default.hud script was going into the def Pageobsperiscope_AnimationStopped( Animation ): part of the script, which it does in an endless loop (Good).

Whereas in my script above it never goes into the def Pageobsperiscope_AnimationStopped( Animation ): part of the script hence the ScriptManagerManaged popup I placed in it does not show up, nor does the Item I wasnt to control work. (The script appears to only cycle once - although the [ Toggle( None ) ] functions in the InilalizeScript (): work ok when there corresponding button is clicked.

So the script works perfectly when the game runs for first time, but after that the timer part does not appear to do anything???
reaper7 is offline   Reply With Quote
Old 05-05-10, 09:20 AM   #9
TheDarkWraith
Black Magic
 
Join Date: Jun 2007
Posts: 11,962
Downloads: 147
Uploads: 5


Default

Move this line to InitializeScript from PageActivated:

Pageobsperiscope.AnimationStopped += Pageobsperiscope_AnimationStopped

move it's assocaited -= to unload script

add this to the end of InitializeScript:

Menu_PageActivated( Pageobsperiscope )

remove pass from startgame and unloadscript

remove stray comma after 5:

if d.Hour in [ 22,23,0,1,2,3,4,5, ]:
TheDarkWraith is offline   Reply With Quote
Old 05-05-10, 12:53 PM   #10
reaper7
sim2reality
 
Join Date: Jun 2007
Location: AM 82
Posts: 2,280
Downloads: 258
Uploads: 30
Default

Quote:
Originally Posted by TheDarkWraith View Post
Move this line to InitializeScript from PageActivated:

Pageobsperiscope.AnimationStopped += Pageobsperiscope_AnimationStopped

move it's assocaited -= to unload script

Had tried that from copying the Dafault Hud format:
But whats follows I didn't see in that script, looks Interesting.
That looks like it will kickstart it into doing the Animationstop part .

Quote:
Originally Posted by TheDarkWraith View Post
add this to the end of InitializeScript:
Menu_PageActivated( Pageobsperiscope )

remove pass from startgame and unloadscript

remove stray comma after 5:

if d.Hour in [ 22,23,0,1,2,3,4,5, ]:
Don't know how that comma keeps making it back into my code, could have sworn I deleted it .

Will Test this soon, Did something silly - disabled My WIP UI Mod from JGSME to try something without backing up what I had done for the last few days. (The second I clicked on remove it dawned on me ) So now I have to redo my work to get back to this point . At least its just stuff in the Menu Editor that needs redoing as Graphics are all duplicated - Phew.
reaper7 is offline   Reply With Quote
Old 05-05-10, 04:37 PM   #11
reaper7
sim2reality
 
Join Date: Jun 2007
Location: AM 82
Posts: 2,280
Downloads: 258
Uploads: 30
Default Yes its Working

Thank you DW that did the trick perfectly. Script is now running the Timer and accessing the AnimationStopped function nicely.
Just had to tweak my script a bit and everyting is now workin as hoped for.

Here's some pics of how its getting around the stock bug of the Markings group not working ingame for the Obs Periscope (Attack and UZO work fine in stock).

Here's my new Obs Graticule and obs RAOBF in action.

Day-time:


Night-time:


So now when the time is between 10Pm and 6am the Graticules are Flourecent Green (Glow in the dark style) and during the rest of the Day the revert to Jet black not transparent grey as in stock.
Also redone the compass to have a more imbedded look rather than floating over the scope:
Just need to make this hidden when RAOBF is activated.


Also have the AttackScope done as well. This was a hell of a lot easier as the bug did not apply to them so they don't require the same means of script to change between night and day. (The attack scope will change just as the stock ones do)
reaper7 is offline   Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -5. The time now is 10:16 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Copyright © 1995- 2025 Subsim®
"Subsim" is a registered trademark, all rights reserved.