summaryrefslogblamecommitdiff
path: root/evolved.py
blob: 256116cea863b786f48cd844140acf0d5542e8ae (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12











                                         































                                                                                                  
           





                                                                                             
                                         
                                                           
                                                                             




















                                                                                      
                 

                                      
                                 








                                                


                

               
             















                     






                    


                 


                                         





                                              
                  
                        
                    
                        
                    
                        
                    
                        
                    







                                                                                        

 
               








                                         






































                                                           

                               














                                   




                                    











                            











































                                                 





                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                


 
 
 
 
 
 

 







                                 

                 








                                     
                        
















                                          
                  

                

                                   



                                                                                           























































                                                                          
                            


                                                                        
                                 
 


 






                                                            
                   


















                                                      

                           
                            
                         






























                                       
                                             
                           





                                    






                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                     















                                                                                                                                                                             

























                                                                       
                                                                                                                                                                                                                                                                                             
                                                                                                                                        
                                                                                                   








                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        



                                                          

                                                            






































                                                                
















                    
           
          


           
             


            
#! /usr/bin/env python3
# -*- coding: utf8 -*-
#
# Copyright (C) 2010-2011  Evol Online
# Copyright (C) 2018-2021  TMW-2
# Copyright (C) 2022       The Mana World
# Author: Andrei Karas (4144)
# Author: Jesusalva

import datetime
import sys, traceback

aegis=open("../world/map/db/const-aegis.txt", "w")

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

AllItems={}


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

def showHeader():
    print("Evolved->Legacy DB Generator")
    print("Run at: " + datetime.datetime.now().isoformat())
    #print("Usage: ./evolved.py [<path_to_serverdata> <path_to_clientdata>]")
    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
    self.size="1"
    self.race="0" # TODO Convert RC_*
    self.elem="0" # TODO Convert Ele_*
    self.elLv="0" # Element Level
    self.mode="0" # TODO Convert MD_* and fields

    # General
    self.mobpt="0" # Mob Points “Level”
    self.hp="0"
    self.sp="0"
    self.xp="0"
    self.jp="0"

    # MvP
    self.mvp="0"

    # Defensive
    self.st=""
    self.md=0
    self.df="0"
    self.mdf="0"

    # Stats
    self.str="0"
    self.agi="0"
    self.int="0"
    self.vit="0"
    self.dex="0"
    self.luk="0"

    # Offensive
    self.atk="[0, 0]"
    self.range="0"
    self.chase="1"
    self.move="0"
    self.adelay="0"
    self.amotion="0"
    self.dmotion="0"

    # Misc
    self.mtcnt="0"
    self.mtstr="0"
    self.drops=[]

def MobAlloc(ab):
    if ab.name == "Unknown Monster Name":
        return

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

    aegis.write("%s %s\n" % (ab.aegis, ab.id))
    if maab <= 19:
        Mobs1.append(ab)
    elif maab <= 39:
        Mobs2.append(ab)
    elif maab <= 59:
        Mobs3.append(ab)
    elif maab <= 79:
        Mobs4.append(ab)
    elif maab <= 99:
        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():
    MD_CANMOVE =           1
    MD_LOOTER =            2
    MD_AGGRESSIVE =        4
    MD_ASSIST =            8
    MD_CASTSENSOR_IDLE =   16
    MD_BOSS =              32
    MD_PLANT =             64
    MD_CANATTACK =         128
    print("\nGenerating Mob Database...")
    if len(sys.argv) >= 2:
        src=open(sys.argv[1]+"/db/pre-re/mob_db.conf", "r")
    else:
        src=open("../world/map/db/mob_db.conf", "r")

    start=False
    dropper=False
    x=Mob() # Only for pyflakes2

    for a in src:
        # Evol2-only scripts
        if "@EVOL2" in a:
            continue
        if "@TMWA" in a:
            a=a.replace("//", "").replace("@TMWA", "")
        # Initiate the script
        if a == "{\n":
            if start:
                MobAlloc(x)
            else:
                start=True
            x=Mob()

        if "	Id:" in a:
            x.id=stp(a)
        elif "	SpriteName:" in a:
            x.aegis=stp(a)
        elif "	Name:" in a:
            x.name=stp(a)
        elif "	Hp:" in a:
            x.hp=stp(a)
        elif "	Sp:" in a:
            x.sp=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 "	MvpExp: " in a:
            x.mvp=stp(a)
        elif "	Def:" in a:
            x.df=stp(a)
        elif "	Mdef:" in a:
            x.mdf=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 "	ChaseRange:" in a:
            x.chase=stp(a)
        elif "	AttackDelay:" in a:
            x.adelay=stp(a)
        elif "	AttackMotion:" in a:
            x.amotion=stp(a)
        elif "	DamageMotion:" in a:
            x.dmotion=stp(a)
        elif "\tStr: " in a:
            x.str=stp(a)
        elif "\tAgi: " in a:
            x.agi=stp(a)
        elif "\tVit: " in a:
            x.vit=stp(a)
        elif "\tDex: " in a:
            x.dex=stp(a)
        elif "\tInt: " in a:
            x.int=stp(a)
        elif "\tLuk: " in a:
            x.luk=stp(a)
        elif "\tMutationCount: " in a:
            x.mtcnt=stp(a)
        elif "\tMutationStrength: " in a:
            x.mtstr=stp(a)
        elif "\tSize: " in a:
            x.size=stp(a)
        elif "\tRace: " in a:
            x.race=stp(a) # TODO: Conversion
        elif "\tElement: " in a:
            tmp=stp(a).split(",")
            #Element: (type, level)
            x.elem=tmp[0].replace("(","").strip()
            x.elLv=tmp[1].replace(")","").strip()
            try:
                if int(x.elem) in [4, 5]:
                    x.elem = "2"
                elif int(x.elem) in [8, 9, "10"]:
                    x.elem="7"
            except:
                traceback.print_exc()
        elif "\tCanMove: true" in a:
            x.md = x.md | MD_CANMOVE
        elif "\tLooter: true" in a:
            x.md = x.md | MD_LOOTER
        elif "\tAggressive: true" in a:
            x.md = x.md | MD_AGGRESSIVE
        elif "\tAssist: true" in a:
            x.md = x.md | MD_ASSIST
        elif "\tCastSensorIdle: true" in a:
            x.md = x.md | MD_CASTSENSOR_IDLE
        elif "\tBoss: true" in a:
            x.md = x.md | MD_BOSS
        elif "\tPlant: true" in a:
            x.md = x.md | MD_PLANT
        elif "\tCanAttack: true" in a:
            x.md = x.md | MD_CANATTACK
        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)

    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('SpriteName: ','').replace('Name: ','').replace('AttackDelay: ', '').replace('AttackMotion: ', '').replace('DamageMotion: ', '').replace('MoveSpeed: ', '').replace('AttackRange: ', '').replace('ViewRange: ','').replace('ChaseRange: ','').replace('Attack: ','').replace('Hp: ','').replace('Sp: ','').replace('Id: ','').replace('Lv: ','').replace('view range','').replace('attack range','').replace('move speed','').replace('health','').replace('(int','').replace('attack delay','atk.').replace("Str:", "").replace("Agi:", "").replace("Vit:", "").replace("Int:", "").replace("Dex:", "").replace("Luk:", "").replace("Mdef:","").replace("Def:","").replace("Size:","").replace("Race:", "").replace("Element:","").replace("JExp: ","").replace("MvpExp: ","").replace("Exp: ","").replace("MutationCount: ","").replace("MutationStrength: ","").strip()












