In Memoriam: Tai'lahr

OpenUru.org, along with the rest of the Mystonline community, is mourning the loss of Tai'lahr on October 16th, 2019.

Rest in Peace, friend.

Python Files And Your Age: Please Read!

From OpenUru
Jump to navigation Jump to search

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,):
    __module__ = __name__
    __module__ = __name__

    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:

http://assets.openuru.org/wiki/andy/MaxTutPics1/Globalpyth1.jpg

Once you have decided where to put your python file, you need to add it. Here is what the roll out will look like:

http://assets.openuru.org/wiki/andy/MaxTutPics1/Globalpyth2.jpg

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 Plugin Tutorials

Copyright (C) 2011 Andy Legate.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU Free Documentation License".