# For each occurance of *YourAge* and *YourTexture* you have to replace this with
# the actual name of your age and your textures.
from Plasma import *
from PlasmaNetConstants import *
# Due to their length journal texts are usually stored in external Python files.
# The line below imports them. Remove this line if you do not use external journals.
from TINA_TestingJournals import *
# Variables that can be used in BookPages:
PageStart = '<pb>'
ImgStart = '<img src="'
TransImgStart = '<img opacity=0.7 src="'
ImgEnd = '" align=center link=%d blend=alpha>'
ImgEndNoLink = '" align=center blend=alpha>'
AlignCenter = '<p align=center>'
AlignLeft = '<p align=left>'
AlignRight = '<p align=right>'
# Retrieve local player name in case you want to fake a "personal" note
plyrName = PtGetLocalPlayer().getPlayerName()
###############################################################################
# AgeBooks Dictionary Section: #
# 1 = same names as the clickable book objects! #
# 2 = book cover and margin #
# 3 = main font #
# 4 = start book open or closed. 0 closed book, 1 open book #
# 5 = force owned setting. 0 off, 1 on #
# 6 = book GUI. 'BkBook' or 'bkNotebook' #
# 7 = width #
# 8 - height #
# #
# Notes: - The cover can have the same texture as the book object itself. #
# - The main font can be changed later in the BookPages definition. #
# If you don't need a main font (because you are changing it later), #
# you can set an empty string. #
# - force owned: If set to 1 the code checks if the original book has #
# been found. A player who does not own the age will not see the #
# linking panel. If you need this restriction set force owned to 1. #
# - the 'bkBahroRockBook' GUI should work as well but it may not be a #
# good idea to use it with this multi-page template. #
###############################################################################
AgeBooks = {'good_journal': ('<cover src="ValJournal_nosymbol.png"><margin right=32 left=32>', '<font size=12 face=Arial color=000000>', 0, 0, 'BkBook', 0.8, 1.0)}
###############################################################################################
# BookPages Dictionary Section: #
# 1 = Same names as link destinations! #
# 2 = The page layout: for linking books insert the name of your linking panel image here. #
# This can be a seperate texture in your age prp file on a hidden Blender object. #
# (or use PRP Explorer to add a plain texture to the prp without modeling an object) #
# Once you get the hang of this you can mix and match layouts into your pages. #
# #
# Notes: - AlignCenter is used to center text, for example to place below a linking panel. #
# - Use ImgEndNoLink to add images without a hotspot. #
###############################################################################################
BookPages = {'TINA_TestingJournal': ((DefTINA_TestingJournal))}
###############################################################################
# LinkDestinations Dictionary Section: #
# 1 = Same names as book pages! #
# 2 = age name #
# 3 = spawnpoint #
# 4 = spawnpoint title #
# 5 = linkingrule #
# #
# Notes: - Variables for journals are dummies and must be set to None. #
# - Spawnpoint title None is only allowed for LinkInPointDefault #
# (although it would be better to set it to 'Default') #
# CleftFissureDrop in this example will fail due to a missing title #
# (the correct title is 'FissureDrop') #
# - You can tie special actions to linking panels or other journal #
# images by defining only the age name. The other definitions must #
# be set to None (see 'CleftSpecial') #
###############################################################################
LinkDestinations = {'TINA_TestingJournal': (None, None, None, None)}
D'Lanor wrote:Wouldn't it be strange if the book looks differently in distant and close up view?
AgeBooks = {'good_journal': ('<cover src="ValJournal_nosymbol"><margin right=32 left=32>', ....
###########################################
# #
# Dynamic Book Template v3.0 by D'Lanor #
# #
###########################################
# For each occurance of *YourAge* you have to replace this with the actual name of your age.
from Plasma import *
from PlasmaTypes import *
from PlasmaKITypes import *
from PlasmaNetConstants import *
import xLinkingBookDefs
actClickableObject = ptAttribActivator(1, 'Act: Clickable Object')
ObjectMsg = ptAttribString(2, 'Object String')
### DO NOT CHANGE THESE 2 VARIABLES ###
ourBook = None
bkLinks = []
### CHANGE THE GLOBAL CONSTANTS BELOW TO FIT YOUR AGE ######################################
# #
# modPageDefs: Replace *YourAge*PageDefs with the name of the module that contains your #
# page definitions. Do not remove the quotes! #
# ageBooks: These are your clickable objects. They must be defined in *YourAge*PageDefs #
# in the AgeBooks Dictionary Section by the same name(s). #
# bookPages: Names in bookPages must be defined in the *YourAge*PageDefs file under #
# BookPages. An ageBook can have multiple bookPages as long as they are #
# enclosed together between the same square brackets. #
# Please keep the nesting structure [square brackets] intact! #
# #
# If there are multiple books in an age the code will find the right one automagically. #
# You can add as many books as you like. Just define them in the global variables ageBooks #
# and bookPages. The order is important here. The first book will be matched to the first #
# page list, the second book to the second page list etc. #
############################################################################################
modPageDefs = __import__('TINA_TestingPageDefs')
ageBooks = ['good_journal','barn_journal','barn_linkbook']
bookPages = [['TINA_TestingJournal'], ['BarnJournal'], ['SecretAge']]
class TINA_TestingBookGUI(ptModifier,):
def __init__(self):
ptModifier.__init__(self)
self.version = '3.0'
print ('__init__%s v.%s' % (self.__class__.__name__, self.version))
def OnNotify(self, state, id, events):
print ('%s: OnNotify called' % self.__class__.__name__)
if ((id == actClickableObject.id) and state):
print ('Someone clicked on object %s' % ObjectMsg.value)
if PtWasLocallyNotified(self.key):
print 'It was you'
for (a, b,) in zip(ageBooks, bookPages):
print ('Trying book %s with page(s) %s' % (a, b))
if (ObjectMsg.value == a):
print 'Match found! Start opening book...'
self.IOpenBook(a, b)
break
else:
print 'No match'
else:
for event in events:
if ((event[0] == PtEventType.kBook) and PtWasLocallyNotified(self.key)):
#print('BookNotify: event=%d, id=%d' % (event[1], event[2]))
if (event[1] == PtBookEventTypes.kNotifyImageLink):
print ('BookNotify: Linking panel id=%d, event=%d' % (event[2], event[1]))
ourBook.hide()
if (event[2] == 0):
print 'Warning: No link id, define proper link destination or use non-clickable image'
elif (event[2] >= xLinkingBookDefs.kFirstLinkPanelID):
for i in range(0, len(bkLinks)):
if (event[2] == bkLinks[i][0]):
try:
self.IlinkToAge(bkLinks[i][1], bkLinks[i][2], bkLinks[i][3], bkLinks[i][4], bkLinks[i][5])
except Exception, detail:
print ('ERROR: Unable to initialize link - %s' % detail)
break
elif (event[1] == PtBookEventTypes.kNotifyShow):
print ('BookNotify: Show book, event=%d' % event[1])
PtToggleAvatarClickability(0)
elif (event[1] == PtBookEventTypes.kNotifyHide):
print ('BookNotify: Hide book, event=%d' % event[1])
PtToggleAvatarClickability(1)
elif (event[1] == PtBookEventTypes.kNotifyNextPage):
print ('BookNotify: To next page %d, event=%d' % (ourBook.getCurrentPage(), event[1]))
elif (event[1] == PtBookEventTypes.kNotifyPreviousPage):
print ('BookNotify: To previous page %d, event=%d' % (ourBook.getCurrentPage(), event[1]))
elif (event[1] == PtBookEventTypes.kNotifyCheckUnchecked):
print ('BookNotify: Relto page toggle, event=%d' % event[1])
elif (event[1] == PtBookEventTypes.kNotifyClose):
print ('BookNotify: Close book, event=%d' % event[1])
def IOpenBook(self, ageBook, bkPages = None):
global ourBook
global bkLinks
print ('%s: IOpenBook: Page(s) requested %s' % (self.__class__.__name__, bkPages))
if (type(bkPages) == type(None)):
print 'ERROR: no pages defined'
return
if (not (ageBook in modPageDefs.AgeBooks)):
print ('ERROR: Definition %s does not exist in AgeBooks' % ageBook)
return
bkParams = modPageDefs.AgeBooks[ageBook]
(bkCover, bkFont, startOpen, forceOwned, bookGUI, width, height,) = bkParams
PageDef = (bkCover + bkFont)
if (not startOpen):
if (not self.IsThereACover(PageDef)):
print 'Warning: Missing cover, forcing book open'
startOpen = 1
PageCount = xLinkingBookDefs.kFirstLinkPanelID
bkLinks = []
for bkPage in bkPages:
if (not (bkPage in modPageDefs.LinkDestinations)):
print ('Warning: %s skipped, definition does not exist in LinkDestinations' % bkPage)
continue
pgParams = modPageDefs.LinkDestinations[bkPage]
(bkAge, spawnPoint, spTitle, linkRule,) = pgParams
alink = 1
if ((type(bkAge) != type(None)) and forceOwned):
print ('Ownership check for %s book' % bkAge)
vault = ptVault()
ainfo = ptAgeInfoStruct()
ainfo.setAgeFilename(bkAge)
alink = vault.getOwnedAgeLink(ainfo)
if alink:
print ('Showing %s, link destination %s' % (bkPage, bkAge))
if (type(bkAge) != type(None)):
t = (PageCount, bkPage, bkAge, spawnPoint, spTitle, linkRule)
bkLinks.append(t)
PageDef = ((PageDef + (modPageDefs.BookPages[bkPage] % PageCount)) + '<pb>')
else:
PageDef = ((PageDef + modPageDefs.BookPages[bkPage]) + '<pb>')
PageCount = (PageCount + 1)
else:
print ('No owner of age %s so we are not showing %s' % (bkAge, bkPage))
if (PageCount == xLinkingBookDefs.kFirstLinkPanelID):
print 'No pages created...'
return
else:
TotalCount = (PageCount - xLinkingBookDefs.kFirstLinkPanelID)
print ('%d item(s) created, linking page(s): %d' % (TotalCount, len(bkLinks)))
PageDef = PageDef[:-4]
ourBook = ptBook(PageDef, self.key)
ourBook.setSize(width, height)
ourBook.setGUI(bookGUI)
ourBook.show(startOpen)
def IsThereACover(self, bookHtml):
idx = bookHtml.find('<cover')
if (idx >= 0):
return 1
return 0
def IlinkToAge(self, bookPage, ageName, spawnPoint, spTitle, linkRule = PtLinkingRules.kBasicLink):
print ('%s: ILinkToAge: Link request from page %s to age %s' % (self.__class__.__name__, bookPage, ageName))
if ((type(ageName) == type(None)) or (len(ageName) == 0)):
print 'ERROR: Cannot link to age without name'
return
if ((type(spawnPoint) == type(None)) or (len(spawnPoint) == 0)):
print 'No spawnpoint defined, checking special actions...'
self.IDoSpecialAction(bookPage)
return
als = ptAgeLinkStruct()
ainfo = ptAgeInfoStruct()
ainfo.setAgeFilename(ageName)
ainfo.setAgeInstanceName(self.IConvertAgeInstanceName(ageName))
als.setAgeInfo(ainfo)
if ((type(spTitle) == type(None)) or (len(spTitle) == 0)):
if ((linkRule == PtLinkingRules.kOriginalBook) or PtIsSinglePlayerMode()):
#################################################################################
# Linkingrule kOriginalBook writes spawnpoint and title to the agelink node, #
# so we must make absolutely sure that a proper title is given! #
# In singleplayer mode all linkingrules behave like kOriginalBook, no matter #
# which linkingrule is set in the definition. #
#################################################################################
if (spawnPoint == 'LinkInPointDefault'):
spTitle = 'Default'
#################################################################################
# We did not define a spawnpoint title, but since the spawnpoint is the default #
# it is safe to continue and write it to the agelink node with default title. #
#################################################################################
else:
print 'Warning: Empty spawnpoint title not allowed, check your link destinations!'
return
else:
print 'Empty spawnpoint title allowed, continue linking'
spTitle = ''
als.setLinkingRules(linkRule)
spPoint = ptSpawnPointInfo(spTitle, spawnPoint)
als.setSpawnPoint(spPoint)
linkMgr = ptNetLinkingMgr()
linkMgr.linkToAge(als)
print ('Linking to age %s, spawnpoint %s with title %s, using linkingrule %d' % (ageName, spawnPoint, spTitle, linkRule))
def IConvertAgeInstanceName(self, ageName):
#########################################################################################################################
# Optional: You can add a friendly name to this list for the age you link to. This is the name that shows up in the KI. #
# Ahra Pahts and Relto are used here only as examples. #
# Some Cyan age names are converted to friendly names in the KI but we cannot expect the KI to do that for user ages. #
# Beware: Age instance names are written to the vault if the kOriginalBook rule is used. That will happen whether you #
# set a name here or not. And it would happen regardless of this function. #
# By default the age instance name is the same as the age name. #
# btw, if you plan to link to Cyan ages you should set the correct age instance name here. Correct? You figure it out! #
#########################################################################################################################
if (ageName == 'Personal'):
return 'Relto'
if (ageName == 'Pahts'):
return 'Ahra Pahts'
return ageName
def IDoSpecialAction(self, bookPage):
#######################################################
# Replace *YourPage* with the bookPage that contains #
# the clickable image triggering the special action. #
#######################################################
if (bookPage == '*YourPage*'):
print ('Special action found for %s' % bookPage)
# Do some special action here
else:
print 'No special actions found'
glue_cl = None
glue_inst = None
glue_params = None
glue_paramKeys = None
try:
x = glue_verbose
except NameError:
glue_verbose = 0
def glue_getClass():
global glue_cl
if (glue_cl == None):
try:
cl = eval(glue_name)
if issubclass(cl, ptModifier):
glue_cl = cl
elif glue_verbose:
print ('Class %s is not derived from modifier' % cl.__name__)
except NameError:
if glue_verbose:
try:
print ('Could not find class %s' % glue_name)
except NameError:
print 'Filename/classname not set!'
return glue_cl
def glue_getInst():
global glue_inst
if (type(glue_inst) == type(None)):
cl = glue_getClass()
if (cl != None):
glue_inst = cl()
return glue_inst
def glue_delInst():
global glue_inst
global glue_cl
global glue_paramKeys
global glue_params
if (type(glue_inst) != type(None)):
del glue_inst
glue_cl = None
glue_params = None
glue_paramKeys = None
def glue_getVersion():
inst = glue_getInst()
ver = inst.version
glue_delInst()
return ver
def glue_findAndAddAttribs(obj, glue_params):
if isinstance(obj, ptAttribute):
if glue_params.has_key(obj.id):
if glue_verbose:
print 'WARNING: Duplicate attribute ids!'
print ('%s has id %d which is already defined in %s' % (obj.name,
obj.id,
glue_params[obj.id].name))
else:
glue_params[obj.id] = obj
elif (type(obj) == type([])):
for o in obj:
glue_findAndAddAttribs(o, glue_params)
elif (type(obj) == type({})):
for o in obj.values():
glue_findAndAddAttribs(o, glue_params)
elif (type(obj) == type(())):
for o in obj:
glue_findAndAddAttribs(o, glue_params)
def glue_getParamDict():
global glue_paramKeys
global glue_params
if (type(glue_params) == type(None)):
glue_params = {}
gd = globals()
for obj in gd.values():
glue_findAndAddAttribs(obj, glue_params)
glue_paramKeys = glue_params.keys()
glue_paramKeys.sort()
glue_paramKeys.reverse()
return glue_params
def glue_getClassName():
cl = glue_getClass()
if (cl != None):
return cl.__name__
if glue_verbose:
print ('Class not found in %s.py' % glue_name)
return None
def glue_getBlockID():
inst = glue_getInst()
if (inst != None):
return inst.id
if glue_verbose:
print ('Instance could not be created in %s.py' % glue_name)
return None
def glue_getNumParams():
pd = glue_getParamDict()
if (pd != None):
return len(pd)
if glue_verbose:
print ('No attributes found in %s.py' % glue_name)
return 0
def glue_getParam(number):
pd = glue_getParamDict()
if (pd != None):
if (type(glue_paramKeys) == type([])):
if ((number >= 0) and (number < len(glue_paramKeys))):
return pd[glue_paramKeys[number]].getdef()
else:
print ('glue_getParam: Error! %d out of range of attribute list' % number)
else:
pl = pd.values()
if ((number >= 0) and (number < len(pl))):
return pl[number].getdef()
elif glue_verbose:
print ('glue_getParam: Error! %d out of range of attribute list' % number)
if glue_verbose:
print 'GLUE: Attribute list error'
return None
def glue_setParam(id, value):
pd = glue_getParamDict()
if (pd != None):
if pd.has_key(id):
try:
pd[id].__setvalue__(value)
except AttributeError:
if isinstance(pd[id], ptAttributeList):
try:
if (type(pd[id].value) != type([])):
pd[id].value = []
except AttributeError:
pd[id].value = []
pd[id].value.append(value)
else:
pd[id].value = value
elif glue_verbose:
print "setParam: can't find id=",
print id
else:
print 'setParma: Something terribly has gone wrong. Head for the cover.'
def glue_isNamedAttribute(id):
pd = glue_getParamDict()
if (pd != None):
try:
if isinstance(pd[id], ptAttribNamedActivator):
return 1
if isinstance(pd[id], ptAttribNamedResponder):
return 2
except KeyError:
if glue_verbose:
print ('Could not find id=%d attribute' % id)
return 0
def glue_isMultiModifier():
inst = glue_getInst()
if isinstance(inst, ptMultiModifier):
return 1
return 0
def glue_getVisInfo(number):
pd = glue_getParamDict()
if (pd != None):
if (type(glue_paramKeys) == type([])):
if ((number >= 0) and (number < len(glue_paramKeys))):
return pd[glue_paramKeys[number]].getVisInfo()
else:
print ('glue_getVisInfo: Error! %d out of range of attribute list' % number)
else:
pl = pd.values()
if ((number >= 0) and (number < len(pl))):
return pl[number].getVisInfo()
elif glue_verbose:
print ('glue_getVisInfo: Error! %d out of range of attribute list' % number)
if glue_verbose:
print 'GLUE: Attribute list error'
return None
# For each occurance of *YourAge* and *YourTexture* you have to replace this with
# the actual name of your age and your textures.
from Plasma import *
from PlasmaNetConstants import *
# Due to their length journal texts are usually stored in external Python files.
# The line below imports them. Remove this line if you do not use external journals.
from TINA_TestingJournals import *
# Variables that can be used in BookPages:
PageStart = '<pb>'
ImgStart = '<img src="'
TransImgStart = '<img opacity=0.7 src="'
ImgEnd = '" align=center link=%d blend=alpha>'
ImgEndNoLink = '" align=center blend=alpha>'
AlignCenter = '<p align=center>'
AlignLeft = '<p align=left>'
AlignRight = '<p align=right>'
# Retrieve local player name in case you want to fake a "personal" note
plyrName = PtGetLocalPlayer().getPlayerName()
###############################################################################
# AgeBooks Dictionary Section: #
# 1 = same names as the clickable book objects! #
# 2 = book cover and margin #
# 3 = main font #
# 4 = start book open or closed. 0 closed book, 1 open book #
# 5 = force owned setting. 0 off, 1 on #
# 6 = book GUI. 'BkBook' or 'bkNotebook' #
# 7 = width #
# 8 - height #
# #
# Notes: - The cover can have the same texture as the book object itself. #
# - The main font can be changed later in the BookPages definition. #
# If you don't need a main font (because you are changing it later), #
# you can set an empty string. #
# - force owned: If set to 1 the code checks if the original book has #
# been found. A player who does not own the age will not see the #
# linking panel. If you need this restriction set force owned to 1. #
# - the 'bkBahroRockBook' GUI should work as well but it may not be a #
# good idea to use it with this multi-page template. #
###############################################################################
AgeBooks = {'good_journal': ('<cover src="ValJournal_nosymbol"><margin right=32 left=32>', '<font size=12 face=Arial color=000000>', 0, 0, 'BkBook', 0.8, 1.0),
'barn_journal': ('<cover src="ValJournal"><margin right=32 left=32>', '<font size=16 face=Arial color=000000>', 0, 0, 'BkBook', 0.9, 1.0),
'barn_linkbook': ('<cover src="ValJournalGreen"><margin right=32 left=32>', '<font size=16 face=Arial color=000000>', 0, 0, 'BkBook', 0.9, 1.0)}
###############################################################################################
# BookPages Dictionary Section: #
# 1 = Same names as link destinations! #
# 2 = The page layout: for linking books insert the name of your linking panel image here. #
# This can be a seperate texture in your age prp file on a hidden Blender object. #
# (or use PRP Explorer to add a plain texture to the prp without modeling an object) #
# Once you get the hang of this you can mix and match layouts into your pages. #
# #
# Notes: - AlignCenter is used to center text, for example to place below a linking panel. #
# - Use ImgEndNoLink to add images without a hotspot. #
###############################################################################################
BookPages = {'TINA_TestingJournal': ((DefTINA_TestingJournal)), 'BarnJournal': ((DefBarnJournal)),
'SecretAge': (PageStart + ImgStart + 'Star_LinkPanel' + ImgEnd)}
###############################################################################
# LinkDestinations Dictionary Section: #
# 1 = Same names as book pages! #
# 2 = age name #
# 3 = spawnpoint #
# 4 = spawnpoint title #
# 5 = linkingrule #
# #
# Notes: - Variables for journals are dummies and must be set to None. #
# - Spawnpoint title None is only allowed for LinkInPointDefault #
# (although it would be better to set it to 'Default') #
# CleftFissureDrop in this example will fail due to a missing title #
# (the correct title is 'FissureDrop') #
# - You can tie special actions to linking panels or other journal #
# images by defining only the age name. The other definitions must #
# be set to None (see 'CleftSpecial') #
###############################################################################
LinkDestinations = {'TINA_TestingJournal': (None, None, None, None), 'BarnJournal': (None, None, None, None), 'SecretAge': ('TINA_Testing', 'SecretAge_spawn', 'SecretAge', PtLinkingRules.kOriginalBook)}
AgeBooks = {'good_journal': ('<cover src="ValJournal_nosymbol"><margin right=32 left=32>', '<font size=12 face=Arial color=000000>', 0, 0, 'BkBook', 0.8, 1.0),
'barn_journal': ('<cover src="ValJournal"><margin right=32 left=32>', '<font size=16 face=Arial color=000000>', 0, 0, 'BkBook', 0.9, 1.0),
'barn_linkbook': ('<cover src="ValJournalGreen"><margin right=32 left=32>', '<font size=16 face=Arial color=000000>', 0, 0, 'BkBook', 0.9, 1.0)}
Users browsing this forum: No registered users and 0 guests