From daf646220047c78ab29b79070db7874b7f798c1d Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Tue, 7 Apr 2020 11:59:22 -0300 Subject: Broken version of wikigen.py (DO NOT USE) which I used to build https://wiki.themanaworld.org/index.php/Monsters Initial version. Some code can still be scavanged, the rest must burn in :fire: --- wiki/wikigen.py | 884 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 884 insertions(+) create mode 100755 wiki/wikigen.py diff --git a/wiki/wikigen.py b/wiki/wikigen.py new file mode 100755 index 0000000..3d7f8e3 --- /dev/null +++ b/wiki/wikigen.py @@ -0,0 +1,884 @@ +#! /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 [ ]") + ##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="" + self.df="0" + self.mdf="0" + + # Offensive + self.atk="[0, 0]" + self.range="0" + self.move="0" + self.delay="0" + self.drops=[] + + # 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 <= 2000: + Mobs1.append(ab) + elif maab <= 4000: + Mobs2.append(ab) + elif maab <= 6000: + Mobs3.append(ab) + elif maab <= 8000: + Mobs4.append(ab) + elif maab <= 10000: + Mobs5.append(ab) + elif maab <= 15000: + 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() + a=a.replace('\t', ' ') + + 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 " Def:" in a: + x.df=stp(a) + elif " Mdef:" in a: + x.mdf=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 " 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 " Looter: true" in a: + x.st+="Looter," + elif " Assist: true" in a: + x.st+="Assist," + elif " Aggressive: true" in a: + x.st+="Aggro," + 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('Def: ','').replace('Mdef: ','').replace('Id: ','').replace('Lv: ','').replace('view range','').replace('attack range','').replace('move speed','').replace('health','').replace('(int','').replace('attack delay','atk.').replace('Str: ', '').replace('Dex: ', '').replace('Agi: ', '').replace('Vit: ', '').replace('Int: ', '').replace('Luk: ', '') + + +def MonsterWrite(tbl): + # TODO: Check _mobs files to determine the usual monster density (a misc info to aid adding proper drop specs) + for i in tbl: + if not i.chch: + wikid.write("%s:%s\n" % (i.id, i.name)) + + aegis2=i.name.replace(" ", "_") + + if i.boss: + i.name="'''"+i.name+"'''" + if i.st == "": + i.st="Normal" + + wikib.write('|-\n') + wikib.write('| align="center" | [[Image:%s.png]]\n' % (aegis2)) + wikib.write("""| height="82px;" | [[%s|%s]] '' (%s) ''
'' Level: %s - %s/%s/%s/%s/%s/%s '' - '' %s ''\n""" % (aegis2, i.name, i.id, i.mobpt, i.str, i.agi, i.vit, i.int, i.dex, i.luk, i.st)) + wikib.write("""| align="center" | %s\n| align="center" | %s / %s\n""" % (i.hp, i.df, i.mdf)) + try: + dps=str(int(i.atk)*1000/int(i.delay)) + except: + dps="over %s ms" % i.delay + wikib.write("""| align="center" | %s (%s)
''DPS %s''\n""" % (i.atk, i.range, dps)) + wikib.write("""| align="center" | %s (%s)\n""" % (i.xp, i.jp)) + wikib.write("""| ''
%s
''\n""" % (mb_rddrop(i))) + wikib.write("""|-\n""") + + wikib.write("""|-\n|}\n""") + +def writeMob(): + wikib.write("""{{Meta}}{{I18n}} +{{Category playerinfo}} +{{Status_green}} + +This is for '''THE MANA WORLD: REVOLT'''. If you're interested in the Legacy game, see instead: [[Legacy:Monsters]] + +The monsters are sorted roughly by their fighting strength, calculated solely by their level. For more information on the drops please see the [[Items]]. + +'''Key:''' HP is health points, DEF is defense, ATT is attack, EXP is the calculated base experience, JEXP is the job experience. The others are self-explanatory. Traits (such as aggressive) are written in ''italics''. + +{| border="1" cellspacing="0" cellpadding="5" class="responsive" align="center" +! style="background:#efdead;" | Image +! style="background:#efdead;" | Name (ID) +! style="background:#efdead;" | HP +! style="background:#efdead;" | DEF/MDEF +! style="background:#efdead;" | ATK
MIN/MAX (RANGE) +! style="background:#efdead;" | EXP/(JEXP) +! style="background:#efdead;" | Drops (Rate %) +""") + MonsterWrite(Mobs1) + +def mbdt(summary, content): + return "
\ +"+summary+"\ +
"+content+"
" + +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: + url=ax[0].replace(" ", "_") + ctr=str(int(ax[1])/100.0) + buff+="[[%s|%s]] (%s%%)
" % (url, ax[0], ctr) + #buff+=ax[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: + a=a.replace("\t", " ") + 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', False) + ArmorWrite("Right Accessory",'EQP_ACC_R', False) + ArmorWrite("Headgear",'EQP_HEAD_TOP') + ArmorWrite("Chest",'EQP_HEAD_MID') + ArmorWrite("Pants",'EQP_HEAD_LOW') + ArmorWrite("Shoes",'EQP_SHOES') + ArmorWrite("Necklaces",'1024', False) + ArmorWrite("Rings",'2048', False) + 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+="(dp)" + if not it.trade: + buff+="(tr)" + if not it.sell: + buff+="(sl)" + if not it.store: + buff+="(gg)" + 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=True, DEF=False, LVL=False, ATK=False, RANGE=False, HEALING=False, SCRIPT=False, DROPPER=False): + wikia.write("\n") + wikia.write("") + if ID: + wikia.write("") + if AEGIS: + wikia.write("") + if NAME: + wikia.write("") + if PRICE: + wikia.write("") + if WEIGHT: + wikia.write("") + if DEF: + wikia.write("") + if LVL: + wikia.write("") + if ATK: + wikia.write("") + wikia.write("") + if RANGE: + wikia.write("") + if HEALING: + wikia.write("") + wikia.write("") + wikia.write("") + if SCRIPT: + wikia.write("") + if DROPPER: + wikia.write("") + + wikia.write("\n") + + for i in tbl: + try: + zt=int(i.weight) + except: + tbl.remove(i) + + for i in sorted(tbl, key=lambda xcv: int(xcv.weight), reverse=True): + if ID: + wikia.write("" % (i.id,i.id)) + if AEGIS: + wikia.write("" % hl(i)) + if NAME: + wikia.write("" % i.name) + if PRICE: + wikia.write("" % i.price) + if WEIGHT: + wikia.write("" % i.weight) + if DEF: + wikia.write("" % i.defs) + if LVL: + wikia.write("" % i.lvl) + if ATK: + wikia.write("" % i.atk) + wikia.write("" % i.matk) + if RANGE: + wikia.write("" % i.range) + if HEALING: + wikia.write("" % i.minheal) + wikia.write("" % i.maxheal) + wikia.write("" % i.delheal) + if SCRIPT: + wikia.write("" % 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("" % mbdt("monsters", tmp_droppers)) + else: + wikia.write("") + + wikia.write("") + + wikia.write("
IDAegisNamePriceWeightDefLvlAtkMatkRangeMinMaxDelayScriptMobs
%s%s%s%s GP%s gDef: %sLv: %sAtk: %s%s%s%s%s%s s%s%s-
\n") + wikia.write("\n[(↑) Return to top](#items)\n\n") + +def ArmorWrite(name,scope,defitem=True): + wikia.write("## "+name+"\n") + ItemWrite(IT_ARMOR[scope], ID=True, AEGIS=True, PRICE=True, WEIGHT=True, DEF=defitem, LVL=True, DROPPER=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 + self.giver="" + self.reward="" + self.loc="" + +def qnt(string): + return string.replace(' ','').replace('"','').replace("'","").replace('<','').replace('>','').replace('nowiki=1', '').replace('nowiki', '') + +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 + nw=False + + for e in src: + # Handle Comments and Ignored lines + if '' in e: + continue + elif '' in e: + ig=False + if '' in e: + q.ent.append(qe) + elif ' tag: %s (arg was %s) (line was %s)" % (e, rc[1], l)) + exit(1) + rc=[False, ""] + + # Fill stuff in Quest Entry + if '','').replace('','').replace('','').replace('','').replace('','').replace('','').strip() + elif '','').replace('','').replace("@@", "text").replace('') + qe.loc=b[1].replace('','').replace('','').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("\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) -- cgit v1.2.3-60-g2f50