Jump to content

LocaleInfo.py - Refactored


Recommended Posts

  • Forum Moderator

There are a lot of people which had problem with localeInfo because korean-characters and bad encoding, there's a clean file with refactored code.

  • Removed all the code which isn't used like korean characters < bad encoding [runmain error / crash](editors problem) and more checks.
  • Removed over 500 lines unused.
  • Removed function mapping(**kwargs) and use constructor of dict > dict(**kwarg) which is same (**kwarg let you take arbitrary number of keyword arguments).
  • Removed function CutMoneyString because is used just when locale is HongKong, CIBN.
  • Removed check IsYMIR from function LoadLocaleData which load locale as locale/ymir or locale/we_korea.
  • Removed GUILD_MARK_NOT_ENOUGH_LEVEL, GUILD_HEADQUARTER, GUILD_FACILITY, GUILD_OBJECT, MAP_TRENT02, MAP_WL, MAP_NUSLUCK, MAP_TREE2, LOGIN_FAILURE_WEB_BLOCK, LOGIN_FAILURE_BLOCK_LOGIN, CHANNEL_NOTIFY_FULL, now they're readed directly from locale_game.txt.
  • Removed declared global variables.
  • Removed checks for declaring LOCALE_FILE_NAME, FN_GM_MARK and use current path.
  • Removed korean functions/lists/dictionaries/characters GetAuxiliaryWordType, JOBINFO_DATA_LIST, dictSingleWord, dictDoubleWord, etc.
  • Removed unused things: locale mapping, 'all' list etc.
  • Removed IN_GAME_SHOP_ENABLE declaration, should be declared inside of constInfo directly.
  • Removed checks (locale path) - 949, 932 == app.GetDefaultCodePage(), IsHONGKONG, IsNEWCIBN() or IsCIBN10() from declaration of functions like (NumberToMoneyString, NumberToSecondaryCoinString, ...),now they're declared directly from old style (IsEUROPE() and not IsWE_KOREA() and not IsYMIR()).
  • Added custom string format(format_string, *args, **kwargs) instead of %. (old-style).
  • Added new checks inside of LoadLocaleFile for security:
  •     Check if token3 (token1=original_string, token2=return-string, token3=function) function name exist in our types (SA, SNA, SAA, SAN) then try to call it.
  •     Check if string line have no tabs.

Diff-checker: (856 Removals + 301 Additions)

 

Spoiler

"""
	File: localeInfo.py
	Refactored code date: 12.05.2016
	Changes:
		Removed all the code which isn't used like korean characters < bad encoding(editors problem) and more checks.
		Removed over 500 lines unused.
		Removed function mapping(**kwargs) and use constructor of dict > dict(**kwarg) which is same (**kwarg let you take arbitrary number of keyword arguments).
		Removed function CutMoneyString because is used just when locale is HongKong, CIBN.
		Removed check IsYMIR from function LoadLocaleData which load locale as locale/ymir or locale/we_korea.
		Removed GUILD_MARK_NOT_ENOUGH_LEVEL, GUILD_HEADQUARTER, GUILD_FACILITY, GUILD_OBJECT, MAP_TRENT02, MAP_WL, MAP_NUSLUCK, MAP_TREE2, 
			LOGIN_FAILURE_WEB_BLOCK, LOGIN_FAILURE_BLOCK_LOGIN, CHANNEL_NOTIFY_FULL, now they're readed directly from locale_game.txt.
		Removed declared global variables.
		Removed checks for declaring LOCALE_FILE_NAME, FN_GM_MARK and use current path.
		Removed korean functions/lists/dictionaries/characters GetAuxiliaryWordType, JOBINFO_DATA_LIST, dictSingleWord, dictDoubleWord, etc.
		Removed unused things: locale mapping, 'all' list etc.
		Removed IN_GAME_SHOP_ENABLE declaration, should be declared inside of constInfo directly.
		Removed checks (locale path) - 949, 932 == app.GetDefaultCodePage(), IsHONGKONG, IsNEWCIBN() or IsCIBN10() from declaration of functions like (NumberToMoneyString, NumberToSecondaryCoinString, ...),
			now they're declared directly from old style (IsEUROPE() and not IsWE_KOREA() and not IsYMIR()).
		
		Added custom string format(format_string, *args, **kwargs) instead of %. (old-style).
		Added new checks inside of LoadLocaleFile for security:
			* Check if token3 (token1=original_string, token2=return-string, token3=function) function name exist in our types (SA, SNA, SAA, SAN) then try to call it.
			* Check if string line have no tabs.
"""

import app
import constInfo
import dbg

APP_GET_LOCALE_PATH					= app.GetLocalePath()
APP_GET_LOCALE_SERVICE_NAME 		= app.GetLocaleServiceName()
	
APP_TITLE 							= 'METIN2'

