Developer Store
Support
Member Forums

Screenshots
FAQ
Documentation
License
Known Issues
Downloads

MMOWorkshop.com Store Opened!
Torque MMO Kit - Open Sourced!
Torque MMO Kit - 1.5.2 Port Alpha Test
Torque MMO Kit - OSX Status

GarageGames.com irc.prairiegames.com
#mmoworkshop

PyTorque
TGB Web Browser


chayfo

hallsofvalhalla - After a long epiphany
Leathel - FoHO pre-Alpha 2.42
OldRod - More Musings on the MMO Industry
xapken - nice
J.C. Smith - 0.0.4.1 Build Notes
Wolf Dreamer - Pointless blog of pointless things
AthlonJedi2 - Server Nuked !!!!!
gamer_goof - New character model GIRL1 available only $4
... MORE BLOGS!

My other project
A Message to all the new people.
MyGame
changing the primary class
See Ya Classes, Hello Skills!
XP Based Skills
fxFoliageReplicator zone loading...
Is it just me, or is it slow in ...
Places where NPC quest-givers ha...
TalentRaspel Grid

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