summaryrefslogblamecommitdiff
path: root/wiki/wikigen.py
blob: d5c139db6f019cdb81a304d5c222e3a2c907ffba (plain) (tree)
1
2
3
4
5
6
7
8
9



                                      
                           
                             
                   

               
          


                              

                                                                          
 









                                                    

                                                     



                                            
                                                                                                  
                                                                                              
                                                                   
                                                  
                                             
 




        
        
        
 
           
 







                                                                                             
                                                                            







                                                                               
 
 


 






                                                                                       
                   
                   














                                           
                 














                          

                        
                      
                        

                                                                                        

               
                                     




                                                            
                                       

                 
                                
 

                      




                           
 
                          
                       
                            
                         
                          
                       
                          
                          
                           
                       
                            
                       
                              
                        
                                   
                          
                                 
                         
                                 
                         
                                   
                          

                                 
                                   
                        
                                   
                        
                                       
                        

                                        




                                  
                                              
                      


               








                                                 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

 
                      
                                                                                                                  
                                     
                                                                                                                                                         
                 

                                                   

                                      
                                                           
                                      




                                            




                                                               
                                                                 
 

                  




                                 
                             
                                  

      

                                 
 

                                    
 








                                      


                                

                                      
 







                                 

                                            





                                           
                                        





                          

                                                                            












                                                                             



                                                
               





























                                          



                               





                     






                                                                                           














                             
                                                      




                                                                       
 
















                                               

                                       

                                       

                                            

                                                         
             
                                                                          

                
                                      



                                                             







                      
                          
                       
                                 
                          
                            
                          
                            
                          
                              
                           
                            
                         
                           
                        
                           
                        
                            
                         
                             
                          
                           
                         
                               
                        



                                  













                                       
                          
                            
                          










                            
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
 
            
                                                                                                                                                                             
 








                                    
                      


                                


                                          



                            
                              


                          
      
                                                

                                               



                                              

                   
                                       
                                                                                                   


                                    
                                                                                               


                                     
                                                                                            


                            
                                                                             


                             
                                                                               


                                
                                                                     
 



                                                                                 
                                                                        



                                  
                                                                                                                  
 

                                  
                                                                                                                
 













                                                                        
 


                                   

                 
                  
             
                   
                                                          
                    
                                                          
                   
                                                          
                    
                                                          
               
 


                                                    
                                                                                                                                                                           











                                      

                                   










                                     

                                      

                                    






                           
                                                                       
                 
                                              





                                                   

                                                    










                                                    

                                                 
                                                                                       






                                                       
                                                                                            




                                                                                  


                                                                           





                                                      

                                
                                                                                                             
 






























                                                                                                 
                 
                                                                                                                                                       
 
              
                                       



                                                     






                   
                                           





                                      

                          















                                                        
                           
                            
                            


























                                                                                                   
                     
                                                                                                                                                    
                                



                                                                                     
                                                                                                                            



                                                           
 


                       
             

                                                          



                                                        





                                                                
                                  

                         
                                                    
                                                                  
                                  
                     
 
                  
                       
                       
                                                    
                          






                                                              
                                                                        



                                                     


                                      
                                                                                                    

                 


                                                   
                      



                                    
 
            
 
          
           
         


             
             
             
                     
 
            
       
#! /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
import sys

wikia=open("Items.md", "w")
wikib=open("Monsters.md", "w")
wikic=open("../../client-data/dyes.diff", "w") # Dye Report
wikid=open("../../server-data/changechase.diff", "w") # ChangeChase Report

# the TYPEs we use to determine where to pack things
IT_HEALING=[]
IT_ETC=[]
IT_USABLE=[]
IT_AMMO=[]
IT_CARD=[]
IT_PETEGG=[]
IT_WEAPON={ 'HAND_2': [],           # TWO HAND (LR)
            'HAND_1':[]}            # WEAPONS (R)
