Python Files And Your Age: Please Read!
If you are planing on using Python with your Age, anything from making Linking Books or Journals, to complex puzzles like Neolbah's Keypad, there is something you MUST do for your Age, or else your python is not going to work correctly.
You MUST set up a "Dummy" python file for your Age. This file will have the same name as your .age file. For example, Neolbah's .age file is Neolbah.age, and the "Dummy" python file for it is called Neolbah.py.
This "Dummy" python file must be in your python .pak file.
You must also assign it to an object that is in your Age, so you will have to make copies of both the complied and uncomplied (.py and .pyc) versions of the file and place them in your python folders in your Max export folder.
Making a "Dummy" python file is easy, you can copy the one I have for Eder Tomahn below and just edit it (I'll tell you where):
from Plasma import *
from PlasmaTypes import *
class Tomahn(ptResponder,):
def __init__(self):
ptResponder.__init__(self)
self.id = 1022605
self.version = 1
def OnFirstUpdate(self):
pass
def OnServerInitComplete(self):
pass
def OnNotify(self, state, id, events):
pass
def OnSDLNotify(self, VARname, SDLname, playerID, tag):
pass
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
At the top of the file, where it says:
class Tomahn(ptResponder,):
__module__ = __name__
__module__ = __name__
def __init__(self):
ptResponder.__init__(self)
self.id = 1022605
self.version = 1
You need to change where it says "class Tomahn(ptResponder,):" to have YOUR Age's name instead. This MUST be the SAME name as your .age file name. So if my Age is named Candy Island, and the .age file is Candy_Island.age, then I would change the above script to read:
class Candy_Island(ptResponder,):
You will also need to change the "self.id" number. This is a unique number that is like a serial number. Many times I'll just use my Age's sequence number, and add 3 more digits. So if my Age's sequence number is 5883, I would make the self.id number 5883001.
Once you have made, saved and added this file to your python .pak file for your Age and have placed copies of it in your Max Export folder with the other python files, you now need to add it to your Age.
Open up Max, and you can either just select an object you already have in your Age, or you can make a "Dummy" point like I did:
Once you have decided where to put your python file, you need to add it. Here is what the roll out will look like:
Make sure you put a check mark where it says "Make Global".
That's all you have to do. If you DO NOT do this, then you will have problems getting your python to work in your Age, like you will be able to click on a linking book or journal, but NOTHING will happen.
Return To: 3DS Max and Plasma Plugin tutorials.