Jump to content
.ZeNu

python Metin2 | Cool Notify Friends | Python

Recommended Posts

12602fe277941f3e0055a8e9a6bec028.png

https://i.gyazo.com/b72a19cfa9cbb9ad7b52342662f94e41.mp4


### 0.1 Root / uiMessenger.py:

# 1. Search: 

	def OnLogin(self, groupIndex ...
	
# 1. After: 

		member.Online()
		self.OnRefreshList()
		
# 1. Add:

		if not name in constInfo.ALREADY_NOTIFY_LIST:
			self.onlinePopup = uiCommon.OnlinePopup()
			self.onlinePopup.SetUserName(name)
			self.onlinePopup.SetEvent(ui.__mem_func__(self.OpenWhisper), "MOUSE_LEFT_BUTTON_UP", name)
			self.onlinePopup.SlideIn()
		
			constInfo.ALREADY_NOTIFY_LIST.append(name)	
			
# 1.1 After: def OnLogin(... Add:

	def OpenWhisper(self, eventType, userName):
		self.whisperButtonEvent(userName)
		
### 0.2 Root / constInfo.py:

# 2. Add:

ALREADY_NOTIFY_LIST = []

### 0.3 Root / ui.py

# 3 Search:

class Board(Window): 

	(....)

# 3 REPLACE this class with:

class Board(Window):
	CORNER_WIDTH = 32
	CORNER_HEIGHT = 32
	LINE_WIDTH = 128
	LINE_HEIGHT = 128

	LT = 0
	LB = 1
	RT = 2
	RB = 3
	L = 0
	R = 1
	T = 2
	B = 3
	
	BASE_PATH = "d:/ymir work/ui/pattern"
	IMAGES = {
		'CORNER' : {
			0 : "Board_Corner_LeftTop",
			1 : "Board_Corner_LeftBottom",
			2 : "Board_Corner_RightTop",
			3 : "Board_Corner_RightBottom"
		},
		'BAR' : {
			0 : "Board_Line_Left",
			1 : "Board_Line_Right",
			2 : "Board_Line_Top",
			3 : "Board_Line_Bottom"
		},
		'FILL' : "Board_Base"
	}

	def __init__(self, layer = "UI"):
		Window.__init__(self, layer)
		self.skipMaxCheck = False

		self.MakeBoard()
		
	def MakeBoard(self):
		CornerFileNames = [ ]
		LineFileNames = [ ]
		
		for imageDictKey in (['CORNER', 'BAR']):
			for x in xrange(len(self.IMAGES[imageDictKey])):
				if imageDictKey == "CORNER":
					CornerFileNames.append("%s/%s.tga" % (self.BASE_PATH, self.IMAGES[imageDictKey][x]))
				elif imageDictKey == "BAR":
					LineFileNames.append("%s/%s.tga" % (self.BASE_PATH, self.IMAGES[imageDictKey][x]))
		
		self.Corners = []
		for fileName in CornerFileNames:
			Corner = ExpandedImageBox()
			Corner.AddFlag("not_pick")
			Corner.LoadImage(fileName)
			Corner.SetParent(self)
			Corner.SetPosition(0, 0)
			Corner.Show()
			self.Corners.append(Corner)

		self.Lines = []
		for fileName in LineFileNames:
			Line = ExpandedImageBox()
			Line.AddFlag("not_pick")
			Line.LoadImage(fileName)
			Line.SetParent(self)
			Line.SetPosition(0, 0)
			Line.Show()
			self.Lines.append(Line)

		self.Lines[self.L].SetPosition(0, self.CORNER_HEIGHT)
		self.Lines[self.T].SetPosition(self.CORNER_WIDTH, 0)

		self.Base = ExpandedImageBox()
		self.Base.AddFlag("not_pick")
		self.Base.LoadImage("%s/%s.tga" % (self.BASE_PATH, self.IMAGES['FILL']))
		self.Base.SetParent(self)
		self.Base.SetPosition(self.CORNER_WIDTH, self.CORNER_HEIGHT)
		self.Base.Show()

	def __del__(self):
		Window.__del__(self)

	def SetSize(self, width, height):
		if not self.skipMaxCheck:
			width = max(self.CORNER_WIDTH*2, width)
			height = max(self.CORNER_HEIGHT*2, height)
			
		Window.SetSize(self, width, height)

		self.Corners[self.LB].SetPosition(0, height - self.CORNER_HEIGHT)
		self.Corners[self.RT].SetPosition(width - self.CORNER_WIDTH, 0)
		self.Corners[self.RB].SetPosition(width - self.CORNER_WIDTH, height - self.CORNER_HEIGHT)
		self.Lines[self.R].SetPosition(width - self.CORNER_WIDTH, self.CORNER_HEIGHT)
		self.Lines[self.B].SetPosition(self.CORNER_HEIGHT, height - self.CORNER_HEIGHT)

		verticalShowingPercentage = float((height - self.CORNER_HEIGHT*2) - self.LINE_HEIGHT) / self.LINE_HEIGHT
		horizontalShowingPercentage = float((width - self.CORNER_WIDTH*2) - self.LINE_WIDTH) / self.LINE_WIDTH
		self.Lines[self.L].SetRenderingRect(0, 0, 0, verticalShowingPercentage)
		self.Lines[self.R].SetRenderingRect(0, 0, 0, verticalShowingPercentage)
		self.Lines[self.T].SetRenderingRect(0, 0, horizontalShowingPercentage, 0)
		self.Lines[self.B].SetRenderingRect(0, 0, horizontalShowingPercentage, 0)

		if self.Base:
			self.Base.SetRenderingRect(0, 0, horizontalShowingPercentage, verticalShowingPercentage)
			
# 3 AFTER CLASS BOARD ADD THIS CLASS:

class BorderB(Board):
	CORNER_WIDTH = 16
	CORNER_HEIGHT = 16
	LINE_WIDTH = 16
	LINE_HEIGHT = 16
	
	BASE_PATH = "d:/ymir work/ui/pattern"

	IMAGES = {
		'CORNER' : {
			0 : "border_b_left_top",
			1 : "border_b_left_bottom",
			2 : "border_b_right_top",
			3 : "border_b_right_bottom"
		},
		'BAR' : {
			0 : "border_b_left",
			1 : "border_b_right",
			2 : "border_b_top",
			3 : "border_b_bottom"
		},
		'FILL' : "border_b_center"
	}
	
	def __init__(self):
		Board.__init__(self)
			
		self.eventFunc = {
			"MOUSE_LEFT_BUTTON_UP" : None, 
		}
		self.eventArgs = {
			"MOUSE_LEFT_BUTTON_UP" : None, 
		}

	def __del__(self):
		Board.__del__(self)
		self.eventFunc = None
		self.eventArgs = None

	def SetSize(self, width, height):
		Board.SetSize(self, width, height)
		
	def SetEvent(self, func, *args) :
		result = self.eventFunc.has_key(args[0])		
		if result :
			self.eventFunc[args[0]] = func
			self.eventArgs[args[0]] = args
		else :
			print "[ERROR] ui.py SetEvent, Can`t Find has_key : %s" % args[0]
			
	def OnMouseLeftButtonUp(self):
		if self.eventFunc["MOUSE_LEFT_BUTTON_UP"] :
			apply(self.eventFunc["MOUSE_LEFT_BUTTON_UP"], self.eventArgs["MOUSE_LEFT_BUTTON_UP"])
			
			
			
### 0.4 Root / uiCommon.py

# 4 Add this to the end of file:


### (Check if you have in this file import app )

class OnlinePopup(ui.BorderB):
	def __init__(self):
		ui.BorderB.__init__(self)
		
		self.isActiveSlide = False
		self.isActiveSlideOut = False
		self.endTime = 0
		self.wndWidth = 0

		self.textLine = ui.TextLine()
		self.textLine.SetParent(self)
		self.textLine.SetWindowHorizontalAlignCenter()
		self.textLine.SetWindowVerticalAlignCenter()
		self.textLine.SetHorizontalAlignCenter()
		self.textLine.SetVerticalAlignCenter()
		self.textLine.SetPosition(13, 0)
		self.textLine.Show()
		
		self.onlineImage = ui.ImageBox()
		self.onlineImage.SetParent(self)
		self.onlineImage.SetPosition(8, 8)
		self.onlineImage.LoadImage("d:/ymir work/ui/game/windows/messenger_list_online.sub")
		self.onlineImage.Show()
		
	def __del__(self):
		ui.BorderB.__del__(self)

	def SlideIn(self):
		self.SetTop()
		self.Show()
		
		self.isActiveSlide = True
		self.endTime = app.GetGlobalTimeStamp() + 5

	def Close(self):
		self.Hide()

	def Destroy(self):
		self.Close()

	def SetUserName(self, name):
		self.textLine.SetText("Player %s is online." % str(name))
		
		self.wndWidth = self.textLine.GetTextSize()[0] + 40
		self.SetSize(self.wndWidth, 25)
		self.SetPosition(-self.wndWidth, wndMgr.GetScreenHeight() - 200)
		
	def OnUpdate(self):
		if self.isActiveSlide and self.isActiveSlide == True:
			x, y = self.GetLocalPosition()
			if x < 0:
				self.SetPosition(x + 4, y)
				
		if self.endTime - app.GetGlobalTimeStamp() <= 0 and self.isActiveSlideOut == False and self.isActiveSlide == True:
			self.isActiveSlide = False
			self.isActiveSlideOut = True
				
		if self.isActiveSlideOut and self.isActiveSlideOut == True:
			x, y = self.GetLocalPosition()
			if x > -(self.wndWidth):
				self.SetPosition(x - 4, y)
				
			if x <= -(self.wndWidth):
				self.isActiveSlideOut = False
				self.Close()


######## Please write in topic If i forgot something. ########

Images for board:

https://mega.nz/#!O1ZjmQxY!tKJdWNXRP6Wgb3DGxzdFRNV9U-bfRIStwnq3ETd6gKo

  • Love 17

Share this post


Link to post

Nice. Idea for an update: maybe add the notification for when someone goes offline?

Share this post


Link to post

0727 15:46:02092 :: Traceback (most recent call last):

0727 15:46:02093 ::   File "introLogo.py", line 60, in OnUpdate

0727 15:46:02094 ::   File "networkModule.py", line 177, in SetLoginPhase

0727 15:46:02094 ::   File "system.py", line 188, in __hybrid_import

0727 15:46:02094 ::   File "system.py", line 153, in _process_result

0727 15:46:02095 ::   File "introLogin.py", line 14, in <module>

0727 15:46:02095 ::   File "system.py", line 188, in __hybrid_import

0727 15:46:02095 ::   File "
0727 15:46:02095 :: uiCommon.py
0727 15:46:02095 :: ", line 
0727 15:46:02095 :: 677
0727 15:46:02095 :: 

0727 15:46:02095 ::     
0727 15:46:02095 :: self.endTime = 0

0727 15:46:02095 ::     
0727 15:46:02096 ::  
0727 15:46:02096 ::  
0727 15:46:02096 ::  
0727 15:46:02096 ::  
0727 15:46:02096 ::  
0727 15:46:02096 ::  
0727 15:46:02096 ::  
0727 15:46:02096 ::  
0727 15:46:02096 ::  
0727 15:46:02096 ::  
0727 15:46:02096 ::  
0727 15:46:02096 ::  
0727 15:46:02096 ::  
0727 15:46:02096 :: ^

0727 15:46:02096 :: SyntaxError
0727 15:46:02096 :: : 
0727 15:46:02096 :: invalid syntax
0727 15:46:02096 :: 

Share this post


Link to post

Thanks! Nice release work fine, just miss a import in root/uicommon.py :)

