コード例 #1
0
ファイル: loot.py プロジェクト: keaysma/solinia_depreciated
    def initRandomLoot():
        #to do, better
        randomProtos = Loot.randomItemProtos = []
        spellScrolls = Loot.spellScrolls = {}
        protos = {}

        con = ItemProto._connection.getConnection()

        for id, spell_proto_id in con.execute(
                "SELECT id,spell_proto_id FROM item_proto WHERE spell_proto_id OR (rating = 1 AND NOT flags & ?);",
            (RPG_ITEM_SOULBOUND, )):
            ip = protos.setdefault(id, ItemProto.get(id))

            if spell_proto_id:
                for classname, level in con.execute(
                        "SELECT classname,level FROM spell_class WHERE spell_proto_id = ?;",
                    (spell_proto_id, )):
                    spellScrolls.setdefault(classname,
                                            {}).setdefault(level,
                                                           []).append(ip)
            else:
                randomProtos.append(ip)

        # 'unique' variant loot
        uloot = {}
        for itemid, freq in con.execute(
                "SELECT DISTINCT item_proto_id,freq FROM loot_item WHERE freq >= ? AND loot_proto_id IN (SELECT DISTINCT loot_proto_id FROM spawn WHERE NOT flags & ?);",
            (RPG_FREQ_COMMON, RPG_SPAWN_UNIQUE)):
            if con.execute(
                    "SELECT id FROM item_slot WHERE item_proto_id = ? LIMIT 1;",
                (itemid, )).fetchone():
                # equippable
                if freq > uloot.get(itemid, 0):
                    uloot[itemid] = freq

        # level -> list of item protos
        uniqueProtos = Loot.uniqueItemProtos = {}
        for itemid, freq in uloot.iteritems():
            ip = protos.setdefault(itemid, ItemProto.get(itemid))

            level = ip.level
            for cl in ip.classes:
                if cl.level > level:
                    level = cl.level
            if level == 1:
                continue

            uniqueProtos.setdefault(level, []).append((freq, ip))
コード例 #2
0
def SiftItemProtos():
    from mud.world.item import ItemProto
    
    sounds = ("sndAttack1","sndAttack2","sndAttack3","sndAttack4","sndAttack5",
              "sndAttack6","sndAttack7","sndAttack8",
              
              "sndHit1","sndHit2","sndHit3","sndHit4","sndHit5","sndHit6",
              "sndHit7","sndHit8","sndUse","sndEquip")
    
    for item in ItemProto.select():
        if not item.bitmap:
            print "WARNING: %s has no bitmap"%item.name
        else:
            texture = "./$/data/ui/items/%s/0_0_0"%item.bitmap
            AddTexture(texture)
        
        if item.model:
            AddDTS("./$/data/shapes/equipment/%s"%item.model)
        
        if item.material and "head/" not in item.material.lower() and \
            "weapons/" not in item.material.lower():
            AddTexture("./$/data/shapes/character/textures/%s"%item.material)
        elif item.material:
            AddTexture("./$/data/shapes/equipment/%s"%item.material)
        
        if item.sndProfile:
            for s in sounds:
                snd = getattr(item.sndProfile,s)
                if snd:
                    AddSound("./$/data/sound/%s"%snd)
コード例 #3
0
def SiftItemProtos():
    from mud.world.item import ItemProto

    sounds = ("sndAttack1", "sndAttack2", "sndAttack3", "sndAttack4",
              "sndAttack5", "sndAttack6", "sndAttack7", "sndAttack8",
              "sndHit1", "sndHit2", "sndHit3", "sndHit4", "sndHit5", "sndHit6",
              "sndHit7", "sndHit8", "sndUse", "sndEquip")

    for item in ItemProto.select():
        if not item.bitmap:
            print "WARNING: %s has no bitmap" % item.name
        else:
            texture = "./$/data/ui/items/%s/0_0_0" % item.bitmap
            AddTexture(texture)

        if item.model:
            AddDTS("./$/data/shapes/equipment/%s" % item.model)

        if item.material and "head/" not in item.material.lower() and \
            "weapons/" not in item.material.lower():
            AddTexture("./$/data/shapes/character/textures/%s" % item.material)
        elif item.material:
            AddTexture("./$/data/shapes/equipment/%s" % item.material)

        if item.sndProfile:
            for s in sounds:
                snd = getattr(item.sndProfile, s)
                if snd:
                    AddSound("./$/data/sound/%s" % snd)