BLEND_POTION_NO_TIME 				= 'BLEND_POTION_NO_TIME'
BLEND_POTION_NO_INFO				= 'BLEND_POTION_NO_INFO'

LOGIN_FAILURE_WRONG_SOCIALID 		= 'LOGIN_FAILURE_WRONG_SOCIALID'
LOGIN_FAILURE_SHUTDOWN_TIME 		= 'LOGIN_FAILURE_SHUTDOWN_TIME'

GUILD_MEMBER_COUNT_INFINITY 		= 'INFINITY'
GUILD_MARK_MIN_LEVEL 				= '3'
GUILD_BUILDING_LIST_TXT 			= '{:s}/GuildBuildingList.txt'.format(APP_GET_LOCALE_PATH)
FN_GM_MARK 							= '{:s}/effect/gm.mse'.format(APP_GET_LOCALE_PATH)

MAP_TREE2 							= 'MAP_TREE2'

ERROR_MARK_UPLOAD_NEED_RECONNECT	= 'UploadMark: Reconnect to game'
ERROR_MARK_CHECK_NEED_RECONNECT		= 'CheckMark: Reconnect to game'

VIRTUAL_KEY_ALPHABET_LOWERS			= r"[1234567890]/qwertyuiop\=asdfghjkl;`'zxcvbnm.,"
VIRTUAL_KEY_ALPHABET_UPPERS			= r"{1234567890}?QWERTYUIOP|+ASDFGHJKL:~'ZXCVBNM<>"
VIRTUAL_KEY_SYMBOLS    				= "!@#$%^&*()_+|{}:'<>?~"
VIRTUAL_KEY_NUMBERS					= "1234567890-=\[];',./`"
VIRTUAL_KEY_SYMBOLS_BR				= "!@#$%^&*()_+|{}:'<>?~áàãâéèêíìóòôõúùç"

__IS_ENGLISH						= 'ENGLISH' == APP_GET_LOCALE_SERVICE_NAME
__IS_HONGKONG						= 'HONGKONG' == APP_GET_LOCALE_SERVICE_NAME
__IS_EUROPE							= 'EUROPE' == APP_GET_LOCALE_SERVICE_NAME

__IS_NEWCIBN						= 'locale/newcibn' == APP_GET_LOCALE_PATH		
__IS_CANADA							= 'locale/ca' == APP_GET_LOCALE_PATH
__IS_BRAZIL							= 'locale/br' == APP_GET_LOCALE_PATH
__IS_SINGAPORE						= 'locale/sg' == APP_GET_LOCALE_PATH
__IS_VIETNAM						= 'locale/vn' == APP_GET_LOCALE_PATH
__IS_ARABIC							= 'locale/ae' == APP_GET_LOCALE_PATH
__IS_CIBN10							= 'locale/cibn10' == APP_GET_LOCALE_PATH
__IS_WE_KOREA						= 'locale/we_korea' == APP_GET_LOCALE_PATH
__IS_YMIR							= 'locale/ymir' == APP_GET_LOCALE_PATH
__IS_TAIWAN							= 'locale/taiwan' == APP_GET_LOCALE_PATH
__IS_JAPAN							= 'locale/japan' == APP_GET_LOCALE_PATH

if __IS_CANADA:
	__IS_EUROPE = TRUE

def IsYMIR():
	return __IS_YMIR

def IsJAPAN():
	return __IS_JAPAN

def IsENGLISH():
	return __IS_ENGLISH

def IsHONGKONG():
	return __IS_HONGKONG

def IsTAIWAN():
	return __IS_TAIWAN

def IsNEWCIBN():
	return __IS_NEWCIBN

def IsCIBN10():
	return __IS_CIBN10
	
def IsEUROPE():
	return __IS_EUROPE

def IsCANADA():
	return __IS_CANADA

def IsBRAZIL():
	return __IS_BRAZIL

def IsVIETNAM():
	return __IS_VIETNAM

def IsSINGAPORE():
	return __IS_SINGAPORE
	
def IsARABIC():
	return __IS_ARABIC

def IsWE_KOREA():
	return __IS_WE_KOREA
	
def IsCHEONMA():
	return __IS_YMIR

# Load locale data by specific path
def LoadLocaleData():
	app.LoadLocaleData(app.GetLocalePath())