Quote

import wndMgr

 

Share this post


Link to post
1 hour ago, BKernighan said:

Nice release work fine just import wndMgr in uicommon :)

Thank you

Share this post


Link to post

Why wouldn't you use ui.Bar instead of creating a new window? 

The idea is nice, but I must say that it used to be this kind of window on Polish servers and people complained about it. You should make option to disable this, because it can be annoying when you have a lot of friends 

Share this post


Link to post
Acum 3 ore, filipw1 a spus:

Why wouldn't you use ui.Bar instead of creating a new window? 

The idea is nice, but I must say that it used to be this kind of window on Polish servers and people complained about it. You should make option to disable this, because it can be annoying when you have a lot of friends 

Anyone can make a Config Option for this feature, there is many examples in binary .. about that ...

This notification can be improved a lot, first thing is to delete OnUpdate .. from code. 

Share this post


Link to post

Nice release.
Is your notification also shown when players move/teleport to other maps?
Because this is really annoying.


Best regards
Raylee

Share this post


Link to post
Acum 20 minute, Raylee a spus:

Nice release.
Is your notification also shown when players move/teleport to other maps?
Because this is really annoying.


Best regards
Raylee

No, just once per session.

  • Love 2

Share this post


Link to post

Nice thanks.

 

There is one bug. When player goes online first time it works, but when relog or teleport the message dont show up again. You have to restart client after that it works again.

 

