From The Mana World
m (respond)
(Yes, I ''should'' know better...)
Line 1: Line 1:
==Autogenerating page==
==How to generate the main page==
The main article is generated by a python script that creates the monster page in wikicode from the eAthena configuration files.
The main article is generated by a python script that creates the monster page in wikicode from the eAthena configuration files. Please use the python script to update the page, as manual changes may be overwritten by someone pasting in the results from the script below.


The program will write the complete Monster reference page to stdout (standard output). It is just to copy and paste that text. If you want to edit the introductory text or add images, please do so in the script below.
The python script will write the ''complete'' Monster reference page to stdout (standard output). Then it is only a matter of copying and pasting in that text. If you want to edit the introductory text or add images, please do so in the script below.


If you run <code>dbtowiki</code> without any arguments, the program will try to find the files <code>item_db.txt</code> and <code>mob_db.txt</code> in the current directory. To specify custom files, call <code>dbtowiki <mob_db> <item_db></code>.
The python script takes the following arguments:


=== Python program dbtowiki ===
mobdbtowiki <path to item database> <path to monster database>
 
If you run <code>dbtowiki</code> without any arguments, the script will try to find the files <code>item_db.txt</code> and <code>mob_db.txt</code> inside the working directory.
 
=== The python script mobdbtowiki ===
<pre>
<pre>
#!/usr/bin/python
#!/usr/bin/python
#Licensed under GNU General Public License
# Licensed under GNU General Public License
 
import sys, os, datetime;
import sys, os, datetime;


debug=0
 
# If something seems not to work, set this value to 1
debug = 0
 
 
#####################################
##                                ##
##  ADD WIKILINKS TO IMAGES BELOW  ##
##                                ##
#####################################


imageurls = {
imageurls = {
Line 49: Line 63:
'SpikyMushroom': "[[Image:Shroom.png]]",
'SpikyMushroom': "[[Image:Shroom.png]]",
'YellowSlime':  "[[Image:YellowSlime.png]]"
'YellowSlime':  "[[Image:YellowSlime.png]]"
# Note that the last line above should not be ended by a comma!
}
}
##########################################
##                                      ##
##  CHANGE THE INTRODUCTORY TEXT BELOW  ##
##                                      ##
##########################################
def printintroduction():
    sys.stdout.write('{{Category_playerinfo}}\n')
    sys.stdout.write('{{Status_green}}\n')
    sys.stdout.write('\'\'\'Page last generated on %s.\'\'\'\n' % datetime.date.today())
    sys.stdout.write('\n')
    sys.stdout.write('\'\'\'Warning:\'\'\' this reference might be out of date. The python script to generate this page can be found on the discussion page. Please be aware that any manual changes made to this page may be lost when the page is generated anew. Also, this reference might not reflect what is currently in the game. [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/server-data/trunk/db/mob_db.txt?revision=HEAD&view=markup You can view the most up-to-date version here.]\n')
    sys.stdout.write('\n')
    sys.stdout.write('The monsters are sorted roughly by their fighting strength, calculated as: <code>health_points * (attack_min + attack_max)</code>.\n')
    sys.stdout.write('\n')
# The table headers
def printtableheader():
    sys.stdout.write('! style="background:#efdead;" | Image\n')
    sys.stdout.write('! style="background:#efdead;" | Name\n')
    sys.stdout.write('! style="background:#efdead;" | ID\n')
    sys.stdout.write('! style="background:#efdead;" | HP\n')
    sys.stdout.write('! style="background:#efdead;" | Def.\n')
    sys.stdout.write('! style="background:#efdead;" | Attack\n')
    sys.stdout.write('! style="background:#efdead;" | Exp.\n')
    sys.stdout.write('! style="background:#efdead;" | Job exp.\n')
    sys.stdout.write('! style="background:#efdead;" | Dropped items\n')
    sys.stdout.write('|-\n')
# Number of rows between table header
headerafterrow = 10