# Load locale_game.txt
def LoadLocaleFile(srcFileName, localeDict):
	def SNA(text):
		def f(x):
			return text
		return f

	def SA(text):
		def f(x):
			return text % x
		return f

	def SAN(text):
		def f(x):
			return text % x
		return f

	def SAA(text):
		def f(x):
			return text % x
		return f

	funcDict = {"SA": SA, "SNA": SNA, "SAA": SAA, "SAN": SAN}
	lineIndex = 1

	try:
		lines = open(srcFileName, "r").readlines()
	except IOError:
		dbg.LogBox("LoadLocaleError(%(srcFileName)s)" % locals())
		app.Abort()

	for line in lines:
		if line.count("\t") == 0:
			continue

		try:
			tokens = line[:-1].split("\t")
			if len(tokens) == 2:
				localeDict[tokens[0]] = tokens[1]
			elif len(tokens) >= 3:
				type = tokens[2].strip()
				if type:
					if type in funcDict:
						localeDict[tokens[0]] = funcDict[type](tokens[1])
					else:
						localeDict[tokens[0]] = tokens[1]
				else:
					localeDict[tokens[0]] = tokens[1]
			else:
				raise RuntimeError, "Unknown TokenSize"

			lineIndex += 1
		except:
			dbg.LogBox("%s: line(%d): %s" % (srcFileName, lineIndex, line), "Error")
			raise

LoadLocaleFile("{:s}/locale_game.txt".format(APP_GET_LOCALE_PATH), locals())
		
# Option pvp messages
OPTION_PVPMODE_MESSAGE_DICT = {
	0: PVP_MODE_NORMAL,
	1: PVP_MODE_REVENGE,
	2: PVP_MODE_KILL,
	3: PVP_MODE_PROTECT,
	4: PVP_MODE_GUILD,
}

# Whisper messages
WHISPER_ERROR = {
	1: CANNOT_WHISPER_NOT_LOGON,
	2: CANNOT_WHISPER_DEST_REFUSE,
	3: CANNOT_WHISPER_SELF_REFUSE,
}

# Exception of graphic device.
error = dict(
	CREATE_WINDOW = GAME_INIT_ERROR_MAIN_WINDOW,
	CREATE_CURSOR = GAME_INIT_ERROR_CURSOR,
	CREATE_NETWORK = GAME_INIT_ERROR_NETWORK,
	CREATE_ITEM_PROTO = GAME_INIT_ERROR_ITEM_PROTO,
	CREATE_MOB_PROTO = GAME_INIT_ERROR_MOB_PROTO,
	CREATE_NO_DIRECTX = GAME_INIT_ERROR_DIRECTX,
	CREATE_DEVICE = GAME_INIT_ERROR_GRAPHICS_NOT_EXIST,
	CREATE_NO_APPROPRIATE_DEVICE = GAME_INIT_ERROR_GRAPHICS_BAD_PERFORMANCE,
	CREATE_FORMAT = GAME_INIT_ERROR_GRAPHICS_NOT_SUPPORT_32BIT,
	NO_ERROR = str()
)

# Job information (none, skill_group1, skill_group2)
JOBINFO_TITLE = [
	[JOB_WARRIOR0, JOB_WARRIOR1, JOB_WARRIOR2,],
	[JOB_ASSASSIN0, JOB_ASSASSIN1, JOB_ASSASSIN2,],
	[JOB_SURA0, JOB_SURA1, JOB_SURA2,],
	[JOB_SHAMAN0, JOB_SHAMAN1, JOB_SHAMAN2,],
]

#if app.ENABLE_WOLFMAN_CHARACTER:
	#JOBINFO_TITLE += [[JOB_WOLFMAN0,JOB_WOLFMAN1,JOB_WOLFMAN2,],]

# Guild war description
GUILDWAR_NORMAL_DESCLIST = 					(GUILD_WAR_USE_NORMAL_MAP, GUILD_WAR_LIMIT_30MIN, GUILD_WAR_WIN_CHECK_SCORE)
# Guild war warp description
GUILDWAR_WARP_DESCLIST = 					(GUILD_WAR_USE_BATTLE_MAP, GUILD_WAR_WIN_WIPE_OUT_GUILD, GUILD_WAR_REWARD_POTION)
# Guild war flag description
GUILDWAR_CTF_DESCLIST = 					(GUILD_WAR_USE_BATTLE_MAP, GUILD_WAR_WIN_TAKE_AWAY_FLAG1, GUILD_WAR_WIN_TAKE_AWAY_FLAG2, GUILD_WAR_REWARD_POTION)

# Mode of pvp options
MODE_NAME_LIST = 							(PVP_OPTION_NORMAL, PVP_OPTION_REVENGE, PVP_OPTION_KILL, PVP_OPTION_PROTECT,)
# Title name of alignment
TITLE_NAME_LIST = 							(PVP_LEVEL0, PVP_LEVEL1, PVP_LEVEL2, PVP_LEVEL3, PVP_LEVEL4, PVP_LEVEL5, PVP_LEVEL6, PVP_LEVEL7, PVP_LEVEL8,)

# Horse levels
LEVEL_LIST = 								(str(), HORSE_LEVEL1, HORSE_LEVEL2, HORSE_LEVEL3)
# Horse health
HEALTH_LIST = 								(HORSE_HEALTH0, HORSE_HEALTH1, HORSE_HEALTH2, HORSE_HEALTH3)