How to fix that? 

 

Kind regards ;)

Share this post


Link to post
Spoiler
Quote

There is one bug. When player goes online first time it works, but when relog or teleport the message dont show up again. You have to restart client after that it works again.

 

How to fix that? 

 

Remove these lines:

Spoiler
  • if not name in constInfo.ALREADY_NOTIFY_LIST:
  • constInfo.ALREADY_NOTIFY_LIST.append(name)
  • ALREADY_NOTIFY_LIST = []

It's not a bug btw :D

Regards

Share this post


Link to post
19 minutes ago, Heathcliff™ said:
  Hide contents

 

Remove these parts:

  Hide contents
  • if not name in constInfo.ALREADY_NOTIFY_LIST:
  •  constInfo.ALREADY_NOTIFY_LIST.append(name)
  • ALREADY_NOTIFY_LIST = []

It's not a bug btw :D

Regards

dont work

  • Confused 1

Share this post


Link to post
14 minutes ago, Heathcliff™ said:

Then check what you did wrong :D

  • # Online member
    ALREADY_NOTIFY_LIST = []

 

  •         if not name in constInfo.ALREADY_NOTIFY_LIST:
                self.onlinePopup = uiCommon.OnlinePopup()
                self.onlinePopup.SetUserName(name)
                self.onlinePopup.SetEvent(ui.__mem_func__(self.OpenWhisper), "MOUSE_LEFT_BUTTON_UP", name)
                self.onlinePopup.SlideIn()
            
                constInfo.ALREADY_NOTIFY_LIST.append(name)    

