Developer Store
Support
Member Forums

Screenshots
FAQ
Documentation
License
Known Issues
Downloads

MMOWorkshop BACK!

PyTorque
TGB Web Browser


DarkBaneStudios

hallsofvalhalla - Been A while
xapken - Wizards and Champions
J.C. Smith - The Repopulation - 0.5.2 Build Notes
EmpireGames - Elementals in Rise of Heroes
Empire Games - WarPath.
jaidurn - Warcall 0.0.1.0 build notes
medafor - Final detailing of models
Thamior - Presence system GONE! [May 25th 2009)]
... MORE BLOGS!

Building a MMO
Wow I had no idea....
Quest Remnants of Chaos
Checking to see if anyone is sti...
Well here I am again :)
T3D and MMOKit
afx 2.0
Terrain specularity [video]
Torque T3D MMO Kit
[3dFoin] Dragon Bug

This patch allows item specific stats i.e. alternativ stats to what the ItemProto has.

In item.py define a persistent class for the stats similar to ItemStat:

class ItemItemStat(Persistent):
    item = ForeignKey('Item')
    statname = StringCol()
    value = FloatCol()

These are pulled in the __init__ function of Item:

    uniqueStats = MultipleJoin("ItemItemStat")

To remove the stats when an item is removed we have to change the functions in Item to:

    def expire(self):
        for v in self.variants:
            v.expire()
        for v in self.uniqueStats:
            v.expire()
        Persistent.expire(self)
    
    
    def destroySelf(self):
        for v in self.variants:
            v.destroySelf()
        for v in self.uniqueStats:
            v.destroySelf()
        Persistent.destroySelf(self)

The ItemInstance holds the stats from ItemProto. For the specific stats we need a way to override.

In __init__ we add the dict and a flag whether the item has unique stats:

        self.hasUniqueStats = False
        self.itemUniqueStats = {}

and in loadFromItem just before the call to refreshFromProto we fill the dict from the Item and ItemItemStat:

        if len(item.uniqueStats):
            self.stats = []
            for stat in item.uniqueStats:
                self.stats.append((stat.statname,stat.value))
                self.itemUniqueStats[stat.statname] = stat
            self.hasUniqueStats = True

This is to store the stats back to the Item:

        # copy unique stats to item
        # self.itemUniqueStats is a dict holding all ItemItemStat objects, key is the statname
        try:
            if self.hasUniqueStats:
                updatedStats = []
                for statname,value in self.stats:
                    if self.itemUniqueStats.has_key(statname):
                        self.itemUniqueStats[statname].value = value
                    else:
                        self.itemUniqueStats[statname] = ItemItemStat(item = self.item, statname = statname, value = value)
                    updatedStats.append(statname)
                # delete all we haven't used in above loop
                for i in self.itemUniqueStats:
                    if not i in updatedStats:
                        self.itemUniqueStats[i].destroySelf()
        except:
            traceback.print_stack()

and finally in clone() we add a line for the stats:

        if self.hasUniqueStats:
            nitem.stats         = copy(self.stats)

The stacking code does not handle this out of the box so better make such items non-stackable.

The ItemItemStat class has to be added to Genesis.py and worldupdate.py to make this addition really persistent. Similar to the ItemVariant we have to add a copier to worldupdate.py:

class ItemStatCopier:
    def __init__(self,cur,id):
        self.dbAttr = {}
        t = mixedToUnder("ItemItemStat")
        cur.execute("SELECT * from %s WHERE id = %i;"%(t,id))
        for name,value in zip(WSCHEMA["ItemItemStat"],cur.fetchall()[0]):
            self.dbAttr[str(name)]=value
            
    def install(self,item):
        FilterColumns(ItemItemStat,self.dbAttr)
        self.dbAttr["itemID"]=item.id
        ItemItemStat(**self.dbAttr)

and add it to the ItemCopier:

        stats = self.stats = []

        try:
            cur.execute("select id from item_item_stat where item_id = %i;"%id)
            for r in cur.fetchall():
                f = ItemStatCopier(cur,r[0])
                stats.append(f)
        except:
            traceback.print_exc()
            pass

and at the end of the install member:

        for stat in self.stats:
            stat.install(item)

The ItemItemStat has to be added to TABLES and import of course.

Back to the Cookbook