From The Mana World
Revision as of 14:16, 18 November 2008 by Kess (talk | contribs) (As I don’t have the time to finish this currently, here is my sad attempt of changing the script)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
  1. !/usr/bin/python
  2. Licensed under GNU General Public License

import sys, os, popen2; import xml.parsers.expat

debug=0


    1. ##
    2. ADD WIKILINKS TO IMAGES OF ITEMS THAT ARE DYED ##
    3. OR DO NOT HAVE THE SAME NAME IN WIKI AND SVN ##
    4. ##

imageurls = { 'AlizarinHerb': "Alizarin-herb.png",

'BlackDye': "Use-potion-blackdye.png", 'BlackRose': "Generic-blackrose.png", 'BlackScorpionStinger': "Generic-blackscorpionstinger.png", 'BlueRose': "Generic-bluerose.png",

'CactusDrink': "Use-potion-cactusdrink.png", 'CactusPotion': "Use-potion-cactuspotion.png", 'Cap': "Armor-head-cap.png", 'CaveSnakeEgg': "Use-food-cavesnakeegg.png", 'CaveSnakeTongue': "Generic-cavesnaketongue.png", 'CobaltHerb': "Cobalt-herb.png", 'ConcentrationPotion': "Use-potion-concentrationpotion.png", 'CottonCloth': "Generic-fabric.png", 'CottonHeadband': "Armor-legs-cottonheadband.png", 'CottonShorts': "Armor-legs-cottonshorts.png", 'CottonSkirt': "Armor-legs-skirt.png",

'DarkBlueDye': "Use-potion-darkbluedye.png", 'DarkGreenDye': "Use-potion-darkgreendye.png", 'DarkRedRose': "Generic-darkredrose.png", 'DevelopersCap': "Armor-head-devcap.png",

'GambogeHerb': "Gamboge-herb.png", 'GMRobe': "Armor-chest-gmrobe.png", 'GoldenPlatemail': "Armor-chest-lightplatemailgold.png", 'GoldenScorpionStinger': "Generic-goldenscorpionstinger.png", 'GoldenWarlordPlate': "Armor-chest-warlordplategold.png", 'GrassSnakeEgg': "Use-food-grasssnakeegg.png", 'GrassSnakeTongue': "Generic-grasssnaketongue.png", 'GreenDye': "Use-potion-greendye.png",

'IronPotion': "Use-potion-ironpotion.png", 'IronPowder': "Generic-ironpowder.png", 'Iten': "Generic-iten.png",

'JeansShorts': "Armor-legs-jeanshorts.png",

'LargeHealingPotion': "Use-potion-largehealingpotion.png", 'LightBlueDye': "Use-potion-lightbluedye.png", 'LightPlatemail': "Armor-chest-lightplatemail.png",

'MagicPotion': "Use-potion-magicpotion.png", 'MauveHerb': "Mauve-herb.png", 'MediumHealingPotion': "Use-potion-mediumhealingpotion.png", 'MonsterOilPotion': "Use-potion-monsteroilpotion.png", 'MountainSnakeEgg': "Use-food-mountainsnakeegg.png", 'MountainSnakeTongue': "Generic-mountainsnaketongue.png",

'OrangeDye': "Use-potion-orangedye.png", 'OrangeRose': "Generic-orangerose.png", 'OrangeTulip': "Generic-orangetulip.png",

'PileOfAsh': "Generic-ashpowder.png", 'PinkDye': "Use-potion-pinkdye.png", 'PinkRose': "Generic-pinkrose.png", 'PinkTulip': "Generic-pinktulip.png", 'PurpleDye': "Use-potion-purpledye.png", 'PurpleTulip': "Generic-purpletulip.png",

'RedDye': "Use-potion-reddye.png", 'RedRose': "Generic-redrose.png", 'RedScorpionStinger': "Generic-redscorpionstinger.png", 'RedTulip': "Generic-redtulip.png",

'ScorpionStinger': "Generic-scorpionstinger.png", 'SilkRobe': "Armor-chest-robe.png", 'SmallHealingPotion': "Use-potion-smallhealingpotion.png", 'SnakeEgg': "Use-food-snakeegg.png", 'SnakeTongue': "Generic-snaketongue.png", 'Steak': "Use-food-steak.png", 'SulphurPowder': "Generic-sulphurpowder.png",

'TinyHealingPotion': "Use-potion-tinyhealingpotion.png", 'TurtleneckSweater': "Armor-chest-tnecksweater.png",

'VNeckSweater': "Armor-chest-vnecksweater.png",

'WarlordPlate': "Armor-chest-warlordplate.png", 'WhiteRose': "Generic-whiterose.png", 'WhiteShortTankTop': "Armor-chest-whiteshorttanktop.png", 'WhiteTankTop': "Armor-chest-whitetanktop.png", 'WhiteTulip': "Generic-whitetulip.png",

'YellowDye': "Use-potion-yellowdye.png", 'YellowRose': "Generic-yellowrose.png", 'YellowTulip': "Generic-yellowtulip.png"

  1. Note that the last line above should not be ended by a comma!

}


    1. ##
    2. OTHER ITEM INFORMATION ##
    3. ##
  1. Availability