class whatever: pass
class whatever: pass
Line 82: Line 132:
                 while (len(values) > 54):
                 while (len(values) > 54):
                     values.pop()
                     values.pop()
             o = whatever()
             o = whatever()
             o.id = saveint(values[0])
 
             o.label = values[1]
             o.id             = saveint(values[0])   # Monster ID
             o.name = values[2]
             o.label         =         values[1]   # The label (name) used in GM commands
             o.lvl = saveint(values[3])
             o.name           =         values[2]   # The name known to the server (not to the client)
             o.hp = saveint(values[4])
             o.level          = saveint(values[3])   # Level
             o.sp = saveint(values[5])
             o.hp             = saveint(values[4])   # Health points
             o.experience = saveint(values[6])
             o.sp             = saveint(values[5])   # SP
             o.monsterpoints = saveint(values[7])
             o.experience     = saveint(values[6])   # Experience points
             o.range1 = saveint(values[8])
             o.jobexperience  = saveint(values[7])   # Job experience points
             o.attackmin = saveint(values[9])
             o.range1         = saveint(values[8])   # Range of attack
             o.attackmax = saveint(values[10])
             o.attackmin     = saveint(values[9])   # Minimum attack damage
             o.defense = saveint(values[11])
             o.attackmax     = saveint(values[10]) # Maximum attack damage
             o.magicaldefense = saveint(values[12])
             o.defense       = saveint(values[11])  # Defense (relative in percent)
             o.strength = saveint(values[13])
             o.magicaldefense = saveint(values[12])  # Magical defense (ditto)
             o.agility = saveint(values[14])
             o.strength       = saveint(values[13]) # Strength level
             o.vitality = saveint(values[15])
             o.agility       = saveint(values[14]) # Agility level
             o.intelligence = saveint(values[16])
             o.vitality       = saveint(values[15]) # Vitality level
             o.dexterity = saveint(values[17])
             o.intelligence   = saveint(values[16]) # Intelligence level
             o.luck = saveint(values[18])
             o.dexterity     = saveint(values[17]) # Dexterity level
             o.range2 = saveint(values[19])
             o.luck           = saveint(values[18]) # Luck level
             o.range3 = saveint(values[20])
             o.range2         = saveint(values[19]) # Some-other range ???
             o.scale = saveint(values[21])
             o.range3         = saveint(values[20]) # Line-of-sight range ???
             o.race = saveint(values[22])
             o.scale         = saveint(values[21]) # The size type
             o.element = saveint(values[23])
             o.race           = saveint(values[22]) # Race
             o.mode = saveint(values[24])
             o.element       = saveint(values[23]) # Element level and type
             o.speed = saveint(values[25])
             o.mode           = saveint(values[24])  # Behaviour type (aggressive etc.)
             o.attackdelay = saveint(values[26])
             o.speed         = saveint(values[25])  # Walking speed (faster for lower values)
             o.attackmotion = saveint(values[27])
             o.attackdelay   = saveint(values[26])  # Attack delay (attack speed is the inverse)
             o.defencemotion = saveint(values[28])
             o.attackmotion   = saveint(values[27]) # Speed of attack animation ???
             o.damagemotion  = saveint(values[28]) # Speed of damage animation ???
 
             o.drop = []
             o.drop = []
             for i in range(8):
             for i in range(8):
                 o.drop.append(whatever())
                 o.drop.append(whatever())
             o.drop[0].id = saveint(values[29])
 
             o.drop[0].per = saveint(values[30])
             o.drop[0].id     = saveint(values[29]) # The following are 8 groups of item IDs and
             o.drop[1].id = saveint(values[31])
             o.drop[0].per   = saveint(values[30]) #    drop rates (100 = 1%) for drops 1 to 8
             o.drop[1].per = saveint(values[32])
             o.drop[1].id     = saveint(values[31])
             o.drop[2].id = saveint(values[33])
             o.drop[1].per   = saveint(values[32])
             o.drop[2].per = saveint(values[34])
             o.drop[2].id     = saveint(values[33])
             o.drop[3].id = saveint(values[35])
             o.drop[2].per   = saveint(values[34])
             o.drop[3].per = saveint(values[36])
             o.drop[3].id     = saveint(values[35])
             o.drop[4].id = saveint(values[37])
             o.drop[3].per   = saveint(values[36])
             o.drop[4].per = saveint(values[38])
             o.drop[4].id     = saveint(values[37])
             o.drop[5].id = saveint(values[39])
             o.drop[4].per   = saveint(values[38])
             o.drop[5].per = saveint(values[40])
             o.drop[5].id     = saveint(values[39])
             o.drop[6].id = saveint(values[41])
             o.drop[5].per   = saveint(values[40])
             o.drop[6].per = saveint(values[42])
             o.drop[6].id     = saveint(values[41])
             o.drop[7].id = saveint(values[43])
             o.drop[6].per   = saveint(values[42])
             o.drop[7].per = saveint(values[44])
             o.drop[7].id     = saveint(values[43])
             o.item1 = saveint(values[45])
             o.drop[7].per   = saveint(values[44])
             o.item2 = saveint(values[46])
 
             o.mexp = saveint(values[47])
             o.item1         = saveint(values[45]) # ???
             o.expper = saveint(values[48])
             o.item2         = saveint(values[46]) # ???
             o.mexp           = saveint(values[47]) # ???
             o.expper         = saveint(values[48]) # ???
 
             o.mvp = []
             o.mvp = []
             for i in range(3):
             for i in range(3):
                 o.mvp.append(whatever())
                 o.mvp.append(whatever())
             o.mvp[0].id = saveint(values[49])
 
             o.mvp[0].per = saveint(values[50])
             o.mvp[0].id     = saveint(values[49]) # The following are 3 groups of item IDs and
             o.mvp[1].id = saveint(values[51])
             o.mvp[0].per     = saveint(values[50]) #    drop rates (100 = 1%) for what drops ???
             o.mvp[1].per = saveint(values[52])
             o.mvp[1].id     = saveint(values[51])
             o.mvp[2].id = saveint(values[53])
             o.mvp[1].per     = saveint(values[52])
             o.mvp[2].per = saveint(values[54])
             o.mvp[2].id     = saveint(values[53])
             o.mvp[2].per     = saveint(values[54])


             objects.append(o)
             objects.append(o)


     return objects
     return objects