IT_ARMOR={  'MISC': [],             # FOR FAILURE
            'EQP_ACC_L': [],        # ACCESSORY LEFT
            'EQP_ACC_R': [],        # ACCESSORT RIGHT
            'EQP_HEAD_MID': [],     # CHEST
            'EQP_SHOES': [],        # FEET
            'EQP_GARMENT': [],      # GLOVES
            'EQP_HEAD_LOW':[],      # PANTS
            '1024': [],             # NECKLACES (should be EQP_COSTUME_HEAD_TOP instead of number)
            '2048': [],             # RINGS (should be EQP_COSTUME_HEAD_MID instead of number)
            'EQP_MOUNT':[],         # MOUNTS (ie. EQP_SHADOW_SHOES)
            'EQP_HEAD_TOP':[],      # HATS/HELMETS
            'EQP_HAND_L': []}       # SHIELDS

Mobs1=[]
Mobs2=[]
Mobs3=[]
Mobs4=[]
Mobs5=[]
Mobs6=[]
MobsA=[]

SysDrops=[]


def printSeparator():
    print("--------------------------------------------------------------------------------")

def showHeader():
    print("TMW2 Wiki Generator")
    ##print "Evol client data validator."
    print("Run at: " + datetime.datetime.now().isoformat())
    print("Usage: ./wikigen.py [<path_to_serverdata> <path_to_clientdata>]")
    ##print "https://gitlab.com/evol/evol-tools/blob/master/testxml/testxml.py"
    printSeparator()

def showFooter():
    #pass
    #printSeparator()
    print("Done.")






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.chch=False
    self.boss=False

    # 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=[]

def MobAlloc(ab):
    try:
        maab=int(ab.mobpt)
    except:
        maab=9901

    if maab <= 20:
        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)
    elif maab != 9901:
        MobsA.append(ab)
    else:
        print("WARNING, Disregarding \"%s\" (ID: %s) as invalid mob" % (ab.name, ab.id))

def testMobs():
    print("\nGenerating Mob Wiki...")
    if len(sys.argv) >= 2:
        src=open(sys.argv[1]+"/db/re/mob_db.conf", "r")
    else:
        src=open("../../server-data/db/re/mob_db.conf", "r")

    wikib.write("# Monster Database\n")
    start=False
    dropper=False
    x=Mob() # Only for pyflakes2

    for a in src:
        if a == "{\n":
            if start:
                MobAlloc(x)
            else:
                start=True
            x=Mob()

        if "	Id:" in a:
            x.id=stp(a)
        elif "	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 "	Boss: true" in a:
            x.boss=True
        elif "	Looter: true" in a:
            x.st+="Lot,"
        elif "	Assist: true" in a:
            x.st+="Ass,"
        elif "	Aggressive: true" in a:
            x.st+="Agr,"
        elif "	ChangeChase: true" in a:
            x.chch=True
        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('AttackDelay: ', '').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.')


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>HP</th><th>Atk</th><th>Delay</th><th>Modes</th><th>Misc Info</th><th>Rewards</th><th>Drops</th></tr>\n")
    for i in tbl:
        if not i.chch:
            wikid.write("%s:%s\n" % (i.id, i.name))
        if i.boss:
            i.name="<b>"+i.name+"</b>"
        wikib.write('<tr><td><a name="' + i.id + '"></a>' +
                    i.id +"</td><td>"+
                    i.name +"</td><td>HP: "+
                    i.hp +"</td><td>Atk: "+
                    i.atk +"</td><td>"+
                    i.delay +" ms</td><td>"+
                    i.st +"</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[(↑) Return to top](#monster-database)\n\n")

def writeMob():
    wikib.write("\
+ [Level 0-20](#starter)\n\
+ [Level 21-40](#apprentice)\n\
+ [Level 41-60](#intermediary)\n\
+ [Level 61-80](#advanced)\n\
+ [Level 81-100](#expert)\n\
+ [Level 101-150](#master)\n\
+ [Level 100+](#out-of-scope)\n\n\
    ")

    wikib.write("## Starter\n\n")
    MonsterWrite(Mobs1)

    wikib.write("## Apprentice\n\n")
    MonsterWrite(Mobs2)

    wikib.write("## Intermediary\n\n")
    MonsterWrite(Mobs3)

    wikib.write("## Advanced\n\n")
    MonsterWrite(Mobs4)

    wikib.write("## Expert\n\n")
    MonsterWrite(Mobs5)

    wikib.write("## Master\n\n")
    MonsterWrite(Mobs6)

    wikib.write("## Out Of Scope\n\n")
    MonsterWrite(MobsA)


