From 51da42665a00756ecbeae5e264875c312fd1536d Mon Sep 17 00:00:00 2001 From: Asheraf Date: Tue, 17 Apr 2018 19:25:22 +0100 Subject: Add tool to convert old mob skill db to new format --- tools/mobskilldbconverter.py | 264 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 tools/mobskilldbconverter.py (limited to 'tools') 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 . + +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 ******************************************** + ************************************************************************** + : { + : { + 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]) -- cgit v1.2.3-60-g2f50