コード例 #4
0
 def giveItem(self,itemname,fullStack=False,caseInsensitive=False):
     try:
         if caseInsensitive:
             con = ItemProto._connection.getConnection()
             ip = ItemProto.get(con.execute("SELECT id FROM item_proto WHERE lower(name)=lower(\"%s\") LIMIT 1;"%itemname).fetchone()[0])
         else:
             ip = ItemProto.byName(itemname)
     except:
         return None
     
     item = ip.createInstance()
     if fullStack:
         item.stackCount = ip.stackMax
     
     if not self.curChar.giveItemInstance(item):
         item.destroySelf()
         return None
     
     return item
コード例 #5
0
    def giveItem(self, itemname, fullStack=False, caseInsensitive=False):
        try:
            if caseInsensitive:
                con = ItemProto._connection.getConnection()
                ip = ItemProto.get(
                    con.execute(
                        "SELECT id FROM item_proto WHERE lower(name)=lower(\"%s\") LIMIT 1;"
                        % itemname).fetchone()[0])
            else:
                ip = ItemProto.byName(itemname)
        except:
            return None

        item = ip.createInstance()
        if fullStack:
            item.stackCount = ip.stackMax

        if not self.curChar.giveItemInstance(item):
            item.destroySelf()
            return None

        return item
コード例 #6
0
 def initRandomLoot():
     #to do, better
     randomProtos = Loot.randomItemProtos = []
     spellScrolls = Loot.spellScrolls = {}
     protos = {}
     
     con = ItemProto._connection.getConnection()
     
     for id,spell_proto_id in con.execute("SELECT id,spell_proto_id FROM item_proto WHERE spell_proto_id OR (rating = 1 AND NOT flags & ?);",(RPG_ITEM_SOULBOUND,)):
         ip = protos.setdefault(id,ItemProto.get(id))
         
         if spell_proto_id:
             for classname,level in con.execute("SELECT classname,level FROM spell_class WHERE spell_proto_id = ?;",(spell_proto_id,)):
                 spellScrolls.setdefault(classname,{}).setdefault(level,[]).append(ip)
         else:
             randomProtos.append(ip)
     
     # 'unique' variant loot
     uloot = {}
     for itemid,freq in con.execute("SELECT DISTINCT item_proto_id,freq FROM loot_item WHERE freq >= ? AND loot_proto_id IN (SELECT DISTINCT loot_proto_id FROM spawn WHERE NOT flags & ?);",(RPG_FREQ_COMMON,RPG_SPAWN_UNIQUE)):
         if con.execute("SELECT id FROM item_slot WHERE item_proto_id = ? LIMIT 1;",(itemid,)).fetchone():
             # equippable
             if freq > uloot.get(itemid,0):
                 uloot[itemid] = freq
     
     # level -> list of item protos
     uniqueProtos = Loot.uniqueItemProtos = {}
     for itemid,freq in uloot.iteritems():
         ip = protos.setdefault(itemid,ItemProto.get(itemid))
         
         level = ip.level
         for cl in ip.classes:
             if cl.level > level:
                 level = cl.level
         if level == 1:
             continue
         
         uniqueProtos.setdefault(level,[]).append((freq,ip))
コード例 #7
0
 def install(self,owner,bank=False):
     try:
         ip = ItemProto.byName(self.protoName)
     except:
         print "Item: %s no longer exists"%self.protoName
         return None
     
     FilterColumns(Item,self.dbAttr)
     self.dbAttr["itemProtoID"] = ip.id
     if owner:
         # Bank items need a player assigned and no
         #  character. Otherwise, item would show up
         #  in character inventory list which could
         #  screw up things.
         if bank:
             self.dbAttr["characterID"] = None
             self.dbAttr["playerID"] = owner.id
         # Inventory items will require the player set
         #  to None or they will show up in bank list
         #  which could screw up things. They might
         #  get deleted!
         else:
             self.dbAttr["characterID"] = owner.id
             self.dbAttr["playerID"] = None
     # No owner means this is a vault item.
     # Owner is set on CharacterVaultItem, not here.
     # Otherwise, this item would appear in characters
     #  item list, which could screw up things.
     else:
         self.dbAttr["characterID"] = None
         self.dbAttr["playerID"] = None
     if not self.dbAttr["stackCount"]:
         if ip.stackMax > 1:
             self.dbAttr["stackCount"] = ip.stackDefault
         else:
             self.dbAttr["stackCount"] = 1
     item = Item(**self.dbAttr)
     
     for iv in self.variants:
         iv.install(item)
     
     for cc in self.content:
         cc.install(item)
     
     return item
