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