def addimageurls(monsters):
def addimageurls(monsters):
Line 158: Line 216:
             if debug:
             if debug:
                 log.append('Warning: Could not find imageurl for %s' % m.label)
                 log.append('Warning: Could not find imageurl for %s' % m.label)


def adddropnames(monsters,dropnames):
def adddropnames(monsters,dropnames):
Line 168: Line 227:
                 d.name = ''
                 d.name = ''
      
      


def parseitemnames(file):
def parseitemnames(file):
Line 193: Line 251:
     for line in log:
     for line in log:
         sys.stdout.write(line+'\n')
         sys.stdout.write(line+'\n')


def getdropstring(monster):
def getdropstring(monster):
Line 209: Line 268:
                     s = "%1.1f" % (d.per/100.0)
                     s = "%1.1f" % (d.per/100.0)
                 else:
                 else:
                     s = "%d" % (d.per/100)
                     s = "%d"   % (d.per/100)
             else:
             else:
                 if (d.per % 1000) != 0:
                 if (d.per % 1000) != 0:
                     s = "%.2f" % (d.per/100.0)
                     s = "%.2f" % (d.per/100.0)
                 else:
                 else:
                     s = "%.1f" % (d.per/100.0)
                     s = "%.1f" % (d.per/100.0)
             output += ("%s (%s%%)" % (d.name.replace('\t',''), s))
             output += ("%s (%s%%)" % (d.name.replace('\t',''), s))
             i = i + 1
             i = i + 1
     return output
     return output


def printintroduction():
    sys.stdout.write('{{Category_playerinfo}}\n{{Status_green}}\n')
    sys.stdout.write('\'\'\'Page last generated on %s.\'\'\'\n' % datetime.date.today())
    sys.stdout.write('\n')
    sys.stdout.write('\'\'\'Warning:\'\'\' this reference might be out of date. The python program to autogenerate this page can be found on the discussion page. Also, this reference might not reflect whats currently in the game. [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/server-data/trunk/db/mob_db.txt?revision=HEAD&view=markup You can view the most up-to-date version here.]\n')
    sys.stdout.write('\n')
    sys.stdout.write('The monsters are sorted roughly by their fighting strength, calculated as: <code>health_points * (attack_min + attack_max)</code>.\n')
    sys.stdout.write('\n')