i remove these parts

Share this post


Link to post
'OnlinePopup' object has no attribute 'SetEvent'

?? Can someone help me with this?

Share this post


Link to post
26 minutes ago, sepheri0n said:

'OnlinePopup' object has no attribute 'SetEvent'

?? Can someone help me with this?

class ImageBox(Window):
	def __init__(self, layer = "UI"):
		Window.__init__(self, layer)

		self.eventDict={}	
		self.eventFunc = {
			"MOUSE_LEFT_BUTTON_UP" : None, 
			"MOUSE_LEFT_BUTTON_DOWN" : None, 
			"MOUSE_RIGHT_BUTTON_UP" : None, 
			"MOUSE_RIGHT_BUTTON_DOWN" : None, 
			"MOUSE_OVER_IN" : None, 
			"MOUSE_OVER_OUT" : None
		}
		self.eventArgs = {
			"MOUSE_LEFT_BUTTON_UP" : None, 
			"MOUSE_LEFT_BUTTON_DOWN" : None, 
			"MOUSE_RIGHT_BUTTON_UP" : None, 
			"MOUSE_RIGHT_BUTTON_DOWN" : None, 
			"MOUSE_OVER_IN" : None, 
			"MOUSE_OVER_OUT" : None
		}

	def __del__(self):
		Window.__del__(self)	
		self.eventFunc = None
		self.eventArgs = None

	def RegisterWindow(self, layer):
		self.hWnd = wndMgr.RegisterImageBox(self, layer)

	def LoadImage(self, imageName):
		self.name=imageName
		wndMgr.LoadImage(self.hWnd, imageName)

	def GetImageName(self):
		return self.name
		
	def SetAlpha(self, alpha):
		wndMgr.SetDiffuseColor(self.hWnd, 1.0, 1.0, 1.0, alpha)
		
	def SetColor(self, r, g, b, a):
		wndMgr.SetDiffuseColor(self.hWnd, r, g, b, a)

	def GetWidth(self):
		return wndMgr.GetWidth(self.hWnd)

	def GetHeight(self):
		return wndMgr.GetHeight(self.hWnd)

	def SetEvent(self, func, *args) :
		result = self.eventFunc.has_key(args[0])		
		if result :
			self.eventFunc[args[0]] = func
			self.eventArgs[args[0]] = args
		else :
			print "[ERROR] ui.py SetEvent, Can`t Find has_key : %s" % args[0]
			
	def SAFE_SetEvent(self, func, *args):
		result = self.eventFunc.has_key(args[0])		
		if result :
			self.eventFunc[args[0]] = __mem_func__(func)
			self.eventArgs[args[0]] = args
		else :
			print "[ERROR] ui.py SAFE_SetEvent, Can`t Find has_key : %s" % args[0]

	def OnMouseLeftButtonUp(self):
		if self.eventFunc["MOUSE_LEFT_BUTTON_UP"] :
			apply(self.eventFunc["MOUSE_LEFT_BUTTON_UP"], self.eventArgs["MOUSE_LEFT_BUTTON_UP"])
			
	def OnMouseLeftButtonDown(self):
		if self.eventFunc["MOUSE_LEFT_BUTTON_DOWN"] :
			apply(self.eventFunc["MOUSE_LEFT_BUTTON_DOWN"], self.eventArgs["MOUSE_LEFT_BUTTON_DOWN"])

	def OnMouseRightButtonUp(self):
		if self.eventFunc["MOUSE_RIGHT_BUTTON_UP"] :
			apply(self.eventFunc["MOUSE_RIGHT_BUTTON_UP"], self.eventArgs["MOUSE_RIGHT_BUTTON_UP"])
			
	def OnMouseRightButtonDown(self):
		if self.eventFunc["MOUSE_RIGHT_BUTTON_DOWN"] :
			apply(self.eventFunc["MOUSE_RIGHT_BUTTON_DOWN"], self.eventArgs["MOUSE_RIGHT_BUTTON_DOWN"])
			
	def OnMouseOverIn(self) :
		if self.eventFunc["MOUSE_OVER_IN"] :
			apply(self.eventFunc["MOUSE_OVER_IN"], self.eventArgs["MOUSE_OVER_IN"])

	def OnMouseOverOut(self) :
		if self.eventFunc["MOUSE_OVER_OUT"] :
			apply(self.eventFunc["MOUSE_OVER_OUT"], self.eventArgs["MOUSE_OVER_OUT"])
			
	def SAFE_SetStringEvent(self, event, func,isa=False):
		if not isa:
			self.eventDict[event]=__mem_func__(func)
		else:
			self.eventDict[event]=func
			
	def LeftRightReverse(self):
		wndMgr.LeftRightReverseImageBox(self.hWnd)
	
	def SetCoolTime(self, time):
		wndMgr.SetCoolTimeImageBox(self.hWnd, time)

	def SetStartCoolTime(self, time):
		wndMgr.SetStartCoolTimeImageBox(self.hWnd, time)

 

