# -*- coding: utf8 -*-
#
# Copyright (C) 2014 Evol Online
# Author: Andrei Karas (4144)
import math
import os
import re
from code.configutils import isHaveData, writeCondField2, writeStartBlock, writeEndBlock, writeIntField, writeStrField, writeFieldArr, writeIntField2, writeFieldList, writeSubField
from code.fileutils import readFile
def getMobDbFile(srcDir):
files = os.listdir(srcDir)
for srcFile in files:
if srcFile.find("mob_db") >= 0:
yield srcFile
def replaceStr(line):
vals = [
("lanternaJack", "LanternaJack"),
("foice", "Foice"),
("BlueFairy", "BlueFairyMob"),
("RedFairy", "RedFairyMob"),
("GreenFairy", "GreenFairyMob"),
("Scorpion", "ScorpionMob"),
("Tritan", "TritanMob"),
("Ukar", "UkarMob"),
]
for val in vals:
line = line.replace(val[0], val[1])
return line
def convertMobDb(items):
srcDir = "oldserverdata/world/map/db/"
dstFile = "newserverdata/db/re/mob_db.conf"
fieldsSplit = re.compile(",")
tpl = readFile("templates/mob_db.tpl")
with open(dstFile, "w") as w:
w.write(tpl)
for srcFile in getMobDbFile(srcDir):
with open(srcDir + srcFile, "r") as r:
for line in r:
if len(line) < 2 or line[:2] == "//" or line[:1] == "#":
w.write(line)
continue
line = replaceStr(line)
rows = fieldsSplit.split(line)
for f in xrange(0, len(rows)):
rows[f] = rows[f].strip()
try:
val = int(rows[23])
if val < 20:
rows[23] = "20"
except:
None
# Experience and Job experience, following *tmw-eathena*/src/map/mob.c
calc_exp = 0
if rows[6] == "0":
if int(rows[4]) <= 1:
calc_exp = 1
mod_def = 100 - int(rows[11])
if mod_def == 0:
mod_def = 1
effective_hp = ((50 - int(rows[18])) * int(rows[4]) / 50) + (2 * int(rows[18]) * int(rows[4]) / mod_def)
attack_factor = (int(rows[9]) + int(rows[10]) + int(rows[13]) / 3 + int(rows[17]) / 2 + int(rows[18])) * (1872 / int(rows[26])) / 4
dodge_factor = (int(rows[3]) + int(rows[14]) + int(rows[18]) / 2)**(4 / 3)
persuit_factor = (3 + int(rows[8])) * (int(rows[24]) % 2) * 1000 / int(rows[25])
aggression_factor = 1
if False:
aggression_factor = 10 / 9
base_exp_rate = 100 # From *tmw-eathena-data*/conf/battle_athena.conf
calc_exp = int(math.floor(effective_hp * (math.sqrt(attack_factor) + math.sqrt(dodge_factor) + math.sqrt(persuit_factor) + 55)**3 * aggression_factor / 2000000 * base_exp_rate / 100))
if calc_exp < 1:
calc_exp = 1
else:
calc_exp = rows[6]
w.write("{\n")
writeIntField(w, "Id", rows[0])
writeStrField(w, "SpriteName", rows[1])
if (rows[2] != rows[1]):
writeStrField(w, "Name", rows[2])
else:
writeStrField(w, "Name", "The %s" % rows[2])
writeIntField(w, "Lv", rows[3])
writeIntField(w, "Hp", rows[4])
writeIntField(w, "Sp", rows[5])
writeIntField(w, "Exp", calc_exp)
writeIntField(w, "JExp", rows[7])
writeIntField(w, "AttackRange", rows[8])
writeFieldArr(w, "Attack", rows[9], rows[10])
writeIntField(w, "Def", rows[11])
writeIntField(w, "Mdef", rows[12])
writeStartBlock(w, "Stats")
writeIntField2(w, "Str", rows[13])
writeIntField2(w, "Agi", rows[14])
writeIntField2(w, "Vit", rows[15])
writeIntField2(w, "Int", rows[16])
writeIntField2(w, "Dex", rows[17])
writeIntField2(w, "Luk", rows[18])
writeEndBlock(w)
writeIntField(w, "ViewRange", rows[19])
writeIntField(w, "ChaseRange", 10)
writeIntField(w, "Size", rows[21])
writeIntField(w, "Race", rows[22])
writeFieldList(w, "Element", int(rows[23]) % 10, int(rows[23]) / 20)
mode = int(rows[24], 0)
if mode != 0:
writeStartBlock(w, "Mode")
writeCondField2(w, mode & 0x0001, "CanMove")
writeCondField2(w, mode & 0x0002, "Looter")
writeCondField2(w, mode & 0x0004, "Aggressive")
writeCondField2(w, mode & 0x0008, "Assist")
writeCondField2(w, mode & 0x0010, "CastSensorIdle")
writeCondField2(w, mode & 0x0020, "Boss")
writeCondField2(w, mode & 0x0040, "Plant")
writeCondField2(w, mode & 0x0080, "CanAttack")
writeCondField2(w, mode & 0x0100, "Detector")
writeCondField2(w, mode & 0x0200, "CastSensorChase")
writeCondField2(w, mode & 0x0400, "ChangeChase")
writeCondField2(w, mode & 0x0800, "Angry")
writeCondField2(w, mode & 0x1000, "ChangeTargetMelee")
writeCondField2(w, mode & 0x2000, "ChangeTargetChase")
writeCondField2(w, mode & 0x4000, "TargetWeak")
writeCondField2(w, mode & 0x8000, "LiveWithoutMaster")
writeEndBlock(w)
writeIntField(w, "MoveSpeed", rows[25])
writeIntField(w, "AttackDelay", rows[26])
writeIntField(w, "AttackMotion", rows[27])
writeIntField(w, "DamageMotion", rows[28])
writeIntField(w, "MvpExp", rows[45])
if isHaveData(rows, 47, 3):
writeStartBlock(w, "MvpDrops")
for f in range(0, 3):
value = rows[47 + f * 2]
chance = rows[47 + f * 2]
if value == "" or value == "0" or chance == "" or chance == "0":
continue
value = int(value)
if value not in items:
w.write("// Error: mvp drop with id {0} not found in item db\n".format(value))
print("Error: mvp drop with id {0} not found in item db".format(value))
else:
writeSubField(w, items[value]["name"], chance)
writeEndBlock(w)
if isHaveData(rows, 29, 10):
writeStartBlock(w, "Drops")
for f in range(0, 10):
value = rows[29 + f * 2]
chance = rows[30 + f * 2]
if value == "" or value == "0" or chance == "" or chance == "0":
continue
value = int(value)
if value not in items:
w.write("// Error: drop with id {0} not found in item db\n".format(value))
print("Error: drop with id {0} not found in item db".format(value))
else:
writeSubField(w, items[value]["name"], chance)
writeEndBlock(w)
w.write("},\n")
w.write(")\n")