def printtableheader():
    sys.stdout.write('! style="background:#efdead;" | Image\n')
    sys.stdout.write('! style="background:#efdead;" | Name\n')
    sys.stdout.write('! style="background:#efdead;" | ID\n')
    sys.stdout.write('! style="background:#efdead;" | HP\n')
    sys.stdout.write('! style="background:#efdead;" | Def.\n')
    sys.stdout.write('! style="background:#efdead;" | Attack\n')
    sys.stdout.write('! style="background:#efdead;" | Exp.\n')
    sys.stdout.write('! style="background:#efdead;" | Job Exp.\n')
    sys.stdout.write('! style="background:#efdead;" | Dropped items\n')
    sys.stdout.write('|-\n')


def printmonsters(monsters):
def printmonsters(monsters):
    printintroduction()
     sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%" align="center"\n')
     sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%" align="center"\n')


     i = 0
     i = 0
     for m in monsters:
     for m in monsters:
         if (i == 10):
         if (i == headerafterrow):
             i = 0
             i = 0
         if (i == 0):
         if (i == 0):
             printtableheader()
             printtableheader()


         sys.stdout.write('| align="center" | %s\n' % m.imgurl)
         sys.stdout.write('| align="center" | %s\n'       % m.imgurl)
         sys.stdout.write('| %s\n' % m.name)
         sys.stdout.write('| %s\n'                         % m.name)
         sys.stdout.write('| align="center" | %d\n' % m.id)
         sys.stdout.write('| align="center" | %d\n'       % m.id)
         sys.stdout.write('| align="center" | %d\n' % m.hp)
         sys.stdout.write('| align="center" | %d\n'       % m.hp)
         sys.stdout.write('| align="center" | %d%%\n' % m.defense)
         sys.stdout.write('| align="center" | %d%%\n'     % m.defense)


         if m.attackmin < m.attackmax:
         if m.attackmin < m.attackmax:
             sys.stdout.write('| align="center" | %d-%d\n' % (m.attackmin, m.attackmax))
             sys.stdout.write('| align="center" | %d-%d\n' % (m.attackmin, m.attackmax))
         else:
         else:
             sys.stdout.write('| align="center" | %d\n' % m.attackmin)
             sys.stdout.write('| align="center" | %d\n'   % m.attackmin)


         sys.stdout.write('| align="center" | %d\n' % m.experience)
         sys.stdout.write('| align="center" | %d\n'       % m.experience)
         sys.stdout.write('| align="center" | %d\n' % m.monsterpoints)
         sys.stdout.write('| align="center" | %d\n'       % m.jobexperience)
         sys.stdout.write('| %s\n' % getdropstring(m))
         sys.stdout.write('| %s\n'                         % getdropstring(m))
         sys.stdout.write('|-\n')
         sys.stdout.write('|-\n')


Line 311: Line 349:
         monsters.sort(lambda x, y: x.hp*(x.attackmin+x.attackmax) - y.hp*(y.attackmin+y.attackmax))
         monsters.sort(lambda x, y: x.hp*(x.attackmin+x.attackmax) - y.hp*(y.attackmin+y.attackmax))


        printintroduction()
         printmonsters(monsters)
         printmonsters(monsters)


Line 331: Line 370:


:Another column for attributes (aggressive, cowardly, etc.) or name highlighting. &mdash; [[User:Jaxad0127|<span style="color: #160196">Jaxad</span>]][[User Talk:Jaxad0127|<span style="color: #5B038F">0127</span>]] 01:48, 19 April 2008 (CEST)
:Another column for attributes (aggressive, cowardly, etc.) or name highlighting. &mdash; [[User:Jaxad0127|<span style="color: #160196">Jaxad</span>]][[User Talk:Jaxad0127|<span style="color: #5B038F">0127</span>]] 01:48, 19 April 2008 (CEST)
:: I will take a look on this the next time I am working on the script, unless someone else wishes to take a look? (This is the first time I’m working with python.) ✎ [[User:Kess|Kess]]<sup>[[User talk:Kess|☽]]</sup> 23:45, 28 October 2008 (CET)


=== Accuracy/Evade ===
=== Accuracy/Evade ===
Line 354: Line 395:
: Fixed in an earlier revision. ✎ [[User:Kess|Kess]]<sup>[[User talk:Kess|☽]]</sup> 10:32, 28 October 2008 (CET)
: Fixed in an earlier revision. ✎ [[User:Kess|Kess]]<sup>[[User talk:Kess|☽]]</sup> 10:32, 28 October 2008 (CET)


=== Question ===
=== [SOLVED] Question ===


