#! /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 stgen=True wikia=open("EleItems.html", "w") # the TYPEs we use to determine where to pack things 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 IT_WEAPON={ 'RANGED': [], # RANGED WEAPONS 'HAND_2':[], # TWO HAND (LR) 'HAND_1':[]} # WEAPONS (R) def printSeparator(): print("--------------------------------------------------------------------------------") def showHeader(): print("TMW2 EleItems Generator") ##print "Evol client data validator." print("Run at: " + datetime.datetime.now().isoformat()) print("Usage: ./sedesign.py [info|level|none] []") print("SeDesign determines the reference defense for every item.") print("Tweak as needed. Bonuses/Rarity/etc not taken in account.") print("Running this without Redesign (or vice versa) will break balance") ##print "https://gitlab.com/evol/evol-tools/blob/master/testxml/testxml.py" printSeparator() def showFooter(): #pass #printSeparator() print("Done.") 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="" self.fc=0.0 # 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="" # Visual self.sl="0" # Slots self.ac=False # Allow Cards 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 and it.id != "ID(int"): print("WARNING, item id "+it.id+" bad slots length: %d (%s)" % (len(it.sl), it.sl)) a=it.type if "IT_ARMOR" in a: if 'EQP_ACC_L' in it.loc: IT_ARMOR['EQP_ACC_L'].append(it) it.fc=0.00 elif 'EQP_ACC_R' in it.loc: IT_ARMOR['EQP_ACC_R'].append(it) it.fc=0.00 elif 'EQP_HEAD_MID' in it.loc: IT_ARMOR['EQP_HEAD_MID'].append(it) if ("bSpeedAddRate, -" in it.script or "bSpeedAddRate,-" in it.script): it.fc=0.40 else: it.fc=0.30 elif 'EQP_SHOES' in it.loc: IT_ARMOR['EQP_SHOES'].append(it) it.fc=0.05 elif 'EQP_GARMENT' in it.loc: IT_ARMOR['EQP_GARMENT'].append(it) it.fc=0.05 elif 'EQP_HEAD_LOW' in it.loc: IT_ARMOR['EQP_HEAD_LOW'].append(it) it.fc=0.10 elif 'EQP_HEAD_TOP' in it.loc: IT_ARMOR['EQP_HEAD_TOP'].append(it) if ("bSpeedAddRate, -" in it.script or "bSpeedAddRate,-" in it.script): it.fc=0.15 else: it.fc=0.10 elif 'EQP_HAND_L' in it.loc: IT_ARMOR['EQP_HAND_L'].append(it) it.fc=0.25 elif '1024' in it.loc: IT_ARMOR['1024'].append(it) it.fc=0.00 elif '2048' in it.loc: IT_ARMOR['2048'].append(it) it.fc=0.00 elif 'EQP_SHADOW_SHOES' in it.loc: IT_ARMOR['EQP_MOUNT'].append(it) it.fc=0.00 elif 'EQP_SHADOW_ACC_R' in it.loc: IT_ARMOR['EQP_ACC_R'].append(it) # Not really it.fc=0.00 else: raise Exception("Invalid Loc for ID %s: %s" % (it.id, it.loc)) elif "IT_WEAPON" in a: if int(it.range) > 2: IT_WEAPON["RANGED"].append(it) elif "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) def newItemDB(): print("\nGenerating Item Wiki...") if len(sys.argv) >= 3: src=open(sys.argv[2]+"/db/re/item_db.conf", "r") else: src=open("../../server-data/db/re/item_db.conf", "r") lg=False 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: lg=True x.script+="
"
        elif lg and "\">" in a:
            lg=False
            x.script+="
" elif lg: if not "announce" in a and not "debugmes" in a and not "logmes" in a: x.script+=str(a.replace('\t', '').replace('getiteminfo(getequipid(', 'iteminfo((').replace('Flee2','Block')) # 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("

Armors

\n\ \n\n") wikia.write("Restrictions Reference
\n") wikia.write("
\n") #################################################################### 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') #for i in sorted(IT_ARMOR['EQP_HEAD_TOP'], key=lambda xcv: int(xcv.lvl)): # # Name | Level | Location | Specification # print("`%s`|%d| :grey_question: | " % (i.name, int(i.lvl))) #################################################################### 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) # 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) # Ranged Items wikia.write("

Ranged Weapons