def mbdt(summary, content):
    return "<details>\
<summary>"+summary+"</summary>\
<pre>"+content+"</pre></details>"

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+="Move speed: %s ms\n" % (mb.move)
    return buff

def mb_rdrw(mb):
    buff=""
    buff+="MobPoints: %s\n" % (mb.mobpt)
    buff+="%s\n" % (mb.xp)
    buff+="%s\n" % (mb.jp)
    return buff

def mb_rddrop(mb):
    buff=""
    # sorted
    for ax in sorted(mb.drops, key=lambda xcv: float(xcv[1]), reverse=True):
        # 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


class It:
  def __init__(self):
    # Basic
    self.id="0"
    self.aegis="UnknownItem"
    self.name="Unknown Item Name"
    self.price="0" # Sell price, of course
    self.weight="0"
    self.type="IT_ETC" # default type
    self.loc=""

    # Offensive/Defensive
    self.atk="0"
    self.matk="0"
    self.range="0"
    self.defs="0"

    # Restrictions (EquipLv)
    self.lvl="0"
    self.drop=True
    self.trade=True
    self.sell=True
    self.store=True

    # Special settings
    self.rare=False         # DropAnnounce
    self.script=False

    # Visual
    self.sl="0" # Slots
    self.ac=False # Allow Cards

    # Script settings
    self.minheal="0"
    self.maxheal="0"
    self.delheal="0"

def ItAlloc(it):
    if (it.sl == "0" and it.ac) or (it.sl in ["1","2","3","4"] and not it.ac):
        print("WARNING, item id "+it.id+" invalid dye/card setting!")
    if (len(it.sl) > 1):
        print("WARNING, item id "+it.id+" bad slots length: %d (%s)" % (len(it.sl), it.sl))
    if it.ac:
        wikic.write(it.id + ": " + it.name + "\n")

    a=it.type
    if "IT_HEALING" in a:
        IT_HEALING.append(it)
    elif "IT_ETC" in a:
        IT_ETC.append(it)
    elif "IT_USABLE" in a:
        IT_USABLE.append(it)
    elif "IT_AMMO" in a:
        IT_AMMO.append(it)
    elif "IT_CARD" in a:
        IT_CARD.append(it)
    elif "IT_PETEGG" in a:
        IT_PETEGG.append(it)

    elif "IT_WEAPON" in a:
        if "HAND_L" in it.loc or "EQP_ARMS" in it.loc:
            IT_WEAPON["HAND_2"].append(it)
        elif "HAND_R" in it.loc:
            IT_WEAPON["HAND_1"].append(it)
        else:
            raise Exception("Invalid location for weapon: %s" % it.loc)

    elif "IT_ARMOR" in a:
        if 'EQP_ACC_L' in it.loc:
            IT_ARMOR['EQP_ACC_L'].append(it)
        elif 'EQP_ACC_R' in it.loc:
            IT_ARMOR['EQP_ACC_R'].append(it)
        elif 'EQP_HEAD_MID' in it.loc:
            IT_ARMOR['EQP_HEAD_MID'].append(it)
        elif 'EQP_SHOES' in it.loc:
            IT_ARMOR['EQP_SHOES'].append(it)
        elif 'EQP_GARMENT' in it.loc:
            IT_ARMOR['EQP_GARMENT'].append(it)
        elif 'EQP_HEAD_LOW' in it.loc:
            IT_ARMOR['EQP_HEAD_LOW'].append(it)
        elif 'EQP_HEAD_TOP' in it.loc:
            IT_ARMOR['EQP_HEAD_TOP'].append(it)
        elif 'EQP_HAND_L' in it.loc:
            IT_ARMOR['EQP_HAND_L'].append(it)
        elif '1024' in it.loc:
            IT_ARMOR['1024'].append(it)
        elif '2048' in it.loc:
            IT_ARMOR['2048'].append(it)
        elif 'EQP_SHADOW_SHOES' in it.loc:
            IT_ARMOR['EQP_MOUNT'].append(it)
        elif 'EQP_SHADOW_ACC_R' in it.loc:
            IT_ARMOR['EQP_ACC_R'].append(it) # Not really
        else:
            raise Exception("Invalid Loc for ID %s: %s" % (it.id, it.loc))