B = 1 # (0) Buyable: can be bought from shops Q = 2 # (1) Quest reward: available from quests C = 4 # (2) Common drop: commonly dropped by monsters (> 1% chance) R = 8 # (3) Rare drop: rarely dropped by monsters (<= 1% chance) O = 16 # (4) Old: was previously available in the game U = 32 # (5) Unreleased: unreleased or otherwise unobtainable G = 64 # (6) GM only: only for game masters D = 128 # (7) Dev only: only for developers S = 256 # (8) Special: special purpose (e.g. Wedding Ring)

  1. Other

Y = 512 # (9) Dyeable: can be dyed

extrainfo = { 'AlizarinHerb': C, 'AntlerHat': O, 'Apple': B + C, 'Arrow': B + C, 'Axe': U, 'AxeHat': O,

'Bandana': O, 'Bardiche': U, 'Beer': B, 'Beheader': U, 'BlackCowboyHat': Q, 'BlackDye': Q, 'BlackRose': B, 'BlackScorpionStinger': C, 'BlacksmithsAxe': U, 'BlueEasterEgg': O, 'BluePresentBox': Q + C, 'BlueRose': B, 'BoneDarts': U, 'BoneKnife': Q, 'Boots': B + C, 'BottleOfSand': U, 'BottleOfWater': C, 'Bow': B + Q, 'BugLeg': Q + C, 'BunnyEars': O,

'CactusDrink': B + C, 'CactusPotion': B + Q + C, 'Cake': B + Q + C, 'Candy': Q + C, 'CandyCane': Q + C, 'Cap': U, 'CasinoCoins': B + Q + C, 'CatEars': U, 'CaveSnakeEgg': C, 'CaveSnakeLamp': C, 'CaveSnakeTongue': C, 'ChainmailShirt': B, 'CherryCake': B + Q + C, 'ChickenLeg': B, 'ChocolateBar': Q + C, 'ChristmasElfHat': O, 'ChristmasTreeHat': O, 'Circlet': O, 'CobaltHerb': C, 'CoinBag': C, 'ConcentrationPotion': B + Q + R, 'CottonCloth': C, 'CottonHeadband': U, 'CottonShirt': B + Q, 'CottonShorts': B + Q, 'CottonSkirt': B, 'CrescentRod': U, 'Crown': U, 'CrusadeHelmet': Q,

'Dagger': B + C, 'DarkBlueDye': Q, 'DarkCrystal': O, 'DarkGreenDye': Q, 'DarkRedRose': B, 'DecorCandy': Q + C, 'DemonMask': U, 'DesertBow': U, 'DesertHat': U, 'DesertShirt': B, 'DevelopersCap': D,

'EasterEgg': Q, 'EmptyBottle': C, 'Eyepatch': O,

'FaceMask': O, 'Falcion': U, 'FancyHat': B + C, 'ForestBow': B + Q, 'FunkyHat': O, 'FurBoots': Q,

'GambogeHerb': C, 'GingerBreadMan': Q + C, 'GMsCap': G, 'GMRobe': G, 'Goggles': O, 'GoldenPlatemail': U, 'GoldenScorpionStinger': Q, 'GoldenWarlordPlate': U, 'GraduationCap': Q, 'GrassSnakeEgg': C, 'GrassSnakeTongue': C, 'GreenDye': Q, 'GreenEasterEgg': O, 'GreenPresentBox': C,

'Halberd': U, 'HardSpike': C, 'HeartNecklace': U, 'HighPriestCrown': U, 'Hint1': O, 'Hint2': O, 'Hint3': O, 'Hint4': O, 'Hint5': O, 'Hint6': O, 'Hint7': O, 'Hint8': O, 'Hint9': O, 'Hint10': O,

'InfantryHelmet': R, 'IronArrow': B, 'IronOre': C, 'IronPotion': B + Q + C, 'IronPowder': U, 'Iten': U,

'Jackal': U, 'JeansChaps': Q, 'JeansShorts': R,

'Knife': B + C, 'KnightsHelmet': Q,

'LargeHealingPotion': Q, 'LeatherGloves': R, 'LeatherGoggles': O, 'LeatherPatch': Q, 'LeatherShield': B, 'LeatherShirt': B + C, 'LightBlueDye': Q, 'LightPlatemail': B,

'MaggotSlime': Q + C, 'MauveHerb': C, 'MediumHealingPotion': Q, 'Milk': B + C, 'MinerGloves': B + C, 'MinersHat': B + C, 'MonsterOilPotion': Q, 'MonsterSkullHelmet': U, 'MoubooHead': U, 'MountainSnakeEgg': C, 'MountainSnakeTongue': C, 'MushHat': O,

'NohMask': Q,

'Orange': B + C, 'OrangeCupcake': B + C, 'OrangeDye': Q, 'OrangeRose': B, 'OrangeTulip': B,

'Pearl': R, 'Petal': C, 'PileOfAsh': C, 'PinkAntenna': C, 'PinkDye': Q, 'PinkEasterEgg': O, 'PinkRose': B, 'PinkTulip': B, 'PirateHat': O, 'PumpkinHelmet': O, 'PurpleDye': Q, 'PurplePresentBox': Q + C, 'PurpleTulip': B,

'RangerHat': O, 'RawLog': C, 'RedChristmasStocking': O, 'RedDye': Q, 'RedEasterEgg': O, 'RedRose': B, 'RedScorpionStinger': Q + C, 'RedTulip': B, 'RoastedMaggot': B + C, 'RockKnife': U,

'Sabre': U, 'SandCutter': U, 'SantaBeardHat': O, 'SantaCookie': O, 'SantaHat': Q, 'ScarabArmlet': O, 'Scimitar': U, 'Scorpion': U, 'ScorpionStinger': Q + C, 'Scythe': Q, 'SerfHat': B, 'Setzer': Q, 'SharpKnife': B + C, 'ShortBow': B, 'ShortSword': Q, 'ShroomHat': O, 'SilkCocoon': C, 'SilkHeadband': B, 'SilkRobe': Q, 'SmallHealingPotion': Q, 'SmallMushroom': C, 'SnakeSkin': C, 'SnakeEgg': C, 'SnakeTongue': C, 'StaffOfFire': U, 'StaffOfIce': U, 'StaffOfLife': U, 'StandardHeadband': B, 'Steak': B, 'SteelShield': Q, 'SulphurPowder': U,

'TealEasterEgg': O, 'TinyHealingPotion': Q, 'TopHat': O, 'ToySabre': O, 'TreasureKey': C, 'TurtleneckSweater': O,

'VNeckSweater': O,

'WarlordHelmet': Q, 'WarlordPlate': B, 'WeddingRing': S, 'WhiteCowboyHat': Q, 'WhiteFur': C, 'WhiteRose': B, 'WhiteShortTankTop': Q, 'WhiteTankTop': Q, 'WhiteTulip': B, 'WinterGloves': Q, 'WoodenShield': Q,

'XmasCake': Q + C, 'XmasCandyCane': Q + C,

'YellowDye': Q, 'YellowEasterEgg': O, 'YellowRose': B, 'YellowTulip': B

  1. Note that the last line above should not be ended by a comma!

}


    1. ##
    2. INTRO TEXT ##
    3. ##

