diff options
author | Jesusaves <cpntb1@ymail.com> | 2022-10-23 23:45:19 -0300 |
---|---|---|
committer | Jesusaves <cpntb1@ymail.com> | 2022-10-23 23:45:19 -0300 |
commit | c2ccb14ffff0e45398365e19dfd2874307ddb943 (patch) | |
tree | 976eaea586fb8f1ee0ab8cae67c69071aed8b952 /client | |
download | tools-c2ccb14ffff0e45398365e19dfd2874307ddb943.tar.gz tools-c2ccb14ffff0e45398365e19dfd2874307ddb943.tar.bz2 tools-c2ccb14ffff0e45398365e19dfd2874307ddb943.tar.xz tools-c2ccb14ffff0e45398365e19dfd2874307ddb943.zip |
Initial commit
Diffstat (limited to 'client')
-rwxr-xr-x | client/aurora.py | 37 | ||||
-rwxr-xr-x | client/dailylogin.py | 86 | ||||
-rwxr-xr-x | client/magicacademy.py | 60 | ||||
-rwxr-xr-x | client/minimap-dyecmd.py | 17 | ||||
-rwxr-xr-x | client/minimap-dyecmd.sh | 0 | ||||
-rw-r--r-- | client/minimap-override/none.png | bin | 0 -> 280 bytes | |||
-rwxr-xr-x | client/minimap-render.py | 171 | ||||
-rwxr-xr-x | client/skills.py | 137 | ||||
-rwxr-xr-x | client/tmxrasterizer | bin | 0 -> 1525440 bytes | |||
-rwxr-xr-x | client/weapons.py | 89 |
10 files changed, 597 insertions, 0 deletions
diff --git a/client/aurora.py b/client/aurora.py new file mode 100755 index 0000000..38ed174 --- /dev/null +++ b/client/aurora.py @@ -0,0 +1,37 @@ +#!/usr/bin/python2.7 + +# Setup +events=["Expo", "Fishing", "Kamelot", "Regnum", "Raid", "Tower", "Mining", + "Anniversary", "Christmas", "Easter", "Patrick", "Thanksgiving", "Valentine", + "Olympics", "Candor", "Worker"] + +# Functions +def headers(val): + return '\n\t<dialog name="aurora_%s" hideText="true">\n\t\t<menu>\n' % val + +def navigation(): + nav="" + nav+='\t\t\t<button x="300" y="20" name="Next" value="Ok" />\n' + return nav + +def tail(): + return '\t\t</menu>\n\t</dialog>\n' + +def data(val): + bf='\t\t\t<image x="0" y="0" image="graphics/images/aurora/%s.png" />\n' % val + return bf + +# Begin +f=open("aurora.tmp", "w") + +f.write('<?xml version="1.0" encoding="utf-8"?>\n<!-- This file is generated automatically, editing it will have no effect.\n Aurora Event Framework\n (C) Jesusalva, 2020 -->\n<dialogs>') + +for evtc in sorted(events): + f.write(headers(evtc)) + f.write(data(evtc)) + f.write(navigation()) + f.write(tail()) + +f.write('\n</dialogs>') +f.close() + diff --git a/client/dailylogin.py b/client/dailylogin.py new file mode 100755 index 0000000..52c945d --- /dev/null +++ b/client/dailylogin.py @@ -0,0 +1,86 @@ +#!/usr/bin/python2.7 + +# Setup +x=y=0 +i=j=0 + +# Functions +def headers(val): + return '\n\t<dialog name="daily_%d" hideText="true">\n\t\t<menu>\n\t\t\t<text x="45" y="0" width="310" height="30" text="##BDaily Login Rewards##b" />\n <button x="157" y="280" name="Claim" value="Ok" />\n\n' % val + +def tail(): + return '\n\t\t</menu>\n\t</dialog>\n' + +def override_check(vl, over, text1, text2): + global j + if not over: + j=0 + return '\t\t\t<image %s image="graphics/images/%s.png" />\n' % (text1, text2) + else: + j+=1 + if (j == vl): + return '\t\t\t<image %s image="graphics/images/done.png" />\n' % (text1) + elif (j < vl): + return '\t\t\t<image %s image="graphics/images/ok.png" />\n' % (text1) + else: + return "" + +def spammer(val, override=False): + bf="" + + bf+=override_check(val, override, 'x="35" y="35"', 'jexp') + bf+=override_check(val, override, 'x="70" y="35"', 'bexp') + bf+=override_check(val, override, 'x="105" y="35"', 'sc') + bf+=override_check(val, override, 'x="140" y="35"', 'jexp') + bf+=override_check(val, override, 'x="175" y="35"', 'bexp') + + bf+=override_check(val, override, 'x="35" y="70"', 'gp') + bf+=override_check(val, override, 'x="70" y="70"', 'sc') + bf+=override_check(val, override, 'x="105" y="70"', 'bexp') + bf+=override_check(val, override, 'x="140" y="70"', 'gp') + bf+=override_check(val, override, 'x="175" y="70"', 'jexp') + + bf+=override_check(val, override, 'x="35" y="105"', 'bexp') + bf+=override_check(val, override, 'x="70" y="105"', 'gp') + bf+=override_check(val, override, 'x="105" y="105"', 'jexp') + bf+=override_check(val, override, 'x="140" y="105"', 'gift') + bf+=override_check(val, override, 'x="175" y="105"', 'gp') + + bf+=override_check(val, override, 'x="35" y="140"', 'jexp') + bf+=override_check(val, override, 'x="70" y="140"', 'bexp') + bf+=override_check(val, override, 'x="105" y="140"', 'gp') + bf+=override_check(val, override, 'x="140" y="140"', 'jexp') + bf+=override_check(val, override, 'x="175" y="140"', 'bexp') + + bf+=override_check(val, override, 'x="35" y="175"', 'gift') + bf+=override_check(val, override, 'x="70" y="175"', 'jexp') + bf+=override_check(val, override, 'x="105" y="175"', 'bexp') + bf+=override_check(val, override, 'x="140" y="175"', 'gp') + bf+=override_check(val, override, 'x="175" y="175"', 'jexp') + + bf+=override_check(val, override, 'x="35" y="210"', 'bexp') + bf+=override_check(val, override, 'x="70" y="210"', 'last') + bf+=override_check(val, override, 'x="105" y="210"', 'sc') + bf+=override_check(val, override, 'x="140" y="210"', 'sc') + bf+=override_check(val, override, 'x="175" y="210"', 'sc') + + bf+=override_check(val, override, 'x="35" y="245"', 'sc') + + return bf + +# Begin +f=open("daily.tmp", "w") + +f.write('<?xml version="1.0" encoding="utf-8"?>\n<!-- This file is generated automatically, editing it will have no effect.\n (C) Jesusalva, 2019 -->\n<dialogs>') + +while (i < 31): + i+=1 + f.write(headers(i)) + f.write(spammer(i, False)) + f.write('\n\t\t\t<image x="245" y="52" image="graphics/images/final.png" />\n\n\t\t\t<!-- Complete -->\n') + f.write(spammer(i, True)) + f.write(tail()) + +f.write('\n</dialogs>') +f.close() + diff --git a/client/magicacademy.py b/client/magicacademy.py new file mode 100755 index 0000000..c6ee44c --- /dev/null +++ b/client/magicacademy.py @@ -0,0 +1,60 @@ +#!/usr/bin/python2.7 + +# Setup +class dlist(list): + def __setitem__(self, index, value): + size = len(self) + if index >= size: + self.extend(None for _ in range(size, index + 1)) + list.__setitem__(self, index, value) + +class Skill: + def __init__(self, ID, NAME, DESC): + self.id=ID + self.name=NAME + self.desc=DESC + +def skill_tree(sk1=None, sk2=None, sk3=None, sk4=None, sk5=None): + return [sk1, sk2, sk3, sk4, sk5] + +academy={} + +# Skill shortcuts +SK_HEAL=Skill("heal", "Healing", "Heals target") +SK_ABHEAL=Skill("abheal", "High Healing", "Supremely heals target") + +# Scholarship +academy["scholarship"]=dlist() +academy["scholarship"].append(skill_tree(SK_HEAL, None, SK_ABHEAL, None, None)) + + +# Functions +def headers(classe, val): + return '\n\t<dialog name="mga_%s_%s" hideText="true">\n\t\t<menu>\n' % (classe, val) + +def navigation(): + nav="" + nav+='\t\t\t<button x="300" y="20" name="Next" value="Ok" />\n' + return nav + +def tail(): + return '\t\t</menu>\n\t</dialog>\n' + +def data(val): + bf='\t\t\t<image x="0" y="0" image="graphics/images/aurora/%s.png" />\n' % val + return bf + +# Begin +f=open("aurora.tmp", "w") + +f.write('<?xml version="1.0" encoding="utf-8"?>\n<!-- This file is generated automatically, editing it will have no effect.\n Magic Academy Learning Interface\n (C) Jesusalva, 2020 -->\n<dialogs>') + +for evtc in sorted(events): + f.write(headers("none", evtc)) + f.write(data(evtc)) + f.write(navigation()) + f.write(tail()) + +f.write('\n</dialogs>') +f.close() + diff --git a/client/minimap-dyecmd.py b/client/minimap-dyecmd.py new file mode 100755 index 0000000..c43a4e4 --- /dev/null +++ b/client/minimap-dyecmd.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- + +import os +f=open("minimap-dyecmd.sh", "w"); +CLIENT_DATA_ROOT="../../clientdata" + +map_names = sorted([os.path.splitext(p)[0] for p in os.listdir(os.path.join(CLIENT_DATA_ROOT, u'graphics', u'minimaps'))]) + +f.write('cd '+os.path.join(CLIENT_DATA_ROOT, u'graphics', u'minimaps')+'\n') +for c in map_names: + if os.path.exists(os.path.join(CLIENT_DATA_ROOT, u'graphics', u'minimaps', c+u'.png')): + i=c+u'.png' + f.write("dyecmd %s tmp ; mv tmp %s\n" % (i, i)) + f.write("echo \"Converted "+i+" successfully.\"\n") + +f.close() diff --git a/client/minimap-dyecmd.sh b/client/minimap-dyecmd.sh new file mode 100755 index 0000000..e69de29 --- /dev/null +++ b/client/minimap-dyecmd.sh diff --git a/client/minimap-override/none.png b/client/minimap-override/none.png Binary files differnew file mode 100644 index 0000000..539e992 --- /dev/null +++ b/client/minimap-override/none.png diff --git a/client/minimap-render.py b/client/minimap-render.py new file mode 100755 index 0000000..9d4bac1 --- /dev/null +++ b/client/minimap-render.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- + +import sys +import os +import subprocess +import tempfile + +CLIENT_DATA_ROOT = os.path.realpath( + os.path.join( + os.path.dirname(__file__), + u'../../clientdata', + ) +) + +SKIP_DOMAIN="030-" + +class MinimapRenderer(object): + + PROGRAMS = { + 'default': { + 'tmxrasterizer': 'tmxrasterizer', + 'im_convert': 'convert', + }, + 'win32': { + 'tmxrasterizer': 'tmxrasterizer.exe', + 'im_convert': 'convert.exe', + }, + } + + def __init__(self, map_name, tilesize, useAntiAliasing): + self.map_name = map_name + self.tilesize = tilesize + self.useAntiAliasing = useAntiAliasing + + def render(self): + """ + Processes a map + """ + if not os.path.exists(os.path.join(CLIENT_DATA_ROOT, u'maps', self.map_name+u'.tmx')): + sys.stderr.write(u'Invalid map name: %s. Skipping.\n' % self.map_name) + return 1 + if not self.map_name.endswith(u'.tmx'): + self.map_name = self.map_name+u'.tmx' + if SKIP_DOMAIN in self.map_name: + print(u'Skipping %s (regex)...\n' % self.map_name) + return 0 + + map_number = os.path.splitext(os.path.basename(self.map_name))[0] + tmx_file = os.path.join(CLIENT_DATA_ROOT, u'maps', self.map_name) + minimap_file = os.path.join(CLIENT_DATA_ROOT, u'graphics', u'minimaps', map_number+u'.png') + + prefix = os.path.commonprefix((tmx_file, minimap_file)) + sys.stdout.write(u'%s -> %s\n' % (os.path.relpath(tmx_file, prefix), os.path.relpath(minimap_file, prefix))) + + try: + self.do_render(tmx_file, minimap_file) + except Exception as e: + sys.stderr.write(u'\x1b[31m\x1b[1mError while rendering %s: %s\x1b[0m\n' % (self.map_name, e)) + return 1 + else: + return 0 + + def do_render(self, tmx_file, bitmap_file): + """ + The map rendering implementation + """ + platform_programs = MinimapRenderer.PROGRAMS.get(sys.platform, MinimapRenderer.PROGRAMS.get('default')) + # tmx rasterize + mrf, map_raster = tempfile.mkstemp(suffix='.png') + tmxrasterizer_cmd = [ + #platform_programs.get('tmxrasterizer'), + '../../tiled/default/install-root/usr/local/bin/tmxrasterizer', + '--tilesize', str(self.tilesize), '--hide-layer', 'Collision','--hide-layer', 'Height','--hide-layer', 'Collisions','--hide-layer', 'collision','--hide-layer', 'height','--hide-layer', 'Heights', '--hide-layer', 'height', '--ignore-visibility', '--hide-object-layers', + ] + if self.useAntiAliasing: + tmxrasterizer_cmd.append('--anti-aliasing') + tmxrasterizer_cmd += [tmx_file, map_raster] + subprocess.check_call(tmxrasterizer_cmd) + if os.stat(map_raster).st_size == 0: + raise Exception('A problem was encountered when rendering a map') + # add cell-shading to the minimap to improve readability + ebf, edges_bitmap = tempfile.mkstemp(suffix='.png') + subprocess.check_call([ + platform_programs.get('im_convert'), map_raster, + '-set', 'option:convolve:scale', '-1!', + '-morphology', 'Convolve', 'Laplacian:0', + '-colorspace', 'gray', + '-auto-level', + '-threshold', '2.8%', + '-negate', + '-transparent', 'white', + edges_bitmap + ]) + subprocess.check_call([ + platform_programs.get('im_convert'), map_raster, edges_bitmap, + '-compose', 'Dissolve', + '-define', 'compose:args=35', + '-composite', + bitmap_file + ]) + os.unlink(map_raster) + os.unlink(edges_bitmap) + + @staticmethod + def check_programs(): + """ + Checks the require programs are available + """ + def which(program): + import os + def is_exe(fpath): + return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + fpath, fname = os.path.split(program) + if fpath: + if is_exe(program): + return program + else: + for path in os.environ["PATH"].split(os.pathsep): + exe_file = os.path.join(path, program) + if is_exe(exe_file): + return exe_file + return None + + platform_programs = MinimapRenderer.PROGRAMS.get(sys.platform, MinimapRenderer.PROGRAMS.get('default')) + for program in platform_programs.values(): + if not which(program): + raise Exception('The required "%s" program is missing from your PATH.' % program) + +def usage(): + sys.stderr.write(u'''Usage: %s MAP_NAME... + + Example: + $ ./minimap-render.py 007-1 + will render the map at maps/007-1.tmx in the graphics/minimaps directory. + $ ./minimap-render.py all + will render all existing maps found in the maps directory. + $ ./minimap-render.py update + will update all existing minimaps found in the graphics/minimaps directory. + + For convenience, + $ ./minimap-render.py 007-1.tmx + is also accepted. + \n''' % sys.argv[0]) + +def main(): + if not len(sys.argv) > 1: + usage() + return 127 + try: + MinimapRenderer.check_programs() + except Exception as e: + sys.stderr.write(u'%s\n' % e) + return 126 + + status = 0 + if sys.argv[1].lower() == 'all': + map_names = sorted([os.path.splitext(p)[0] for p in os.listdir(os.path.join(CLIENT_DATA_ROOT, u'maps'))]) + elif sys.argv[1].lower() == 'update': + map_names = sorted([os.path.splitext(p)[0] for p in os.listdir(os.path.join(CLIENT_DATA_ROOT, u'graphics', u'minimaps'))]) + else: + map_names = sys.argv[1:] + + for map_name in map_names: + # Render tiles at 1 pixel size + map_renderer = MinimapRenderer(map_name, 1, True) + status += map_renderer.render() + return 0 + +if __name__ == '__main__': + sys.exit(main()) diff --git a/client/skills.py b/client/skills.py new file mode 100755 index 0000000..bfe59f3 --- /dev/null +++ b/client/skills.py @@ -0,0 +1,137 @@ +#!/usr/bin/python2.7 + +# Setup +x=y=0 +i=j=0 + +skills=[] + +class Skill: + def __init__(self, sid, name, icon, desc, bmp, amp, cmd, maxlv): + self.id=sid + self.lv=maxlv + self.name=name + self.icon=icon + self.cmd=cmd + + self.desc=desc + self.bmp=bmp + self.amp=amp + +def fillskill(sk, lv): + sid=sk.id + name=sk.name + icon=sk.icon + desc=sk.desc + bmp=sk.bmp + amp=sk.amp + cmd=sk.cmd + + if lv > 0: + lvstr='\t\t\tlevel="%d"\n' % lv + mpstr='%d MP. ' % int(bmp+(amp*(lv-1))) + cmdstr='\t\t\tinvokeCmd="@sk-%s"\n' % cmd + else: + lvstr='' + lv=1 + mpstr='' + cmdstr='' + + msg='\ +\t\t<skill\n\ +\t\t\tid="%d"\n\ +\t\t\tname="%s"\n\ +\t\t\ticon="graphics/skills/%s.png"\n\ +\t\t\tdescription="%s%s"\n\ +%s\ +%s\ +\t\t/>\n' % (sid, name, icon, mpstr, desc, cmdstr, lvstr) + return msg + + + + + + + + + + + +# Declare the skills + +######################### +### Transmutation Skills +######################### +#skills.append(Skill(20024, "Parum", "other/parum", "Transmutate wood into stuff.", +#50, 0, "parum", 0)) +#skills.append(Skill(20027, "Transmutation", "transmutation", "Transmute stuff into other stuff.", +#215, -5, "trans", 10)) + +######################### +### Summon Skills +######################### +skills.append(Skill(20025, "Summon Maggots", "other/kalmurk", "2x Maggot Slime.", +40, 5, "kalmurk", 0)) +skills.append(Skill(20029, "Summon Dragon", "none", "4x Dragon Scale.", +50, 4, "dragokin", 0)) +skills.append(Skill(20030, "Summon Slimes", "none", "15x Maggot Slime.", +30, 3, "limerizer", 0)) +skills.append(Skill(20043, "Summon Fluffies", "none", "1x White Fur.", +25, 4, "cuteheart", 0)) +skills.append(Skill(20042, "Summon Spiky", "none", "1x Mushroom Spores.", +25, 5, "kalspike", 0)) +skills.append(Skill(20041, "Summon Mouboo", "none", "1x Mouboo Figurine.", +25, 5, "kalboo", 0)) +skills.append(Skill(20036, "Summon Snakes", "none", "1x Snake Egg.", +35, 6, "halhiss", 0)) +skills.append(Skill(20037, "Summon Wolverns", "none", "5x White Fur.", +45, 5, "kalwulf", 0)) +skills.append(Skill(20038, "Summon Fairies", "none", "1x Fluo Powder.", +40, 4, "fairykingdom", 0)) +skills.append(Skill(20039, "Summon Yetis", "none", "1x Frozen Yeti Tear.", +37, 5, "frozenheart", 0)) +skills.append(Skill(20040, "Summon Terranite", "none", "1x Terranite Ore.", +47, 5, "stoneheart", 0)) +skills.append(Skill(20044, "Summon Plants", "none", "2x Root.", +30, 3, "plantkingdom", 5)) +skills.append(Skill(20047, "Summon Ducks", "none", "1x Cherry Cake. Req. Rubber Ducky.", +40, 7, "ducky", 0)) +skills.append(Skill(20049, "Summon Pixies", "none", "3x Fluo Powder.", +40, 4, "fairyempire", 0)) + +skills.append(Skill(20023, "Summon Cave Maggot", "none", "Req. Zarkor Scroll.", +40, 7, "zarkor", 0)) + + + + + + + + + + + + +# Begin +f=open("skills.tmp", "w") + +f.write('<?xml version="1.0" encoding="utf-8"?>\n<!-- This file is generated automatically, editing it will have no effect.\n (C) Jesusalva, 2019-2020 -->\n<skills>\n\t<set name="Summon">\n') + +for sk in skills: + i=0 + while (i < sk.lv): + i+=1 + f.write(fillskill(sk, i)) + + # Fill the fallback + if (int(sk.lv)): + sk.desc="MP + "+str(sk.amp)+"/lv. "+sk.desc + f.write(fillskill(sk, -1)) + f.write("\n") + +# We're done +f.write('\n\t</set>\n</skills>') +f.close() + diff --git a/client/tmxrasterizer b/client/tmxrasterizer Binary files differnew file mode 100755 index 0000000..f079132 --- /dev/null +++ b/client/tmxrasterizer diff --git a/client/weapons.py b/client/weapons.py new file mode 100755 index 0000000..cc45d01 --- /dev/null +++ b/client/weapons.py @@ -0,0 +1,89 @@ +#!/usr/bin/python2.7 + +class Item: + def __init__(self, xid): + self.id=xid + self.lvl=0 + +a=open("../../clientdata/items.xml", "r") + +swords=[] +bows=[] +shields=[] + +gid="0" +rid=0 +ctx=Item(0) +mem=[] + +for l in a: + if "<item id=" in l: + if ctx.id > 0: + mem.append(ctx) + + gid=l.replace('\t', '').replace(' ','').replace('<itemid=', '').replace('"', '').replace("'", "") + rid=0 + if "-" in gid: + gid="0" + continue + try: + rid=int(gid) + except: + print "[CRITICAL] Invalid item ID format: " + l + exit(1) + + ctx=Item(rid) + + if "\tlevel=" in l or " level=" in l: + gid=l.replace('\t', '').replace(' ','').replace('level=', '').replace('"', '').replace("'", "") + try: + rid=int(gid) + except: + print "[CRITICAL] Invalid item level format: " + l + exit(1) + ctx.lvl=0+rid + +mem=sorted(mem, key=lambda xcv: xcv.lvl, reverse=True) + +for r in mem: + rid=r.id + if rid >= 2700 and rid <= 2899: + shields.append(rid) + elif rid >= 3500 and rid <= 3999: + swords.append(rid) + elif rid >= 6000 and rid <= 6499: + bows.append(rid) + +a.close() + +#shields=sorted(shields, reverse=True) +#bows=sorted(bows, reverse=True) +#swords=sorted(swords, reverse=True) + +b=open("weapons.tmp", "w") + +b.write('<?xml version="1.0" encoding="utf-8"?>\n\ +<!-- Author: 4144, Jesusalva\n\ +Copyright (C) 2015 Evol Online\n\ +Copyright (C) 2018 TMW2: Moubootaur Legends\n -->\n\ +\n\ +<weapons>\n') + +b.write(' <swords>\n') + +for i in swords: + b.write(' <item id="%d"/>\n' % i) + +b.write(' </swords>\n <bows>\n') + +for i in bows: + b.write(' <item id="%d"/>\n' % i) + +b.write(' </bows>\n <shields>\n') + +for i in shields: + b.write(' <item id="%d"/>\n' % i) + +b.write(' </shields>\n</weapons>') + +b.close() |