def newItemDB():
    print("\nGenerating Item Wiki...")
    if len(sys.argv) >= 2:
        src=open(sys.argv[1]+"/db/re/item_db.conf", "r")
    else:
        src=open("../../server-data/db/re/item_db.conf", "r")

    x=It()
    for a in src:
        if a == "{\n":
            ItAlloc(x)
            x=It()

        # sti() block
        if "	Id:" in a:
            x.id=sti(a)
        elif "	AegisName:" in a:
            x.aegis=sti(a)
        elif "	Name:" in a:
            x.name=stin(a)
        elif "	Sell:" in a:
            x.price=sti(a)
        elif "	Weight:" in a:
            x.weight=sti(a)
        elif "	Type:" in a:
            x.type=sti(a)
        elif "	Loc:" in a:
            x.loc=sti(a)
        elif "	Atk:" in a:
            x.atk=sti(a)
        elif "	Matk:" in a:
            x.matk=sti(a)
        elif "	Range:" in a:
            x.range=sti(a)
        elif "	Def:" in a:
            x.defs=sti(a)
        elif "	EquipLv:" in a:
            x.lvl=sti(a)
        elif "	Slots:" in a:
            x.sl=sti(a)
        elif "	AllowCards:" in a:
            x.ac=True
        # Write booleans
        elif "DropAnnounce: true" in a:
            x.rare=True
        elif "nodrop: true" in a:
            x.drop=False
        elif "notrade: true" in a:
            x.trade=False
        elif "noselltonpc: true" in a:
            x.sell=False
        elif "nostorage: true" in a:
            x.store=False
        elif "Script" in a:
            x.script=True
        # For healing items
        elif "@min " in a:
            x.minheal=sti(a)
        elif "@max " in a:
            x.maxheal=sti(a)
        elif "@delay" in a:
            x.delheal=sti(a)

    # Write last entry
    ItAlloc(x)
    writeItems()

    src.close()

def sti(x):
    return x.replace('\n', '').replace('|', '').replace(')', '').replace('Id: ', '').replace('"','').replace("    ","").replace("\t","").replace('AegisName: ', '').replace('Name: ','').replace('Sell: ', '').replace('Weight: ', '').replace('Type: ', '').replace('Loc: ', '').replace('Atk: ', '').replace('Matk: ', '').replace('Range: ', '').replace('Def: ', '').replace('EquipLv: ', '').replace('Slots: ','').replace(" ", "").replace('@min=','').replace('@max=','').replace('@delay=','').replace(';','')

def stin(x):
    return x.replace('\n', '').replace('|', '').replace(')', '').replace('Id: ', '').replace('"','').replace("    ","").replace("\t","").replace('Name: ','').replace(';','')


