#! /usr/bin/env python3
# -*- coding: utf8 -*-
#
# Copyright (C) 2010-2011 Evol Online
# Copyright (C) 2018 TMW-2
# Author: Andrei Karas (4144)
# Author: Jesusalva
import datetime
wikib=open("EleMonsters.html", "w")
wikib.write('<html><head><meta charset=utf8 /><title>EleGen File</title></head><body>')
totalid=0
bifs=False
def printSeparator():
print("--------------------------------------------------------------------------------")
def showHeader():
print("TMW2 Ele Generator")
print("This stuff analyzes and sorts mobs elementals, races and walkmasks.")
##print "Evol client data validator."
print("Run at: " + datetime.datetime.now().isoformat())
##print "https://gitlab.com/evol/evol-tools/blob/master/testxml/testxml.py"
printSeparator()
def showFooter():
#pass
#printSeparator()
print("Done.")
Mobs0=[]
Mobs1=[]
Mobs2=[]
Mobs3=[]
Mobs4=[]
Mobs5=[]
Mobs6=[]
Mobs7=[]
Mobs8=[]
Mobs9=[]
MobsA=[]
SysDrops=[]
def fwalk(wmask):
if wmask == 'WATER':
return '<font color=#00f>%s</font>' % (wmask)
elif wmask == 'AIR':
return '<font color=#093>%s</font>' % (wmask)
elif wmask == 'WALL':
return '<font color=#f00>%s</font>' % (wmask)
elif wmask == 'NORMAL' or wmask == 'DEFAULT':
return '<font color=#111>%s</font>' % (wmask)
else:
print("Invalid walk mask: "+wmask)
exit(1)
def WhatRace(rac):
rc=rac.race
if rc == 0:
return "Formless"
elif rc == 1:
return "Undead"
elif rc == 2:
return "Brute"
elif rc == 3:
return "Plant"
elif rc == 4:
return "Insect"
elif rc == 5:
return "Mineral"
elif rc == 6:
return "Evil"
elif rc == 7:
return "SemiHuman"
elif rc == 8:
return "Angel"
elif rc == 9:
return "Dragon"
elif rc == 10:
return "Player"
elif rc == 11:
return "Boss"
elif rc == 12:
return "NonBoss"
elif rc == 14:
return "NonSemiHuman"
elif rc == 15:
return "NonPlayer"
elif rc == 16:
return "SemiPlayer"
elif rc == 17:
return "NonSemiPlayer"
else:
print("ERROR, INVALID RACE ID: %d (ID: %s)" % (rc, rac.id))
exit(1)
def WhatElem(rac):
rc=rac.elem
tl="ERROR"
cl="#F00"
if rc == 0:
tl,cl="Neutral","#000"
elif rc == 1:
tl,cl="Water","#00F"
elif rc == 2:
tl,cl="Earth","#7A0"
elif rc == 3:
tl,cl="Fire","#F00"
elif rc == 4:
tl,cl="Wind","#093"
elif rc == 5:
tl,cl="Nature","#040"
elif rc == 6:
tl,cl="Holy","#afa"
elif rc == 7:
tl,cl="Dark","#908"
elif rc == 8:
tl,cl="Ghost","#404"
elif rc == 9:
tl,cl="Undead","#440"
else:
print("ERROR, INVALID ELEM ID: %d (ID: %s)" % (rc, rac.id))
exit(1)
return "<font color=%s>%s</font>" % (cl, tl)
class Mob:
def __init__(self):
# Basic
self.id="0"
#self.aegis="UnknownMonster" # SpriteName is not used anywhere, we are using its ID
self.name="Unknown Monster Name"
self.view="1"
# Defensive
self.mobpt="0" # Mob Points “Level”
self.hp="0"
self.xp="0"
self.jp="0"
self.st=""
# Offensive
self.atk="[0, 0]"
self.range="0"
self.move="0"
self.delay="0"
self.drops=[]
# New
self.race=-1
self.elem=-1
self.elel=-1
self.walk="NORMAL"
def MobAlloc(ab):
try:
maab=int(ab.elem)
except:
maab=9901
if maab == 0:
Mobs0.append(ab)
elif maab == 1:
Mobs1.append(ab)
elif maab == 2:
Mobs2.append(ab)
elif maab == 3:
Mobs3.append(ab)
elif maab == 4:
Mobs4.append(ab)
elif maab == 5:
Mobs5.append(ab)
elif maab == 6:
Mobs6.append(ab)
elif maab == 7:
Mobs7.append(ab)
elif maab == 8:
Mobs8.append(ab)
elif maab == 9:
Mobs9.append(ab)
else:
MobsA.append(ab)
def testMobs():
global totalid
print("Generating Elem-Mob Wiki...")
src=open("../../serverdata/db/re/mob_db.conf", "r")
wikib.write("<h1 id=#x>EleGen Monster Database</h1>\n")
start=False
dropper=False
x=Mob() # Only for pyflakes2
for a in src:
if a == "{\n":
if start and not bifs and ((int(x.hp) <= 50) or (x.race == 3)):
start=False
if start:
MobAlloc(x)
else:
start=True
x=Mob()
if " Id:" in a:
x.id=stp(a)
totalid+=1
if x.id == "ID":
continue
if " Name:" in a:
x.name=stp(a)
elif " Hp:" in a:
x.hp=stp(a)
elif " Lv:" in a:
x.mobpt=stp(a)
elif " Exp:" in a:
x.xp=stp(a)
elif " JExp:" in a:
x.jp=stp(a)
elif " Attack:" in a:
x.atk=stp(a)
elif " AttackRange:" in a:
x.range=stp(a)
elif " MoveSpeed:" in a:
x.move=stp(a)
elif " ViewRange:" in a:
x.view=stp(a)
elif " AttackDelay:" in a:
x.delay=stp(a)
elif " Looter: true" in a:
x.st+="<font color=#790>Lot</font>,"
elif " Assist: true" in a:
x.st+="<font color=#0a0>Ass</font>,"
elif " Aggressive: true" in a:
x.st+="<font color=#f00>Agr</font>,"
elif " WalkMask:" in a:
x.walk=stp(a)
elif " Element:" in a:
tmp=stp(a)
tmp2=tmp.split(',')
try:
x.elem=int(tmp2[0])
x.elel=int(tmp2[1])
except:
print("Invalid Element for mob %s: %s" % (x.id, tmp))
exit(1)
elif " Race:" in a:
try:
x.race=int(stp(a))
except:
print("Invalid Race for mob %s: %s" % (x.id, a))
exit(1)
elif 'Drops: ' in a:
dropper=True
elif dropper and '}' in a:
dropper=False
elif dropper:
x.drops.append(stp(a).split(": "))
# Write last entry
MobAlloc(x)
writeMob()
wikib.write('\n\n|Mode|Desc|\n|----|----|\n')
wikib.write('|Lot|Looter|\n')
wikib.write('|Ass|Assist|\n')
wikib.write('|Agr|Aggressive|\n')
src.close()
def stp(x):
return x.replace('\n', '').replace('|', '').replace('(int, defaults to ', '').replace(')', '').replace('basic experience', '').replace('"','').replace(" ","").replace("\t","").replace('(string', '').replace('Name: ','').replace('Element: ','').replace('Race: ','').replace('AttackDelay: ', '').replace('WalkMask: ','').replace('MoveSpeed: ', '').replace('AttackRange: ', '').replace('ViewRange: ','').replace('Attack: ','').replace('ViewRange: ','').replace('Hp: ','').replace('Id: ','').replace('Lv: ','').replace('view range','').replace('attack range','').replace('move speed','').replace('health','').replace('(int','').replace('attack delay','atk.').replace('(','').replace(')','').replace('WALK_','')
def MonsterWrite(tbl):
# TODO: Check _mobs files to determine the usual monster density (a misc info to aid adding proper drop specs)
wikib.write("<table border=1>\n")
wikib.write("<tr><th>ID</th><th>Name</th><th>Mob Info</th><th>Elegen</th><th>Misc Info</th><th>Rewards</th><th>Drops</th></tr>\n")
for i in sorted(tbl, key=lambda tbl: int(tbl.mobpt)):
if i.id == 'ID':
continue
wikib.write('<tr><td><a name="' + i.id + '"></a>' +
i.id +"</td><td>"+
i.name +"</td><td>"+
mb_core(i) +"</td><td>"+
mb_eleg(i) +"</td><td>"+
mbdt('misc', mb_rdmisc(i)) +"</td><td>"+
mbdt('Exp\'s', mb_rdrw(i)) +"</td><td>"+
mbdt('drops', mb_rddrop(i)) +"</td></tr>\n"
)
wikib.write("</table>\n")
wikib.write("\n<a href=#x>(↑) Return to top</a><br/><br/>\n\n")
def writeMob():
wikib.write("Total monsters: %d<br/>" % totalid)
wikib.write("<ul>\
<li><a href=#0>Neutral</a></li>\n\
<li><a href=#1>Water</a></li>\n\
<li><a href=#2>Earth</a></li>\n\
<li><a href=#3>Fire</a></li>\n\
<li><a href=#4>Wind</a></li>\n\
<li><a href=#5>Nature (Poison)</a></li>\n\
<li><a href=#6>Holy</a></li>\n\
<li><a href=#7>Dark (Shadow)</a></li>\n\
<li><a href=#8>Ghost</a></li>\n\
<li><a href=#9>Undead</a></li>\n\
<li><a href=#Nan>-</a></li>\n\
<li><a href=Elements><font color=#f00>Elemental Reference</font></a></li>\n\
</ul> ")
wikib.write("<h1 id=0>Neutral</h1>\n\n")
wikib.write("<i>Total: %d Monsters</i><br/>\n\n" % len(Mobs0))
MonsterWrite(Mobs0)
wikib.write("<h1 id=1>Water</h1>\n\n")
wikib.write("<i>Total: %d Monsters</i><br/>\n\n" % len(Mobs1))
MonsterWrite(Mobs1)
wikib.write("<h1 id=2>Earth</h1>\n\n")
wikib.write("<i>Total: %d Monsters</i><br/>\n\n" % len(Mobs2))
MonsterWrite(Mobs2)
wikib.write("<h1 id=3>Fire</h1>\n\n")
wikib.write("<i>Total: %d Monsters</i><br/>\n\n" % len(Mobs3))
MonsterWrite(Mobs3)
wikib.write("<h1 id=4>Wind</h1>\n\n")
wikib.write("<i>Total: %d Monsters</i><br/>\n\n" % len(Mobs4))
MonsterWrite(Mobs4)
wikib.write("<h1 id=5>Nature</h1>\n\n")
wikib.write("<i>Total: %d Monsters</i><br/>\n\n" % len(Mobs5))
MonsterWrite(Mobs5)
wikib.write("<h1 id=6>Holy</h1>\n\n")
wikib.write("<i>Total: %d Monsters</i><br/>\n\n" % len(Mobs6))
MonsterWrite(Mobs6)
wikib.write("<h1 id=7>Dark</h1>\n\n")
wikib.write("<i>Total: %d Monsters</i><br/>\n\n" % len(Mobs7))
MonsterWrite(Mobs7)
wikib.write("<h1 id=8>Ghost</h1>\n\n")
wikib.write("<i>Total: %d Monsters</i><br/>\n\n" % len(Mobs8))
MonsterWrite(Mobs8)
wikib.write("<h1 id=9>Undead</h1>\n\n")
wikib.write("<i>Total: %d Monsters</i><br/>\n\n" % len(Mobs9))
MonsterWrite(Mobs9)
wikib.write("<h1 id=NaN>Error</h1>\n\n")
wikib.write("<i>Total: %d Monsters</i><br/>\n\n" % len(MobsA))
MonsterWrite(MobsA)
def mbdt(summary, content):
return "<pre>%s</pre>" % (content)
return "<details>\
<summary>"+summary+"</summary>\
<pre>"+content+"</pre></details>"
def mb_core(mb):
buff=""
buff+="Lvl: %s<br/>\n" % (mb.mobpt)
buff+="HP: <b><font color=#0a0>%s</font></b><br/>\n" % (mb.hp)
buff+="ATK: <b><font color=#a00>%s</font></b><br/>\n" % (mb.atk)
if mb.st != "":
buff+="Modes: <i>%s</i>" % (mb.st)
return buff
def mb_eleg(mb):
buff=""
buff+="Race: %s<br/>\n" % (WhatRace(mb))
buff+="Walk: %s<br/>\n" % (fwalk(mb.walk))
buff+="Element: %s<br/>\n" % (WhatElem(mb))
return buff
def mb_rdmisc(mb):
buff=""
if "agr" in mb.st.lower():
buff+="View Range: %s\n" % (mb.view)
buff+="Attack Range: %s\n" % (mb.range)
buff+="AtkDelay: %s ms\n" % (mb.delay)
buff+="Move speed: %s ms\n" % (mb.move)
buff+="Element Level: %d\n" % (mb.elel)
return buff
def mb_rdrw(mb):
buff=""
try:
buff+="MobPoints: %d\n" % (int(mb.mobpt)*11/10)
except:
pass
buff+="%s\n" % (mb.xp)
buff+="%s\n" % (mb.jp)
return buff
def mb_rddrop(mb):
buff=""
for ax in mb.drops:
# Ignore disabled drops
if ax[0].startswith("//"):
continue
# Write drop
try:
buff+=ax[0]+': ' + str(int(ax[1])/100.0) + ' %\n'
except IndexError:
print("Fatal: invalid %s mob with %s drops" % (mb.name, str(ax)))
exit(1)
except:
print("[Warning] %s incorrect drop: %s" % (mb.name, str(ax)))
buff+=ax[0]+': ' + ax[1] + ' ppm\n'
# Save to SysDrops
SysDrops.append([ax[0], ax[1], mb.name])
return buff
showHeader()
testMobs()
print("Total monsters: %d" % totalid)
wikib.write('</body></html>')
wikib.close()
#print(str(SysDrops))
showFooter()
exit(0)