summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/mobskilldbconverter.py264
1 files changed, 264 insertions, 0 deletions
diff --git a/tools/mobskilldbconverter.py b/tools/mobskilldbconverter.py
new file mode 100644
index 000000000..310331043
--- /dev/null
+++ b/tools/mobskilldbconverter.py
@@ -0,0 +1,264 @@
+#!/usr/bin/python
+# -*- coding: utf8 -*-
+#
+# This file is part of Hercules.
+# http://herc.ws - http://github.com/HerculesWS/Hercules
+#
+# Copyright (C) 2018 Hercules Dev Team
+# Copyright (C) 2018 Asheraf
+#
+# Hercules is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import re
+import sys
+import utils.common as Tools
+
+SKILL_STATES = {
+ "any": "MSS_ANY",
+ "idle": "MSS_IDLE",
+ "walk": "MSS_WALK",
+ "loot": "MSS_LOOT",
+ "dead": "MSS_DEAD",
+ "attack": "MSS_BERSERK",
+ "angry": "MSS_ANGRY",
+ "chase": "MSS_RUSH",
+ "follow": "MSS_FOLLOW",
+ "anytarget": "MSS_ANYTARGET"
+}
+SKILL_COND1 = {
+ "always": "MSC_ALWAYS",
+ "myhpltmaxrate": "MSC_MYHPLTMAXRATE",
+ "myhpinrate": "MSC_MYHPINRATE",
+ "friendhpltmaxrate": "MSC_FRIENDHPLTMAXRATE",
+ "friendhpinrate": "MSC_FRIENDHPINRATE",
+ "mystatuson": "MSC_MYSTATUSON",
+ "mystatusoff": "MSC_MYSTATUSOFF",
+ "friendstatuson": "MSC_FRIENDSTATUSON",
+ "friendstatusoff": "MSC_FRIENDSTATUSOFF",
+ "attackpcgt": "MSC_ATTACKPCGT",
+ "attackpcge": "MSC_ATTACKPCGE",
+ "slavelt": "MSC_SLAVELT",
+ "slavele": "MSC_SLAVELE",
+ "closedattacked": "MSC_CLOSEDATTACKED",
+ "longrangeattacked": "MSC_LONGRANGEATTACKED",
+ "skillused": "MSC_SKILLUSED",
+ "afterskill": "MSC_AFTERSKILL",
+ "casttargeted": "MSC_CASTTARGETED",
+ "rudeattacked": "MSC_RUDEATTACKED",
+ "masterhpltmaxrate": "MSC_MASTERHPLTMAXRATE",
+ "masterattacked": "MSC_MASTERATTACKED",
+ "alchemist": "MSC_ALCHEMIST",
+ "onspawn": "MSC_SPAWN"
+}
+SKILL_COND2 = {
+ "anybad": "MSC_ANY",
+ "stone": "SC_STONE",
+ "freeze": "SC_FREEZE",
+ "stun": "SC_STUN",
+ "sleep": "SC_SLEEP",
+ "poison": "SC_POISON",
+ "curse": "SC_CURSE",
+ "silence": "SC_SILENCE",
+ "confusion": "SC_CONFUSION",
+ "blind": "SC_BLIND",
+ "hiding": "SC_HIDING",
+ "sight": "SC_SIGHT"
+}
+SKILL_TARGET = {
+ "target": "MST_TARGET",
+ "randomtarget": "MST_RANDOM",
+ "self": "MST_SELF",
+ "friend": "MST_FRIEND",
+ "master": "MST_MASTER",
+ "around5": "MST_AROUND5",
+ "around6": "MST_AROUND6",
+ "around7": "MST_AROUND7",
+ "around8": "MST_AROUND8",
+ "around1": "MST_AROUND1",
+ "around2": "MST_AROUND2",
+ "around3": "MST_AROUND3",
+ "around4": "MST_AROUND4",
+ "around": "MST_AROUND"
+}
+
+def printHeader():
+ print("""
+mob_skill_db:(
+{
+/**************************************************************************
+ ************* Entry structure ********************************************
+ **************************************************************************
+ <Monster_Constant>: {
+ <Skill_Constant>: {
+ ClearSkills: (boolean, defaults to false) allows cleaning all previous defined skills for the mob.
+ SkillLevel: (int, defaults to 1)
+ SkillState: (int, defaults to 0)
+ SkillTarget: (int, defaults to 0)
+ Rate: (int, defaults to 1)
+ CastTime: (int, defaults to 0)
+ Delay: (int, defaults to 0)
+ Cancelable: (boolean, defaults to false)
+ CastCondition: (int, defaults to 0)
+ ConditionData: (int, defaults to 0)
+ val0: (int, defaults to 0)
+ val1: (int, defaults to 0)
+ val2: (int, defaults to 0)
+ val3: (int, defaults to 0)
+ val4: (int, defaults to 0)
+ Emotion: (int, defaults to 0)
+ ChatMsgID: (int, defaults to 0)
+ }
+ }
+**************************************************************************/""")
+
+def printFooter():
+ print('}\n)\n')
+
+def isValidEntry(line):
+ if re.match('^[0-9]+,.*', line):
+ return True
+ return False
+
+def commaSplit(line):
+ return line.split(',')
+
+def stripLinebreak(line):
+ return line.replace('\r', '').replace('\n', '')
+
+def printInt(key, value):
+ if key in value:
+ if int(value[key]) is not 0:
+ print('\t\t\t{}: {}'.format(key, value[key]))
+
+def printStrToInt(key, value):
+ if value[key] is not '':
+ if int(value[key]) is not 0:
+ print('\t\t\t{}: {}'.format(key, value[key]))
+
+def printBool(key, value):
+ if value[key] == 'yes':
+ print('\t\t\t{}: true'.format(key))
+
+def printClearSkills(key, value):
+ if value[key] == 'clear':
+ print('\t\t\t{}: true'.format(key))
+
+def printSkillState(key, value):
+ if value[key]:
+ print('\t\t\t{}: "{}"'.format(key, SKILL_STATES[value[key]]))
+
+def printSkillTarget(key, value):
+ if value[key]:
+ print('\t\t\t{}: "{}"'.format(key, SKILL_TARGET[value[key]]))
+
+def printCastCondition(key, value):
+ if value[key]:
+ print('\t\t\t{}: "{}"'.format(key, SKILL_COND1[value[key]]))
+
+def printConditionData(key, value):
+ if value[key] in SKILL_COND2:
+ print('\t\t\t{}: "{}"'.format(key, SKILL_COND2[value[key]]))
+ elif value[key] is not '':
+ if int(value[key]) is not 0:
+ print('\t\t\t{}: {}'.format(key, value[key]))
+
+def printEmotion(key, value):
+ if value[key] is not '':
+ print('\t\t\t{}: {}'.format(key, value[key]))
+
+def LoadOldDB(mode, serverpath):
+
+ r = open('{}db/{}/mob_skill_db.txt'.format(serverpath, mode), "r")
+
+ Db = dict()
+ for line in r:
+ if isValidEntry(line) == True:
+ entry = commaSplit(stripLinebreak(line))
+ MonsterId = entry[0]
+ if MonsterId not in Db:
+ Db[MonsterId] = dict()
+ skillidx = len(Db[MonsterId])
+ Db[MonsterId][skillidx] = dict()
+ Db[MonsterId][skillidx]['ClearSkills'] = entry[1]
+ Db[MonsterId][skillidx]['SkillState'] = entry[2]
+ Db[MonsterId][skillidx]['SkillId'] = entry[3]
+ Db[MonsterId][skillidx]['SkillLevel'] = entry[4]
+ Db[MonsterId][skillidx]['Rate'] = entry[5]
+ Db[MonsterId][skillidx]['CastTime'] = entry[6]
+ Db[MonsterId][skillidx]['Delay'] = entry[7]
+ Db[MonsterId][skillidx]['Cancelable'] = entry[8]
+ Db[MonsterId][skillidx]['SkillTarget'] = entry[9]
+ Db[MonsterId][skillidx]['CastCondition'] = entry[10]
+ Db[MonsterId][skillidx]['ConditionData'] = entry[11]
+ for i in range(5):
+ if entry[12 + i] is '':
+ continue
+ try:
+ Db[MonsterId][skillidx]['val{}'.format(i)] = int(entry[12 + i])
+ except:
+ Db[MonsterId][skillidx]['val{}'.format(i)] = int(entry[12 + i], 16)
+ Db[MonsterId][skillidx]['Emotion'] = entry[17]
+ Db[MonsterId][skillidx]['ChatMsgID'] = entry[18]
+ return Db
+
+def ConvertDB(mode, serverpath):
+ db = LoadOldDB(mode, serverpath)
+ MobDB = Tools.LoadDBConsts('mob_db', mode, serverpath)
+ SkillDB = Tools.LoadDBConsts('skill_db', mode, serverpath)
+
+ printHeader()
+ for mobid in sorted(db.iterkeys()):
+ print('\t{}: {{'.format(MobDB[int(mobid)]))
+ for skillidx in sorted(db[mobid].iterkeys()):
+ valid = True
+ if int(db[mobid][skillidx]['SkillId']) not in SkillDB:
+ valid = False
+ print('/*')
+ print('// Can\'t find skill with id {} in skill_db'.format(db[mobid][skillidx]['SkillId']))
+ print('\t\t{}: {{'.format(db[mobid][skillidx]['SkillId']))
+ else:
+ print('\t\t{}: {{'.format(SkillDB[int(db[mobid][skillidx]['SkillId'])]))
+ printClearSkills('ClearSkills', db[mobid][skillidx])
+ printSkillState('SkillState', db[mobid][skillidx])
+ printStrToInt('SkillLevel', db[mobid][skillidx])
+ printStrToInt('Rate', db[mobid][skillidx])
+ printStrToInt('CastTime', db[mobid][skillidx])
+ printStrToInt('Delay', db[mobid][skillidx])
+ printBool('Cancelable', db[mobid][skillidx])
+ printSkillTarget('SkillTarget', db[mobid][skillidx])
+ printCastCondition('CastCondition', db[mobid][skillidx])
+ printConditionData('ConditionData', db[mobid][skillidx])
+ for i in range(5):
+ printInt('val{}'.format(i), db[mobid][skillidx])
+ printEmotion('Emotion', db[mobid][skillidx])
+ printStrToInt('ChatMsgID', db[mobid][skillidx])
+ print('\t\t}')
+ if valid is False:
+ print('*/')
+ print('\t}')
+ printFooter()
+
+if len(sys.argv) != 3:
+ print('Monster Skill db converter from txt to conf format')
+ print('Usage:')
+ print(' mobskilldbconverter.py mode serverpath')
+ print("example:")
+ print(' mobskilldbconverter.py pre-re ../')
+ exit(1)
+
+if sys.argv[1] != 're' and sys.argv[1] != 'pre-re':
+ print('you have entred an invalid server mode')
+ exit(1)
+
+ConvertDB(sys.argv[1], sys.argv[2])