コード例 #8
0
    def install(self, owner, bank=False):
        try:
            ip = ItemProto.byName(self.protoName)
        except:
            print "Item: %s no longer exists" % self.protoName
            return None

        FilterColumns(Item, self.dbAttr)
        self.dbAttr["itemProtoID"] = ip.id
        if owner:
            # Bank items need a player assigned and no
            #  character. Otherwise, item would show up
            #  in character inventory list which could
            #  screw up things.
            if bank:
                self.dbAttr["characterID"] = None
                self.dbAttr["playerID"] = owner.id
            # Inventory items will require the player set
            #  to None or they will show up in bank list
            #  which could screw up things. They might
            #  get deleted!
            else:
                self.dbAttr["characterID"] = owner.id
                self.dbAttr["playerID"] = None
        # No owner means this is a vault item.
        # Owner is set on CharacterVaultItem, not here.
        # Otherwise, this item would appear in characters
        #  item list, which could screw up things.
        else:
            self.dbAttr["characterID"] = None
            self.dbAttr["playerID"] = None
        if not self.dbAttr["stackCount"]:
            if ip.stackMax > 1:
                self.dbAttr["stackCount"] = ip.stackDefault
            else:
                self.dbAttr["stackCount"] = 1
        item = Item(**self.dbAttr)

        for iv in self.variants:
            iv.install(item)

        for cc in self.content:
            cc.install(item)

        return item