def writeItems():
    wikia.write("# Items\n\
+ [Healing Items](#healing-items)\n\
+ [Usable Items](#usable-items)\n\
+ [Generic Items](#generic-items)\n\
+ [Ammo](#ammo)\n\
+ [Cards](#cards)\n\
+ [Pet Eggs](#pet-eggs)\n\
+ [Mounts](#mounts)\n\
+ [Weapons](#weapons)\n\
  + [1H Weapons](#1h-weapons)\n\
  + [2H Weapons](#2h-weapons)\n\
+ [Armors](#armors)\n\
  + [Left Accessory](#left-accessory)\n\
  + [Right Accessory](#right-accessory)\n\
  + [Headgear](#headgear)\n\
  + [Chest](#chest)\n\
  + [Pants](#pants)\n\
  + [Shoes](#shoes)\n\
  + [Necklaces](#necklaces)\n\
  + [Rings](#rings)\n\
  + [Gloves](#gloves)\n\
  + [Shields](#shields)\n\
\n\n")
    wikia.write("#### Restrictions Reference\n")
    wikia.write("Special Aegis Name Markers:\n\
+ * - Rare item with drop announce.\n\
+ (dp) - This item cannot be dropped.\n\
+ (tr) - This item cannot de traded.\n\
+ (sl) - This item cannot be sold.\n\
+ (gg) - This item cannot go to storage.\n\n")

    # Healing Items
    wikia.write("## Healing Items\n\n")
    ItemWrite(IT_HEALING, ID=True, AEGIS=True, PRICE=True, WEIGHT=True, HEALING=True, DROPPER=True)

    # Usable Items
    wikia.write("## Usable Items\n")
    ItemWrite(IT_USABLE, ID=True, AEGIS=True, NAME=True, PRICE=True, WEIGHT=True, DROPPER=True)

    # Generic Items
    wikia.write("## Generic Items\n")
    ItemWrite(IT_ETC, ID=True, AEGIS=True, NAME=True, PRICE=True, WEIGHT=True, DROPPER=True)

    # Ammo Items
    wikia.write("## Ammo\n")
    ItemWrite(IT_AMMO, ID=True, AEGIS=True, NAME=True, WEIGHT=True, ATK=True)

    # Card Items
    wikia.write("## Cards\n")
    ItemWrite(IT_CARD, ID=True, AEGIS=True, NAME=True, PRICE=True, WEIGHT=True)

    # Pet Egg Items
    wikia.write("## Pet Eggs\n")
    ItemWrite(IT_PETEGG, ID=True, AEGIS=True, NAME=True, WEIGHT=True)

    # Mount Items
    wikia.write("## Mounts\n")
    ItemWrite(IT_ARMOR['EQP_MOUNT'], ID=True, AEGIS=True, NAME=True, WEIGHT=True)

    ####################################################################
    wikia.write("# Weapons\n")

    # 1 Hand Items
    wikia.write("## 1H Weapons\n")
    ItemWrite(IT_WEAPON['HAND_1'], ID=True, AEGIS=True, PRICE=True, WEIGHT=True, ATK=True, LVL=True, DROPPER=True)

    # 2 Hand Items
    wikia.write("## 2H Weapons\n")
    ItemWrite(IT_WEAPON['HAND_2'], ID=True, AEGIS=True, PRICE=True, WEIGHT=True, ATK=True, LVL=True, RANGE=True)


    ####################################################################
    wikia.write("# Armors\n")

    ArmorWrite("Left Accessory",'EQP_ACC_L')
    ArmorWrite("Right Accessory",'EQP_ACC_R')
    ArmorWrite("Headgear",'EQP_HEAD_TOP')
    ArmorWrite("Chest",'EQP_HEAD_MID')
    ArmorWrite("Pants",'EQP_HEAD_LOW')
    ArmorWrite("Shoes",'EQP_SHOES')
    ArmorWrite("Necklaces",'1024')
    ArmorWrite("Rings",'2048')
    ArmorWrite("Gloves",'EQP_GARMENT')
    ArmorWrite("Shields",'EQP_HAND_L')

# Write AegisName with restrictions
def hl(it):
    buff=""
    if it.rare:
        buff+="*"
    buff+=it.aegis
    buff+=" "
    if not it.drop:
        buff+="<a href='#restrictions-reference'>(dp)</a>"
    if not it.trade:
        buff+="<a href='#restrictions-reference'>(tr)</a>"
    if not it.sell:
        buff+="<a href='#restrictions-reference'>(sl)</a>"
    if not it.store:
        buff+="<a href='#restrictions-reference'>(gg)</a>"
    return buff

#    wikia.write("Id|Aegis|Name|Weight|Atk|Matk|\n")
#    wikia.write("Id|Aegis|Name|Price|Weight|\n")