\n") ItemWrite(IT_WEAPON['RANGED'], ID=True, AEGIS=True, PRICE=True, WEIGHT=True, ATK=True, LVL=True, RANGE=True) # 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=False, DEF=False, LVL=False, ATK=False, RANGE=False, HEALING=False, SCRIPT=False, DROPPER=False): global stgen 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 stgen: wikia.write("") if LVL: wikia.write("") if ATK: wikia.write("") if stgen: 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") try: if (sys.argv[1] in ["level", "info"]): sort=sorted(tbl, key=lambda xcv: int(xcv.lvl)) elif (sys.argv[1] == "none"): sort=tbl else: print("Syntax: ./sedesign.py [info|level|none]") sort=tbl if (sys.argv[1] == "info"): stgen=False except: sort=tbl for i in sort: wikia.write('') 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 stgen: lv=int(i.lvl) wikia.write("" % int((lv**1.255)*2.5*i.fc)) if LVL: wikia.write("" % i.lvl) if ATK: wikia.write("" % i.atk) if stgen: lv=int(i.lvl) at=int(i.atk) fc=7.5 ## Two hand swords are stronger if i in IT_WEAPON['HAND_2']: fc+=0.62 ## Calculate guns if int(i.id) == 6010 or int(i.id) == 6050: lv+=20 if int(i.id) == 6020: lv=0 if int(i.id) == 6040: fc/=2.5 ## Progression fc-=1.0 fc+=((100-lv)/100.0) ## Even slower progression (note bows doesn't gets the 0.8 2hand bonus) if not i in IT_WEAPON['RANGED']: fc-=(lv/15.0)/10.0 ## After level 50 weapons progression is slowed down if lv > 45: fc-=(lv-45)/90.0 ## This is because mob HP scaling is buggy if lv > 45 and not i in IT_WEAPON['RANGED']: fc-=(lv-45)/100.0 ## HAT is for craft or rare items. lat=lv*fc hat=lv*(fc+max(0.01, 1.0-(lv/100.0))) # Edge Cases ## Don't calculate magic weapons if int(i.matk) > 0: lat=hat=0 ## Don't recalculate noob weapon if lv <= 20: lat=hat=at wikia.write("" % (lat, hat, fc)) 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) if DROPPER: wikia.write("") wikia.write("") wikia.write("
IDAegisNamePriceWeightDefAdj.DefLvlAtkAdj. Atk.MatkRangeMinMaxDelayScriptMobs
%s%s%s%s GP%s gDef: %sAdj. Df: %dLv: %sAtk: %s%d ~ %d (%.2f)%s%s%s%s%s s%s-

\n") wikia.write("\n
(↑) Return to top

\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) showHeader() wikia.write("") wikia.write('SeDesign\n') wikia.write("") newItemDB() wikia.write('
') wikia.write(""" Reference Equipment
(?): Item not updated.
(*): Drop/rare item only
LevelWeaponShield HeadChestShortsBootsGloves
5 Knife, SmallKnifeNone - CreasedShirt CreasedShorts CreasedBoots CreasedGloves
10 SharpKnifeRoundLeatherShield CandorHeadBand CandorShirt CandorShorts CandorBoots, LousyMoccassins CandorGloves
15 MinerKnife, Dagger? Bandana, SerfHat, *AntlersHat CottonShirt, *TneckSweater CottonShorts, MiniSkirt CottonBoots, *Boots CottonGloves
20 WoodenSwordLeatherShield SerfHat, *FancyHat, *PinkieHat CottonShirt, SilkRobe FarmerPants, *PirateShorts TulimsharGuardBoots ?
25 BronzeGladius, BugSlayer, Scythe? *FluffyHat LeatherShirt JeansShorts ? MinerGloves
30 ShortGladiusWoodenShield MinerHat, *DarkEggshellHat ? ? SquirrelBoots Armbands
35 ButcherKnife, *IceGladius? *BrimmedHat, *MoubooHat ? ? ? ?
40 RealBronzeGladius, ShortSword, MiereCleaverBladeShield Bucket, BurglarMask, SailorHat, *ShroomHat DesertShirt CottonTrousers, *RaidTrousers FurBoots LeatherGloves
45 BackswordBraknarShield ChefHat, *YetiMask, *ForestShroomHat Chainmail *BanditPants ? ?
50 Broadsword, **ShortSword? *PinkHelmet ForestArmor ? ? CopperArmbands
60 *BlacksmithAxe, *Kanabo? FafiMask, *WickedShroomHat LightPlatemail ? ? ?
65 ?? *AlphaMoubooHat ? ChainmailSkirt ? ?
70 ?? *WarlordHelmet, *MoonshroomHat *WarlordPlate ? ? IronArmbands
80 ?? ? ? ? ? ?
90 ?? ? ? ? ? ?
100 ?? ? ? ? ? ?
110 ?? ? ? ? ? ?
120 ?? ? ? ? ? ?
130 ?? ? ? ? ? ?
140 ?? ? ? ? ? ?
150 ?? ? ? ? ? ?
""") wikia.write("
") wikia.write("Run at: " + datetime.datetime.now().isoformat()) wikia.write("") wikia.close() # Print for reference the landmarks i=0 while i < 100: i+=10 print("%d Level %d Defense" % (i, (i**1.255)*2.5) ); showFooter() exit(0)