#! /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 'MAGICAL':[], # MAGICAL WEAPONS 'HAND_2':[], # TWO HAND (LR) 'HAND_1':[]} # WEAPONS (R) def printSeparator(): print("--------------------------------------------------------------------------------") def showHeader(): print("TMW2 EleItems Generator") 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") printSeparator() print("Output is: EleItems.html") 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.08 elif 'EQP_GARMENT' in it.loc: IT_ARMOR['EQP_GARMENT'].append(it) it.fc=0.07 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.matk) > 0: IT_WEAPON["MAGICAL"].append(it) elif 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", encoding="utf-8") else: src=open("../../server-data/db/re/item_db.conf", "r", encoding="utf-8") lg=False x=It() for a2 in src: a=a2.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: 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) # Magic Items wikia.write("

Magical Weapons

\n") ItemWrite(IT_WEAPON['MAGICAL'], ID=True, AEGIS=True, PRICE=True, WEIGHT=True, ATK=True, MATK=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, MATK=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 MATK: wikia.write("") if ATK and MATK: wikia.write("") if ATK or MATK: if stgen: 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) bb=(lv**1.255)*2.5*i.fc hc=bb*350.0/810.0 # Hercules value: Capped at 350 # Magic penalty if ("bMatk," in i.script): hc=hc/2.0 # Precise rounding if (hc % 1 >= 0.5): hc+=1 wikia.write("" % int(hc)) if LVL: wikia.write("" % i.lvl) if ATK: wikia.write("" % i.atk) if MATK: wikia.write("" % i.matk) if ATK and MATK: try: tmpatmat=i.atk.replace("Atk: ", "") #print("`%s`+`%s`=?" % (tmpatmat, i.matk)) wikia.write("" % str(int(i.matk)+int(tmpatmat))) except: wikia.write("") if ATK or MATK: 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 if int(i.matk) <= 0 or int(at) > 0: 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 ## Magic Weapons adjustment if int(i.matk) > 0: fc+=0.0 ## Physical and Magic Weapons adjustment if int(i.matk) > 0 and int(at) > 0: fc=7.0+((100-lv)/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 recalculate noob weapon if lv <= 20: lat=hat=at wikia.write("" % (lat, hat, fc)) 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.DefLvlAtkMatk+Adj. Atk.RangeMinMaxDelayScriptMobs
%s%s%s%s GP%s gDef: %sAdj. Df: %dLv: %sAtk: %s%s%s?%d ~ %d (%.2f)%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() # Ending 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 bb=(i**1.255)*2.5 hc=bb*350.0/810.0 # Hercules value: Capped at 350 df=(100.0 - hc / (hc + 400.0) * 90.0) / 100.0 * 100 print("%d Level %d Defense (%.2f%% DMG)" % (i, hc, df) ); showFooter() exit(0)