def ItemWrite(tbl, ID=False, AEGIS=False, NAME=False, PRICE=False, WEIGHT=False, DEF=False, LVL=False, ATK=False, RANGE=False, HEALING=False, SCRIPT=False, DROPPER=False):
    wikia.write("<table border=1>\n")
    wikia.write("<tr>")
    if ID:
        wikia.write("<th>ID</th>")
    if AEGIS:
        wikia.write("<th>Aegis</th>")
    if NAME:
        wikia.write("<th>Name</th>")
    if PRICE:
        wikia.write("<th>Price</th>")
    if WEIGHT:
        wikia.write("<th>Weight</th>")
    if DEF:
        wikia.write("<th>Def</th>")
    if LVL:
        wikia.write("<th>Lvl</th>")
    if ATK:
        wikia.write("<th>Atk</th>")
        wikia.write("<th>Matk</th>")
    if RANGE:
        wikia.write("<th>Range</th>")
    if HEALING:
        wikia.write("<th>Min</th>")
        wikia.write("<th>Max</th>")
        wikia.write("<th>Delay</th>")
    if SCRIPT:
        wikia.write("<th>Script</th>")
    if DROPPER:
        wikia.write("<th>Mobs</th>")

    wikia.write("</tr>\n")

    for i in tbl:
        wikia.write('<tr>')

        if ID:
            wikia.write("<td><a name=\"%s\"></a>%s</td>" % (i.id,i.id))
        if AEGIS:
            wikia.write("<td>%s</td>" % hl(i))
        if NAME:
            wikia.write("<td>%s</td>" % i.name)
        if PRICE:
            wikia.write("<td>%s GP</td>" % i.price)
        if WEIGHT:
            wikia.write("<td>%s g</td>" % i.weight)
        if DEF:
            wikia.write("<td>Def: %s</td>" % i.defs)
        if LVL:
            wikia.write("<td>Lv: %s</td>" % i.lvl)
        if ATK:
            wikia.write("<td>Atk: %s</td>" % i.atk)
            wikia.write("<td>%s</td>" % i.matk)
        if RANGE:
            wikia.write("<td>%s</td>" % i.range)
        if HEALING:
            wikia.write("<td>%s</td>" % i.minheal)
            wikia.write("<td>%s</td>" % i.maxheal)
            wikia.write("<td>%s s</td>" % i.delheal)
        if SCRIPT:
            wikia.write("<td>%s</td>" % i.script)
        # TODO: Check for item Aegis in npc/ folder too, to determine shops and quests.
        if DROPPER:
            tmp_droppers=""
            tmp_drpalign=[]
            for ax in SysDrops:
                if ax[0] == i.aegis:
                    tmp_drpalign.append([ax[2], ax[1]])
            if len(tmp_drpalign) > 0:
                for a in sorted(tmp_drpalign,  key=lambda xcv: float(xcv[1]), reverse=True):
                    try:
                        ppm=int(a[1])/100.0
                        tmp_droppers+=("%s: %.2f %% \n" % (a[0], ppm))
                    except:
                        print("[Warning] %s whodrop error: %s" % (i.name, str(a)))
                wikia.write("<td>%s</td>" % mbdt("monsters", tmp_droppers))
            else:
                wikia.write("<td>-</td>")

        wikia.write("</tr>")

    wikia.write("</table>\n")
    wikia.write("\n[(↑) Return to top](#items)\n\n")

def ArmorWrite(name,scope):
    wikia.write("## "+name+"\n")
    ItemWrite(IT_ARMOR[scope], ID=True, AEGIS=True, PRICE=True, WEIGHT=True, DEF=True, LVL=True, SCRIPT=True)











class Quest:
  def __init__(self, ide):
    # Basic
    self.id=ide
    self.name="Unknown Quest Name"
    self.group="Unknown"
    self.ent=[]


class QuestEntry:
  def __init__(self):
    # Basic
    self.complete=False
    self.entry=[] # collection of <text>
    self.giver=""
    self.reward=""
    self.loc=""

def qnt(string):
    return string.replace(' ','').replace('"','').replace("'","").replace('<','').replace('>','')

def qnt2(string):
    return string.replace('##B','**').replace('##b','**').replace('##0','*').replace('##1','*').replace('##2','*').replace('##3','*').replace('##','*')