def printwarningcomments():


def printintrotext():


    1. ##
    2. TABLE HEADERS ##
    3. ##

health_titles = ["Image",

                "Name",
                "ID",
                "HP",
                "SP",
                "Price
BUY/sell", "Weight", "Description", "Other"]

status_titles = ["Image",

                "Name",
                "ID",
                "Spell name",
                "Parameter 1",
                "Parameter 2",
                "Price
BUY/sell", "Weight", "Description", "Other"]

weapon_titles = ["Image",

                "Name",
                "ID",
                "Damage
(range)", "Price
BUY/sell", "Weight", "Description", "Other"]

armor_titles = ["Image",

                "Name",
                "ID",
                "Defense", 
                "Price
BUY/sell", "Weight", "Description", "Other"]

other_titles = ["Image",

                "Name",
                "ID",
                "Price
BUY/sell", "Weight", "Description", "Other"]


class whatever: pass

log = []


  1. parseitems(file)
    1. Returns list with items from eathena item_db file.

def saveint(string, altval = 0):

   a = 0
   try:
       a = int(string)
   except:
       a = altval
   return a


def parsescript(s):

   # Assumes that there's only one call of each method, otherwise it would need to know
   # how to combine those function calls. In practice, the latter call would prevail.
   script = {}
   scriptentry = ""
   parentry = ""
   mode = 0
   for a in s:
       if mode == 0: # looking for method
           if a.isalpha(): 
               mode = 1
               scriptentry += a
           elif a == '}': mode = 9
       elif mode == 1: # reading method name
           if a in " ;}":
               if a == " ": mode = 2
               elif a == ";": mode = 1
               elif a == "}": mode = 9
               parentry = ""
               script[scriptentry] = []
           else: scriptentry += a
       elif mode == 2: #looking for param
           if a == " ": pass
           elif a == ";": 
               mode = 0
               scriptentry = ""
           else:
               mode = 3
               parentry = a
       elif mode == 3: #reading param
           if (a == " ") or (a == ",") or (a == ";"):
               script[scriptentry].append(parentry)
               parentry = ""
               if (a == ';'): 
                   mode = 0
                   scriptentry = ""
               else: mode = 2
           else: 
               parentry += a
       elif mode == 9: #finished
           pass
   # Convert all possible parameters to integers
   for i in script.keys():
       for j in range(len(script[i])):
           try:
               script[i][j] = int(script[i][j])
           except:
               #print script[i][j]
               pass
   return script


def parseitems(file):

   objects = []
   for line in file:
       s = line[0:line.find('//')].strip().replace('\t',)
       if s:
           #Replace commas inbetween {} with |, so we can use split
           mode = 0
           sout = ""
           for a in s:
               if mode == 0: #Out of {}
                   if a == '{': mode = 1
                   sout += a
               elif mode == 1: #Inside {}
                   if a == ',': sout += '|'
                   else:
                       sout += a
                       if a == '}': mode = 0
           values_norm = 20
           values = sout.split(',')
           if line[0] == '#':
               if debug:
                   log.append("FOUND COMMENT LINE: %s" % str(values))
               continue
           if (len(values) != values_norm):
               log.append("item_db: Warning, item-line with ID %s has %d values instead of %d" % (values[0], len(values), values_norm))
               if debug:
                   log.append("  line was %s" % str(values))
               while (len(values) < values_norm):
                   values.append()
               while (len(values) > values_norm):
                   values.pop()
           o = whatever()
           o.id          = int(values[0])
           o.label       = values[1]
           o.name        = values[2]
           o.type        = saveint(values[3])
           o.price       = saveint(values[4])
           o.sell        = saveint(values[5])
           o.weight      = saveint(values[6])
           o.attack      = saveint(values[7])
           o.defense     = saveint(values[8])
           o.range       = saveint(values[9])
           o.magicbonus  = saveint(values[10])
           o.slot        = saveint(values[11],-1)
           o.job         = saveint(values[12],-1)
           o.gender      = saveint(values[13],-1)
           o.loc         = saveint(values[14])
           o.wlv         = saveint(values[15])
           o.elv         = saveint(values[16])
           o.view        = saveint(values[17],-1)
           o.usescript   = parsescript(values[18].replace('|',','))
           o.equipscript = parsescript(values[19].replace('|',','))
           objects.append(o)
   return objects


  1. parsexmlitems(file)
    1. Creates a dictionary containing the values of a client items.xml
    2. Yeah, there are XML parsers in the standard python libraries, but they're too object
    3. oriented and thus don't fit the style of this program.

def parsexmlitems(file):

   items = {}
   pre = "<item "
   term = ">"
   attrs = ["id", "image", "name", "description", "type", "weight"]
   intattrs = ["id", "weight"]
   s = file.read()
   index = 0
   debug = 0
   while s[index:].find(pre) >= 0:
       index += s[index:].find(pre) + len(pre)
       curitem = {}
       termstart = index + s[index:].find(term) + len(term)
       for attr in attrs:
           found = s[index:].find(attr+'="')
           if found >= 0:
               start = index + found + len(attr+'="')
               end = start + s[start:].find('"')
           else:
               start = termstart
           if (start < termstart):
               curitem[attr] = s[start:end]
       for a in intattrs:
           try:
               if curitem.has_key(a): curitem[a] = int(curitem[a])
           except:
               log.append("Item-ID %s: Cannot convert integer attribute %s to an integer. Value: '%s'" % (curitem["id"], a, curitem[a]))
       # For now, IDs below 500 are no real items and IDs 2xxx are dyed variants
       if ((curitem.get('id') > 499) and (curitem.get('id') < 2000)):
           items[curitem.get('id')] = curitem
   return items


  1. addclientinformation(items, citems)
    1. Extends the item data with the data collected from the client items.xml. Adding imageurls,
    2. client name, description and effect

def addclientinformation(items, citems):

   global imageurls
   for i in items:
       if citems.has_key(i.id):
           if imageurls.has_key(i.label):
               url = imageurls[i.label]
           else:
               i.imagename=citems[i.id]["image"]
               url=i.imagename[0].upper() + i.imagename[1:]
           i.imgurl = "File:"+ url + ""
           i.description = citems[i.id]["description"]
           i.clientname = citems[i.id]["name"]
       else:
           i.imgurl = 
           i.description = 
           i.clientname = 


  1. gettypedir (items)
    1. Returns sorted lists of items by itemtype

def gettypedir(items):

   items.sort(lambda x,y: (x.price+x.sell) - (y.price+y.sell))
   typedir = whatever()
   typedir.legarmor = []
   typedir.onehandedweapons = []
   typedir.handarmor = []
   typedir.shields = []
   typedir.twohandedweapons = []
   typedir.footarmor = []
   typedir.rings = []
   typedir.headarmor = []
   typedir.chestarmor = []
   typedir.ammo = []
   typedir.healthy = []
   typedir.status = []
   typedir.inspiring = []
   typedir.other = []
   for item in items:
       if (item.imgurl.strip() or item.clientname.strip()):
           # -1- Check the equipable items
           if (item.loc == 1): typedir.legarmor.append(item)
           elif (item.loc == 2): typedir.onehandedweapons.append(item)
           elif (item.loc == 4): typedir.handarmor.append(item)
           elif (item.loc == 32): typedir.shields.append(item)
           elif (item.loc == 34): typedir.twohandedweapons.append(item)
           elif (item.loc == 64): typedir.footarmor.append(item)
           elif (item.loc == 128): typedir.rings.append(item)
           elif (item.loc == 256): typedir.headarmor.append(item)
           elif (item.loc == 512): typedir.chestarmor.append(item)
           elif (item.loc == 32768): typedir.ammo.append(item)
           else:
               if (item.loc < 0):
                   log.append("Warning: Script needs to be updated with new armor type for item %d." % item.id)
               # -2- Check other items
               elif item.usescript.has_key("itemheal"): 
                   if item.usescript["itemheal"][0] >= item.usescript["itemheal"][1]: 
                       typedir.healthy.append(item)
                   if item.usescript["itemheal"][1] >= item.usescript["itemheal"][0]: 
                       typedir.inspiring.append(item)
               #elif item.usescript.has_key("sc_start"): typedir.status.append(item)
               else: typedir.other.append(item)
   typedir.onehandedweapons.sort(lambda x,y: x.attack - y.attack)
   typedir.twohandedweapons.sort(lambda x,y: x.attack - y.attack)
   typedir.ammo.sort(lambda x,y: x.attack - y.attack)
   typedir.legarmor.sort(lambda x,y: x.defense - y.defense)
   typedir.handarmor.sort(lambda x,y: x.defense - y.defense)
   typedir.shields.sort(lambda x,y: x.defense - y.defense)
   typedir.footarmor.sort(lambda x,y: x.defense - y.defense)
   typedir.rings.sort(lambda x,y: x.defense - y.defense)
   typedir.headarmor.sort(lambda x,y: x.defense - y.defense)
   typedir.chestarmor.sort(lambda x,y: x.defense - y.defense)
   typedir.healthy.sort(lambda x,y: (int(x.usescript["itemheal"][0])+int(x.usescript["itemheal"][1])) -
                                    (int(y.usescript["itemheal"][0])+int(y.usescript["itemheal"][1])))
   typedir.inspiring.sort(lambda x,y: int(x.usescript["itemheal"][1]) - int(y.usescript["itemheal"][1]))
   typedir.status.sort(lambda x,y: (x.price+x.sell) - (y.price+y.sell))
   typedir.other.sort(lambda x,y: x.id - y.id)
   return typedir
   


  1. printlog()
    1. Prints the global variable log to stdout

def printlog():

   global log
   if len(log) > 0:
       sys.stdout.write('\n---------------------------------------\n')
   for line in log:
       sys.stdout.write(line+'\n')


    1. ##
    2. CREATE THE WIKI TABLES ##
    3. ##

def getmoneystring(buy, sell):

   return '| align="right" | %d GP
%d gp\n' % (buy,sell)

def getidstring(id):

   return '| style="text-align:center;" | [%d]\n' % id

def getextrainfostring(i):

   global extrainfo
   returnstring = 
   if extrainfo.has_key(i.label):
       # Availability/rarity
       if (extrainfo[i.label] >> 0 & 1 == 1): returnstring += '
Buyable' if (extrainfo[i.label] >> 1 & 1 == 1): returnstring += '
Quest reward' if (extrainfo[i.label] >> 2 & 1 == 1): returnstring += '
Common drop' if (extrainfo[i.label] >> 3 & 1 == 1): returnstring += '
Rare drop' if (extrainfo[i.label] >> 4 & 1 == 1): returnstring += '
Previously available' if (extrainfo[i.label] >> 5 & 1 == 1): returnstring += '
Unobtainable' if (extrainfo[i.label] >> 6 & 1 == 1): returnstring += '
GM only' if (extrainfo[i.label] >> 7 & 1 == 1): returnstring += '
Dev only' if (extrainfo[i.label] >> 8 & 1 == 1): returnstring += '
Special'
       # Other
       if (extrainfo[i.label] >> 9 & 1 == 1): returnstring += '
Dyeable\n'
   # Spell
   if i.usescript.has_key("sc_start"):
       returnstring += '
Spell: %s (%d, %d)' % (i.usescript["sc_start"][0], i.usescript["sc_start"][1], i.usescript["sc_start"][2])
   # Bonus
   if i.equipscript.has_key("bonus"):
       returnstring += '
Bonus: %s %d' % (i.equipscript["bonus"][0], i.equipscript["bonus"][1])
   # Do not return the first instance of the 
tag return returnstring[6:] + '\n'

def tablestart(title, text):

   sys.stdout.write('== %s ==\n' % title)
   sys.stdout.write('%s\n' % text)
   sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%"\n')

def tableend():

   sys.stdout.write('|}\n\n')


def printhealitems(items, title):

   tablestart(title, 'Sorted by combined HP and SP effect.')
   for title in health_titles:
       sys.stdout.write('! style="background:#efdead;" | %s\n' % title)
       
   for i in items:
       sys.stdout.write('|-\n')
       sys.stdout.write('| style="text-align:center;" | %s\n' % i.imgurl)
       sys.stdout.write('| %s\n' % i.clientname)
       sys.stdout.write( getidstring(i.id) )
       sys.stdout.write('| style="text-align:center;" | %d\n' % i.usescript["itemheal"][0])
       sys.stdout.write('| style="text-align:center;" | %d\n' % i.usescript["itemheal"][1])
       sys.stdout.write( getmoneystring(i.price,i.sell) )
       sys.stdout.write('| style="text-align:center;" | %d\n' % i.weight)
       sys.stdout.write('| %s\n' % i.description)
       sys.stdout.write('| ' + getextrainfostring(i))
   tableend()


def printstatusitems(items, title):

   tablestart(title, 'Sorted by price.')
   for title in status_titles:
       sys.stdout.write('! style="background:#efdead;" | %s\n' % title)
       
   for i in items:
       sys.stdout.write('|-\n')
       sys.stdout.write('| style="text-align:center;" | %s\n' % i.imgurl)
       sys.stdout.write('| %s\n' % i.clientname)
       sys.stdout.write( getidstring(i.id) )
       sys.stdout.write('| style="text-align:center;" | %s\n' % i.usescript["sc_start"][0])
       sys.stdout.write('| style="text-align:center;" | %s\n' % i.usescript["sc_start"][1])
       sys.stdout.write('| style="text-align:center;" | %s\n' % i.usescript["sc_start"][2])
       sys.stdout.write( getmoneystring(i.price,i.sell) )
       sys.stdout.write('| style="text-align:center;" | %d\n' % i.weight)
       sys.stdout.write('| %s\n' % i.description)
       sys.stdout.write('| ' + getextrainfostring(i))
   tableend()
           

def printweaponitems(items, title):

   tablestart(title, 'Sorted by attack.')
   for title in weapon_titles:
       sys.stdout.write('! style="background:#efdead;" | %s\n' % title)
   for i in items:
       sys.stdout.write('|-\n')
       sys.stdout.write('| style="text-align:center;" | %s\n' % i.imgurl)
       sys.stdout.write('| %s\n' % i.clientname)
       sys.stdout.write( getidstring(i.id) )
       sys.stdout.write('| style="text-align:center;" | %d (%d)\n' % (i.attack,i.range))
       sys.stdout.write( getmoneystring(i.price,i.sell) )
       sys.stdout.write('| style="text-align:center;" | %d\n' % i.weight)
       sys.stdout.write('| %s\n' % i.description)
       sys.stdout.write('| ' + getextrainfostring(i))
   tableend()
   

def printarmoritems(items, title):

   tablestart(title, 'Sorted by defence.')
   for title in armor_titles:
       sys.stdout.write('! style="background:#efdead;" | %s\n' % title)
   for i in items:
       sys.stdout.write('|-\n')
       sys.stdout.write('| style="text-align:center;" | %s\n' % i.imgurl)
       sys.stdout.write('| %s\n' % i.clientname)
       sys.stdout.write( getidstring(i.id) )
       sys.stdout.write('| style="text-align:center;" | %d%%\n' % i.defense)
       sys.stdout.write( getmoneystring(i.price,i.sell) )
       sys.stdout.write('| style="text-align:center;" | %d\n' % i.weight)
       sys.stdout.write('| %s\n' % i.description)
       sys.stdout.write('| ' + getextrainfostring(i))
   tableend()


def printotheritems(items, title):

   tablestart(title, 'Sorted by ID.')
   for title in other_titles:
       sys.stdout.write('! style="background:#efdead;" | %s\n' % title)
   for i in items:
       sys.stdout.write('|-\n')
       sys.stdout.write('| style="text-align:center;" | %s\n' % i.imgurl)
       sys.stdout.write('| %s\n' % i.clientname)
       sys.stdout.write( getidstring(i.id) )
       sys.stdout.write( getmoneystring(i.price,i.sell) )
       sys.stdout.write('| style="text-align:center;" | %d\n' % i.weight)
       sys.stdout.write('| %s\n' % i.description)
       sys.stdout.write('| ' + getextrainfostring(i))
   tableend()


    1. ##
    2. MAIN ##
    3. ##

try:

   if (len(sys.argv) == 1):
       item_db = "item_db.txt"
       item_xml = "items.xml"
   elif (len(sys.argv) == 3):
       item_db = sys.argv[1]
       item_xml = sys.argv[2]
   else: 
       item_db = 
       item_xml = 
       sys.stdout.write("Wrong number of arguments\n")
   if item_db and (not os.path.isfile(item_db)):
       sys.stdout.write("File does not exist: %s\n" % item_db)
       item_db = 
   if item_xml and (not os.path.isfile(item_xml)):
       sys.stdout.write("File does not exist: %s\n" % item_xml)
       item_db = 
   
   if not (item_db and item_xml):
       sys.stdout.write("\nUSAGE:\n")
       sys.stdout.write("dbtowiki without any arguments will use item_db.txt and items.xml in the current directory.\n")
       sys.stdout.write("to specify custom files, call: dbtowiki <item_db> <item_xml>\n")
       exit(-1);
   else:
       if debug:
           log.append("Item-list [item_db] = %s" % item_db)
           log.append("Item-list [item_xml] = %s" % item_xml)
       f = open(item_db)
       items = parseitems(f);
       f = open(item_xml)
       citems = parsexmlitems(f);
       addclientinformation(items, citems)
       printwarningcomments()
       printintrotext()
       typedir = gettypedir(items)
       if len(typedir.healthy) > 0: printhealitems(typedir.healthy, "Health items")
       if len(typedir.status) > 0: printstatusitems(typedir.status, "Status items")
       if len(typedir.inspiring) > 0: printhealitems(typedir.inspiring, "Mana items")
       if len(typedir.other) > 0: printotheritems(typedir.other, "Other items")
       if len(typedir.onehandedweapons) > 0: printweaponitems(typedir.onehandedweapons, "One-handed weapons")
       if len(typedir.twohandedweapons) > 0: printweaponitems(typedir.twohandedweapons, "Two-handed weapons")
       if len(typedir.ammo) > 0: printweaponitems(typedir.ammo, "Ammo")
       if len(typedir.headarmor) > 0: printarmoritems(typedir.headarmor, "Head armor")
       if len(typedir.legarmor) > 0: printarmoritems(typedir.legarmor, "Leg armor")
       if len(typedir.chestarmor) > 0: printarmoritems(typedir.chestarmor, "Chest armor")
       if len(typedir.footarmor) > 0: printarmoritems(typedir.footarmor, "Foot armor")
       if len(typedir.handarmor) > 0: printarmoritems(typedir.handarmor, "Gloves")
       if len(typedir.shields) > 0: printarmoritems(typedir.shields, "Shields")
       if len(typedir.rings) > 0: printarmoritems(typedir.rings, "Rings")

finally:

   printlog()