# Use-skill messages
USE_SKILL_ERROR_TAIL_DICT = {	
	'IN_SAFE':								CANNOT_SKILL_SELF_IN_SAFE,
	'NEED_TARGET': 							CANNOT_SKILL_NEED_TARGET,
	'NEED_EMPTY_BOTTLE': 					CANNOT_SKILL_NEED_EMPTY_BOTTLE,
	'NEED_POISON_BOTTLE': 					CANNOT_SKILL_NEED_POISON_BOTTLE,
	'REMOVE_FISHING_ROD': 					CANNOT_SKILL_REMOVE_FISHING_ROD,
	'NOT_YET_LEARN': 						CANNOT_SKILL_NOT_YET_LEARN,
	'NOT_MATCHABLE_WEAPON':					CANNOT_SKILL_NOT_MATCHABLE_WEAPON,
	'WAIT_COOLTIME':						CANNOT_SKILL_WAIT_COOLTIME,
	'NOT_ENOUGH_HP':						CANNOT_SKILL_NOT_ENOUGH_HP,
	'NOT_ENOUGH_SP':						CANNOT_SKILL_NOT_ENOUGH_SP,
	'CANNOT_USE_SELF':						CANNOT_SKILL_USE_SELF,
	'ONLY_FOR_ALLIANCE': 					CANNOT_SKILL_ONLY_FOR_ALLIANCE,
	'CANNOT_ATTACK_ENEMY_IN_SAFE_AREA':		CANNOT_SKILL_DEST_IN_SAFE,
	'CANNOT_APPROACH':						CANNOT_SKILL_APPROACH,
	'CANNOT_ATTACK':						CANNOT_SKILL_ATTACK,
	'ONLY_FOR_CORPSE':						CANNOT_SKILL_ONLY_FOR_CORPSE,
	'EQUIP_FISHING_ROD':					CANNOT_SKILL_EQUIP_FISHING_ROD, 
	'NOT_HORSE_SKILL':						CANNOT_SKILL_NOT_HORSE_SKILL,
	'HAVE_TO_RIDE':							CANNOT_SKILL_HAVE_TO_RIDE,
}

# Notify messages
NOTIFY_MESSAGE = {
	'CANNOT_EQUIP_SHOP': 					CANNOT_EQUIP_IN_SHOP,
	'CANNOT_EQUIP_EXCHANGE': 				CANNOT_EQUIP_IN_EXCHANGE,
}

# Attack messages
ATTACK_ERROR_TAIL_DICT = {
	'IN_SAFE': 								CANNOT_ATTACK_SELF_IN_SAFE,
	'DEST_IN_SAFE': 						CANNOT_ATTACK_DEST_IN_SAFE,
}

# Shot messages
SHOT_ERROR_TAIL_DICT = {
	'EMPTY_ARROW': 							CANNOT_SHOOT_EMPTY_ARROW,
	'IN_SAFE':								CANNOT_SHOOT_SELF_IN_SAFE,
	'DEST_IN_SAFE':							CANNOT_SHOOT_DEST_IN_SAFE,
}

# Skill messages
USE_SKILL_ERROR_CHAT_DICT = {	
	'NEED_EMPTY_BOTTLE': 					SKILL_NEED_EMPTY_BOTTLE,
	'NEED_POISON_BOTTLE': 					SKILL_NEED_POISON_BOTTLE, 
	'ONLY_FOR_GUILD_WAR': 					SKILL_ONLY_FOR_GUILD_WAR,
}

# Shop/private-shop messages
SHOP_ERROR_DICT = {
	'NOT_ENOUGH_MONEY': 					SHOP_NOT_ENOUGH_MONEY,
	'SOLDOUT': 								SHOP_SOLDOUT,
	'INVENTORY_FULL': 						SHOP_INVENTORY_FULL,
	'INVALID_POS': 							SHOP_INVALID_POS,
	'NOT_ENOUGH_MONEY_EX': 					SHOP_NOT_ENOUGH_MONEY_EX,
}

# Character status description
STAT_MINUS_DESCRIPTION = {
	'HTH-': 								STAT_MINUS_CON,
	'INT-': 								STAT_MINUS_INT,
	'STR-': 								STAT_MINUS_STR,
	'DEX-': 								STAT_MINUS_DEX,
}