コード例 #9
0
ファイル: loot.py プロジェクト: keaysma/solinia_depreciated
    def generateCorpseLoot(self):

        loot = self.items

        if self.corpseLootGenerated:
            return (self.tin or len(loot))

        spawn = self.mob.spawn
        proto = self.lootProto
        self.corpseLootGenerated = True

        if proto:
            #$$$, to do, curve these
            if proto.tin:
                self.tin = randint(0, proto.tin)
    #Start code modified and expanded by BellyFish
            for lootitem in proto.lootItems:
                if not len(lootitem.itemProto.slots):
                    freq = lootitem.freq
                    r = 0
                    if freq > 1:
                        r = randint(0, freq - 1)
                    if not r:
                        iproto = lootitem.itemProto
                        # check if the item has a start and end day
                        if (iproto.startDayRL != "" or iproto.endDayRL != ""):
                            startDayRL = date(*strptime(
                                iproto.startDayRL + "-" +
                                strftime('%Y'), "%m-%d-%Y")[0:3])
                            endDayRL = date(*strptime(
                                iproto.endDayRL + "-" +
                                strftime('%Y'), "%m-%d-%Y")[0:3])
                            todayRL = date.today()
                            #check if spawn period crosses a yearly boundary
                            if endDayRL < startDayRL:
                                #crosses yearly boundary, so check if the day is outside the allowed date range
                                if endDayRL < todayRL < startDayRL:
                                    continue  #day is outside the allowed date range, so skip it
                            #no boundaries are crossed, so check if the day is ouside the allowed date range
                            elif not (startDayRL <= todayRL <= endDayRL):
                                continue  #day is outside the allowed date range, so skip it

                        #If we get here, the item can be added to the loot table.
    #End code modified and expanded by BellyFish
    #Create an instance of the item
                        item = iproto.createInstance()

                        #possibly generate a variant
                        GenVariantItem(item, self.mob.plevel)

                        item.slot = -1
                        loot.append(item)

                    if len(loot) == 16:
                        break

        # Check if this particular spawn drops random loot or if the loot
        #  table already is maxed out.
        if len(loot) >= 16 or spawn.flags & RPG_SPAWN_NORANDOMLOOT:
            # No random loot or loot table full,
            #  so finish the corpse loot generation.
            return self.finishCorpseLootGeneration()

    #Start code added by BellyFish
    # Zone dependent Seasonal drops
        if ZONE_SEASONALITEMS.has_key(self.mob.zone.zone.name):
            # check if mob can have a Seasonal drop, a 1 in 4 chance
            # as the ZONE_SEASONALITEMS list increases for the same time period the chance for a
            # specific drop decreases.
            if not randint(0, 3):
                tempSeasonalItemlist = []
                zoneSeasonalItemList = ZONE_SEASONALITEMS[
                    self.mob.zone.zone.name]
                if len(zoneSeasonalItemList) > 0:
                    #sort through the zoneSeasonalItemList list
                    for eachSeasonalItem in zoneSeasonalItemList:
                        #get the items prototype so we can reference the items info
                        try:
                            # If an item is not found, an SQLObjectNotFound exception is raised.
                            testItem = ItemProto.byName(eachSeasonalItem)
                        # So continue to the next item.
                        except SQLObjectNotFound:
                            continue
                        # check if the item has a start and end day
                        if (testItem.startDayRL != ""
                                or testItem.endDayRL != ""):
                            startDayRL = date(*strptime(
                                testItem.startDayRL + "-" +
                                strftime('%Y'), "%m-%d-%Y")[0:3])
                            endDayRL = date(*strptime(
                                testItem.endDayRL + "-" +
                                strftime('%Y'), "%m-%d-%Y")[0:3])
                            todayRL = date.today()
                            #check if spawn period crosses a yearly boundary
                            if endDayRL < startDayRL:
                                #crosses yearly boundary, so check if the day is outside the allowed date range
                                if endDay < todayRL < startDayRL:
                                    continue  #day is outside the allowed date range, so skip it
                            #no boundaries are crossed, so check if the day is ouside the allowed date range
                            elif not (startDayRL <= todayRL <= endDayRL):
                                continue  #day is outside the allowed date range, so skip it
                        #add the item to a tempSeasonalItemlist and repeat the for loop
                        tempSeasonalItemlist.append(testItem)

                    #Does the tempSeasonalItemlist contain data?
                    if len(tempSeasonalItemlist) > 0:
                        #pick a random item from the list
                        seasonalItem = tempSeasonalItemlist[randint(
                            0,
                            len(tempSeasonalItemlist) - 1)]
                        #create an instance of the item
                        itemInstance = seasonalItem.createInstance()
                        #make sure the item does not fit in a slot, only in inventory
                        itemInstance.slot = -1
                        #add the item to the loot list
                        loot.append(itemInstance)

    #End code added by BellyFish

    # If there is still room in the loot table, check
    #  if this mob carries additional random goodies.
        if len(loot) < 16:
            # Higher level mob possibly carries more random stuff.
            num = randint(0, int(spawn.plevel / 10) + 1)
            for x in xrange(0, num):
                # For each single item 25% chance to have or not to have.
                if randint(0, 3):
                    continue

                # Get one of the random item protos.
                iproto = Loot.randomItemProtos[randint(
                    0,
                    len(Loot.randomItemProtos) - 1)]
                item = iproto.createInstance()
                # Eventually create a variant of this item.
                GenVariantItem(item, self.mob.plevel)

                # Finally add random item to loot table.
                item.slot = -1
                loot.append(item)
                if len(loot) == 16:
                    break

        # If there's still room in the loot table, check
        #  if this mob carries a zone potion.
        if len(loot) < 16:
            # The higher level the mob, the higher the chance
            #  to carry a zone potion.
            chance = 35 - spawn.plevel / 3
            if not randint(0, chance):
                # Success, try to get an appropriate zone potion.
                try:
                    zpotion = ZONE_POTIONS[self.mob.zone.zone.name]
                    zpotion = ItemProto.byName(zpotion)
                    item = zpotion.createInstance()
                    item.slot = -1
                    loot.append(item)
                except:
                    pass

        # If there's still room in the loot table, check
        #  if this mob carries some Moon Powder.
        if len(loot) < 16:
            # The higher level the mob, the higher the chance
            #  to carry Moon Powder.
            chance = 35 - spawn.plevel / 4
            if not randint(0, chance):
                # Success, try to add one Moon Powder to
                #  this mobs loot table.
                try:
                    p = ItemProto.byName("Moon Powder")
                    item = p.createInstance()
                    item.slot = -1
                    loot.append(item)
                except:
                    traceback.print_exc()

        # If there's still room in the loot table, check
        #  whether this mob carries a stat potion.
        num = 1
        # Unique mobs may carry more than one potion.
        if self.mob.uniqueVariant:
            num = 2
        for x in xrange(0, num):
            if len(loot) < 16:
                # The higher level the mob, the higher the chance
                #  to carry a stat potion.
                chance = (110 - spawn.plevel) / 2
                if not randint(0, chance):
                    try:
                        index = randint(0, len(STAT_POTIONS) - 1)
                        stat = STAT_POTIONS[index]
                        potion = "Potion of %s" % stat
                        # Mobs above level 25 may even carry an Elixir
                        #  instead of a normal stat potion.
                        if spawn.plevel >= 25:
                            chance = (110 - spawn.plevel) / 3
                            if not randint(0, chance):
                                potion = "Elixir of %s" % stat

                        potion = ItemProto.byName(potion)
                        item = potion.createInstance()
                        item.slot = -1
                        loot.append(item)
                    except:
                        traceback.print_exc()

        num = 2 if self.mob.uniqueVariant else 1
        for x in xrange(0, num):
            if len(loot) < 16:
                if not randint(0, 4):  #got one
                    scrolls = set()
                    if not randint(0, 2):
                        wclass = WILDTOMES[randint(0, len(WILDTOMES) - 1)]
                        wlevel = spawn.plevel
                        classes = ((spawn.pclassInternal, spawn.plevel),
                                   (spawn.sclassInternal, spawn.slevel),
                                   (spawn.tclassInternal,
                                    spawn.tlevel), (wclass, wlevel))
                    else:
                        classes = ((spawn.pclassInternal, spawn.plevel),
                                   (spawn.sclassInternal, spawn.slevel),
                                   (spawn.tclassInternal, spawn.tlevel))

                    for cl, level in classes:
                        spellScrolls = Loot.spellScrolls.get(cl)
                        if spellScrolls:
                            for x in xrange(max(1, level - 5), level + 11):
                                try:
                                    scrolls.update(spellScrolls[x])
                                except KeyError:
                                    continue

                    scroll = None
                    if len(scrolls) == 1:
                        scroll = scrolls.pop()
                    elif len(scrolls) > 1:
                        scroll = list(scrolls)[randint(0, len(scrolls) - 1)]

                    if scroll:
                        v = (0, 30, 55, 75, 85, 90, 94, 97, 101)
                        x = randint(0, 100)
                        for z in xrange(0, 9):
                            if x < v[z]:
                                break
                        x = z + 1

                        if self.mob.uniqueVariant:
                            x += 5
                            if x > 10:
                                x = 10

                        item = getTomeAtLevelForScroll(scroll, x)
                        item.slot = -1
                        item.itemInfo.reset()

                        loot.append(item)

        #books of learning
        num = 2 if self.mob.uniqueVariant else 1
        for x in xrange(0, num):
            if len(loot) < 16:
                chance = (110 - spawn.plevel) / 2
                if not randint(0, chance):
                    try:
                        iname = "Scroll of Learning"
                        if spawn.plevel >= 60:
                            chance = (110 - spawn.plevel) / 3
                            if not randint(0, chance):
                                iname = "Book of Learning"

                        book = ItemProto.byName(iname)
                        item = book.createInstance()
                        item.slot = -1
                        loot.append(item)

                    except:
                        traceback.print_exc()

        # Unique variant mobs may carry even more additional
        #  random items.
        if len(loot) < 16 and self.mob.uniqueVariant:
            x = max(1, spawn.plevel - 20)

            # Build a list of possible random items
            #  to add to the loot table.
            items = {}
            uniqueProtos = Loot.uniqueItemProtos
            for level in xrange(x, spawn.plevel + 1):
                try:
                    for freq, ip in uniqueProtos[level]:
                        items.setdefault(freq, []).append(ip)
                except KeyError:
                    continue

            # If there are random items available...
            if len(items):
                # Try to add maximally 3.
                for x in xrange(3):
                    ip = None
                    # 33% Chance to get an additional item per iteration.
                    if not randint(0, 2):
                        # Start iteration over possible items at lowest
                        #  drop frequency.
                        for freq in sorted(items.iterkeys(), reverse=True):
                            if not randint(0, freq):
                                if len(items[freq]) == 1:
                                    ip = items[freq][0]
                                    break
                                else:
                                    ip = items[freq][randint(
                                        0,
                                        len(items[freq]) - 1)]
                                    break
                        # If we got an item, add it to the loot table.
                        if ip:
                            item = ip.createInstance()
                            item.slot = -1
                            loot.append(item)

        # zone dependend enchanting-item drop, last item per list is more rare than the rest
        if len(loot) < 16:
            # check if we got one; ok, this is actually 1 in RPG_FREQ_RARE+1 but that's good enough
            if not randint(0, RPG_FREQ_RARE):
                try:
                    zoneEnchItemList = ZONE_ENCHANTINGITEMS[
                        self.mob.zone.zone.name]
                    enchQuality = 0

                    # check if this is even an uber enchantment type (chance total: 1 in 561)
                    # this seems like an extremely low drop chance, but considering it gets applied to every single loot collection...
                    # because the special enchantments are this rare and because of their power, they're always exquisite
                    if not randint(0, RPG_FREQ_IMPOSSIBLE):
                        # Get last item of list (uber enchantment).
                        enchName = zoneEnchItemList[-1]
                        enchQuality = len(ENCHANT_QualityPrefix) - 1
                    else:
                        # Otherwise, get a random normal type.
                        enchName = zoneEnchItemList[randint(
                            0,
                            len(zoneEnchItemList) - 2)]
                        # Random quality for item (lower quality items can be combined
                        #  for higher quality), but don't allow index 0 (raw drop).
                        qualityCursor = randint(1, 100)
                        for qualityTester in xrange(
                                len(ENCHANT_QualityPrefix)):
                            if qualityCursor <= ENCHANT_QualityDropDistribution[
                                    qualityTester]:
                                break
                            enchQuality += 1

                    enchItem = ItemProto.byName(enchName)
                    item = enchItem.createInstance()
                    # Hack, spellEnhanceLevel is used for quality of this item type
                    #  (less attribs), values < 10 are used to identify tomes,
                    #  so use values 10 - 17
                    item.spellEnhanceLevel = enchQuality + 10
                    item.name = ENCHANT_QualityPrefix[enchQuality] + item.name
                    item.slot = -1
                    loot.append(item)

                except:
                    pass

        #Essence of the Void
        if len(loot) < 16:
            if not randint(0, RPG_FREQ_IMPOSSIBLE * 3):
                try:
                    p = ItemProto.byName("Essence of the Void")
                    item = p.createInstance()
                    item.slot = -1
                    loot.append(item)

                except:
                    traceback.print_exc()

        # Finish corpse loot generation.
        return self.finishCorpseLootGeneration()
