summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xwiki/redesign.py764
1 files changed, 764 insertions, 0 deletions
diff --git a/wiki/redesign.py b/wiki/redesign.py
new file mode 100755
index 0000000..a6e9b16
--- /dev/null
+++ b/wiki/redesign.py
@@ -0,0 +1,764 @@
+#! /usr/bin/env python3
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2010-2011 Evol Online
+# Copyright (C) 2018 TMW-2
+# Author: Andrei Karas (4144)
+# Author: Jesusalva
+#
+# The use of the data
+
+import datetime
+import sys
+
+stgen=False
+aeros=False
+bifs=False
+skipCI=False
+
+wikib=open("EleMonsters.html", "w")
+wikib.write('<html><head><meta charset=utf8 /><title>EleGen File</title></head><body>')
+
+
+def printSeparator():
+ print("--------------------------------------------------------------------------------")
+
+def showHeader():
+ global stgen, aeros, bifs, skipCI
+ print("TMW2 Ele Generator")
+ print("Run at: " + datetime.datetime.now().isoformat())
+ print("Usage: ./redesign.py [default|aeros|none|update|all] [<path_to_serverdata>]")
+ if len(sys.argv) >= 2:
+ if sys.argv[1] == "default":
+ stgen=True
+ aeros=False
+ bifs=False
+ skipCI=False
+ elif sys.argv[1] == "aeros":
+ stgen=False
+ aeros=True
+ bifs=False
+ skipCI=False
+ elif sys.argv[1] == "none":
+ stgen=False
+ aeros=False
+ bifs=False
+ skipCI=False
+ elif sys.argv[1] == "update":
+ stgen=True
+ aeros=False
+ bifs=False
+ skipCI=True
+ elif sys.argv[1] == "all":
+ stgen=True
+ aeros=True
+ bifs=True
+ skipCI=False
+ else:
+ exit(1)
+ print("This stuff analyzes and sorts monsters and then create base stats for Moubootaur Legends.")
+ print("Drops aren't calculated or taken in account, TWEAK AS NEEDED")
+ printSeparator()
+ print("Output is: EleMonsters.html")
+
+def showFooter():
+ #pass
+ #printSeparator()
+ print("Done.")
+
+
+
+Mobs1=[]
+Mobs2=[]
+Mobs3=[]
+Mobs4=[]
+Mobs5=[]
+Mobs6=[]
+MobsA=[]
+
+# [N, W, E, F, W, -, H, H, G, -]
+Ele=[0, 0, 0, 0, 0, 0, 0, 0, 0]
+
+# This is for Aeros
+Plants=[]
+Level50=[]
+Level100=[]
+Aggressive=[]
+Assistant=[]
+Looter=[]
+Boss=[]
+
+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 "-"
+ 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="Nature","#7A0"
+ elif rc == 3:
+ tl,cl="Fire","#F00"
+ elif rc == 4:
+ tl,cl="Error(W)","#093"
+ elif rc == 5:
+ tl,cl="Error(P)","#040"
+ elif rc == 6:
+ tl,cl="Holy","#afa"
+ elif rc == 7:
+ tl,cl="Dark","#908"
+ elif rc == 8:
+ tl,cl="Error(G)","#404"
+ elif rc == 9:
+ tl,cl="Error(U)","#440"
+ else:
+ print("ERROR, INVALID ELEM ID: %d (ID: %s)" % (rc, rac.id))
+ exit(1)
+ Ele[rc]+=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"
+ self.boss=False
+ self.plant=False
+
+ # Defensive
+ self.mobpt="0" # Mob Points “Level”
+ self.hp="0"
+ self.xp="Exp: 0"
+ self.jp="JExp: 0"
+ self.st=""
+ self.dfn=0
+ self.mdf=0
+
+ # Offensive
+ self.atk="[0, 0]"
+ self.range="1"
+ self.move="0"
+ self.delay="0"
+ self.drops=[]
+
+ # New
+ self.race=-1
+ self.elem=-1
+ self.elel=-1
+ self.walk="NORMAL"
+
+ # Stats
+ self.str='0'
+ self.agi='0'
+ self.vit='0'
+ self.int='0'
+ self.dex='0'
+ self.luk='0'
+
+def MobAlloc(ab):
+ try:
+ maab=int(ab.mobpt)
+ except:
+ maab=9901
+
+ if maab <= 20 or skipCI:
+ Mobs1.append(ab)
+ elif maab <= 40:
+ Mobs2.append(ab)
+ elif maab <= 60:
+ Mobs3.append(ab)
+ elif maab <= 80:
+ Mobs4.append(ab)
+ elif maab <= 100:
+ Mobs5.append(ab)
+ elif maab <= 150:
+ Mobs6.append(ab)
+ else:
+ MobsA.append(ab)
+
+ # Aeros allocation
+ """Plants=[]
+ Level50=[]
+ Level100=[]
+ Aggressive=[]
+ Assistant=[]
+ Looter=[]
+ Boss=[]"""
+ normie=True
+ if ab.plant:
+ Plants.append(ab.id)
+ normie=False
+ if ab.boss:
+ Boss.append(ab.id)
+ normie=False
+ if normie:
+ if "Agr" in ab.st:
+ Aggressive.append(ab.id)
+ normie=False
+ if "Lot" in ab.st:
+ Looter.append(ab.id)
+ normie=False
+ if "Ass" in ab.st:
+ Assistant.append(ab.id)
+ normie=False
+ if normie:
+ if maab <= 55:
+ Level50.append(ab.id)
+ else:
+ Level100.append(ab.id)
+
+def testMobs():
+ print("Generating Elem-Mob Wiki...")
+ if len(sys.argv) >= 3:
+ src=open(sys.argv[2]+"/db/pre-re/mob_db.conf", "r", encoding="utf-8")
+ else:
+ src=open("../../server-data/db/pre-re/mob_db.conf", "r", encoding="utf-8")
+
+ wikib.write("<h1 id=#x>EleGen Monster Database</h1>\n")
+ start=False
+ dropper=False
+ skip=0
+ x=Mob() # Only for pyflakes2
+
+ for a2 in src:
+ a=a2.replace(' ', '\t');
+ if a == "{\n":
+ if skip:
+ skip=0
+ if start:
+ MobAlloc(x)
+ else:
+ start=True
+ x=Mob()
+
+ if skip:
+ start=False
+ x=Mob()
+ continue
+ if " Id:" in a:
+ x.id=stp(a)
+ 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 " Def:" in a:
+ x.dfn=stp(a)
+ elif " Mdef:" in a:
+ x.mdf=stp(a)
+
+ elif " Str:" in a:
+ x.str=stp(a)
+ elif " Agi:" in a:
+ x.agi=stp(a)
+ elif " Vit:" in a:
+ x.vit=stp(a)
+ elif " Int:" in a:
+ x.int=stp(a)
+ elif " Dex:" in a:
+ x.dex=stp(a)
+ elif " Luk:" in a:
+ x.luk=stp(a)
+
+
+ elif " Boss: true" in a:
+ x.boss=True
+ elif " Plant: true" in a:
+ x.plant=True
+ 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(": "))
+ elif "Plant: true" in a:
+ skip=1
+ # 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_','').replace('Def: ','').replace('Mdef: ','')
+
+
+def MonsterWrite(tbl):
+ global skipCI
+ # 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")
+ if stgen:
+ wikib.write("<tr><th>ID</th><th>Name</th><th>Mob Info</th><th>Stgen</th><th>Elegen</th><th>Misc Info</th><th>Rewards</th><th>Stats</th><th>Drops</th></tr>\n")
+ else:
+ wikib.write("<tr><th>ID</th><th>Name</th><th>Mob Info</th><th>Elegen</th><th>Misc Info</th><th>Rewards</th><th>Stats</th><th>Drops</th></tr>\n")
+
+ if not skipCI:
+ tbl=sorted(tbl, key=lambda tbl: int(tbl.mobpt))
+
+ for i in tbl:
+ if i.id == 'ID':
+ continue
+
+ # Special skips for REDESIGN
+ #if (int(i.id) < 1187):
+ # continue
+ if not bifs and ((int(i.hp) <= 50) or (i.race == 3)):
+ continue
+
+ if i.boss:
+ i.name="<b>"+i.name+"</b>"
+ if stgen:
+ wikib.write('<tr><td><a name="' + i.id + '"></a>' +
+ i.id +"</td><td>"+
+ i.name +"</td><td>"+
+ mb_core(i) +"</td><td>"+
+ mbdt('advise',mb_stgen(i)) +"</td><td>"+
+ mb_eleg(i) +"</td><td>"+
+ mbdt('misc', mb_rdmisc(i)) +"</td><td>"+
+ mbdt('Exp\'s', mb_rdrw(i)) +"</td><td>"+
+ mbdt('stats', mb_rdstat(i)) +"</td><td>"+
+ mbdt('drops', mb_rddrop(i)) +"</td></tr>\n"
+ )
+ else:
+ 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('stats', mb_rdstat(i)) +"</td><td>"+
+ mbdt('drops', mb_rddrop(i)) +"</td></tr>\n"
+ )
+ wikib.write("</table>\n")
+ wikib.write("<b>Total: %02d Monsters</b><br/>\n" % len(tbl))
+ wikib.write("\n<a href=#x>(↑) Return to top</a><br/><br/>\n\n")
+
+def writeMob():
+ wikib.write("<ul>\
+<li><a href=#0>Starter</a></li>\n\
+<li><a href=#1>Apprentice</a></li>\n\
+<li><a href=#2>Intermediary</a></li>\n\
+<li><a href=#3>Advanced</a></li>\n\
+<li><a href=#4>Expert</a></li>\n\
+<li><a href=#5>Master</a></li>\n\
+<li><a href=#Nan>OoS</a></li>\n\
+</ul> ")
+
+ wikib.write("<h1 id=0>Lv 0-20</h1>\n\n")
+ MonsterWrite(Mobs1)
+ wikib.write("<h1 id=1>Lv 21-40</h1>\n\n")
+ MonsterWrite(Mobs2)
+ wikib.write("<h1 id=2>Lv 41-60</h1>\n\n")
+ MonsterWrite(Mobs3)
+ wikib.write("<h1 id=3>Lv 61-80</h1>\n\n")
+ MonsterWrite(Mobs4)
+ wikib.write("<h1 id=4>Lv 81-100</h1>\n\n")
+ MonsterWrite(Mobs5)
+ wikib.write("<h1 id=5>Lv 101-150</h1>\n\n")
+ MonsterWrite(Mobs6)
+
+ wikib.write("<h1 id=NaN>Lv 101+</h1>\n\n")
+ MonsterWrite(MobsA)
+
+
+def mbdt(summary, content):
+ return "<b>"+summary+"</b><br/><pre>"+content+"</pre>"
+ 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)
+ buff+="DEF: <b><font color=#775>%s/%s</font></b><br/>\n" % (mb.dfn, mb.mdf)
+ if mb.st != "":
+ buff+="Modes: <i>%s</i>" % (mb.st)
+ return buff
+
+def mb_eleg(mb):
+ buff=""
+ buff+="Race: %s<br/>\n" % (WhatRace(mb))
+ if (mb.walk != "NORMAL"):
+ buff+="Walk: %s<br/>\n" % (fwalk(mb.walk))
+ buff+="Element: %s<br/>\n" % (WhatElem(mb))
+ return buff
+
+############################################################
+def mb_stgen(mb):
+ lv=int(mb.mobpt)
+ st=int(mb.str.replace(' ', '').replace('Str:',''))
+ #ag=int(mb.agi.replace(' ', '').replace('Agi:',''))
+ vi=int(mb.vit.replace(' ', '').replace('Vit:',''))
+ #it=int(mb.int.replace(' ', '').replace('Int:',''))
+ #dx=int(mb.dex.replace(' ', '').replace('Dex:',''))
+ #lk=int(mb.luk.replace(' ', '').replace('Luk:',''))
+
+ # Attack Range vs Attack Delay
+ ar=int(mb.range)
+ ad=int(mb.delay)
+ mv=int(mb.move)
+ magr=False
+ mass=False
+ if ('Agr' in mb.st):
+ magr=True
+ if ('Ass' in mb.st):
+ mass=True
+
+ if (not ar):
+ ar=1
+
+
+ # Over100 Special Formula
+ OVER100=0
+ if lv > 100:
+ OVER100=lv-100
+ lv=100+OVER100*0.25
+
+ # Fórmula da HPTable: 400+(x*50)
+ # MASTERED
+ lat=(lv*40+lv**1.2+lv*(st/100))
+ hat=(lv*40+lv**1.5+lv*(st/100))
+ if (ar > 1):
+ lat*=max(0.5, 1.0-((ar-1)/10.0))
+ hat*=max(0.5, 1.0-((ar-1)/10.0))
+
+ # Casos especiais
+ if mb.boss:
+ lat*=1.2
+ hat*=1.4
+ if "slime" in mb.name.lower():
+ lat*=0.3
+ hat*=0.3
+ # Attack is DPS. So we must adjust to be a damage per second
+ lat*=(ad/1872)
+ hat*=(ad/1872)
+ # Formula is not reliable
+ lat*=0.55
+ hat*=0.55
+ lat*=max(0.5, 1.0-(lv/10.0))
+ hat*=max(0.5, 1.0-(lv/10.0))
+ # Consider Aggressive and Assist mobs
+ if magr:
+ lat*=0.78
+ hat*=0.78
+ if mass:
+ lat*=0.89
+ hat*=0.89
+
+
+ # Over100 Special Formula
+ if OVER100:
+ lv=100+OVER100*2
+
+ # HP: Each 10 levels give you 100 extra weapon damage
+ # I expect from 6 to 14 hits to kill
+ # You deliver in average two hits per second
+ # Mobs deliver one hit each four seconds (and that's 1hand advantage)
+ lhp=lv*20*6+lv*(vi/100)
+ hhp=lv*20*14+lv*(vi/100)
+ if mb.boss:
+ lhp*=1.4
+ hhp*=1.8
+ if "slime" in mb.name.lower():
+ lhp*=0.6
+ hhp*=0.6
+ if ar > 1 and not OVER100:
+ lhp*=0.9
+ hhp*=0.9
+
+ # Experience is way too non-linear and I prefer to do it with reference formula
+ # like I was doing before
+ # But let's use a formula based on mobs-to-lvl-up where you must kill 1580 lv 60 mobs
+ # to raise from lv 60 (you can kill lv 50 mobs easier - but then I expect 3700 kills)
+ # mobs to kill to raise level
+
+ # This is the current mob-lvl-exp-table generated by this software
+ # As you see, it is somewhat similar to TMW Org.
+ # Remember aggressive, fast, and assistant mobs give even more exp
+
+
+ # Over100 Special Formula
+ if OVER100:
+ lv=100+OVER100
+
+ try:
+ calc_exp = max(1, int(math.floor(effective_hp * (math.sqrt(attack_factor) + math.sqrt(dodge_factor) + math.sqrt(persuit_factor) + 55)**3 * aggression_factor / 2000000)))
+ hxp=int(calc_exp*(1+lv/50.0))
+ lxp=int(calc_exp)
+ except:
+ hxp=1
+ lxp=1
+ print("Warning: Invalid exp for mob \033[1m%s\033[0m" % (mb.name.replace("<b>", "").replace("</b>", "")))
+
+
+ # Over100 Special Formula (kinda)
+ olv=0
+ if lv > 80:
+ olv=lv+0
+ lv=80+(lv-80)*0.25
+
+ # Defense follows the same player formula
+ dfn=((lv**1.255)*2.5)
+ dfn=dfn*350.0/810.0
+ mdf=max(0, lv-5)+(lv/10.0)
+ if not mb.boss:
+ mdf/=2
+ if ar > 3:
+ dfn/=2
+
+ # Nerf mobs def in 50% (to be more realistic to what we have)
+ dfn/=2
+
+ # Over100 Special Formula
+ if OVER100:
+ lv=100+OVER100
+ else:
+ lv=olv+0
+ del olv
+
+ # Force HP to be higher
+ # It'll only start applying from level 40 onwards
+ # It gives a bonus of 0.5% HP per mob level
+ # This means a level 100 mob got 60 times that stronger: 30%
+ if lv > 40:
+ lhp=lhp*(1.0+((lv-40)/210.0))
+ lhp=int(lhp)
+
+ # Norm
+ lhp=int(lhp)
+ hhp=int(hhp)
+ lat=int(lat)
+ hat=int(hat)
+ lxp=int(lxp)
+ hxp=int(hxp)
+ dfn=int(dfn)
+ mdf=int(mdf)
+
+ buff="<pre><font size=-2px>"
+ buff+="HP Range: %s ~ %s<br/>\n" % (lhp, hhp)
+ buff+="ATK Range: %s ~ %s<br/>\n" % (lat, hat)
+ buff+="Maximum XP: %s ~ %s<br/>\n" % (lxp, hxp)
+ buff+="DEF: %s / %s<br/>\n" % (dfn, mdf)
+ buff+="<b>Drop, Move, Elegen, aspd<br/>\n"
+ buff+="</b></font></pre>"
+ return buff
+
+def mb_rdstat(mb):
+ buff="<pre><font size=-4px>"
+ buff+="%s\n" % (mb.str)
+ buff+="%s\n" % (mb.agi)
+ buff+="%s\n" % (mb.vit)
+ buff+="%s\n" % (mb.int)
+ buff+="%s\n" % (mb.dex)
+ buff+="%s\n" % (mb.luk)
+ buff+="</font></pre>"
+ 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=""
+ buff+="<font color=#060><u>%s</b></u></font>\n" % (mb.xp.replace(' ', ' <b>'))
+ buff+="<font color=#006><u>%s</b></u></font>\n" % (mb.jp.replace(' ', ' <b>'))
+ try:
+ buff+="MobPoints: %d\n" % (int(mb.mobpt)*11/10)
+ except:
+ pass
+ 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()
+
+wikib.write('<br/><hr/>')
+wikib.write("Run at: " + datetime.datetime.now().isoformat())
+wikib.write('<hr/>')
+
+wikib.write('<hr/>')
+err=int(Ele[4])+int(Ele[8])+int(Ele[5])
+wikib.write("""
+<h3>Elemental Count</h3>
+<table border=1>
+<tr><td>%s</td><td>%02d</td></tr>
+<tr><td>%s</td><td>%02d</td></tr>
+<tr><td>%s</td><td>%02d</td></tr>
+<tr><td>%s</td><td>%02d</td></tr>
+<tr><td>%s</td><td>%02d</td></tr>
+<tr><td>%s</td><td>%02d</td></tr>
+<tr><td>%s</td><td>%02d</td></tr>
+</table>
+""" % (
+"Neutral", Ele[0],
+"Fire", Ele[3],
+"Water", Ele[1],
+"Nature", Ele[2],
+"Holy", Ele[6],
+"Dark", Ele[7],
+"Error", err))
+
+wikib.write('</body></html>')
+wikib.close()
+#print(str(SysDrops))
+
+# Aeros allocation
+if aeros:
+ print("// These arrays are filled automatically by redesign.py");
+ print("setarray .ML_Plants, "+
+ str(Plants).replace('[','').replace(']','').replace("'","")+";")
+ print("setarray .ML_Boss, "+
+ str(Boss).replace('[','').replace(']','').replace("'","")+";")
+ print("setarray .ML_Aggr, "+
+ str(Aggressive).replace('[','').replace(']','').replace("'","")+";")
+ print("setarray .ML_Asst, "+
+ str(Assistant).replace('[','').replace(']','').replace("'","")+";")
+ print("setarray .ML_Loot, "+
+ str(Looter).replace('[','').replace(']','').replace("'","")+";")
+ print("setarray .ML_Lv50, "+
+ str(Level50).replace('[','').replace(']','').replace("'","").replace('ID, ','')+
+ ";")
+ print("setarray .ML_Lv99, "+
+ str(Level100).replace('[','').replace(']','').replace("'","")+";")
+
+showFooter()
+exit(0)