def DoQuest():
    print("\nGenerating Quest Wiki...")
    if len(sys.argv) >= 3:
        src=open(sys.argv[2]+"/quests.xml", "r")
    else:
        src=open("../../client-data/quests.xml", "r")

    qlog=[]
    q=Quest(-1)
    qe=QuestEntry()
    ig=False

    for e in src:
        # Handle Comments and Ignored lines
        if '<!--' in e and '-->' in e:
            continue
        elif '<!--' in e:
            ig=True
        elif '-->' in e:
            ig=False
        if '<effect' in e:
            continue

        if ig:
            continue

        # Handle Quest Headers
        if '</var' in e:
            qlog.append(q)
        elif '<var' in e:
            g=qnt(e)
            try:
                q=Quest(int(  g.replace('varid=','')  ))
            except:
                print("Invalid quest: %s" % g)
                exit(1)

        # Handle quest entries
        if '</quest>' in e:
            q.ent.append(qe)
        elif '<quest ' in e:
            qe=QuestEntry()
            l=e.split('"')
            rc=[False, ""]
            for arg in l:
                if not rc[0]:
                    if "name" in arg:
                        rc=[True, 'name']
                    elif "group" in arg:
                        rc=[True, 'group']
                    elif "complete" in arg:
                        rc=[True, arg.replace('=','').replace(' ','')]
                else:
                    if rc[1] == "name":
                        q.name=arg
                    elif rc[1] == "group":
                        q.group=arg
                    elif rc[1] == "complete":
                        qe.complete=True
                    elif rc[1] == "incomplete":
                        qe.complete=False
                    else:
                        print("Invalid <quest> tag: %s (arg was %s) (line was %s)" % (e, rc[1], l))
                        exit(1)
                    rc=[False, ""]

        # Fill stuff in Quest Entry
        if '<text' in e:
            a=qnt2(e)
            qe.entry.append(  a.replace('<text>','').replace('</text>','').replace('<text ','<').replace("@@1", "text").replace("@@", "").strip()  )
        elif '<questgiver' in e:
            a=qnt2(e)
            qe.giver=a.replace('<questgiver>','').replace('</questgiver>','').strip()
        elif '<reward' in e:
            a=qnt2(e)
            qe.reward=a.replace('<reward>','').replace('</reward>','').replace("@@", "text").replace('<reward ','<').strip()
        elif '<coord' in e:
            a=qnt2(e)
            b=a.split('>')
            qe.loc=b[1].replace('</coordinates','').strip()

    # Done reading file
    src.close()
    aktbl={}
    aksort=[]
    print("\033[32;1mTotal quests: %d\033[0m" % len(qlog))
    for i in qlog:
        if i.name=="Unknown Quest Name":
            print("Warning, invalid quest: %d" % (i.id))
            qlog.remove(i)
            continue
        # Total Table
        #print(str(i.id)+": "+i.name)
        try:
            aktbl[i.group].append("[%s](q/%d)" % (i.name, i.id))
        except:
            aktbl[i.group]=["[%s](q/%d)" % (i.name, i.id)]
            aksort.append(i.group)

        # Individual file
        f=open("../../wiki/q/"+str(i.id)+'.md', "w")
        f.write("<!-- --- title: %d: %s -->\n\n" % (i.id, i.name))
        f.write("# %s\n" % i.name)
        f.write('\n')

        totalcnt=0
        for a in i.ent:
            totalcnt+=1
            f.write('\n### %d Stage\n\n' % totalcnt)
            if a.complete:
                f.write('*This completes quest*\n\n')

            if a.giver != "" or a.reward != "" or a.loc != "":
                f.write('```\n')
                if a.giver != "":
                    f.write('Quest Giver: %s\n' % a.giver)
                if a.reward != "":
                    f.write('Reward: %s\n' % a.reward.replace('@@', ''))
                if a.loc != "":
                    f.write('Location: %s\n' % a.loc)
                f.write('```\n\n')

            for line in a.entry:
                f.write('%s\n' % line)

        f.write('\n\n****\nThis file is generated automatically. Editing it will have no effect.\n')
        f.close()

    # Write total table
    f=open("Quests.txt", "w")
    f.write("***Total quests: %d***\n" % len(qlog))
    for key in aksort:
        f.write('\n## %s\n\n' % key)
        for a in aktbl[key]:
            f.write('+ '+a+'\n')
    f.close()

showHeader()

testMobs()
newItemDB()
DoQuest()

wikia.close()
wikib.close()
wikic.close()
wikid.close()
#print(str(SysDrops))

showFooter()
exit(0)