class It:
  def __init__(self):
    # Basic
    self.id="0"
    self.aegis="UnknownItem"
    self.name="Unknown Item Name"
    self.buy="0"
    self.sell="0"
    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"
    self.wlvl="0" # TODO

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

def ItAlloc(it):
    if (it.aegis == "UnknownItem"):
        return
    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))

    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_ARMOR' 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))

    if "i" in it.id:
        print("Invalid item: %s" % it.id)
        return

    ## Save the Aegis ID
    if (it.aegis not in []):
        aegis.write("%s %s\n" % (it.aegis, it.id))
    else:
        print("%s: Aegis reused as quest var (please purge)" % it.aegis)
    AllItems[it.aegis]=str(it.id)




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

    scripting=False
    x=It()
    for a in src:
        # Evol2-only scripts
        if "@EVOL2" in a:
            continue
        if "@TMWA" in a:
            a=a.replace("//", "").replace("@TMWA", "")
        # Initiate the script
        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 "	Buy:" in a:
            x.buy=sti(a)
        elif "	Sell:" in a:
            x.sell=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
        # FIXME: Different kind of scripts D:
        elif "Script" in a:
            scripting=True
        # FIXME: Nesting D:
        elif scripting and '}' in a:
            scripting=False
        elif scripting:
            x.script.append(sti(a))

    # Write last entry
    ItAlloc(x)

    src.close()

def sti(x):
    return x.replace('\n', '').replace('|', '').replace(')', '').replace('Id: ', '').replace('"','').replace("    ","").replace("\t","").replace('AegisName: ', '').replace('Name: ','').replace('Buy: ', '').replace('Sell: ', '').replace('Weight: ', '').replace('Type: ', '').replace('Loc: ', '').replace('Atk: ', '').replace('Matk: ', '').replace('Range: ', '').replace('Def: ', '').replace('EquipLv: ', '').replace('Slots: ','').replace(" ", "").strip()

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