Share this post


Link to post
1 hour ago, .ZeNu said:

class ImageBox(Window):
	def __init__(self, layer = "UI"):
		Window.__init__(self, layer)

		self.eventDict={}	
		self.eventFunc = {
			"MOUSE_LEFT_BUTTON_UP" : None, 
			"MOUSE_LEFT_BUTTON_DOWN" : None, 
			"MOUSE_RIGHT_BUTTON_UP" : None, 
			"MOUSE_RIGHT_BUTTON_DOWN" : None, 
			"MOUSE_OVER_IN" : None, 
			"MOUSE_OVER_OUT" : None
		}
		self.eventArgs = {
			"MOUSE_LEFT_BUTTON_UP" : None, 
			"MOUSE_LEFT_BUTTON_DOWN" : None, 
			"MOUSE_RIGHT_BUTTON_UP" : None, 
			"MOUSE_RIGHT_BUTTON_DOWN" : None, 
			"MOUSE_OVER_IN" : None, 
			"MOUSE_OVER_OUT" : None
		}

	def __del__(self):
		Window.__del__(self)	
		self.eventFunc = None
		self.eventArgs = None

	def RegisterWindow(self, layer):
		self.hWnd = wndMgr.RegisterImageBox(self, layer)

	def LoadImage(self, imageName):
		self.name=imageName
		wndMgr.LoadImage(self.hWnd, imageName)

	def GetImageName(self):
		return self.name
		
	def SetAlpha(self, alpha):
		wndMgr.SetDiffuseColor(self.hWnd, 1.0, 1.0, 1.0, alpha)
		
	def SetColor(self, r, g, b, a):
		wndMgr.SetDiffuseColor(self.hWnd, r, g, b, a)

	def GetWidth(self):
		return wndMgr.GetWidth(self.hWnd)

	def GetHeight(self):
		return wndMgr.GetHeight(self.hWnd)

	def SetEvent(self, func, *args) :
		result = self.eventFunc.has_key(args[0])		
		if result :
			self.eventFunc[args[0]] = func
			self.eventArgs[args[0]] = args
		else :
			print "[ERROR] ui.py SetEvent, Can`t Find has_key : %s" % args[0]
			
	def SAFE_SetEvent(self, func, *args):
		result = self.eventFunc.has_key(args[0])		
		if result :
			self.eventFunc[args[0]] = __mem_func__(func)
			self.eventArgs[args[0]] = args
		else :
			print "[ERROR] ui.py SAFE_SetEvent, Can`t Find has_key : %s" % args[0]

	def OnMouseLeftButtonUp(self):
		if self.eventFunc["MOUSE_LEFT_BUTTON_UP"] :
			apply(self.eventFunc["MOUSE_LEFT_BUTTON_UP"], self.eventArgs["MOUSE_LEFT_BUTTON_UP"])
			
	def OnMouseLeftButtonDown(self):
		if self.eventFunc["MOUSE_LEFT_BUTTON_DOWN"] :
			apply(self.eventFunc["MOUSE_LEFT_BUTTON_DOWN"], self.eventArgs["MOUSE_LEFT_BUTTON_DOWN"])

	def OnMouseRightButtonUp(self):
		if self.eventFunc["MOUSE_RIGHT_BUTTON_UP"] :
			apply(self.eventFunc["MOUSE_RIGHT_BUTTON_UP"], self.eventArgs["MOUSE_RIGHT_BUTTON_UP"])
			
	def OnMouseRightButtonDown(self):
		if self.eventFunc["MOUSE_RIGHT_BUTTON_DOWN"] :
			apply(self.eventFunc["MOUSE_RIGHT_BUTTON_DOWN"], self.eventArgs["MOUSE_RIGHT_BUTTON_DOWN"])
			
	def OnMouseOverIn(self) :
		if self.eventFunc["MOUSE_OVER_IN"] :
			apply(self.eventFunc["MOUSE_OVER_IN"], self.eventArgs["MOUSE_OVER_IN"])

	def OnMouseOverOut(self) :
		if self.eventFunc["MOUSE_OVER_OUT"] :
			apply(self.eventFunc["MOUSE_OVER_OUT"], self.eventArgs["MOUSE_OVER_OUT"])
			
	def SAFE_SetStringEvent(self, event, func,isa=False):
		if not isa:
			self.eventDict[event]=__mem_func__(func)
		else:
			self.eventDict[event]=func
			
	def LeftRightReverse(self):
		wndMgr.LeftRightReverseImageBox(self.hWnd)
	
	def SetCoolTime(self, time):
		wndMgr.SetCoolTimeImageBox(self.hWnd, time)

	def SetStartCoolTime(self, time):
		wndMgr.SetStartCoolTimeImageBox(self.hWnd, time)

 

same error line 822 in uimessenger.py  attribute error 

'OnlinePopup' object has no attribute 'SetEvent'

Share this post


Link to post

I get error.What is needed to add

0409 16:20:12620 :: 
networkModule.py(line:200) SetSelectCharacterPhase
system.py(line:178) __hybrid_import
system.py(line:143) _process_result
introSelect.py(line:30) <module>
system.py(line:178) __hybrid_import
system.py(line:143) _process_result
interfaceModule.py(line:15) <module>
system.py(line:178) __hybrid_import
system.py(line:143) _process_result
uiMessenger.py(line:11) <module>
system.py(line:185) __hybrid_import

networkModule.SetSelectCharacterPhase - <type 'exceptions.ImportError'>:No module named name

0409 16:20:12620 :: ============================================================================================================
0409 16:20:12620 :: Abort!!!!

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.