# Map names
MINIMAP_ZONE_NAME_DICT = {
	'metin2_map_a1': 						MAP_A1,
	'map_a2': 								MAP_A2,
	'metin2_map_a3': 						MAP_A3,
	'metin2_map_b1': 						MAP_B1,
	'map_b2': 								MAP_B2,
	'metin2_map_b3': 						MAP_B3,
	'metin2_map_c1': 						MAP_C1,
	'map_c2': 								MAP_C2,
	'metin2_map_c3': 						MAP_C3,
	'map_n_snowm_01': 						MAP_SNOW,
	'metin2_map_n_flame_01': 				MAP_FLAME,
	'metin2_map_n_desert_01': 				MAP_DESERT,
	'metin2_map_milgyo': 					MAP_TEMPLE,
	'metin2_map_spiderdungeon': 			MAP_SPIDER,
	'metin2_map_deviltower1': 				MAP_SKELTOWER,
	'metin2_map_guild_01': 					MAP_AG,
	'metin2_map_guild_02': 					MAP_BG,
	'metin2_map_guild_03': 					MAP_CG,
	'metin2_map_trent': 					MAP_TREE,
	'metin2_map_trent02': 					MAP_TREE2,
	'season1/metin2_map_WL_01': 			MAP_WL,
	'season1/metin2_map_nusluck01': 		MAP_NUSLUCK,
    'Metin2_map_CapeDragonHead': 			MAP_CAPE,
    'metin2_map_Mt_Thunder': 				MAP_THUNDER,
    'metin2_map_dawnmistwood': 				MAP_DAWN,
    'metin2_map_BayBlackSand': 				MAP_BAY,
}

# Path of quest icon file
def GetLetterImageName():
	return "season1/icon/scroll_close.tga"
	
def GetLetterOpenImageName():
	return "season1/icon/scroll_open.tga"
	
def GetLetterCloseImageName():
	return "season1/icon/scroll_close.tga"
	
# Sell item question
def DO_YOU_SELL_ITEM(sellItemName, sellItemCount, sellItemPrice):
	return DO_YOU_SELL_ITEM2 % (sellItemName, sellItemCount, NumberToMoneyString(sellItemPrice)) if (sellItemCount > 1) else DO_YOU_SELL_ITEM1 % (sellItemName, NumberToMoneyString(sellItemPrice))

# Buy item question
def DO_YOU_BUY_ITEM(buyItemName, buyItemCount, buyItemPrice):
	return DO_YOU_BUY_ITEM2 % (buyItemName, buyItemCount, buyItemPrice) if (buyItemCount > 1) else DO_YOU_BUY_ITEM1 % (buyItemName, buyItemPrice)
		
# Notify when you can't attach a specific item.
def REFINE_FAILURE_CAN_NOT_ATTACH(attachedItemName):
	return REFINE_FAILURE_CAN_NOT_ATTACH0 % (attachedItemName)

def REFINE_FAILURE_NO_SOCKET(attachedItemName):
	return REFINE_FAILURE_NO_SOCKET0 % (attachedItemName)

# Drop item question
def REFINE_FAILURE_NO_GOLD_SOCKET(attachedItemName):
	return REFINE_FAILURE_NO_GOLD_SOCKET0 % (attachedItemName)
	
# Drop item question
def HOW_MANY_ITEM_DO_YOU_DROP(dropItemName, dropItemCount):
	return HOW_MANY_ITEM_DO_YOU_DROP2 % (dropItemName, dropItemCount) if (dropItemCount > 1) else HOW_MANY_ITEM_DO_YOU_DROP1 % (dropItemName)

# Fishing notify when looks like the fish is hooked.
def FISHING_NOTIFY(isFish, fishName):
	return FISHING_NOTIFY1 % (fishName) if isFish else FISHING_NOTIFY2 % (fishName)

# Fishing notify when you capture a fish.
def FISHING_SUCCESS(isFish, fishName):
	return FISHING_SUCCESS1 % (fishName) if isFish else FISHING_SUCCESS2 % (fishName)
	
# Convert a integer amount into a string and add . as separator for money.
def NumberToMoneyString(n):
	return '0 {:s}'.format(MONETARY_UNIT0) if (n <= 0) else '{:s} {:s}'.format('.'.join([(i - 3) < 0 and str(n)[:i] or str(n)[i - 3 : i] for i in range(len(str(n)) % 3, len(str(n)) + 1, 3) if i]), MONETARY_UNIT0)

# Convert a integer amount into a string and add . as separator for secondary coin.
def NumberToSecondaryCoinString(n):
	return '0 {:s}'.format(MONETARY_UNIT_JUN) if (n <= 0) else '{:s} {:s}'.format('.'.join([(i - 3) < 0 and str(n)[:i] or str(n)[i - 3: i] for i in range(len(str(n)) % 3, len(str(n)) + 1, 3) if i]), MONETARY_UNIT_JUN)
	
# Return the title of alignment by points.
def GetAlignmentTitleName(alignment):
	if alignment >= 12000:
		return TITLE_NAME_LIST[0]
	elif alignment >= 8000:
		return TITLE_NAME_LIST[1]
	elif alignment >= 4000:
		return TITLE_NAME_LIST[2]
	elif alignment >= 1000:
		return TITLE_NAME_LIST[3]
	elif alignment >= 0:
		return TITLE_NAME_LIST[4]
	elif alignment > -4000:
		return TITLE_NAME_LIST[5]
	elif alignment > -8000:
		return TITLE_NAME_LIST[6]
	elif alignment > -12000:
		return TITLE_NAME_LIST[7]

	return TITLE_NAME_LIST[8]
	