コード例 #10
0
    def generateCorpseLoot(self):
        
        loot = self.items
        
        if self.corpseLootGenerated:
            return (self.tin or len(loot))
        
        spawn = self.mob.spawn
        proto = self.lootProto
        self.corpseLootGenerated = True
        
        if proto:
            #$$$, to do, curve these
            if proto.tin:
                self.tin = randint(0,proto.tin)
     #Start code modified and expanded by BellyFish           
            for lootitem in proto.lootItems:
                if not len(lootitem.itemProto.slots):
                    freq = lootitem.freq
                    r = 0
                    if freq > 1:
                        r = randint(0,freq-1)
                    if not r:
                        iproto = lootitem.itemProto
                        # check if the item has a start and end day
                        if (iproto.startDayRL != "" or iproto.endDayRL != ""):
                            startDayRL = date(*strptime(iproto.startDayRL + "-" + strftime('%Y'), "%m-%d-%Y")[0:3])
                            endDayRL = date(*strptime(iproto.endDayRL + "-" + strftime('%Y'), "%m-%d-%Y")[0:3])
                            todayRL = date.today()
                            #check if spawn period crosses a yearly boundary
                            if endDayRL < startDayRL:
                                #crosses yearly boundary, so check if the day is outside the allowed date range
                                if endDayRL < todayRL < startDayRL:
                                    continue #day is outside the allowed date range, so skip it
                            #no boundaries are crossed, so check if the day is ouside the allowed date range
                            elif not (startDayRL <= todayRL <= endDayRL):
                                continue #day is outside the allowed date range, so skip it
                      
                        #If we get here, the item can be added to the loot table.
      #End code modified and expanded by BellyFish  
                        #Create an instance of the item
                        item = iproto.createInstance()
                        
                        #possibly generate a variant
                        GenVariantItem(item,self.mob.plevel)
                        
                        item.slot = -1
                        loot.append(item)
                    
                    if len(loot) == 16:
                        break
        
        # Check if this particular spawn drops random loot or if the loot
        #  table already is maxed out.
        if len(loot) >= 16 or spawn.flags & RPG_SPAWN_NORANDOMLOOT:
            # No random loot or loot table full,
            #  so finish the corpse loot generation.
            return self.finishCorpseLootGeneration()
 
    #Start code added by BellyFish
         # Zone dependent Seasonal drops
        if ZONE_SEASONALITEMS.has_key(self.mob.zone.zone.name):
            # check if mob can have a Seasonal drop, a 1 in 4 chance
            # as the ZONE_SEASONALITEMS list increases for the same time period the chance for a
            # specific drop decreases.
            if not randint(0,3): 
                tempSeasonalItemlist = []
                zoneSeasonalItemList = ZONE_SEASONALITEMS[self.mob.zone.zone.name]
                if len(zoneSeasonalItemList) > 0:
                    #sort through the zoneSeasonalItemList list
                    for eachSeasonalItem in zoneSeasonalItemList:
                        #get the items prototype so we can reference the items info
                        try:
                        # If an item is not found, an SQLObjectNotFound exception is raised.
                             testItem = ItemProto.byName(eachSeasonalItem)
                        # So continue to the next item.
                        except SQLObjectNotFound:
                           continue                            
                        # check if the item has a start and end day
                        if (testItem.startDayRL != "" or testItem.endDayRL != ""):
                            startDayRL = date(*strptime(testItem.startDayRL + "-" + strftime('%Y'), "%m-%d-%Y")[0:3])
                            endDayRL = date(*strptime(testItem.endDayRL + "-" + strftime('%Y'), "%m-%d-%Y")[0:3])
                            todayRL = date.today()
                            #check if spawn period crosses a yearly boundary
                            if endDayRL < startDayRL:
                                #crosses yearly boundary, so check if the day is outside the allowed date range
                                if endDay < todayRL < startDayRL:
                                    continue #day is outside the allowed date range, so skip it
                            #no boundaries are crossed, so check if the day is ouside the allowed date range        
                            elif not (startDayRL <= todayRL <= endDayRL):
                                continue #day is outside the allowed date range, so skip it
                        #add the item to a tempSeasonalItemlist and repeat the for loop
                        tempSeasonalItemlist.append(testItem)

                    #Does the tempSeasonalItemlist contain data?
                    if len(tempSeasonalItemlist) > 0:
                        #pick a random item from the list
                        seasonalItem = tempSeasonalItemlist[randint(0,len(tempSeasonalItemlist) - 1)]
                        #create an instance of the item
                        itemInstance = seasonalItem.createInstance()
                        #make sure the item does not fit in a slot, only in inventory
                        itemInstance.slot = -1
                        #add the item to the loot list
                        loot.append(itemInstance)                    
    #End code added by BellyFish
        
        # If there is still room in the loot table, check
        #  if this mob carries additional random goodies.
        if len(loot) < 16:
            # Higher level mob possibly carries more random stuff.
            num = randint(0,int(spawn.plevel / 10) + 1)
            for x in xrange(0,num):
                # For each single item 25% chance to have or not to have.
                if randint(0,3):
                    continue
                
                # Get one of the random item protos.
                iproto = Loot.randomItemProtos[randint(0,len(Loot.randomItemProtos) - 1)]
                item = iproto.createInstance()
                # Eventually create a variant of this item.
                GenVariantItem(item,self.mob.plevel)
                
                # Finally add random item to loot table.
                item.slot = -1
                loot.append(item)
                if len(loot) == 16:
                    break
        
        # If there's still room in the loot table, check
        #  if this mob carries a zone potion.
        if len(loot) < 16:
            # The higher level the mob, the higher the chance
            #  to carry a zone potion.
            chance = 35 - spawn.plevel / 3
            if not randint(0,chance):
                # Success, try to get an appropriate zone potion.
                try:
                    zpotion = ZONE_POTIONS[self.mob.zone.zone.name]
                    zpotion = ItemProto.byName(zpotion)
                    item = zpotion.createInstance()
                    item.slot = -1
                    loot.append(item)
                except:
                    pass
        
        # If there's still room in the loot table, check
        #  if this mob carries some Moon Powder.
        if len(loot) < 16:
            # The higher level the mob, the higher the chance
            #  to carry Moon Powder.
            chance = 35 - spawn.plevel / 4
            if not randint(0,chance):
                # Success, try to add one Moon Powder to
                #  this mobs loot table.
                try:
                    p = ItemProto.byName("Moon Powder")
                    item = p.createInstance()
                    item.slot = -1
                    loot.append(item)
                except:
                    traceback.print_exc()
        
        # If there's still room in the loot table, check
        #  whether this mob carries a stat potion.
        num = 1
        # Unique mobs may carry more than one potion.
        if self.mob.uniqueVariant:
            num = 2
        for x in xrange(0,num):
            if len(loot) < 16:
                # The higher level the mob, the higher the chance
                #  to carry a stat potion.
                chance = (110 - spawn.plevel) / 2
                if not randint(0,chance):
                    try:
                        index = randint(0,len(STAT_POTIONS) - 1)
                        stat = STAT_POTIONS[index]
                        potion = "Potion of %s"%stat
                        # Mobs above level 25 may even carry an Elixir
                        #  instead of a normal stat potion.
                        if spawn.plevel >= 25:
                            chance = (110 - spawn.plevel) / 3
                            if not randint(0,chance):
                                potion = "Elixir of %s"%stat
                        
                        potion = ItemProto.byName(potion)
                        item = potion.createInstance()
                        item.slot = -1
                        loot.append(item)
                    except:
                        traceback.print_exc()
        
        num = 2 if self.mob.uniqueVariant else 1
        for x in xrange(0,num):                    
            if len(loot) < 16:
                if not randint(0,4): #got one
                    scrolls = set()
                    if not randint(0,2):
                        wclass = WILDTOMES[randint(0,len(WILDTOMES)-1)]
                        wlevel = spawn.plevel
                        classes = ((spawn.pclassInternal,spawn.plevel),(spawn.sclassInternal,spawn.slevel),(spawn.tclassInternal,spawn.tlevel),(wclass,wlevel))
                    else:
                        classes = ((spawn.pclassInternal,spawn.plevel),(spawn.sclassInternal,spawn.slevel),(spawn.tclassInternal,spawn.tlevel))
                        
                    for cl,level in classes:
                        spellScrolls = Loot.spellScrolls.get(cl)
                        if spellScrolls:
                            for x in xrange(max(1,level - 5),level + 11):
                                try:
                                    scrolls.update(spellScrolls[x])
                                except KeyError:
                                    continue
                    
                    scroll = None
                    if len(scrolls) == 1:
                        scroll = scrolls.pop()
                    elif len(scrolls) > 1:
                        scroll = list(scrolls)[randint(0,len(scrolls)-1)]
                    
                    if scroll:
                        v = (0,30,55,75,85,90,94,97,101)
                        x = randint(0,100)
                        for z in xrange(0,9):
                            if x < v[z]:
                                break
                        x = z + 1
                        
                        if self.mob.uniqueVariant:
                            x += 5
                            if x > 10:
                                x = 10
                        
                        item = getTomeAtLevelForScroll(scroll,x)
                        item.slot = -1
                        item.itemInfo.reset()
                        
                        loot.append(item)
        
        #books of learning
        num = 2 if self.mob.uniqueVariant else 1
        for x in xrange(0,num):
            if len(loot) < 16:
                chance = (110 - spawn.plevel) / 2
                if not randint(0,chance):
                    try:
                        iname = "Scroll of Learning"
                        if spawn.plevel >= 60:
                            chance = (110 - spawn.plevel) / 3
                            if not randint(0,chance):
                                iname = "Book of Learning"
                        
                        book = ItemProto.byName(iname)
                        item = book.createInstance()
                        item.slot = -1
                        loot.append(item)
                    
                    except:
                        traceback.print_exc()
        
        # Unique variant mobs may carry even more additional
        #  random items.
        if len(loot) < 16 and self.mob.uniqueVariant:
            x = max(1,spawn.plevel - 20)
            
            # Build a list of possible random items
            #  to add to the loot table.
            items = {}
            uniqueProtos = Loot.uniqueItemProtos
            for level in xrange(x,spawn.plevel + 1):
                try:
                    for freq,ip in uniqueProtos[level]:
                        items.setdefault(freq,[]).append(ip)
                except KeyError:
                    continue
            
            # If there are random items available...
            if len(items):
                # Try to add maximally 3.
                for x in xrange(3):
                    ip = None
                    # 33% Chance to get an additional item per iteration.
                    if not randint(0,2):
                        # Start iteration over possible items at lowest
                        #  drop frequency.
                        for freq in sorted(items.iterkeys(),reverse=True):
                            if not randint(0,freq):
                                if len(items[freq]) == 1:
                                    ip = items[freq][0]
                                    break
                                else:
                                    ip = items[freq][randint(0,len(items[freq])-1)]
                                    break
                        # If we got an item, add it to the loot table.
                        if ip:
                            item = ip.createInstance()
                            item.slot = -1
                            loot.append(item)
        
        # zone dependend enchanting-item drop, last item per list is more rare than the rest
        if len(loot) < 16:
            # check if we got one; ok, this is actually 1 in RPG_FREQ_RARE+1 but that's good enough
            if not randint(0,RPG_FREQ_RARE):
                try:
                    zoneEnchItemList = ZONE_ENCHANTINGITEMS[self.mob.zone.zone.name]
                    enchQuality = 0
                    
                    # check if this is even an uber enchantment type (chance total: 1 in 561)
                    # this seems like an extremely low drop chance, but considering it gets applied to every single loot collection...
                    # because the special enchantments are this rare and because of their power, they're always exquisite
                    if not randint(0,RPG_FREQ_IMPOSSIBLE):
                        # Get last item of list (uber enchantment).
                        enchName = zoneEnchItemList[-1]
                        enchQuality = len(ENCHANT_QualityPrefix) - 1
                    else:
                        # Otherwise, get a random normal type.
                        enchName = zoneEnchItemList[randint(0,len(zoneEnchItemList)-2)]
                        # Random quality for item (lower quality items can be combined
                        #  for higher quality), but don't allow index 0 (raw drop).
                        qualityCursor = randint(1,100)
                        for qualityTester in xrange(len(ENCHANT_QualityPrefix)):
                            if qualityCursor <= ENCHANT_QualityDropDistribution[qualityTester]:
                                break
                            enchQuality += 1
                    
                    enchItem = ItemProto.byName(enchName)
                    item = enchItem.createInstance()
                    # Hack, spellEnhanceLevel is used for quality of this item type
                    #  (less attribs), values < 10 are used to identify tomes,
                    #  so use values 10 - 17
                    item.spellEnhanceLevel = enchQuality + 10
                    item.name = ENCHANT_QualityPrefix[enchQuality] + item.name
                    item.slot = -1
                    loot.append(item)
                    
                except:
                    pass
                
        #Essence of the Void
        if len(loot) < 16:
            if not randint(0,RPG_FREQ_IMPOSSIBLE * 3):
                try:
                    p = ItemProto.byName("Essence of the Void")
                    item = p.createInstance()
                    item.slot = -1
                    loot.append(item)
                    
                except:
                    traceback.print_exc()
        
        # Finish corpse loot generation.
        return self.finishCorpseLootGeneration()