What's MOBP? Mob points? Someone changed '''Job Exp.''' for '''Mobp.''' in the monster table.
What's MOBP? Mob points? Someone changed '''Job Exp.''' for '''Mobp.''' in the monster table.
Line 360: Line 401:


:I think Kess meant monster points (for the "quest" in Tulimshar). THose aren't stored in the monster DB yet. I changed teh script back, feel free to regenerate the page. &mdash; [[User:Jaxad0127|<span style="color: #160196">Jaxad</span>]][[User Talk:Jaxad0127|<span style="color: #5B038F">0127</span>]] 20:26, 28 October 2008 (CET)
:I think Kess meant monster points (for the "quest" in Tulimshar). THose aren't stored in the monster DB yet. I changed teh script back, feel free to regenerate the page. &mdash; [[User:Jaxad0127|<span style="color: #160196">Jaxad</span>]][[User Talk:Jaxad0127|<span style="color: #5B038F">0127</span>]] 20:26, 28 October 2008 (CET)
::Yes, I do not know what I was thinking making that change. I probably had a very “bright” moment or some such. The main page will be updated shortly. ✎ [[User:Kess|Kess]]<sup>[[User talk:Kess|☽]]</sup> 23:45, 28 October 2008 (CET)

Revision as of 22:45, 28 October 2008

How to generate the main page

The main article is generated by a python script that creates the monster page in wikicode from the eAthena configuration files. Please use the python script to update the page, as manual changes may be overwritten by someone pasting in the results from the script below.

The python script will write the complete Monster reference page to stdout (standard output). Then it is only a matter of copying and pasting in that text. If you want to edit the introductory text or add images, please do so in the script below.

The python script takes the following arguments:

mobdbtowiki <path to item database> <path to monster database>

If you run dbtowiki without any arguments, the script will try to find the files item_db.txt and mob_db.txt inside the working directory.

The python script mobdbtowiki

#!/usr/bin/python
# Licensed under GNU General Public License

import sys, os, datetime;


# If something seems not to work, set this value to 1
debug = 0


#####################################
##                                 ##
##  ADD WIKILINKS TO IMAGES BELOW  ##
##                                 ##
#####################################

imageurls = {
'AlizarinPlant': "[[Image:Plant-Alizarin.png]]",
'MauvePlant':    "[[Image:Plant-Mauve.png]]",
'Bat':           "[[Image:Bat.png]]",
'BlackScorpion': "[[Image:BlackScorpion.png]]",
'CaveSnake':     "[[Image:LampSnake.png]]",
'CobaltPlant':   "[[Image:Plant-Cobalt.png]]",
'EasterFluffy':  "[[Image:Fluffy.png]]",
'EvilMushroom':  "[[Image:Evilmushroom.png]]",
'FireGoblin':    "[[Image:FireGoblin.png]]",
'FireSkull':     "[[Image:FireSkull.png]]",
'Flower':        "[[Image:Sleepflower.png]]",
'Fluffy':        "[[Image:Fluffy.png]]",
'GambogePlant':  "[[Image:Plant-Gamboge.png]]",
'GiantMaggot':   "[[Image:GiantMaggot.png]]",
'GrassSnake':    "",
'GreenSlime':    "[[Image:GreenSlime.png]]",
'JackO':         "[[Image:JackO.png]]",
'LogHead':       "[[Image:Stumpy.png]]",
'Maggot':        "[[Image:Maggot.png]]",
'Mouboo':        "[[Image:Mouboo.png]]",
'MountainSnake': "[[Image:MountainSnake.png]]",
'Pinkie':        "[[Image:Violet.png]]",
'PoisonSkull':   "[[Image:PoisonSkull.png]]",
'RedScorpion':   "[[Image:RedScorpion.png]]",
'RedSlime':      "[[Image:RedSlime.png]]",
'RudolphSlime':  "[[Image:Rudolphslime.png]]",
'SantaSlime':    "[[Image:Santaslime.png]]",
'Scorpion':      "[[Image:Scorpion.png]]",
'SeaSlime':      "[[Image:Sea-slime.png]]",
'Silkworm':      "",
'Snake' :        "[[Image:Snake.png]]",
'Spider':        "[[Image:Spider.png]]",
'SpikyMushroom': "[[Image:Shroom.png]]",
'YellowSlime':   "[[Image:YellowSlime.png]]"
# Note that the last line above should not be ended by a comma!
}


##########################################
##                                      ##
##  CHANGE THE INTRODUCTORY TEXT BELOW  ##
##                                      ##
##########################################

def printintroduction():
    sys.stdout.write('{{Category_playerinfo}}\n')
    sys.stdout.write('{{Status_green}}\n')
    sys.stdout.write('\'\'\'Page last generated on %s.\'\'\'\n' % datetime.date.today())
    sys.stdout.write('\n')
    sys.stdout.write('\'\'\'Warning:\'\'\' this reference might be out of date. The python script to generate this page can be found on the discussion page. Please be aware that any manual changes made to this page may be lost when the page is generated anew. Also, this reference might not reflect what is currently in the game. [http://themanaworld.svn.sourceforge.net/viewvc/themanaworld/server-data/trunk/db/mob_db.txt?revision=HEAD&view=markup You can view the most up-to-date version here.]\n')
    sys.stdout.write('\n')
    sys.stdout.write('The monsters are sorted roughly by their fighting strength, calculated as: <code>health_points * (attack_min + attack_max)</code>.\n')
    sys.stdout.write('\n')


# The table headers
def printtableheader():
    sys.stdout.write('! style="background:#efdead;" | Image\n')
    sys.stdout.write('! style="background:#efdead;" | Name\n')
    sys.stdout.write('! style="background:#efdead;" | ID\n')
    sys.stdout.write('! style="background:#efdead;" | HP\n')
    sys.stdout.write('! style="background:#efdead;" | Def.\n')
    sys.stdout.write('! style="background:#efdead;" | Attack\n')
    sys.stdout.write('! style="background:#efdead;" | Exp.\n')
    sys.stdout.write('! style="background:#efdead;" | Job exp.\n')
    sys.stdout.write('! style="background:#efdead;" | Dropped items\n')
    sys.stdout.write('|-\n')

# Number of rows between table header
headerafterrow = 10


class whatever: pass

log = []

def saveint(string):
    a = 0
    try:
        a = int(string)
    except:
        a = 0
    return a
        

def parsemonsters(file):
    objects = []
    for line in file:
        s = line[0:line.find('//')].strip().replace('\t','')
        if s:
            values = s.split(',')
            if line[0] == '#':
                if debug:
                    log.append("FOUND COMMENT LINE: %s" % str(values))
                continue
            if (len(values) != 55):
                log.append("mob_db: Warning, monster-line with ID %s has %d values instead of 55" % (values[0], len(values)))
                if debug:
                    log.append("  line was %s" % str(values))
                while (len(values) < 54):
                    values.append('')
                while (len(values) > 54):
                    values.pop()

            o = whatever()

            o.id             = saveint(values[0])   # Monster ID
            o.label          =         values[1]    # The label (name) used in GM commands
            o.name           =         values[2]    # The name known to the server (not to the client)
            o.level          = saveint(values[3])   # Level
            o.hp             = saveint(values[4])   # Health points
            o.sp             = saveint(values[5])   # SP
            o.experience     = saveint(values[6])   # Experience points
            o.jobexperience  = saveint(values[7])   # Job experience points
            o.range1         = saveint(values[8])   # Range of attack
            o.attackmin      = saveint(values[9])   # Minimum attack damage
            o.attackmax      = saveint(values[10])  # Maximum attack damage
            o.defense        = saveint(values[11])  # Defense (relative in percent)
            o.magicaldefense = saveint(values[12])  # Magical defense (ditto)
            o.strength       = saveint(values[13])  # Strength level
            o.agility        = saveint(values[14])  # Agility level
            o.vitality       = saveint(values[15])  # Vitality level
            o.intelligence   = saveint(values[16])  # Intelligence level
            o.dexterity      = saveint(values[17])  # Dexterity level
            o.luck           = saveint(values[18])  # Luck level
            o.range2         = saveint(values[19])  # Some-other range ???
            o.range3         = saveint(values[20])  # Line-of-sight range ???
            o.scale          = saveint(values[21])  # The size type
            o.race           = saveint(values[22])  # Race
            o.element        = saveint(values[23])  # Element level and type
            o.mode           = saveint(values[24])  # Behaviour type (aggressive etc.)
            o.speed          = saveint(values[25])  # Walking speed (faster for lower values)
            o.attackdelay    = saveint(values[26])  # Attack delay (attack speed is the inverse)
            o.attackmotion   = saveint(values[27])  # Speed of attack animation ???
            o.damagemotion   = saveint(values[28])  # Speed of damage animation ???

            o.drop = []
            for i in range(8):
                o.drop.append(whatever())

            o.drop[0].id     = saveint(values[29])  # The following are 8 groups of item IDs and
            o.drop[0].per    = saveint(values[30])  #     drop rates (100 = 1%) for drops 1 to 8
            o.drop[1].id     = saveint(values[31])
            o.drop[1].per    = saveint(values[32])
            o.drop[2].id     = saveint(values[33])
            o.drop[2].per    = saveint(values[34])
            o.drop[3].id     = saveint(values[35])
            o.drop[3].per    = saveint(values[36])
            o.drop[4].id     = saveint(values[37])
            o.drop[4].per    = saveint(values[38])
            o.drop[5].id     = saveint(values[39])
            o.drop[5].per    = saveint(values[40])
            o.drop[6].id     = saveint(values[41])
            o.drop[6].per    = saveint(values[42])
            o.drop[7].id     = saveint(values[43])
            o.drop[7].per    = saveint(values[44])

            o.item1          = saveint(values[45])  # ???
            o.item2          = saveint(values[46])  # ???
            o.mexp           = saveint(values[47])  # ???
            o.expper         = saveint(values[48])  # ???

            o.mvp = []
            for i in range(3):
                o.mvp.append(whatever())

            o.mvp[0].id      = saveint(values[49])  # The following are 3 groups of item IDs and
            o.mvp[0].per     = saveint(values[50])  #     drop rates (100 = 1%) for what drops ???
            o.mvp[1].id      = saveint(values[51])
            o.mvp[1].per     = saveint(values[52])
            o.mvp[2].id      = saveint(values[53])
            o.mvp[2].per     = saveint(values[54])

            objects.append(o)

    return objects


def addimageurls(monsters):
    global imageurls
    for m in monsters:
        if imageurls.has_key(m.label):
            m.imgurl = imageurls[m.label]
        else:
            m.imgurl = ''
            if debug:
                log.append('Warning: Could not find imageurl for %s' % m.label)


def adddropnames(monsters,dropnames):
    for m in monsters:
        for d in m.drop:
            # Only add a dropname if it isn't "default" (id=0)
            if dropnames.has_key(d.id) and int(d.id):
                d.name = dropnames[d.id]
            else:
                d.name = ''
    

def parseitemnames(file):
    global log
    dic = {}
    for line in file:
        if line[0] == '#':
            continue
        s = line[0:line.find('//')].strip()
        if s:
            values = s.split(',')
            if (len(values) < 3):
                if len(values) > 0: log.append("mob_db: Warning, item-line with ID %s doesnt even have 3 values. Skipped." % (values[0], len(values)))
            else:
                id = int(values[0])
                dic[id] = values[2];
    return dic


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


def getdropstring(monster):
    i = 0
    output = ""
    monster.drop.sort(lambda x,y: y.per-x.per)
    for d in monster.drop:
        if d.name: 
            if (i != 0):
                output += '<br>'
            s = ""
            if d.per >= 1000:
                s = "%d" % (d.per/100)
            elif d.per >= 100:
                if (d.per % 100) != 0:
                    s = "%1.1f" % (d.per/100.0)
                else:
                    s = "%d"    % (d.per/100)
            else:
                if (d.per % 1000) != 0:
                    s = "%.2f"  % (d.per/100.0)
                else:
                    s = "%.1f"  % (d.per/100.0)
            output += ("%s (%s%%)" % (d.name.replace('\t',''), s))
            i = i + 1
    return output


def printmonsters(monsters):
    sys.stdout.write('{| border="1" cellspacing="0" cellpadding="5" width="100%" align="center"\n')

    i = 0
    for m in monsters:
        if (i == headerafterrow):
            i = 0
        if (i == 0):
            printtableheader()

        sys.stdout.write('| align="center" | %s\n'        % m.imgurl)
        sys.stdout.write('| %s\n'                         % m.name)
        sys.stdout.write('| align="center" | %d\n'        % m.id)
        sys.stdout.write('| align="center" | %d\n'        % m.hp)
        sys.stdout.write('| align="center" | %d%%\n'      % m.defense)

        if m.attackmin < m.attackmax:
            sys.stdout.write('| align="center" | %d-%d\n' % (m.attackmin, m.attackmax))
        else:
            sys.stdout.write('| align="center" | %d\n'    % m.attackmin)

        sys.stdout.write('| align="center" | %d\n'        % m.experience)
        sys.stdout.write('| align="center" | %d\n'        % m.jobexperience)
        sys.stdout.write('| %s\n'                         % getdropstring(m))
        sys.stdout.write('|-\n')

        i = i + 1

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


#MAIN
try:
    if (len(sys.argv) == 1):
        mob_db = "mob_db.txt"
        item_db = "item_db.txt"
    elif (len(sys.argv) == 3):
        mob_db = sys.argv[1]
        item_db = sys.argv[2]
    else: 
        mob_db = ''
        item_db = ''
        sys.stdout.write("Wrong number of arguments\n")

    if (mob_db and item_db) :
        if (not os.path.isfile(mob_db)):
            sys.stdout.write("File does not exist: %s\n" % mob_db)
            mob_db = ''
        if (not os.path.isfile(item_db)):
            sys.stdout.write("File does not exist: %s\n" % item_db)
            item_db = ''
    
    if not (mob_db and item_db):
        sys.stdout.write("\nUSAGE:\n")
        sys.stdout.write("dbtowiki without any arguments will use item_db.txt and mob_db.txt in the current directory.\n")
        sys.stdout.write("to specify custom files, call: dbtowiki <mob_db> <item_db>\n")
        exit(-1);
    else:
        if debug:
            log.append("Monster-list [mob_db] = %s" % mob_db)
            log.append("Item-list [item_db] = %s" % item_db)
        f = open(mob_db)
        monsters = parsemonsters(f);
        f = open(item_db)
        itemnames = parseitemnames(f);

        addimageurls(monsters)
        adddropnames(monsters,itemnames)
        monsters.sort(lambda x, y: x.hp*(x.attackmin+x.attackmax) - y.hp*(y.attackmin+y.attackmax))

        printintroduction()
        printmonsters(monsters)

finally:
    printlog()

Discussion

Strength of Red Scorpion

Wasnt the RED scorpion supposed to be a miniboss? that HP seems kinda low for one :o --Bear

Cool, I was thinking about bosses too. I believe that Red Guy is like a boss. There are too many snakes and spiders, a DRAGON should be a good idea for a boss. But ONLY ONE DRAGON, please. --BrightCiro (Ciro Leonardo, the char)

Agressive/nonagressive monsters?

Is there an easy way to list this attribute? Hoogli 21:02, 18 April 2008 (CEST)

Another column for attributes (aggressive, cowardly, etc.) or name highlighting. — Jaxad0127 01:48, 19 April 2008 (CEST)
I will take a look on this the next time I am working on the script, unless someone else wishes to take a look? (This is the first time I’m working with python.) ✎ Kess☽ 23:45, 28 October 2008 (CET)

Accuracy/Evade

Wouldn't it effective to put down the accuracy and evade rates of enemies as well? It would help take the guessing game out and prevent further deaths of players via play-testing. (Esp. mountain snakes) Since I am making an evade character, it would be nice to know the % to hit so I can adjust my evade accordingly so I dont go overboard and be weaker than I could be.

Scan9

[SOLVED] Broken Link

This link at the top of the monster list ( [1]) returns:

" An Exception Has Occurred

The root "viewcvs.cgi" is unknown. If you believe the value is correct, then please double-check your configuration. HTTP Response Status

404 Repository not found "

This needs to be fixed.

Fixed in an earlier revision. ✎ Kess☽ 10:32, 28 October 2008 (CET)

[SOLVED] Question

What's MOBP? Mob points? Someone changed Job Exp. for Mobp. in the monster table. I didn't changed it back because i don't know what it is. Gring0 19:36, 28 October 2008 (CET)

I think Kess meant monster points (for the "quest" in Tulimshar). THose aren't stored in the monster DB yet. I changed teh script back, feel free to regenerate the page. — Jaxad0127 20:26, 28 October 2008 (CET)
Yes, I do not know what I was thinking making that change. I probably had a very “bright” moment or some such. The main page will be updated shortly. ✎ Kess☽ 23:45, 28 October 2008 (CET)