# Convert seconds to Days-Hours-Minutes
def SecondToDHM(time):
	if time < 60:
		if IsARABIC():
			return '%.2f %s' % (time, SECOND)
		else:
			return '0' + MINUTE

	minute = int((time / 60) % 60)
	hour = int((time / 60) / 60) % 24
	day = int(int((time / 60) / 60) / 24)

	text = ''
	if day > 0:
		text += str(day) + DAY
		text += ' '

	if hour > 0:
		text += str(hour) + HOUR
		text += ' '

	if minute > 0:
		text += str(minute) + MINUTE
	return text

# Convert seconds to Hours-Minutes
def SecondToHM(time):
	if time < 60:
		if IsARABIC():
			return '%.2f %s' % (time, SECOND)
		else:
			return '0' + MINUTE

	minute = int((time / 60) % 60)
	hour = int((time / 60) / 60)

	text = ''
	if hour > 0:
		text += str(hour) + HOUR
		if hour > 0:
			text += ' '

	if minute > 0:
		text += str(minute) + MINUTE
	return text

 

 

This is the hidden content, please

  • Metin2 Dev 41
  • kekw 1
  • Eyes 1
  • Smile Tear 1
  • Confused 1
  • Good 8
  • Love 47
Link to comment
Share on other sites

  • Premium

I suggest you to put the file inside a Quote, because we're unable to download attachments.

 

At least, it doesn't let me <_<

  • Love 1

 

"Nothing's free in this life.

Ignorant people have an obligation to make up for their ignorance by paying those who help them.

Either you got the brains or cash, if you lack both you're useless."

Syreldar

Link to comment
Share on other sites

  • Forum Moderator
  • Added a gist link for download.
  • Fixed NumberToMoneyString format method. (thanks to @Syreldar)
  • Love 2
Link to comment
Share on other sites

  • 3 months later...
  • Premium
0714 17:03:19906 :: 
uiCharacter.py(line:430) __LoadWindow
uiCharacter.py(line:257) __BindObject
uicharacterdetails.py(line:45) __init__
uicharacterdetails.py(line:73) __LoadScript
uicharacterdetails.py(line:88) __Initialize
uicharacterdetails.py(line:99) CreateTooltip

CharacterWindow.__LoadWindow - <type 'exceptions.AttributeError'>:'module' object has no attribute 'GetVariableName'

0714 17:03:19906 :: ============================================================================================================
0714 17:03:19906 :: Abort!!!!

 

  • Love 1
Link to comment
Share on other sites

  • Honorable Member
43 minutes ago, Caramelito said:

0714 17:03:19906 :: 
uiCharacter.py(line:430) __LoadWindow
uiCharacter.py(line:257) __BindObject
uicharacterdetails.py(line:45) __init__
uicharacterdetails.py(line:73) __LoadScript
uicharacterdetails.py(line:88) __Initialize
uicharacterdetails.py(line:99) CreateTooltip

CharacterWindow.__LoadWindow - <type 'exceptions.AttributeError'>:'module' object has no attribute 'GetVariableName'

0714 17:03:19906 :: ============================================================================================================
0714 17:03:19906 :: Abort!!!!

 

Look at your old locale and find GetVariableName and add to new file

  • Love 1

 

Link to comment
Share on other sites

  • 4 months later...
  • Forum Moderator
22 minutes ago, hardy89 said:

thank you

Some functions would be shorter and more efficient with certain functions ...
Like


def SecondToHM(time):
  return " ".join(map(str, divmod(time, 60)))

 

I could rewrite all of the functions and structure but i don't do it because the scope was to clean it not to change all structure, i did this long time ago.. if you saw the date.

Btw, It's funny how you talk about shorter and efficient functions in python while...

The code everytime can be improved, i don't like maybe a lot of scripts from metin2, but that doesn't means i've to rewrite them, there's isn't so much performance for a python script, if we don't talk about loops, searching, sort etc, it's fine how is it right now.

  • Love 2
Link to comment
Share on other sites

  • Premium
5 minut temu, VegaS™ napisał:

I could rewrite all of the functions and structure but i don't do it because the scope was to clean it not to change all structure, i did this some time ago.

It's funny how you talk about shorter and efficient functions in python while...you've no idea about python ?

Let's don't do off-topic.

I don't get it. You did rewrite bunch of functions except for last 3. Almost 2 years passed since he asked you about that. I think you are a bit cocky 

Link to comment
Share on other sites

  • Forum Moderator
27 minutes ago, filipw1 said:

I don't get it. You did rewrite bunch of functions except for last 3.

I didn't rewrote the functions, is the same code, maybe removed unused lines or put them inline.

Let's take an example, this:

def GetAlignmentTitleName(alignment):
	if alignment >= 12000:
		return TITLE_NAME_LIST[0]
	elif alignment >= 8000:
		return TITLE_NAME_LIST[1]
	elif alignment >= 4000:
		return TITLE_NAME_LIST[2]
	elif alignment >= 1000:
		return TITLE_NAME_LIST[3]
	elif alignment >= 0:
		return TITLE_NAME_LIST[4]
	elif alignment > -4000:
		return TITLE_NAME_LIST[5]
	elif alignment > -8000:
		return TITLE_NAME_LIST[6]
	elif alignment > -12000:
		return TITLE_NAME_LIST[7]

	return TITLE_NAME_LIST[8]

We could do it as (just example, ignore the comparation): (without making a dictionary)

def GetAlignmentTitleName(currentAlignment):
	for alignmentIndex, alignmentValue in enumerate((12000, 8000, 4000, 1000, 0, -4000, -8000, -12000)):
		if currentAlignment >= alignmentValue:
			return TITLE_NAME_LIST[alignmentIndex]
	return TITLE_NAME_LIST[-1]

Do you think people will understand it so well what's the index if they don't know what the function does?
That's why i didn't touch these functions, they've edited (like added alignment grades) and don't know how to extend it.

Btw, if you want to discuss this, we can go in off-topic category, already is enough.

  • Love 3
Link to comment
Share on other sites

Il y a 2 heures, VegaS™ a dit :

I could rewrite all of the functions and structure but i don't do it because the scope was to clean it not to change all structure, i did this long time ago.. if you saw the date.

Btw, It's funny how you talk about shorter and efficient functions in python while...

The code everytime can be improved, i don't like maybe a lot of scripts from metin2, but that doesn't means i've to rewrite them, there's isn't so much performance for a python script, if we don't talk about loops, searching, sort etc, it's fine how is it right now.

I did that a long time ago to... Sorry, bbut seeing that you had refactored some functions, I thought you had forgotten this one. I just give an another way to do this. 

 

il y a une heure, VegaS™ a dit :

 


def GetAlignmentTitleName(currentAlignment):
	for alignmentIndex, alignmentValue in enumerate((12000, 8000, 4000, 1000, 0, -4000, -8000, -12000)):
		if currentAlignment >= alignmentValue:
			return TITLE_NAME_LIST[alignmentIndex]
	return TITLE_NAME_LIST[-1]

Do you think people will understand it so well what's the index if they don't know what the function does?
That's why i didn't touch these functions, they've edited (like added alignment grades) and don't know how to extend it.

Btw, if you want to discuss this, we can go in off-topic category, already is enough.

I think that people will understand better this code, even without actually understanding how it works that the huge ternary conditions of the other functions ... like :

	def NumberToMoneyString(n):
	return '0 {:s}'.format(MONETARY_UNIT0) if (n <= 0) else '{:s} {:s}'.format(('.'.join([(i - 3) < 0 and str(n)[:i] or str(n)[i - 3 : i] for i in range(len(str(n)) % 3, len(str(n)) + 1, 3) if i]), MONETARY_UNIT0))

Word to the wise...

Link to comment
Share on other sites

  • Forum Moderator

You're right, then let's refactor this shit.

Ymir method:

def NumberToMoneyString(n) :
	if n <= 0 :
		return "0 %s" % (MONETARY_UNIT0)
	return "%s %s" % ('.'.join([ i-3<0 and str(n)[:i] or str(n)[i-3:i] for i in range(len(str(n))%3, len(str(n))+1, 3) if i ]), MONETARY_UNIT0)
  
def NumberToSecondaryCoinString(n, coinType) :
	if n <= 0:
		n = 0

	coinTypeString = ""
	if coinType == shop.SHOP_COIN_TYPE_SECONDARY_COIN:
		coinTypeString = MONETARY_UNIT_JUN
	elif coinType == shop.SHOP_COIN_TYPE_BATTLE_POINT:
		coinTypeString = BATTLE_POINT
	elif app.ENABLE_10TH_EVENT and coinType == shop.SHOP_COIN_TYPE_10TH_EVENT:
		coinTypeString = TENTH_COIN
	else:
		return "Not Valied"

	return "%s %s" % ('.'.join([ i-3<0 and str(n)[:i] or str(n)[i-3:i] for i in range(len(str(n))%3, len(str(n))+1, 3) if i ]), coinTypeString)

My method:

This is the hidden content, please

236cbaece01052cf31d3764bb32e7124.png

And yes, Ymir killed the python for no-reason.

Edited by Metin2 Dev
Core X - External 2 Internal
  • Metin2 Dev 17
  • kekw 1
  • Dislove 1
  • Good 6
  • Love 1
  • Love 13
Link to comment
Share on other sites

  • Premium
4 godziny temu, VegaS™ napisał:

You're right, then let's refactor this shit.

Ymir method:


def NumberToMoneyString(n) :
	if n <= 0 :
		return "0 %s" % (MONETARY_UNIT0)
	return "%s %s" % ('.'.join([ i-3<0 and str(n)[:i] or str(n)[i-3:i] for i in range(len(str(n))%3, len(str(n))+1, 3) if i ]), MONETARY_UNIT0)
  