def write_mob(m, f):
    ## Prepare new drop list
    i=0
    dl=[]
    while i < 8:
        if len(m.drops) > i:
            try:
                it = m.drops[i][0] # TODO: Convert to INT
                ch = m.drops[i][1]
                it = AllItems[it]
                ch = int(ch)
            except ValueError:
                ch = ch.split(",")[0].replace('(','')
            # except (40, "ODG_BASICSTAT") => split more
            except:
                print("ERROR mob %s drop %s" % (m.name, repr(m.drops)))
                traceback.print_exc()
                it = 0
                ch = 0
        else:
            it = 0
            ch = 0
        dl.append(str(it))
        dl.append(str(ch))
        i+=1
    ## Write the line
    f.write("""%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %d, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 0, 0, %s, 0, 0, 0, 0, 0, 0, 0, %s, %s\n""" % (m.id, m.aegis, m.aegis, m.mobpt, m.hp, m.sp,
m.xp, m.jp, m.range, m.atk.replace('[','').split(",")[0], m.atk.replace(']','').split(",")[1].strip(), m.df, m.mdf, m.str, m.agi, m.vit,
m.int, m.dex, m.luk, m.view, m.chase, m.size, m.race, int("%s%s" % (m.elLv, m.elem)), m.md, m.move,
m.adelay, m.amotion, m.dmotion, dl[0],dl[1], dl[2],dl[3], dl[4],dl[5], 
dl[6],dl[7], dl[8],dl[9], dl[10],dl[11], dl[12],dl[13], dl[14],dl[15], 
m.mvp, m.mtcnt, m.mtstr))
    return

def write_mob_header(f):
    f.write("//THIS FILE IS GENERATED AUTOMATICALLY\n//DO NOT EDIT IT DIRECTLY\n//Edit mob_db.conf instead!\n")
    f.write("//ID,   Name,                   Jname,                  LV,     HP,     SP,     EXP,    JEXP,   Range1, ATK1,   ATK2,   DEF,    MDEF,   STR,    AGI,    VIT,    INT,    DEX,    LUK,    Range2, Range3, Scale,  Race,   Element,Mode,   Speed,  Adelay, Amotion,Dmotion,Drop1id,Drop1per,Drop2id,Drop2%, Drop3id,Drop3%, Drop4id,Drop4%, Drop5id,Drop5%, Drop6id,Drop6%, Drop7id,Drop7%, Drop8id,Drop8%, Item1,  Item2,  MEXP,   ExpPer, MVP1id, MVP1per,MVP2id, MVP2per,MVP3id, MVP3per,mutationcount,mutationstrength\n")
    return


def save_mobs():
    global Mobs1, Mobs2, Mobs3, Mobs4, Mobs5, Mobs6, MobsA
    ## Mobs
    with open ("../world/map/db/mob_db_0_19.txt", "w") as f:
        write_mob_header(f)
        for m in sorted(Mobs1, key=lambda xcv: xcv.id):
            write_mob(m, f)
            continue

    with open ("../world/map/db/mob_db_20_39.txt", "w") as f:
        write_mob_header(f)
        for m in sorted(Mobs2, key=lambda xcv: xcv.id):
            write_mob(m, f)
            continue

    with open ("../world/map/db/mob_db_40_59.txt", "w") as f:
        write_mob_header(f)
        for m in sorted(Mobs3, key=lambda xcv: xcv.id):
            write_mob(m, f)
            continue

    with open ("../world/map/db/mob_db_60_79.txt", "w") as f:
        write_mob_header(f)
        for m in sorted(Mobs4, key=lambda xcv: xcv.id):
            write_mob(m, f)
            continue

    with open ("../world/map/db/mob_db_80_99.txt", "w") as f:
        write_mob_header(f)
        for m in sorted(Mobs5, key=lambda xcv: xcv.id):
            write_mob(m, f)
            continue

    with open ("../world/map/db/mob_db_over_100.txt", "w") as f:
        write_mob_header(f)
        for m in sorted(Mobs6, key=lambda xcv: xcv.id):
            write_mob(m, f)
            continue

    with open ("../world/map/db/mob_db_over_150.txt", "w") as f:
        write_mob_header(f)
        for m in sorted(MobsA, key=lambda xcv: xcv.id):
            write_mob(m, f)
            continue

    return












showHeader()

newItemDB()
testMobs()

save_mobs()

aegis.close()

showFooter()
exit(0)