def NumberToSecondaryCoinString(n, coinType) :
	if n <= 0:
		n = 0

	coinTypeString = ""
	if coinType == shop.SHOP_COIN_TYPE_SECONDARY_COIN:
		coinTypeString = MONETARY_UNIT_JUN
	elif coinType == shop.SHOP_COIN_TYPE_BATTLE_POINT:
		coinTypeString = BATTLE_POINT
	elif app.ENABLE_10TH_EVENT and coinType == shop.SHOP_COIN_TYPE_10TH_EVENT:
		coinTypeString = TENTH_COIN
	else:
		return "Not Valied"

	return "%s %s" % ('.'.join([ i-3<0 and str(n)[:i] or str(n)[i-3:i] for i in range(len(str(n))%3, len(str(n))+1, 3) if i ]), coinTypeString)

My method:


def NumberToMoneyString(value, currency=MONETARY_UNIT0):
	return "{:0,.0f} {}".format(value, currency).replace(',', '.')

# Test
localeInfo.NumberToMoneyString(1934263992)                # 1.934.263.992 Yang 
localeInfo.NumberToMoneyString(200000, MONETARY_UNIT_JUN) # 200.000 Jun
localeInfo.NumberToMoneyString(4210, BATTLE_POINT)        # 4.210 Combat Points
localeInfo.NumberToMoneyString(500, TENTH_COIN)           # 500 Anniversary Coin(s)

236cbaece01052cf31d3764bb32e7124.png

And yes, Ymir killed the python for no-reason.

My guess is that string formating wasn't a thing when they did that code, so they coded it just to work somewhat good. 

Edited by Metin2 Dev
Core X - External 2 Internal
Link to comment
Share on other sites

  • Forum Moderator
2 hours ago, filipw1 said:

My guess is that string formating wasn't a thing when they did that code, so they coded it just to work somewhat good. 

The function NumberToSecondaryCoinString which i posted is recent in their root, format string exists since Python 2.6, 11 years ago. Who stop them to use it? Nobody, they do a lot of things in a hard-way, they don't use many builtin functions which doing the same thing even in 2019, they prefer to do it manually in a hard way , they like old ways.

Btw, i don't see the reason why we talk about this since we talked about 'refactoring', which means advantages include improved code readability and reduced complexity, doesn't matter what they had before.

I think it's enough for today, let's don't talk about this anymore here, i'll update the gist link when i've time with these functions modified, thanks for support.

  • Metin2 Dev 1
  • Love 2
Link to comment
Share on other sites

  • 2 months later...
  • Forum Moderator

Default code for SecondToXXX:

Spoiler

 


def SecondToDHM(time):
	if time < 60:
		if IsARABIC():
			return '%.2f %s' % (time, SECOND)
		else:
			return '0' + MINUTE

	minute = int((time / 60) % 60)
	hour = int((time / 60) / 60) % 24
	day = int(int((time / 60) / 60) / 24)

	text = ''
	if day > 0:
		text += str(day) + DAY
		text += ' '

	if hour > 0:
		text += str(hour) + HOUR
		text += ' '

	if minute > 0:
		text += str(minute) + MINUTE
	return text

def SecondToHM(time):
	if time < 60:
		if IsARABIC():
			return '%.2f %s' % (time, SECOND)
		else:
			return '0' + MINUTE

	minute = int((time / 60) % 60)
	hour = int((time / 60) / 60)

	text = ''
	if hour > 0:
		text += str(hour) + HOUR
		if hour > 0:
			text += ' '

	if minute > 0:
		text += str(minute) + MINUTE
	return text

 

My extendable version: (I wrote that fast, so, if there's a problem with it, write me a pm, let's don't spam the topic.)

This is the hidden content, please

Results:

print sec2time(100000, "DHMS")
>>> 1Days 3Hours 46Minutes 40Seconds

print sec2time(10000, "HMS")
>>> 2Hours 46Minutes 40Seconds

print sec2time(1000, "MS")
>>> 16Minutes 40Seconds

print sec2time(1000, "M")
>>> 16Minutes

print sec2time(100, "S")
>>> 40Seconds

print sec2time(3600, "DHMS", True)
>>> 0Days 1Hours 0Minutes 0Seconds

print sec2time(3600, "DHMS")
>>> 1Hours

I still don't have the right time to update the module but i'll do it asap.

Edited by VegaS™
  • Metin2 Dev 2
  • Love 13
Link to comment
Share on other sites

  • Forum Moderator
1 hour ago, Hik said:

LoadLocaleError(locale/de/locale_game.txt)

 

Change open method with pack_open in LoadLocaleFile. (for those who've that problem)

Edited by VegaS™
  • Love 3
Link to comment
Share on other sites

Announcements



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.