diff --git a/includes/class.community.php b/includes/community.class.php similarity index 100% rename from includes/class.community.php rename to includes/community.class.php diff --git a/includes/class.database.php b/includes/database.class.php similarity index 100% rename from includes/class.database.php rename to includes/database.class.php diff --git a/includes/defines.php b/includes/defines.php index 78b06cf6..4d242efa 100644 --- a/includes/defines.php +++ b/includes/defines.php @@ -87,6 +87,7 @@ define('LOCALE_DE', 3); define('LOCALE_ES', 6); define('LOCALE_RU', 8); +// generic filter handler define('FILTER_CR_BOOLEAN', 1); define('FILTER_CR_FLAG', 2); define('FILTER_CR_NUMERIC', 3); @@ -98,12 +99,13 @@ define('FILTER_CR_STAFFFLAG', 6); define('GLOBALINFO_SELF', 0x1); // id, name, icon define('GLOBALINFO_RELATED', 0x2); // spells used by pet, classes/races required by spell, ect define('GLOBALINFO_REWARDS', 0x4); // items rewarded by achievement/quest, ect +define('GLOBALINFO_EXTRA', 0x8); // items / spells .. sends exra tooltip info to template for js-manipulation define('GLOBALINFO_ANY', 0xF); define('ITEMINFO_JSON', 0x01); define('ITEMINFO_SUBITEMS', 0x02); define('ITEMINFO_VENDOR', 0x04); -define('ITEMINFO_LOOT', 0x08); +// define('ITEMINFO_LOOT', 0x08); // get these infos from dedicatd loot function [count, stack, pctstack, modes] define('ITEMINFO_GEM', 0x10); define('NPCINFO_TAMEABLE', 0x1); @@ -150,6 +152,20 @@ define('OBJECT_CU_NOT_PERSISTANT', 0x80); define('MAX_LEVEL', 80); +// Loot handles +define('LOOT_FISHING', 'fishing_loot_template'); +define('LOOT_CREATURE', 'creature_loot_template'); +define('LOOT_GAMEOBJECT', 'gameobject_loot_template'); +define('LOOT_ITEM', 'item_loot_template'); +define('LOOT_DISENCHANT', 'disenchant_loot_template'); +define('LOOT_PROSPECTING', 'prospecting_loot_template'); +define('LOOT_MILLING', 'milling_loot_template'); +define('LOOT_PICKPOCKET', 'pickpocketing_loot_template'); +define('LOOT_SKINNING', 'skinning_loot_template'); +define('LOOT_QUEST', 'quest_mail_loot_template'); +define('LOOT_SPELL', 'spell_loot_template'); +define('LOOT_REFERENCE', 'reference_loot_template'); + // Sides define('SIDE_ALLIANCE', 1); define('SIDE_HORDE', 2); @@ -332,7 +348,7 @@ define('OBJECT_DESTRUCTIBLE_BUILDING', 33); define('OBJECT_GUILD_BANK', 34); define('OBJECT_TRAPDOOR', 35); -// InventoryType [slot] +// InventoryType define('INVTYPE_NON_EQUIP', 0); define('INVTYPE_HEAD', 1); define('INVTYPE_NECK', 2); @@ -391,7 +407,7 @@ define('ITEM_CLASS_AMMUNITION', 6); define('ITEM_CLASS_TRADEGOOD', 7); // define('ITEM_CLASS_GENERIC', 8); define('ITEM_CLASS_RECIPE', 9); -// define('ITEM_CLASS_MONEY', 10); +define('ITEM_CLASS_MONEY', 10); define('ITEM_CLASS_QUIVER', 11); define('ITEM_CLASS_QUEST', 12); define('ITEM_CLASS_KEY', 13); @@ -400,14 +416,21 @@ define('ITEM_CLASS_MISC', 15); define('ITEM_CLASS_GLYPH', 16); // ItemFlags -define('ITEM_FLAG_CONJURED', 0x0000002); -define('ITEM_FLAG_OPENABLE', 0x0000004); -define('ITEM_FLAG_HEROIC', 0x0000008); -define('ITEM_FLAG_DEPRECATED', 0x0000010); -define('ITEM_FLAG_PARTYLOOT', 0x0000800); -define('ITEM_FLAG_REFUNDABLE', 0x0001000); -define('ITEM_FLAG_UNIQUEEQUIPPED', 0x0080000); -define('ITEM_FLAG_ACCOUNTBOUND', 0x8000000); +define('ITEM_FLAG_CONJURED', 0x00000002); +define('ITEM_FLAG_OPENABLE', 0x00000004); +define('ITEM_FLAG_HEROIC', 0x00000008); +define('ITEM_FLAG_DEPRECATED', 0x00000010); +define('ITEM_FLAG_INDESTRUCTIBLE', 0x00000020); +define('ITEM_FLAG_NO_EQUIPCD', 0x00000080); +define('ITEM_FLAG_PARTYLOOT', 0x00000800); +define('ITEM_FLAG_REFUNDABLE', 0x00001000); +define('ITEM_FLAG_PROSPECTABLE', 0x00040000); +define('ITEM_FLAG_UNIQUEEQUIPPED', 0x00080000); +define('ITEM_FLAG_USABLE_ARENA', 0x00200000); +define('ITEM_FLAG_USABLE_SHAPED', 0x00800000); +define('ITEM_FLAG_SMARTLOOT', 0x02000000); +define('ITEM_FLAG_ACCOUNTBOUND', 0x08000000); +define('ITEM_FLAG_MILLABLE', 0x20000000); // ItemMod (differ slightly from client, see g_statToJson) define('ITEM_MOD_WEAPON_DMG', 0); // < custom diff --git a/includes/kernel.php b/includes/kernel.php index c721fb20..76a885dc 100644 --- a/includes/kernel.php +++ b/includes/kernel.php @@ -14,21 +14,21 @@ error_reporting($e); define('STATIC_URL', substr('http://'.$_SERVER['SERVER_NAME'].strtr($_SERVER['SCRIPT_NAME'], ['index.php' => '']), 0, -1)); -require 'includes/Smarty-2.6.26/libs/Smarty.class.php'; // Libraray: http://www.smarty.net/ -// require 'includes/Smarty-3.1.14/libs/Smarty.class.php'; // Libraray: http://www.smarty.net/ -require 'includes/DbSimple/Generic.php'; // Libraray: http://en.dklab.ru/lib/DbSimple (mysqli: https://bitbucket.org/brainreaver/dbsimple/src) +require 'includes/libs/Smarty-2.6.26/libs/Smarty.class.php';// Libraray: http://www.smarty.net/ +// require 'includes/libs/Smarty-3.1.14/libs/Smarty.class.php'; // Libraray: http://www.smarty.net/ +require 'includes/libs/DbSimple/Generic.php'; // Libraray: http://en.dklab.ru/lib/DbSimple (using mysqli variant: https://bitbucket.org/brainreaver/dbsimple/src) require 'includes/utilities.php'; -require 'includes/class.user.php'; -require 'includes/class.database.php'; +require 'includes/user.class.php'; +require 'includes/database.class.php'; // autoload List-Classes and Associated Filters spl_autoload_register(function ($class) { if (strpos($class, 'List') && !class_exists($class)) { if (!class_exists('BaseType')) - require 'includes/class.basetype.php'; + require 'includes/types/basetype.class.php'; - require 'includes/class.'.strtr($class, ['List' => '']).'.php'; + require 'includes/types/'.strtr($class, ['List' => '']).'.class.php'; } }); diff --git a/includes/DbSimple/Connect.php b/includes/libs/DbSimple/Connect.php similarity index 100% rename from includes/DbSimple/Connect.php rename to includes/libs/DbSimple/Connect.php diff --git a/includes/DbSimple/Database.php b/includes/libs/DbSimple/Database.php similarity index 100% rename from includes/DbSimple/Database.php rename to includes/libs/DbSimple/Database.php diff --git a/includes/DbSimple/Generic.php b/includes/libs/DbSimple/Generic.php similarity index 100% rename from includes/DbSimple/Generic.php rename to includes/libs/DbSimple/Generic.php diff --git a/includes/DbSimple/Ibase.php b/includes/libs/DbSimple/Ibase.php similarity index 100% rename from includes/DbSimple/Ibase.php rename to includes/libs/DbSimple/Ibase.php diff --git a/includes/DbSimple/Mysql.php b/includes/libs/DbSimple/Mysql.php similarity index 100% rename from includes/DbSimple/Mysql.php rename to includes/libs/DbSimple/Mysql.php diff --git a/includes/DbSimple/Mysqli.php b/includes/libs/DbSimple/Mysqli.php similarity index 100% rename from includes/DbSimple/Mysqli.php rename to includes/libs/DbSimple/Mysqli.php diff --git a/includes/DbSimple/Postgresql.php b/includes/libs/DbSimple/Postgresql.php similarity index 100% rename from includes/DbSimple/Postgresql.php rename to includes/libs/DbSimple/Postgresql.php diff --git a/includes/Smarty-2.6.26/libs/Config_File.class.php b/includes/libs/Smarty-2.6.26/libs/Config_File.class.php similarity index 100% rename from includes/Smarty-2.6.26/libs/Config_File.class.php rename to includes/libs/Smarty-2.6.26/libs/Config_File.class.php diff --git a/includes/Smarty-2.6.26/libs/Smarty.class.php b/includes/libs/Smarty-2.6.26/libs/Smarty.class.php similarity index 100% rename from includes/Smarty-2.6.26/libs/Smarty.class.php rename to includes/libs/Smarty-2.6.26/libs/Smarty.class.php diff --git a/includes/Smarty-2.6.26/libs/Smarty_Compiler.class.php b/includes/libs/Smarty-2.6.26/libs/Smarty_Compiler.class.php similarity index 100% rename from includes/Smarty-2.6.26/libs/Smarty_Compiler.class.php rename to includes/libs/Smarty-2.6.26/libs/Smarty_Compiler.class.php diff --git a/includes/Smarty-2.6.26/libs/debug.tpl b/includes/libs/Smarty-2.6.26/libs/debug.tpl similarity index 100% rename from includes/Smarty-2.6.26/libs/debug.tpl rename to includes/libs/Smarty-2.6.26/libs/debug.tpl diff --git a/includes/Smarty-2.6.26/libs/internals/core.assemble_plugin_filepath.php b/includes/libs/Smarty-2.6.26/libs/internals/core.assemble_plugin_filepath.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.assemble_plugin_filepath.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.assemble_plugin_filepath.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.assign_smarty_interface.php b/includes/libs/Smarty-2.6.26/libs/internals/core.assign_smarty_interface.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.assign_smarty_interface.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.assign_smarty_interface.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.create_dir_structure.php b/includes/libs/Smarty-2.6.26/libs/internals/core.create_dir_structure.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.create_dir_structure.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.create_dir_structure.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.display_debug_console.php b/includes/libs/Smarty-2.6.26/libs/internals/core.display_debug_console.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.display_debug_console.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.display_debug_console.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.get_include_path.php b/includes/libs/Smarty-2.6.26/libs/internals/core.get_include_path.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.get_include_path.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.get_include_path.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.get_microtime.php b/includes/libs/Smarty-2.6.26/libs/internals/core.get_microtime.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.get_microtime.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.get_microtime.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.get_php_resource.php b/includes/libs/Smarty-2.6.26/libs/internals/core.get_php_resource.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.get_php_resource.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.get_php_resource.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.is_secure.php b/includes/libs/Smarty-2.6.26/libs/internals/core.is_secure.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.is_secure.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.is_secure.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.is_trusted.php b/includes/libs/Smarty-2.6.26/libs/internals/core.is_trusted.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.is_trusted.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.is_trusted.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.load_plugins.php b/includes/libs/Smarty-2.6.26/libs/internals/core.load_plugins.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.load_plugins.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.load_plugins.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.load_resource_plugin.php b/includes/libs/Smarty-2.6.26/libs/internals/core.load_resource_plugin.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.load_resource_plugin.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.load_resource_plugin.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.process_cached_inserts.php b/includes/libs/Smarty-2.6.26/libs/internals/core.process_cached_inserts.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.process_cached_inserts.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.process_cached_inserts.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.process_compiled_include.php b/includes/libs/Smarty-2.6.26/libs/internals/core.process_compiled_include.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.process_compiled_include.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.process_compiled_include.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.read_cache_file.php b/includes/libs/Smarty-2.6.26/libs/internals/core.read_cache_file.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.read_cache_file.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.read_cache_file.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.rm_auto.php b/includes/libs/Smarty-2.6.26/libs/internals/core.rm_auto.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.rm_auto.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.rm_auto.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.rmdir.php b/includes/libs/Smarty-2.6.26/libs/internals/core.rmdir.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.rmdir.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.rmdir.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.run_insert_handler.php b/includes/libs/Smarty-2.6.26/libs/internals/core.run_insert_handler.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.run_insert_handler.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.run_insert_handler.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.smarty_include_php.php b/includes/libs/Smarty-2.6.26/libs/internals/core.smarty_include_php.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.smarty_include_php.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.smarty_include_php.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.write_cache_file.php b/includes/libs/Smarty-2.6.26/libs/internals/core.write_cache_file.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.write_cache_file.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.write_cache_file.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.write_compiled_include.php b/includes/libs/Smarty-2.6.26/libs/internals/core.write_compiled_include.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.write_compiled_include.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.write_compiled_include.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.write_compiled_resource.php b/includes/libs/Smarty-2.6.26/libs/internals/core.write_compiled_resource.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.write_compiled_resource.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.write_compiled_resource.php diff --git a/includes/Smarty-2.6.26/libs/internals/core.write_file.php b/includes/libs/Smarty-2.6.26/libs/internals/core.write_file.php similarity index 100% rename from includes/Smarty-2.6.26/libs/internals/core.write_file.php rename to includes/libs/Smarty-2.6.26/libs/internals/core.write_file.php diff --git a/includes/Smarty-2.6.26/libs/plugins/block.textformat.php b/includes/libs/Smarty-2.6.26/libs/plugins/block.textformat.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/block.textformat.php rename to includes/libs/Smarty-2.6.26/libs/plugins/block.textformat.php diff --git a/includes/Smarty-2.6.26/libs/plugins/compiler.assign.php b/includes/libs/Smarty-2.6.26/libs/plugins/compiler.assign.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/compiler.assign.php rename to includes/libs/Smarty-2.6.26/libs/plugins/compiler.assign.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.assign_debug_info.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.assign_debug_info.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.assign_debug_info.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.assign_debug_info.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.config_load.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.config_load.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.config_load.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.config_load.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.counter.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.counter.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.counter.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.counter.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.cycle.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.cycle.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.cycle.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.cycle.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.debug.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.debug.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.debug.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.debug.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.eval.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.eval.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.eval.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.eval.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.fetch.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.fetch.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.fetch.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.fetch.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.html_checkboxes.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.html_checkboxes.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.html_checkboxes.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.html_checkboxes.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.html_image.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.html_image.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.html_image.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.html_image.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.html_options.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.html_options.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.html_options.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.html_options.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.html_radios.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.html_radios.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.html_radios.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.html_radios.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.html_select_date.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.html_select_date.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.html_select_date.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.html_select_date.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.html_select_time.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.html_select_time.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.html_select_time.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.html_select_time.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.html_table.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.html_table.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.html_table.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.html_table.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.mailto.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.mailto.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.mailto.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.mailto.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.math.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.math.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.math.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.math.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.popup.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.popup.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.popup.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.popup.php diff --git a/includes/Smarty-2.6.26/libs/plugins/function.popup_init.php b/includes/libs/Smarty-2.6.26/libs/plugins/function.popup_init.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/function.popup_init.php rename to includes/libs/Smarty-2.6.26/libs/plugins/function.popup_init.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.capitalize.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.capitalize.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.capitalize.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.capitalize.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.cat.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.cat.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.cat.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.cat.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.count_characters.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.count_characters.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.count_characters.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.count_characters.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.count_paragraphs.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.count_paragraphs.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.count_paragraphs.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.count_paragraphs.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.count_sentences.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.count_sentences.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.count_sentences.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.count_sentences.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.count_words.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.count_words.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.count_words.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.count_words.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.date_format.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.date_format.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.date_format.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.date_format.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.debug_print_var.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.debug_print_var.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.debug_print_var.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.debug_print_var.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.default.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.default.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.default.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.default.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.escape.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.escape.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.escape.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.escape.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.indent.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.indent.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.indent.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.indent.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.lower.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.lower.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.lower.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.lower.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.nl2br.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.nl2br.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.nl2br.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.nl2br.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.regex_replace.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.regex_replace.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.regex_replace.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.regex_replace.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.replace.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.replace.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.replace.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.replace.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.spacify.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.spacify.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.spacify.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.spacify.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.string_format.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.string_format.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.string_format.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.string_format.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.strip.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.strip.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.strip.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.strip.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.strip_tags.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.strip_tags.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.strip_tags.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.strip_tags.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.truncate.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.truncate.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.truncate.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.truncate.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.upper.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.upper.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.upper.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.upper.php diff --git a/includes/Smarty-2.6.26/libs/plugins/modifier.wordwrap.php b/includes/libs/Smarty-2.6.26/libs/plugins/modifier.wordwrap.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/modifier.wordwrap.php rename to includes/libs/Smarty-2.6.26/libs/plugins/modifier.wordwrap.php diff --git a/includes/Smarty-2.6.26/libs/plugins/outputfilter.trimwhitespace.php b/includes/libs/Smarty-2.6.26/libs/plugins/outputfilter.trimwhitespace.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/outputfilter.trimwhitespace.php rename to includes/libs/Smarty-2.6.26/libs/plugins/outputfilter.trimwhitespace.php diff --git a/includes/Smarty-2.6.26/libs/plugins/shared.escape_special_chars.php b/includes/libs/Smarty-2.6.26/libs/plugins/shared.escape_special_chars.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/shared.escape_special_chars.php rename to includes/libs/Smarty-2.6.26/libs/plugins/shared.escape_special_chars.php diff --git a/includes/Smarty-2.6.26/libs/plugins/shared.make_timestamp.php b/includes/libs/Smarty-2.6.26/libs/plugins/shared.make_timestamp.php similarity index 100% rename from includes/Smarty-2.6.26/libs/plugins/shared.make_timestamp.php rename to includes/libs/Smarty-2.6.26/libs/plugins/shared.make_timestamp.php diff --git a/includes/class.achievement.php b/includes/types/achievement.class.php similarity index 100% rename from includes/class.achievement.php rename to includes/types/achievement.class.php diff --git a/includes/class.basetype.php b/includes/types/basetype.class.php similarity index 99% rename from includes/class.basetype.php rename to includes/types/basetype.class.php index 9a8a83c6..153eca11 100644 --- a/includes/class.basetype.php +++ b/includes/types/basetype.class.php @@ -521,7 +521,6 @@ trait spawnHelper } } - /* roight! just noticed, that the filters on pages originally pointed to ?filter= @@ -771,10 +770,10 @@ abstract class Filter { if ($this->int2Bool($op)) { - if ($isString) - return [$field, '', $op ? '!' : null]; - else - return [$field, 0, $op ? '>' : '<=']; + $value = $isString ? '' : 0; + $operator = $op ? '!' : null; + + return [$field, $value, $operator]; } return null; diff --git a/includes/class.charclass.php b/includes/types/charclass.class.php similarity index 100% rename from includes/class.charclass.php rename to includes/types/charclass.class.php diff --git a/includes/class.charrace.php b/includes/types/charrace.class.php similarity index 100% rename from includes/class.charrace.php rename to includes/types/charrace.class.php diff --git a/includes/class.creature.php b/includes/types/creature.class.php similarity index 100% rename from includes/class.creature.php rename to includes/types/creature.class.php diff --git a/includes/class.currency.php b/includes/types/currency.class.php similarity index 100% rename from includes/class.currency.php rename to includes/types/currency.class.php diff --git a/includes/class.faction.php b/includes/types/faction.class.php similarity index 100% rename from includes/class.faction.php rename to includes/types/faction.class.php diff --git a/includes/class.gameobject.php b/includes/types/gameobject.class.php similarity index 100% rename from includes/class.gameobject.php rename to includes/types/gameobject.class.php diff --git a/includes/class.item.php b/includes/types/item.class.php similarity index 65% rename from includes/class.item.php rename to includes/types/item.class.php index aa994d97..88e50905 100644 --- a/includes/class.item.php +++ b/includes/types/item.class.php @@ -3,13 +3,23 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); +/* + ! DONT FORGET ! + + REMOVE TEMP-HACK FROM Lang::load + + fix locale files in gereral >.< + + ! DONT FORGET ! +*/ + class ItemList extends BaseType { use ListviewHelper; public static $type = TYPE_ITEM; - public $tooltip = ''; + public $tooltip = []; public $json = []; public $itemMods = []; @@ -21,8 +31,8 @@ class ItemList extends BaseType protected $queryBase = 'SELECT i.*, i.id AS ARRAY_KEY FROM ?_items i'; protected $queryOpts = array( 'is' => [ 's' => ', 1 as score', 'j' => '?_item_stats AS `is` ON `is`.`id` = `i`.`id`', 'h' => 'score > 0', 'o' => 'score DESC'], - 'iet' => [['ire'], 'j' => 'item_enchantment_template AS `iet` ON IF (`ire`.`id` > 0, `iet`.`entry` = `i`.`randomProperty`, `iet`.`entry` = `i`.`randomSuffix`)'], - 'ire' => [['iet'], 'j' => '?_itemrandomenchant AS `ire` ON ABS(ire.id) = iet.ench'], + // 'iet' => [['ire'], 'j' => 'item_enchantment_template AS `iet` ON IF (`ire`.`id` > 0, `iet`.`entry` = `i`.`randomProperty`, `iet`.`entry` = `i`.`randomSuffix`)'], + // 'ire' => [['iet'], 'j' => '?_itemrandomenchant AS `ire` ON ABS(ire.id) = iet.ench'], 'i' => [ 'o' => 'i.quality DESC, i.itemLevel DESC'] ); @@ -72,36 +82,10 @@ class ItemList extends BaseType return Util::localizedString($n, 'name'); } - public static function getEquivalentSetPieces($id) + public function getExtendedCost() { - return DB::Aowow()->selectCol(' - SELECT - a.id - FROM - ?_items a, - ?_items b - WHERE - b.id = ?d AND - a.slotBak = b.slotBak AND - a.itemset = b.itemset', - $id - ); - } - // end static use - - public function getDetailPageData() - { - $data = array( - 'color' => Util::$rarityColorStings[$this->getField('quality')], - 'icon' => $this->getField('iconString'), - 'name' => $this->getField('name', true), - 'displayId' => $this->getField('displayId'), - 'slot' => $this->getField('slot'), - 'stack' => $this->getField('stackable'), - 'class' => $this->getField('class'), - ); - - return $data; + // placeholder + return []; } public function getListviewData($addInfoMask = 0x0) @@ -110,18 +94,16 @@ class ItemList extends BaseType * ITEMINFO_JSON (0x01): itemMods (including spells) and subitems parsed * ITEMINFO_SUBITEMS (0x02): searched by comparison * ITEMINFO_VENDOR (0x04): costs-obj, when displayed as vendor - * ITEMINFO_LOOT (0x08): count, stack, pctstack, modes when displaying loot * ITEMINFO_GEM (0x10): gem infos and score */ + // random item is random + if ($addInfoMask & ITEMINFO_SUBITEMS) + $this->initSubItems(); + $data = []; foreach ($this->iterate() as $__) { - // random item is random - if ($this->curTpl['randomProperty'] > 0 || $this->curTpl['randomSuffix'] > 0) - if ($addInfoMask & ITEMINFO_SUBITEMS) - $this->initSubItems(); - if ($addInfoMask & ITEMINFO_JSON) $this->extendJsonStats(); @@ -137,8 +119,11 @@ class ItemList extends BaseType foreach ($this->itemMods[$this->id] as $k => $v) $data[$this->id][Util::$itemMods[$k]] = $v; - if ($_ = intVal(($this->curTpl['minMoneyLoot'] + $this->curTpl['maxMoneyLoot']) /2)) + if ($_ = intVal(($this->curTpl['minMoneyLoot'] + $this->curTpl['maxMoneyLoot']) / 2)) $data[$this->id]['avgmoney'] = $_; + + if ($_ = $this->curTpl['repairPrice']) + $data[$this->id]['repaircost'] = $_; } if ($addInfoMask & (ITEMINFO_JSON |ITEMINFO_GEM)) @@ -153,14 +138,23 @@ class ItemList extends BaseType if ($addInfoMask & ITEMINFO_VENDOR) { + $data[$this->id]['cost'] = []; // [money, honor (>0:ally; <0:horde), arena, [items?]] + if ($x = $this->curTpl['buyPrice']) + { $data[$this->id]['buyprice'] = $x; + $data[$this->id]['cost'][0] = $x; + } if ($x = $this->curTpl['sellPrice']) $data[$this->id]['sellprice'] = $x; + + // todo (med): use extended cost table to fill arena points ect } - // complicated data + if ($this->curTpl['class'] == ITEM_CLASS_GLYPH) + $data[$this->id]['glyph'] = $this->curTpl['subSubClass']; + if ($x = $this->curTpl['requiredSkill']) $data[$this->id]['reqskill'] = $x; @@ -197,26 +191,45 @@ class ItemList extends BaseType {"source":[5],"sourcemore":[{"n":"Commander Oxheart","t":1,"ti":64606,"z":5842}], cost:[] format unk 0:copper, 1:[items]? 2, 3, 4, 5 - stack [min, max] // when looting avail unk rel unk - glyph major | minor (as id) - modelviewer + modelviewer {type:X, displayid:Y, slot:z} .. not sure, when to set + } */ return $data; } - public function addGlobalsToJscript(&$template, $addMask = 0) + public function addGlobalsToJscript(&$template, $addMask = GLOBALINFO_SELF) { - foreach ($this->iterate() as $__) + foreach ($this->iterate() as $id => $__) { - $template->extendGlobalData(self::$type, [$this->id => array( - 'name' => $this->getField('name', true), - 'quality' => $this->curTpl['quality'], - 'icon' => $this->curTpl['iconString'] - )]); + $extra = null; + $data = null; + + if ($addMask & GLOBALINFO_SELF) + { + $data = array( + $id => array( + 'name' => $this->getField('name', true), + 'quality' => $this->curTpl['quality'], + 'icon' => $this->curTpl['iconString'] + ) + ); + } + + if ($addMask & GLOBALINFO_EXTRA) + { + $extra = array( + 'id' => $id, + 'tooltip' => Util::jsEscape($this->renderTooltip(null, true)), + 'spells' => '' + ); + } + + if ($data || $extra) + $template->extendGlobalData(self::$type, $data, $extra); } } @@ -227,9 +240,9 @@ class ItemList extends BaseType gems: array (:-separated itemIds) rand: >0: randomPropId; <0: randomSuffixId interactive (set to place javascript/anchors to manipulate level and ratings or link to filters (static tooltips vs popup tooltip)) - subT (tabled layout doesn't work if used as sub-tooltip in other item or spell tooltips; use line-break instead) + subOf (tabled layout doesn't work if used as sub-tooltip in other item or spell tooltips; use line-break instead) */ - public function renderTooltip($enhance = [], $interactive = false, $subT = false) + public function renderTooltip($enhance = [], $interactive = false, $subOf = 0) { if ($this->error) return; @@ -237,18 +250,19 @@ class ItemList extends BaseType if (!empty($this->tooltip[$this->id])) return $this->tooltip[$this->id]; - $_name = $this->getField('name', true); - $_reqLvl = $this->curTpl['requiredLevel']; - $_quality = $this->curTpl['quality']; - $_flags = $this->curTpl['flags']; - $_class = $this->curTpl['class']; - $_subClass = $this->curTpl['subClass']; + $_name = $this->getField('name', true); + $_reqLvl = $this->curTpl['requiredLevel']; + $_quality = $this->curTpl['quality']; + $_flags = $this->curTpl['flags']; + $_class = $this->curTpl['class']; + $_subClass = $this->curTpl['subClass']; + $causesScaling = false; if (!empty($enhance['rand'])) { - $rndEnch = DB::Aowow()->selectRow('SELECT * FROM ?_itemrandomenchant WHERE Id = ?d', $enhance['rand']); - $_name .= ' '.Util::localizedString($rndEnch, 'name'); - $randEnchant['stats'] = ''; + $rndEnch = DB::Aowow()->selectRow('SELECT * FROM ?_itemrandomenchant WHERE Id = ?d', $enhance['rand']); + $_name .= ' '.Util::localizedString($rndEnch, 'name'); + $randEnchant = ''; for ($i = 1; $i < 6; $i++) { @@ -258,11 +272,11 @@ class ItemList extends BaseType $enchant = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE Id = ?d', $rndEnch['enchantId'.$i]); if ($rndEnch['allocationPct'.$i] > 0) { - $amount = intVal($rndEnch['allocationPct'.$i] * $this->generateEnchSuffixFactor() / 10000); - $randEnchant['stats'] .= ''.str_replace('$i', $amount, Util::localizedString($enchant, 'text')).'
'; + $amount = intVal($rndEnch['allocationPct'.$i] * $this->generateEnchSuffixFactor()); + $randEnchant .= ''.str_replace('$i', $amount, Util::localizedString($enchant, 'text')).'
'; } else - $randEnchant['stats'] .= ''.Util::localizedString($enchant, 'text').'
'; + $randEnchant .= ''.Util::localizedString($enchant, 'text').'
'; } } @@ -270,11 +284,11 @@ class ItemList extends BaseType $x = ''; // upper table: stats - if (!$subT) + if (!$subOf) $x .= '
'; // name; quality - if ($subT) + if ($subOf) $x .= ''.$_name.''; else $x .= ''.$_name.''; @@ -284,10 +298,10 @@ class ItemList extends BaseType $x .= '
'.Lang::$item['heroic'].''; // requires map (todo: reparse ?_zones for non-conflicting data; generate Link to zone) - if ($this->curTpl['map']) + if ($_ = $this->curTpl['map']) { - $map = DB::Aowow()->selectRow('SELECT * FROM ?_zones WHERE mapId=?d LIMIT 1', $this->curTpl['map']); - $x .= '
'.Util::localizedString($map, 'name'); + $map = DB::Aowow()->selectRow('SELECT * FROM ?_zones WHERE mapId=?d LIMIT 1', $_); + $x .= '
'.Util::localizedString($map, 'name').''; } // requires area @@ -302,14 +316,19 @@ class ItemList extends BaseType $x .= '
'.Lang::$item['conjured']; // bonding - if (($_flags & ITEM_FLAG_ACCOUNTBOUND) && $_quality == ITEM_QUALITY_HEIRLOOM) + if (($_flags & ITEM_FLAG_ACCOUNTBOUND)) $x .= '
'.Lang::$item['bonding'][0]; else if ($this->curTpl['bonding']) $x .= '
'.Lang::$item['bonding'][$this->curTpl['bonding']]; // unique || unique-equipped || unique-limited - if ($this->curTpl['maxCount'] == 1) + if ($this->curTpl['maxCount'] > 0) + { $x .= '
'.Lang::$item['unique']; + + if ($this->curTpl['maxCount'] > 1) + $x .= ' ('.$this->curTpl['maxCount'].')'; + } else if ($_flags & ITEM_FLAG_UNIQUEEQUIPPED) $x .= '
'.Lang::$item['uniqueEquipped']; else if ($this->curTpl['itemLimitCategory']) @@ -326,13 +345,9 @@ class ItemList extends BaseType if ($hId = $this->curTpl['holidayId']) { $hDay = DB::Aowow()->selectRow("SELECT * FROM ?_holidays WHERE id = ?", $hId); - $x .= '
'.sprintf(Lang::$game['requires'], ''.Util::localizedString($hDay, 'name').''); + $x .= '
'.sprintf(Lang::$game['requires'], ''.Util::localizedString($hDay, 'name').''); } - // maxCount - if ($this->curTpl['maxCount'] > 1) - $x .= ' ('.$this->curTpl['maxCount'].')'; - // item begins a quest if ($this->curTpl['startQuest']) $x .= '
'.Lang::$item['startQuest'].''; @@ -365,45 +380,54 @@ class ItemList extends BaseType $x .= '
'; } + else if ($_ = $this->curTpl['slot']) // yes, slot can occur on random items and is than also displayed <_< + $x .= '
'.Lang::$item['inventoryType'][$this->curTpl['slot']].'
'; else $x .= '
'; - // Weapon/Ammunition Stats - if (in_array($_class, [ITEM_CLASS_WEAPON, ITEM_CLASS_AMMUNITION])) - { - $speed = $this->curTpl['delay'] / 1000; - $dmgmin1 = $this->curTpl['dmgMin1'] + $this->curTpl['dmgMin2']; - $dmgmax1 = $this->curTpl['dmgMax1'] + $this->curTpl['dmgMax2']; - $dps = $speed ? ($dmgmin1 + $dmgmax1) / (2 * $speed) : 0; + // Weapon/Ammunition Stats (not limited to weapons (see item:1700)) + $speed = $this->curTpl['delay'] / 1000; + $dmgmin1 = $this->curTpl['dmgMin1'] + $this->curTpl['dmgMin2']; + $dmgmax1 = $this->curTpl['dmgMax1'] + $this->curTpl['dmgMax2']; + $dps = $speed ? ($dmgmin1 + $dmgmax1) / (2 * $speed) : 0; - // regular weapon + if ($_class == ITEM_CLASS_AMMUNITION && $dmgmin1 && $dmgmax1) + $x .= Lang::$item['addsDps'].' '.number_format(($dmgmin1 + $dmgmax1) / 2, 1).' '.Lang::$item['dps2'].'
'; + else if ($dps) + { if ($_class == ITEM_CLASS_WEAPON) { $x .= ''; $x .= ''; $x .= ''; $x .= '
'.sprintf($this->curTpl['dmgType1'] ? Lang::$item['damageMagic'] : Lang::$item['damagePhys'], $this->curTpl['dmgMin1'].' - '.$this->curTpl['dmgMax1'], Lang::$game['sc'][$this->curTpl['dmgType1']]).''.Lang::$item['speed'].' '.number_format($speed, 2).'
'; + } + else + $x .= ''.sprintf($this->curTpl['dmgType1'] ? Lang::$item['damageMagic'] : Lang::$item['damagePhys'], $this->curTpl['dmgMin1'].' - '.$this->curTpl['dmgMax1'], Lang::$game['sc'][$this->curTpl['dmgType1']]).'
'; - // secondary damage is set - if ($this->curTpl['dmgMin2']) - $x .= '+'.sprintf($this->curTpl['dmgType2'] ? Lang::$item['damageMagic'] : Lang::$item['damagePhys'], $this->curTpl['dmgMin2'].' - '.$this->curTpl['dmgMax2'], Lang::$game['sc'][$this->curTpl['dmgType2']]).'
'; + // secondary damage is set + if ($this->curTpl['dmgMin2']) + $x .= '+'.sprintf($this->curTpl['dmgType2'] ? Lang::$item['damageMagic'] : Lang::$item['damagePhys'], $this->curTpl['dmgMin2'].' - '.$this->curTpl['dmgMax2'], Lang::$game['sc'][$this->curTpl['dmgType2']]).'
'; + if ($_class == ITEM_CLASS_WEAPON) $x .= '('.number_format($dps, 1).' '.Lang::$item['dps'].')
'; - // display FeralAttackPower if set - if (in_array($_subClass, [5, 6, 10]) && $dps > 54.8) - $x .= '('.round(($dps - 54.8) * 14, 0).' '.Lang::$item['fap'].')
'; - } - // ammunition - else - $x .= Lang::$item['addsDps'].' '.number_format(($dmgmin1 + $dmgmax1) / 2, 1).' '.Lang::$item['dps2'].'
'; + // display FeralAttackPower if set + if ($fap = $this->getFeralAP()) + $x .= '('.$fap.' '.Lang::$item['fap'].')
'; } // Armor - if ($_class == ITEM_CLASS_ARMOR && ($this->curTpl['armor'] + $this->curTpl['armorDamageModifier']) > 0) - $x .= ''.sprintf(Lang::$item['armor'], $this->curTpl['armor'] + $this->curTpl['armorDamageModifier']).'
'; - else if ($this->curTpl['armor']) - $x .= ''.sprintf(Lang::$item['armor'], $this->curTpl['armor']).'
'; + if ($_class == ITEM_CLASS_ARMOR && $this->curTpl['armorDamageModifier'] > 0) + { + $spanI = 'class="q2"'; + if ($interactive) + $spanI = 'class="q2 tip" onmouseover="$WH.Tooltip.showAtCursor(event, $WH.sprintf(LANG.tooltip_armorbonus, '.$this->curTpl['armorDamageModifier'].'), 0, 0, \'q\')" onmousemove="$WH.Tooltip.cursorUpdate(event)" onmouseout="$WH.Tooltip.hide()"'; + + $x .= ''.sprintf(Lang::$item['armor'], intVal($this->curTpl['armor'] + $this->curTpl['armorDamageModifier'])).'
'; + } + else if (($this->curTpl['armor'] + $this->curTpl['armorDamageModifier']) > 0) + $x .= ''.sprintf(Lang::$item['armor'], intVal($this->curTpl['armor'] + $this->curTpl['armorDamageModifier'])).'
'; // Block if ($this->curTpl['block']) @@ -417,10 +441,10 @@ class ItemList extends BaseType } // Random Enchantment - if random enchantment is set, prepend stats from it - if (($this->curTpl['randomProperty'] || $this->curTpl['randomSuffix']) && !isset($enhance['rand'])) + if ($this->curTpl['randomEnchant'] && !isset($enhance['rand'])) $x .= ''.Lang::$item['randEnchant'].'
'; else if (isset($enhance['rand'])) - $x .= $randEnchant['stats']; + $x .= $randEnchant; // itemMods (display stats and save ratings for later use) for ($j = 1; $j <= 10; $j++) @@ -435,7 +459,7 @@ class ItemList extends BaseType if ($type >= ITEM_MOD_AGILITY && $type <= ITEM_MOD_STAMINA) $x .= ''.($qty > 0 ? '+' : '-').abs($qty).' '.Lang::$item['statType'][$type].'
'; else // rating with % for reqLevel - $green[] = $this->parseRating($type, $qty, $interactive); + $green[] = $this->parseRating($type, $qty, $interactive, $causesScaling); } // magic resistances @@ -469,7 +493,6 @@ class ItemList extends BaseType i.id IN (?a)', $enhance['gems'] ); - echo "ho"; } else $enhance['gems'] = []; @@ -499,7 +522,7 @@ class ItemList extends BaseType $text = $pop ? Util::localizedString($gems[$pop], 'text') : Lang::$item['socket'][$colorId]; if ($interactive) - $x .= ''.$text.'
'; + $x .= ''.$text.'
'; else $x .= ''.$text.'
'; } @@ -573,13 +596,14 @@ class ItemList extends BaseType if ($reqFac = $this->curTpl['requiredFaction']) $x .= '
'.sprintf(Lang::$game['requires'], ''.FactionList::getName($reqFac).' - '.Lang::$game['rep'][$this->curTpl['requiredFactionRank']]); - // locked - if ($lId = $this->curTpl['lockId']) - if ($locks = Lang::getLocks($lId)) - $x .= '
'.Lang::$item['locked'].'
'.implode('
', $locks).'
'; + // locked or openable + if ($locks = Lang::getLocks($this->curTpl['lockId'], true)) + $x .= '
'.Lang::$item['locked'].'
'.implode('
', $locks).'
'; + else if ($this->curTpl['flags'] & ITEM_FLAG_OPENABLE) + $x .= '
'.Lang::$item['openClick'].''; // upper table: done - if (!$subT) + if (!$subOf) $x .= ''; else $x .= '
'; @@ -596,7 +620,7 @@ class ItemList extends BaseType if ($cd < $this->curTpl['spellCategoryCooldown'.$j]) $cd = $this->curTpl['spellCategoryCooldown'.$j]; - $cd = $cd < 5000 ? null : ' ('.sprintf(Lang::$game['cooldown'], Util::formatTime($cd, true)).')'; + $cd = $cd < 5000 ? null : ' ('.sprintf(Lang::$game['cooldown'], Util::formatTime($cd)).')'; $itemSpellsAndTrigger[$this->curTpl['spellId'.$j]] = [$this->curTpl['spellTrigger'.$j], $cd]; } @@ -608,13 +632,29 @@ class ItemList extends BaseType $itemSpells = new SpellList(array(['s.id', array_keys($itemSpellsAndTrigger)])); foreach ($itemSpells->iterate() as $__) - if ($parsed = $itemSpells->parseText('description', $_reqLvl > 1 ? $_reqLvl : MAX_LEVEL)[0]) - $green[] = Lang::$item['trigger'][$itemSpellsAndTrigger[$itemSpells->id][0]] . ($interactive ? ''.$parsed.'' : $parsed) . $itemSpellsAndTrigger[$itemSpells->id][1]; + if ($parsed = $itemSpells->parseText('description', $_reqLvl > 1 ? $_reqLvl : MAX_LEVEL, false, $causesScaling)[0]) + { + if ($interactive) + { + $link = '%s'; + $parsed = preg_replace_callback('/^(.*)( .*<\/small>)(.*)$/i', function($m) use($link) { + $m[1] = sprintf($link, $m[1]); + $m[3] = sprintf($link, $m[3]); + return $m[1].$m[2].$m[3]; + }, $parsed, -1, $nMatches + ); + + if (!$nMatches) + $parsed = sprintF($link, $parsed); + } + + $green[] = Lang::$item['trigger'][$itemSpellsAndTrigger[$itemSpells->id][0]] . $parsed . $itemSpellsAndTrigger[$itemSpells->id][1]; + } } } // lower table (ratings, spells, ect) - if (!$subT) + if (!$subOf) $x .= '
'; if (isset($green)) @@ -624,38 +664,30 @@ class ItemList extends BaseType // Item Set $pieces = []; - $itemset = DB::Aowow()->selectRow(' - SELECT - * - FROM - ?_itemset - WHERE - (item1=?d or item2=?d or item3=?d or item4=?d or item5=?d or item6=?d or item7=?d or item8=?d or item9=?d or item10=?d)', - $this->id, $this->id, $this->id, $this->id, $this->id, $this->id, $this->id, $this->id, $this->id, $this->id - ); + $condition = ['OR', ['item1', $this->id], ['item2', $this->id], ['item3', $this->id], ['item4', $this->id], ['item5', $this->id], ['item6', $this->id], ['item7', $this->id], ['item8', $this->id], ['item9', $this->id], ['item10', $this->id]]; + $itemset = new ItemsetList($condition); - if ($itemset) + if (!$itemset->error) { - $num = 0; // piece counter - for ($i = 1; $i <= 10; $i++) + $pieces = DB::Aowow()->select(' + SELECT b.id AS ARRAY_KEY, b.name_loc0, b.name_loc2, b.name_loc3, b.name_loc6, b.name_loc8, GROUP_CONCAT(a.id SEPARATOR \':\') AS equiv + FROM aowow_items a, aowow_items b + WHERE a.slotBak = b.slotBak AND a.itemset = b.itemset AND b.id IN (?a) + GROUP BY b.id;', + array_keys($itemset->pieceToSet) + ); + + foreach ($pieces as $k => &$p) + $p = ''.Util::localizedString($p, 'name').''; + + $xSet = '
'.$itemset->getField('name', true).' (0/'.count($pieces).')'; + + if ($skId = $itemset->getField('skillId')) // bonus requires skill to activate { - if ($itemset['item'.$i] <= 0) - continue; + $xSet .= '
'.sprintf(Lang::$game['requires'], ''.SkillList::getName($skId).''); - $num++; - $equivalents = ItemList::getEquivalentSetPieces($itemset['item'.$i]); - $pieces[] = ''.ItemList::getName($itemset['item'.$i]).''; - } - - $xSet = '
'.Util::localizedString($itemset, 'name').' (0/'.$num.')'; - - if ($itemset['skillId']) // bonus requires skill to activate - { - $name = DB::Aowow()->selectRow('SELECT * FROM ?_skillline WHERE Id=?d', $itemset['skillId']); - $xSet .= '
'.sprintf(Lang::$game['requires'], ''.Util::localizedString($name, 'name').''); - - if ($itemset['skillLevel']) - $xSet .= ' ('.$itemset['skillLevel'].')'; + if ($_ = $itemset->getField('skillLevel')) + $xSet .= ' ('.$_.')'; $xSet .= '
'; } @@ -666,38 +698,38 @@ class ItemList extends BaseType // get bonuses $setSpellsAndIdx = []; for ($j = 1; $j <= 8; $j++) - if ($itemset['spell'.$j] > 0) - $setSpellsAndIdx[$itemset['spell'.$j]] = $j; + if ($_ = $itemset->getField('spell'.$j)) + $setSpellsAndIdx[$_] = $j; - // todo: get from static prop? + $setSpells = []; if ($setSpellsAndIdx) { $boni = new SpellList(array(['s.id', array_keys($setSpellsAndIdx)])); foreach ($boni->iterate() as $__) { - $itemset['spells'][] = array( - 'tooltip' => $boni->parseText('description', $_reqLvl > 1 ? $_reqLvl : MAX_LEVEL)[0], - 'entry' => $itemset['spell'.$setSpellsAndIdx[$boni->id]], - 'bonus' => $itemset['bonus'.$setSpellsAndIdx[$boni->id]] + $setSpells[] = array( + 'tooltip' => $boni->parseText('description', $_reqLvl > 1 ? $_reqLvl : MAX_LEVEL, false, $causesScaling)[0], + 'entry' => $itemset->getField('spell'.$setSpellsAndIdx[$boni->id]), + 'bonus' => $itemset->getField('bonus'.$setSpellsAndIdx[$boni->id]) ); } } // sort and list bonuses $xSet .= ''; - for ($i = 0; $i < count($itemset['spells']); $i++) + for ($i = 0; $i < count($setSpells); $i++) { - for ($j = $i; $j < count($itemset['spells']); $j++) + for ($j = $i; $j < count($setSpells); $j++) { - if($itemset['spells'][$j]['bonus'] >= $itemset['spells'][$i]['bonus']) + if($setSpells[$j]['bonus'] >= $setSpells[$i]['bonus']) continue; - $tmp = $itemset['spells'][$i]; - $itemset['spells'][$i] = $itemset['spells'][$j]; - $itemset['spells'][$j] = $tmp; + $tmp = $setSpells[$i]; + $setSpells[$i] = $setSpells[$j]; + $setSpells[$j] = $tmp; } - $xSet .= '('.$itemset['spells'][$i]['bonus'].') '.Lang::$item['set'].': '.$itemset['spells'][$i]['tooltip'].''; - if ($i < count($itemset['spells']) - 1) + $xSet .= '('.$setSpells[$i]['bonus'].') '.Lang::$item['set'].': '.$setSpells[$i]['tooltip'].''; + if ($i < count($setSpells) - 1) $xSet .= '
'; } $xSet .= '
'; @@ -709,11 +741,9 @@ class ItemList extends BaseType $craftSpell = new SpellList(array(['s.id', intVal($this->curTpl['spellId2'])])); if (!$craftSpell->error) { + $xCraft = ''; if ($desc = $this->getField('description', true)) - { - $xCraft = ''; - $x .= ''.Lang::$item['trigger'][0].' '.$desc.'
'; - } + $x .= ''.Lang::$item['trigger'][0].' '.$desc.'
'; // recipe handling (some stray Techniques have subclass == 0), place at bottom of tooltipp if ($_class == ITEM_CLASS_RECIPE || $this->curTpl['bagFamily'] == 16) @@ -721,7 +751,7 @@ class ItemList extends BaseType $craftItem = new ItemList(array(['i.id', (int)$craftSpell->curTpl['effect1CreateItemId']])); if (!$craftItem->error) { - if ($itemTT = $craftItem->renderTooltip(null, $interactive)) + if ($itemTT = $craftItem->renderTooltip(null, $interactive, $this->id)) $xCraft .= '

'.$itemTT.'
'; $reagentItems = []; @@ -752,7 +782,7 @@ class ItemList extends BaseType $xMisc[] = $xSet; // funny, yellow text at the bottom, omit if we have a recipe - if ($this->curTpl['description_loc0'] && !isset($xCraft)) + if ($this->curTpl['description_loc0'] && !$this->canTeachSpell()) $xMisc[] = '"'.$this->getField('description', true).'"'; // readable @@ -760,8 +790,8 @@ class ItemList extends BaseType $xMisc[] = ''.Lang::$item['readClick'].''; // charges (i guess checking first spell is enough (single charges not shown)) - if ($this->curTpl['spellCharges1'] > 1) - $xMisc[] = ''.$this->curTpl['spellCharges1'].' '.Lang::$item['charges'].''; + if ($this->curTpl['spellCharges1'] > 1 || $this->curTpl['spellCharges1'] < -1) + $xMisc[] = ''.abs($this->curTpl['spellCharges1']).' '.Lang::$item['charges'].''; if ($sp = $this->curTpl['sellPrice']) $xMisc[] = ''.Lang::$item['sellPrice'].Lang::$colon.Util::formatMoney($sp).''; @@ -773,24 +803,31 @@ class ItemList extends BaseType if ($xMisc) $x .= implode('
', $xMisc); - if (!$subT) + if (!$subOf) $x .= '
'; - // heirloom tooltip scaling - if (isset($this->ssd[$this->id])) + // tooltip scaling + if (!isset($xCraft)) { - $link = array( - $this->id, // itemId - 1, // scaleMinLevel - $this->ssd[$this->id]['maxLevel'], // scaleMaxLevel - $this->ssd[$this->id]['maxLevel'], // scaleCurLevel - $this->curTpl['scalingStatDistribution'], // scaleDist - $this->curTpl['scalingStatValue'], // scaleFlags - ); + $link = [$subOf ? $subOf : $this->id, 1]; // itemid, scaleMinLevel + if (isset($this->ssd[$this->id])) // is heirloom + { + array_push($link, + $this->ssd[$this->id]['maxLevel'], // scaleMaxLevel + $this->ssd[$this->id]['maxLevel'], // scaleCurLevel + $this->curTpl['scalingStatDistribution'], // scaleDist + $this->curTpl['scalingStatValue'] // scaleFlags + ); + } + else // may still use level dependant ratings + { + array_push($link, + $causesScaling ? MAX_LEVEL : 1, // scaleMaxLevel + $_reqLvl > 1 ? $_reqLvl : MAX_LEVEL // scaleCurLevel + ); + } $x .= ''; } - else - $x .= ''; $this->tooltip[$this->id] = $x; @@ -856,11 +893,11 @@ class ItemList extends BaseType switch ($this->curTpl['quality']) { case ITEM_QUALITY_UNCOMMON: - return $rpp['uncommon'.$suffixFactor]; + return $rpp['uncommon'.$suffixFactor] / 10000; case ITEM_QUALITY_RARE: - return $rpp['rare'.$suffixFactor]; + return $rpp['rare'.$suffixFactor] / 10000; case ITEM_QUALITY_EPIC: - return $rpp['epic'.$suffixFactor]; + return $rpp['epic'.$suffixFactor] / 10000; case ITEM_QUALITY_LEGENDARY: case ITEM_QUALITY_ARTIFACT: return 0; // not have random properties @@ -881,9 +918,6 @@ class ItemList extends BaseType if (!$mod ||!$val) continue; - if ($mod == ITEM_MOD_ATTACK_POWER) - @$this->itemMods[$this->id][ITEM_MOD_RANGED_ATTACK_POWER] += $val; - @$this->itemMods[$this->id][$mod] += $val; } @@ -891,11 +925,12 @@ class ItemList extends BaseType $equipSpells = []; for ($h = 1; $h <= 5; $h++) { - // only onEquip - if ($this->curTpl['spellTrigger'.$h] != 1) + if ($this->curTpl['spellId'.$h] <= 0) continue; - if ($this->curTpl['spellId'.$h] <= 0) + // armor & weapons only onEquip && consumables only onUse + if (!(in_array($this->curTpl['class'], [ITEM_CLASS_WEAPON, ITEM_CLASS_ARMOR]) && $this->curTpl['spellTrigger'.$h] == 1) && + !( $this->curTpl['class'] == ITEM_CLASS_CONSUMABLE && $this->curTpl['spellTrigger'.$h] == 0)) continue; $equipSpells[] = $this->curTpl['spellId'.$h]; @@ -913,60 +948,17 @@ class ItemList extends BaseType // fetch and add socketbonusstats if (@$this->json[$this->id]['socketbonus'] > 0) - if ($enh = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE Id = ?;', $this->json[$this->id]['socketbonus'])) - $this->json[$this->id]['socketbonusstat'] = Util::parseItemEnchantment($enh); + $this->json[$this->id]['socketbonusstat'] = Util::parseItemEnchantment($this->json[$this->id]['socketbonus']); // Item is a gem (don't mix with sockets) if ($geId = $this->curTpl['gemEnchantmentId']) { - $gemStats = Util::parseItemEnchantment(DB::Aowow()->selectRow('SELECT * FROM ?_itemEnchantment WHERE id = ?d', $geId)); + $gemStats = Util::parseItemEnchantment($geId); foreach ($gemStats as $mod => $qty) @$this->json[$this->id][$mod] += $qty; } - // gather random Enchantments - // todo (high): extremly high sql-load - if (@$this->json[$this->id]['commondrop'] && isset($this->subItems[$this->id])) - { - foreach ($this->subItems[$this->id] as $k => $sI) - { - $jsonEquip = []; - $jsonText = []; - - for ($i = 1; $i < 6; $i++) - { - if ($sI['enchantId'.$i] <= 0) - continue; - - if (!$this->rndEnchIds[$sI['enchantId'.$i]]) - continue; - - $eData = $this->rndEnchIds[$sI['enchantId'.$i]]; - - if ($sI['allocationPct'.$i] > 0) // RandomSuffix: scaling Enchantment; enchId < 0 - { - $amount = intVal($sI['allocationPct'.$i] * $this->generateEnchSuffixFactor() / 10000); - $jsonEquip = array_merge($jsonEquip, Util::parseItemEnchantment($eData, $amount)); - $jsonText[] = str_replace('$i', $amount, Util::localizedString($eData, 'text')); - } - else // RandomProperty: static Enchantment; enchId > 0 - { - $jsonText[] = Util::localizedString($eData, 'text'); - $jsonEquip = array_merge($jsonEquip, Util::parseItemEnchantment($eData)); - } - } - - $this->subItems[$this->id][$k] = array( - 'name' => Util::localizedString($sI, 'name'), - 'enchantment' => implode(', ', $jsonText), - 'jsonequip' => $jsonEquip - ); - } - - $this->json[$this->id]['subitems'] = $this->subItems[$this->id]; - } - foreach ($this->json[$this->id] as $k => $v) if (!isset($v) || $v === "false" || (!in_array($k, ['classs', 'subclass', 'quality', 'side']) && $v == "0")) unset($this->json[$this->id][$k]); @@ -1019,13 +1011,36 @@ class ItemList extends BaseType if (!in_array($this->curTpl['spellId1'], [483, 55884])) return false; + // needs learnable spell if (!$this->curTpl['spellId2']) return false; return true; } - private function parseRating($type, $value, $interactive = false) + private function getFeralAP() + { + // must be weapon + if ($this->curTpl['class'] != ITEM_CLASS_WEAPON) + return 0; + + // must be 2H weapon (2H-Mace, Polearm, Staff, ..Fishing Pole) + if (!in_array($this->curTpl['subClass'], [5, 6, 10, 20])) + return 0; + + // thats fucked up.. + if (!$this->curTpl['delay']) + return 0; + + // must have enough damage + $dps = ($this->curTpl['dmgMin1'] + $this->curTpl['dmgMin2'] + $this->curTpl['dmgMax1'] + $this->curTpl['dmgMax2']) / (2 * $this->curTpl['delay'] / 1000); + if ($dps < 54.8) + return 0; + + return round(($dps - 54.8) * 14, 0); + } + + private function parseRating($type, $value, $interactive = false, &$scaling = false) { // clamp level range $ssdLvl = isset($this->ssd[$this->id]) ? $this->ssd[$this->id]['maxLevel'] : 1; @@ -1038,8 +1053,10 @@ class ItemList extends BaseType return Lang::$item['trigger'][1] . str_replace('%d', ''.$value, Lang::$item['statType'][$type]); else // rating-Bonuses { + $scaling = true; + if ($interactive) - $js = ' ('.sprintf(Util::$changeLevelString, Util::setRatingLevel($level, $type, $value)).'))'; + $js = ' ('.sprintf(Util::$changeLevelString, Util::setRatingLevel($level, $type, $value)).')'; else $js = " (".Util::setRatingLevel($level, $type, $value).")"; @@ -1107,24 +1124,68 @@ class ItemList extends BaseType } } - private function initSubItems() + public function initSubItems() { - $randId = $this->curTpl['randomProperty'] > 0 ? $this->curTpl['randomProperty'] : $this->curTpl['randomSuffix']; - if ($randomIds = DB::Aowow()->selectCol('SELECT ench FROM item_enchantment_template WHERE entry = ?d', $randId)) + if (!array_keys($this->templates)) + return; + + $ire = DB::Aowow()->select(' + SELECT i.id AS ARRAY_KEY_1, ire.id AS ARRAY_KEY_2, iet.chance, ire.* + FROM aowow_items i + JOIN item_enchantment_template iet ON iet.entry = ABS(i.randomEnchant) + JOIN aowow_itemRandomEnchant ire ON IF(i.randomEnchant > 0, ire.id = iet.ench, ire.id = -iet.ench) + WHERE i.id IN (?a)', + array_keys($this->templates) + ); + + foreach ($ire as $mstItem => $subItem) { - if ($this->curTpl['randomSuffix'] > 0) - array_walk($randomIds, function($val, $key) use(&$randomIds) { - $randomIds[$key] = -$val; - }); + foreach ($subItem as $subId => $data) + { + $jsonEquip = []; + $jsonText = []; - $this->subItems[$this->id] = DB::Aowow()->select('SELECT *, Id AS ARRAY_KEY FROM ?_itemRandomEnchant WHERE Id IN (?a)', $randomIds); - - // subitems may share enchantmentIds - foreach ($this->subItems[$this->id] as $sI) for ($i = 1; $i < 6; $i++) - if (!isset($this->rndEnchIds[$sI['enchantId'.$i]]) && $sI['enchantId'.$i]) - if ($enchant = DB::Aowow()->selectRow('SELECT *, Id AS ARRAY_KEY FROM ?_itemenchantment WHERE Id = ?d', $sI['enchantId'.$i])) - $this->rndEnchIds[$enchant['id']] = $enchant; + { + $enchId = $data['enchantId'.$i]; + + if ($enchId <= 0) + continue; + + // subitems may share enchantmentIds + if (!isset($this->rndEnchIds[$enchId])) + { + $stats = Util::parseItemEnchantment($enchId, false, $text); + $this->rndEnchIds[$enchId] = array( + 'text' => $text, + 'stats' => $stats + ); + } + + if ($data['allocationPct'.$i] > 0) // RandomSuffix: scaling Enchantment; enchId < 0 + { + $qty = intVal($data['allocationPct'.$i] * $this->generateEnchSuffixFactor()); + $stats = array_fill_keys(array_keys($this->rndEnchIds[$enchId]['stats']), $qty); + + $jsonText[] = str_replace('$i', $qty, $this->rndEnchIds[$enchId]['text']); + Util::arraySumByKey($jsonEquip, $stats); + } + else // RandomProperty: static Enchantment; enchId > 0 + { + $jsonText[] = $this->rndEnchIds[$enchId]['text']; + Util::arraySumByKey($jsonEquip, $this->rndEnchIds[$enchId]['stats']); + } + } + + $this->subItems[$mstItem][$subId] = array( + 'name' => Util::localizedString($data, 'name'), + 'enchantment' => implode(', ', $jsonText), + 'jsonequip' => $jsonEquip, + 'chance' => $data['chance'] // hmm, only needed for item detail page... + ); + } + + $this->json[$mstItem]['subitems'] = $this->subItems[$mstItem]; } } @@ -1139,13 +1200,13 @@ class ItemList extends BaseType 'subclass' => $this->curTpl['subClass'], 'subsubclass' => $this->curTpl['subSubClass'], 'heroic' => (string)($this->curTpl['flags'] & 0x8), - 'side' => Util::sideByRaceMask($this->curTpl['requiredRace']), // check for FlagsExtra? 0:both; 1: Horde; 2:Alliance + 'side' => $this->curTpl['flagsExtra'] & 0x3 ? 3 - ($this->curTpl['flagsExtra'] & 0x3) : Util::sideByRaceMask($this->curTpl['requiredRace']), 'slot' => $this->curTpl['slot'], 'slotbak' => $this->curTpl['slotBak'], 'level' => $this->curTpl['itemLevel'], 'reqlevel' => $this->curTpl['requiredLevel'], 'displayid' => $this->curTpl['displayId'], - 'commondrop' => ($this->curTpl['randomProperty'] > 0 || $this->curTpl['randomSuffix'] > 0) ? 'true' : null, // string required :( + // 'commondrop' => 'true' / null // set if the item is a loot-filler-item .. checke common ref-templates..? 'holres' => $this->curTpl['resHoly'], 'firres' => $this->curTpl['resFire'], 'natres' => $this->curTpl['resNature'], @@ -1171,8 +1232,8 @@ class ItemList extends BaseType $json['dmgtype1'] = $this->curTpl['dmgType1']; $json['dmgmin1'] = $this->curTpl['dmgMin1'] + $this->curTpl['dmgMin2']; $json['dmgmax1'] = $this->curTpl['dmgMax1'] + $this->curTpl['dmgMax2']; - $json['dps'] = !$this->curTpl['delay'] ? 0 : number_format(($json['dmgmin1'] + $json['dmgmax1']) / (2 * $this->curTpl['delay'] / 1000), 1); $json['speed'] = number_format($this->curTpl['delay'] / 1000, 2); + $json['dps'] = !floatVal($json['speed']) ? 0 : number_format(($json['dmgmin1'] + $json['dmgmax1']) / (2 * $json['speed']), 1); if (in_array($json['subclass'], [2, 3, 18, 19])) { @@ -1189,8 +1250,8 @@ class ItemList extends BaseType $json['mledps'] = $json['dps']; } - if ($json['classs'] == ITEM_CLASS_WEAPON && in_array($json['subclass'], [5, 6, 10]) && $json['dps'] > 54.8) - $json['feratkpwr'] = max(0, round((($json['dmgmin1'] + $json['dmgmax1']) / (2 * $this->curTpl['delay'] / 1000) - 54.8) * 14, 0)); + if ($fap = $this->getFeralAP()) + $json['feratkpwr'] = $fap; } if ($this->curTpl['armorDamageModifier'] > 0) @@ -1234,6 +1295,23 @@ class ItemListFilter extends Filter 14 => -1, 15 => -1 ), + 87 => array( // reagent for profession + 1 => 171, + 2 => 164, + 3 => 185, + 4 => 333, + 5 => 202, + 6 => 129, + 7 => 755, + 8 => 165, + 9 => 186, + 10 => 197, + 11 => true, + 12 => false, + 13 => 356, + 14 => 182, + 15 => 773, + ), 152 => array( // class-specific null, 1, 2, 3, 4, 5, 6, 7, 8, 9, null, 11, true, false ), @@ -1243,91 +1321,107 @@ class ItemListFilter extends Filter ); // cr => [type, field, misc, extraCol] protected $genericFilter = array( // misc (bool): _NUMERIC => useFloat; _STRING => localized; _FLAG => match Value; _BOOLEAN => stringSet - 146 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_HEROIC ], // heroic - 9 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_CONJURED ], // conjureditem - 83 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_UNIQUEEQUIPPED ], // uniqueequipped - 151 => [FILTER_CR_NUMERIC, 'id', null, true], // id - 100 => [FILTER_CR_NUMERIC, 'is.nsockets' ], // nsockets - 111 => [FILTER_CR_NUMERIC, 'requiredSkillRank', null, true], // reqskillrank - 99 => [FILTER_CR_ENUM, 'requiredSkill' ], // requiresprof - 66 => [FILTER_CR_ENUM, 'requiredSpell' ], // requiresprofspec - 17 => [FILTER_CR_ENUM, 'requiredFaction' ], // requiresrepwith - 169 => [FILTER_CR_ENUM, 'holidayId' ], // requiresevent - 21 => [FILTER_CR_NUMERIC, 'is.agi', null, true], // agi - 23 => [FILTER_CR_NUMERIC, 'is.int', null, true], // int - 22 => [FILTER_CR_NUMERIC, 'is.sta', null, true], // sta - 24 => [FILTER_CR_NUMERIC, 'is.spi', null, true], // spi - 20 => [FILTER_CR_NUMERIC, 'is.str', null, true], // str - 115 => [FILTER_CR_NUMERIC, 'is.health', null, true], // health - 116 => [FILTER_CR_NUMERIC, 'is.mana', null, true], // mana - 60 => [FILTER_CR_NUMERIC, 'is.healthrgn', null, true], // healthrgn - 61 => [FILTER_CR_NUMERIC, 'is.manargn', null, true], // manargn - 41 => [FILTER_CR_NUMERIC, 'is.armor' , null, true], // armor - 44 => [FILTER_CR_NUMERIC, 'is.blockrtng', null, true], // blockrtng - 43 => [FILTER_CR_NUMERIC, 'is.block', null, true], // block - 42 => [FILTER_CR_NUMERIC, 'is.defrtng', null, true], // defrtng - 45 => [FILTER_CR_NUMERIC, 'is.dodgertng', null, true], // dodgertng - 46 => [FILTER_CR_NUMERIC, 'is.parryrtng', null, true], // parryrtng - 79 => [FILTER_CR_NUMERIC, 'is.resirtng', null, true], // resirtng - 77 => [FILTER_CR_NUMERIC, 'is.atkpwr', null, true], // atkpwr - 97 => [FILTER_CR_NUMERIC, 'is.feratkpwr', null, true], // feratkpwr - 114 => [FILTER_CR_NUMERIC, 'is.armorpenrtng', null, true], // armorpenrtng - 96 => [FILTER_CR_NUMERIC, 'is.critstrkrtng', null, true], // critstrkrtng - 117 => [FILTER_CR_NUMERIC, 'is.exprtng', null, true], // exprtng - 103 => [FILTER_CR_NUMERIC, 'is.hastertng', null, true], // hastertng - 119 => [FILTER_CR_NUMERIC, 'is.hitrtng', null, true], // hitrtng - 94 => [FILTER_CR_NUMERIC, 'is.splpen', null, true], // splpen - 123 => [FILTER_CR_NUMERIC, 'is.splpwr', null, true], // splpwr - 52 => [FILTER_CR_NUMERIC, 'is.arcsplpwr', null, true], // arcsplpwr - 53 => [FILTER_CR_NUMERIC, 'is.firsplpwr', null, true], // firsplpwr - 54 => [FILTER_CR_NUMERIC, 'is.frosplpwr', null, true], // frosplpwr - 55 => [FILTER_CR_NUMERIC, 'is.holsplpwr', null, true], // holsplpwr - 56 => [FILTER_CR_NUMERIC, 'is.natsplpwr', null, true], // natsplpwr - 57 => [FILTER_CR_NUMERIC, 'is.shasplpwr', null, true], // shasplpwr - 32 => [FILTER_CR_NUMERIC, 'is.dps', true, true], // dps - 33 => [FILTER_CR_NUMERIC, 'is.dmgmin1', null, true], // dmgmin1 - 34 => [FILTER_CR_NUMERIC, 'is.dmgmax1', null, true], // dmgmax1 - 36 => [FILTER_CR_NUMERIC, 'is.speed', true, true], // speed - 134 => [FILTER_CR_NUMERIC, 'is.mledps', true, true], // mledps - 135 => [FILTER_CR_NUMERIC, 'is.mledmgmin', null, true], // mledmgmin - 136 => [FILTER_CR_NUMERIC, 'is.mledmgmax', null, true], // mledmgmax - 137 => [FILTER_CR_NUMERIC, 'is.mlespeed', true, true], // mlespeed - 138 => [FILTER_CR_NUMERIC, 'is.rgddps', true, true], // rgddps - 139 => [FILTER_CR_NUMERIC, 'is.rgddmgmin', null, true], // rgddmgmin - 140 => [FILTER_CR_NUMERIC, 'is.rgddmgmax', null, true], // rgddmgmax - 141 => [FILTER_CR_NUMERIC, 'is.rgdspeed', true, true], // rgdspeed - 25 => [FILTER_CR_NUMERIC, 'is.arcres', null, true], // arcres - 26 => [FILTER_CR_NUMERIC, 'is.firres', null, true], // firres - 28 => [FILTER_CR_NUMERIC, 'is.frores', null, true], // frores - 30 => [FILTER_CR_NUMERIC, 'is.holres', null, true], // holres - 27 => [FILTER_CR_NUMERIC, 'is.natres', null, true], // natres - 29 => [FILTER_CR_NUMERIC, 'is.shares', null, true], // shares - 37 => [FILTER_CR_NUMERIC, 'is.mleatkpwr', null, true], // mleatkpwr - 84 => [FILTER_CR_NUMERIC, 'is.mlecritstrkrtng', null, true], // mlecritstrkrtng - 78 => [FILTER_CR_NUMERIC, 'is.mlehastertng', null, true], // mlehastertng - 95 => [FILTER_CR_NUMERIC, 'is.mlehitrtng', null, true], // mlehitrtng - 38 => [FILTER_CR_NUMERIC, 'is.rgdatkpwr', null, true], // rgdatkpwr - 40 => [FILTER_CR_NUMERIC, 'is.rgdcritstrkrtng', null, true], // rgdcritstrkrtng - 101 => [FILTER_CR_NUMERIC, 'is.rgdhastertng', null, true], // rgdhastertng - 39 => [FILTER_CR_NUMERIC, 'is.rgdhitrtng', null, true], // rgdhitrtng - 49 => [FILTER_CR_NUMERIC, 'is.splcritstrkrtng', null, true], // splcritstrkrtng - 102 => [FILTER_CR_NUMERIC, 'is.splhastertng', null, true], // splhastertng - 48 => [FILTER_CR_NUMERIC, 'is.splhitrtng', null, true], // splhitrtng - 51 => [FILTER_CR_NUMERIC, 'is.spldmg', null, true], // spldmg - 50 => [FILTER_CR_NUMERIC, 'is.splheal', null, true], // splheal - 8 => [FILTER_CR_BOOLEAN, 'requiredDisenchantSkill' ], // disenchantable - 59 => [FILTER_CR_NUMERIC, 'durability', null, true], // dura - 104 => [FILTER_CR_STRING, 'description', true ], // flavortext - 7 => [FILTER_CR_BOOLEAN, 'description_loc0', true ], // hasflavortext - 142 => [FILTER_CR_STRING, 'iconString', ], // icon - - 176 => [FILTER_CR_STAFFFLAG, 'flags' ], // flags - 177 => [FILTER_CR_STAFFFLAG, 'flagsExtra' ], // flags2 + 9 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_CONJURED ], // conjureditem + 11 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_OPENABLE ], // openable + 83 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_UNIQUEEQUIPPED ], // uniqueequipped + 89 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_PROSPECTABLE ], // prospectable + 98 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_PARTYLOOT ], // partyloot + 133 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_ACCOUNTBOUND ], // accountbound + 146 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_HEROIC ], // heroic + 154 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_REFUNDABLE ], // refundable + 155 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_USABLE_ARENA ], // usableinarenas + 156 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_USABLE_SHAPED ], // usablewhenshapeshifted + 157 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_SMARTLOOT ], // smartloot + 159 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_MILLABLE ], // millable + 162 => [FILTER_CR_FLAG, 'flags', ITEM_FLAG_DEPRECATED ], // deprecated + 127 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_UNAVAILABLE ], // notavailable + // 161 => [FILTER_CR_FLAG, 'cuFlags', ~CUSTOM_UNAVAILABLE ], // availabletoplayers .. wait what?! + 151 => [FILTER_CR_NUMERIC, 'id', null, true], // id + 100 => [FILTER_CR_NUMERIC, 'is.nsockets' ], // nsockets + 111 => [FILTER_CR_NUMERIC, 'requiredSkillRank', null, true], // reqskillrank + 99 => [FILTER_CR_ENUM, 'requiredSkill' ], // requiresprof + 66 => [FILTER_CR_ENUM, 'requiredSpell' ], // requiresprofspec + 17 => [FILTER_CR_ENUM, 'requiredFaction' ], // requiresrepwith + 169 => [FILTER_CR_ENUM, 'holidayId' ], // requiresevent + 21 => [FILTER_CR_NUMERIC, 'is.agi', null, true], // agi + 23 => [FILTER_CR_NUMERIC, 'is.int', null, true], // int + 22 => [FILTER_CR_NUMERIC, 'is.sta', null, true], // sta + 24 => [FILTER_CR_NUMERIC, 'is.spi', null, true], // spi + 20 => [FILTER_CR_NUMERIC, 'is.str', null, true], // str + 115 => [FILTER_CR_NUMERIC, 'is.health', null, true], // health + 116 => [FILTER_CR_NUMERIC, 'is.mana', null, true], // mana + 60 => [FILTER_CR_NUMERIC, 'is.healthrgn', null, true], // healthrgn + 61 => [FILTER_CR_NUMERIC, 'is.manargn', null, true], // manargn + 41 => [FILTER_CR_NUMERIC, 'is.armor' , null, true], // armor + 44 => [FILTER_CR_NUMERIC, 'is.blockrtng', null, true], // blockrtng + 43 => [FILTER_CR_NUMERIC, 'is.block', null, true], // block + 42 => [FILTER_CR_NUMERIC, 'is.defrtng', null, true], // defrtng + 45 => [FILTER_CR_NUMERIC, 'is.dodgertng', null, true], // dodgertng + 46 => [FILTER_CR_NUMERIC, 'is.parryrtng', null, true], // parryrtng + 79 => [FILTER_CR_NUMERIC, 'is.resirtng', null, true], // resirtng + 77 => [FILTER_CR_NUMERIC, 'is.atkpwr', null, true], // atkpwr + 97 => [FILTER_CR_NUMERIC, 'is.feratkpwr', null, true], // feratkpwr + 114 => [FILTER_CR_NUMERIC, 'is.armorpenrtng', null, true], // armorpenrtng + 96 => [FILTER_CR_NUMERIC, 'is.critstrkrtng', null, true], // critstrkrtng + 117 => [FILTER_CR_NUMERIC, 'is.exprtng', null, true], // exprtng + 103 => [FILTER_CR_NUMERIC, 'is.hastertng', null, true], // hastertng + 119 => [FILTER_CR_NUMERIC, 'is.hitrtng', null, true], // hitrtng + 94 => [FILTER_CR_NUMERIC, 'is.splpen', null, true], // splpen + 123 => [FILTER_CR_NUMERIC, 'is.splpwr', null, true], // splpwr + 52 => [FILTER_CR_NUMERIC, 'is.arcsplpwr', null, true], // arcsplpwr + 53 => [FILTER_CR_NUMERIC, 'is.firsplpwr', null, true], // firsplpwr + 54 => [FILTER_CR_NUMERIC, 'is.frosplpwr', null, true], // frosplpwr + 55 => [FILTER_CR_NUMERIC, 'is.holsplpwr', null, true], // holsplpwr + 56 => [FILTER_CR_NUMERIC, 'is.natsplpwr', null, true], // natsplpwr + 57 => [FILTER_CR_NUMERIC, 'is.shasplpwr', null, true], // shasplpwr + 32 => [FILTER_CR_NUMERIC, 'is.dps', true, true], // dps + 33 => [FILTER_CR_NUMERIC, 'is.dmgmin1', null, true], // dmgmin1 + 34 => [FILTER_CR_NUMERIC, 'is.dmgmax1', null, true], // dmgmax1 + 36 => [FILTER_CR_NUMERIC, 'is.speed', true, true], // speed + 134 => [FILTER_CR_NUMERIC, 'is.mledps', true, true], // mledps + 135 => [FILTER_CR_NUMERIC, 'is.mledmgmin', null, true], // mledmgmin + 136 => [FILTER_CR_NUMERIC, 'is.mledmgmax', null, true], // mledmgmax + 137 => [FILTER_CR_NUMERIC, 'is.mlespeed', true, true], // mlespeed + 138 => [FILTER_CR_NUMERIC, 'is.rgddps', true, true], // rgddps + 139 => [FILTER_CR_NUMERIC, 'is.rgddmgmin', null, true], // rgddmgmin + 140 => [FILTER_CR_NUMERIC, 'is.rgddmgmax', null, true], // rgddmgmax + 141 => [FILTER_CR_NUMERIC, 'is.rgdspeed', true, true], // rgdspeed + 25 => [FILTER_CR_NUMERIC, 'is.arcres', null, true], // arcres + 26 => [FILTER_CR_NUMERIC, 'is.firres', null, true], // firres + 28 => [FILTER_CR_NUMERIC, 'is.frores', null, true], // frores + 30 => [FILTER_CR_NUMERIC, 'is.holres', null, true], // holres + 27 => [FILTER_CR_NUMERIC, 'is.natres', null, true], // natres + 29 => [FILTER_CR_NUMERIC, 'is.shares', null, true], // shares + 37 => [FILTER_CR_NUMERIC, 'is.mleatkpwr', null, true], // mleatkpwr + 84 => [FILTER_CR_NUMERIC, 'is.mlecritstrkrtng', null, true], // mlecritstrkrtng + 78 => [FILTER_CR_NUMERIC, 'is.mlehastertng', null, true], // mlehastertng + 95 => [FILTER_CR_NUMERIC, 'is.mlehitrtng', null, true], // mlehitrtng + 38 => [FILTER_CR_NUMERIC, 'is.rgdatkpwr', null, true], // rgdatkpwr + 40 => [FILTER_CR_NUMERIC, 'is.rgdcritstrkrtng', null, true], // rgdcritstrkrtng + 101 => [FILTER_CR_NUMERIC, 'is.rgdhastertng', null, true], // rgdhastertng + 39 => [FILTER_CR_NUMERIC, 'is.rgdhitrtng', null, true], // rgdhitrtng + 49 => [FILTER_CR_NUMERIC, 'is.splcritstrkrtng', null, true], // splcritstrkrtng + 102 => [FILTER_CR_NUMERIC, 'is.splhastertng', null, true], // splhastertng + 48 => [FILTER_CR_NUMERIC, 'is.splhitrtng', null, true], // splhitrtng + 51 => [FILTER_CR_NUMERIC, 'is.spldmg', null, true], // spldmg + 50 => [FILTER_CR_NUMERIC, 'is.splheal', null, true], // splheal + 8 => [FILTER_CR_BOOLEAN, 'requiredDisenchantSkill' ], // disenchantable + 10 => [FILTER_CR_BOOLEAN, 'lockId' ], // locked + 59 => [FILTER_CR_NUMERIC, 'durability', null, true], // dura + 104 => [FILTER_CR_STRING, 'description', true ], // flavortext + 7 => [FILTER_CR_BOOLEAN, 'description_loc0', true ], // hasflavortext + 142 => [FILTER_CR_STRING, 'iconString', ], // icon + 12 => [FILTER_CR_BOOLEAN, 'itemset', ], // partofset + 13 => [FILTER_CR_BOOLEAN, 'randomEnchant', ], // randomlyenchanted + 14 => [FILTER_CR_BOOLEAN, 'pageTextId', ], // readable + 63 => [FILTER_CR_NUMERIC, 'buyPrice', null, true], // buyprice + 64 => [FILTER_CR_NUMERIC, 'sellPrice', null, true], // sellprice + 165 => [FILTER_CR_NUMERIC, 'repairPrice', null, true], // repaircost + 91 => [FILTER_CR_ENUM, 'totemCategory' ], // tool + 176 => [FILTER_CR_STAFFFLAG, 'flags' ], // flags + 177 => [FILTER_CR_STAFFFLAG, 'flagsExtra' ], // flags2 ); - - // $field = Util::$itemFilter[$cr[0]]; - public function __construct($parent) { $classes = new CharClassList(); @@ -1370,10 +1464,14 @@ class ItemListFilter extends Filter if ($this->int2Bool($cr[1])) return ['bonding', 2, $cr[1] ? null : '!']; break; - case 4: - if ($this->int2Bool($cr[1])) // bindonuse [yn] + case 4: // bindonuse [yn] + if ($this->int2Bool($cr[1])) return ['bonding', 3, $cr[1] ? null : '!']; break; + case 5: // questitem [yn] + if ($this->int2Bool($cr[1])) + return ['bonding', [4, 5], $cr[1] ? null : '!']; + break; case 168: // teachesspell [yn] 483: learn recipe; 55884: learn mount/pet if ($this->int2Bool($cr[1])) return ['spellId1', [483, 55884], $cr[1] ? null : '!']; @@ -1412,15 +1510,6 @@ class ItemListFilter extends Filter return ['AND', ['gemEnchantmentId', 0, '!'], ['gemColorMask', $mask, '&']]; } break; - case 133: // acc bound [yn] - if ($this->int2Bool($cr[1])) - { - if ($cr[1]) - return ['AND', ['flags', ITEM_FLAG_ACCOUNTBOUND, '&'], ['quality', 7]]; - else - return ['OR', [['flags', ITEM_FLAG_ACCOUNTBOUND, '&'], 0], ['quality', 7, '!']]; - } - break; case 107: // effecttext [str] not yet parsed ['effectsParsed_loc'.User::$localeId, $cr[2]] /* todo */ return [1]; case 132: // glyphtype [enum] susubclass not yet set @@ -1433,20 +1522,10 @@ class ItemListFilter extends Filter break; case 124: // randomenchants [str] // joining this in one step results in hell .. so .. two steps - $tmp = DB::Aowow()->selectCol('SELECT IF (ire.id > 0, iet.entry, -iet.entry) FROM item_enchantment_template iet JOIN ?_itemrandomenchant ire ON ABS(ire.id) = iet.ench WHERE ire.name_loc'.User::$localeId.' LIKE ?', '%'.$cr[2].'%'); - $suffix = $prop = []; - foreach ($tmp as $t) - { - if ($t > 0) - $prop[] = intVal($t); - else if ($t < 0) - $suffix[] = -intVal($t); - } + $randIds = DB::Aowow()->selectCol('SELECT IF (ire.id > 0, iet.entry, -iet.entry) FROM item_enchantment_template iet JOIN ?_itemrandomenchant ire ON ABS(ire.id) = iet.ench WHERE ire.name_loc'.User::$localeId.' LIKE ?', '%'.$cr[2].'%'); - if ($suffix && $prop) - return ['OR', ['randomProperty', $prop], ['randomSuffix', $suffix]]; - else if ($suffix || $prop) - return $prop ? ['randomProperty', $prop] : ['randomSuffix', $suffix]; + if ($randIds) + return ['randomEnchant', $randIds]; else return [0]; // no results aren't really input errors case 125: // reqarenartng [op] [int] JOIN npc_vendor, game_event_npc_vendor, itemextendedcost.dbc @@ -1477,17 +1556,17 @@ class ItemListFilter extends Filter return ['AND', [['requiredRace', RACE_MASK_ALL, '&'], RACE_MASK_ALL, '!'], ['requiredRace', 1 << ($_ - 1), '&']]; } break; - case 35: // damagetype [enum] + case 35: // damagetype [enum] if (!$this->isSaneNumeric($cr[1]) || $cr[1] > 6 || $cr[1] < 0) break; return ['OR', ['dmgType1', $cr[1]], ['dmgType2', $cr[1]]]; case 109: // armorbonus [op] [int] - if (!$this->isSaneNumeric($cr[2], false)) + if (!$this->isSaneNumeric($cr[2], false) || !$this->int2Op($cr[1])) break; $this->formData['extraCols'][] = $cr[0]; - return ['AND', ['armordamagemodifier', $cr[2], $this->int2Op($cr[1])], ['class', ITEM_CLASS_ARMOR]]; + return ['AND', ['armordamagemodifier', $cr[2], $cr[1]], ['class', ITEM_CLASS_ARMOR]]; case 86: // craftedprof [profession] /* todo */ return [1]; case 16: // dropsin [zone] @@ -1547,74 +1626,67 @@ class ItemListFilter extends Filter case 92: // soldbyvendor [yn] /* todo */ return [1]; case 129: // soldbynpc [str-small] -/* todo */ return [1]; - case 161: // availabletoplayers [yn] /* todo */ return [1]; case 90: // avgbuyout [op] [int] /* todo */ return [1]; case 65: // avgmoney [op] [int] - if (!$this->isSaneNumeric($cr[2]) || $cr[1] < 0) + if (!$this->isSaneNumeric($cr[2]) || !$this->int2Op($cr[1])) break; $this->formData['extraCols'][] = $cr[0]; - return ['AND', ['flags', ITEM_FLAG_OPENABLE, '&'], ['((minMoneyLoot + maxMoneyLoot) / 2)', $cr[2], $this->int2Op($cr[1])]]; + return ['AND', ['flags', ITEM_FLAG_OPENABLE, '&'], ['((minMoneyLoot + maxMoneyLoot) / 2)', $cr[2], $cr[1]]]; case 62: // cooldown [op] [int] fuck it .. too complex atm - if (!$this->isSaneNumeric($cr[2]) || $cr[1] < 0) + if (!$this->isSaneNumeric($cr[2]) || !$this->int2Op($cr[1])) break; $this->formData['extraCols'][] = $cr[0]; - /* 5x - if (id > 0 AND trigger = 0 AND - (((cd > 0 OR (cat = 0 AND cd = 0)) AND cdMatch) OR - ((cat > 0 OR (cat = 0 AND cd = 0)) AND catMatch)) - ) - */ -/* todo */ return [1]; - case 162: // deprecated [yn] /* todo */ return [1]; case 163: // disenchantsinto [disenchanting] - break; - case 10: // locked [yn] - break; - case 159: // millable [yn] - break; - case 127: // notavailable [yn] - break; + if (!$this->isSaneNumeric($cr[1])) + break; + // 35 +/* todo */ return [1]; case 85: // objectivequest [side] - break; - case 11: // openable [yn] - break; - case 12: // partofset [yn] - break; - case 98: // partyloot [yn] - break; - case 89: // prospectable [yn] - break; - case 5: // questitem [yn] - break; - case 13: // randomlyenchanted [yn] - break; - case 14: // readable [yn] - break; - case 87: // reagentforability [profession] - break; - case 63: // buyprice [op] [int] - break; - case 154: // refundable [yn] - break; - case 165: // repaircost [op] [int] - break; - case 64: // sellprice [op] [int] - break; - case 157: // smartloot [yn] +/* todo */ return [1]; + case 87: // reagentforability [enum] + $_ = @$this->enums[$cr[0]][$cr[1]]; + if ($_ !== null) + { + $ids = []; + $spells = DB::Aowow()->select( // todo (med): hmm, selecting all using SpellList would exhaust 128MB of memory :x .. see, that we only select the fields that are really needed + 'SELECT reagent1, reagent2, reagent3, reagent4, reagent5, reagent6, reagent7, reagent8, + reagentCount1, reagentCount2, reagentCount3, reagentCount4, reagentCount5, reagentCount6, reagentCount7, reagentCount8 + FROM ?_spell + WHERE skillLine1 IN (?a)', + is_bool($_) ? array_filter($this->enums[$cr[0]], "is_numeric") : $_ + ); + foreach ($spells as $spell) + for ($i = 1; $i < 9; $i++) + if ($spell['reagent'.$i] > 0 && $spell['reagentCount'.$i] > 0) + $ids[] = $spell['reagent'.$i]; + + if (empty($ids)) + return [0]; + else if ($_) + return ['id', $ids]; + else + return ['id', $ids, '!']; + } break; case 6: // startsquest [side] - break; - case 91: // tool [totemcategory] - break; - case 155: // usableinarenas [yn] - break; - case 156: // usablewhenshapeshifted [yn] + switch ($cr[1]) + { + case 1: // any + return ['startQuest', 0, '>']; + case 2: // exclude horde only + return ['AND', ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], 2]]; + case 3: // exclude alliance only + return ['AND', ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], 1]]; + case 4: // both + return ['AND', ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], 0]]; + case 5: // none + return ['startQuest', 0]; + } break; case 130: // hascomments [yn] break; @@ -1734,16 +1806,16 @@ class ItemListFilter extends Filter $parts[] = $notEx; break; case 2: - $parts[] = ['OR', $notEx, ['requiredRace', RACE_MASK_HORDE, '&']]; + $parts[] = ['AND', [['flagsExtra', 0x3, '&'], [0, 1]], ['OR', $notEx, ['requiredRace', RACE_MASK_HORDE, '&']]]; break; case -2: - $parts[] = ['AND', $ex, ['requiredRace', RACE_MASK_HORDE, '&']]; + $parts[] = ['OR', [['flagsExtra', 0x3, '&'], 1], ['AND', $ex, ['requiredRace', RACE_MASK_HORDE, '&']]]; break; case 1: - $parts[] = ['OR', $notEx, ['requiredRace', RACE_MASK_ALLIANCE, '&']]; + $parts[] = ['AND', [['flagsExtra', 0x3, '&'], [0, 2]], ['OR', $notEx, ['requiredRace', RACE_MASK_ALLIANCE, '&']]]; break; case -1: - $parts[] = ['AND', $ex, ['requiredRace', RACE_MASK_ALLIANCE, '&']]; + $parts[] = ['OR', [['flagsExtra', 0x3, '&'], 2], ['AND', $ex, ['requiredRace', RACE_MASK_ALLIANCE, '&']]]; break; default: unset($_v['si']); diff --git a/includes/class.itemset.php b/includes/types/itemset.class.php similarity index 100% rename from includes/class.itemset.php rename to includes/types/itemset.class.php diff --git a/includes/class.pet.php b/includes/types/pet.class.php similarity index 100% rename from includes/class.pet.php rename to includes/types/pet.class.php diff --git a/includes/class.quest.php b/includes/types/quest.class.php similarity index 91% rename from includes/class.quest.php rename to includes/types/quest.class.php index 57ac949e..7579d1c0 100644 --- a/includes/class.quest.php +++ b/includes/types/quest.class.php @@ -160,28 +160,11 @@ class QuestList extends BaseType private function parseText($type = 'Objectives') { - $replace = array( - '$c' => '<'.Util::ucFirst(Lang::$game['class']).'>', - '$C' => '<'.Util::ucFirst(Lang::$game['class']).'>', - '$r' => '<'.Util::ucFirst(Lang::$game['race']).'>', - '$R' => '<'.Util::ucFirst(Lang::$game['race']).'>', - '$n' => '<'.Util::ucFirst(Lang::$main['name']).'>', - '$N' => '<'.Util::ucFirst(Lang::$main['name']).'>', - '$b' => '
', - '$B' => '
' - ); - $text = $this->getField($type, true); if (!$text) return ''; - $text = strtr($text, $replace); - - // gender switch - $text = preg_replace('/$g([^:;]+):([^:;]+);/ui', '<\1/\2<', $text); - - // nonesense, that the client apparently ignores - $text = preg_replace('/$t([^;]+);/ui', '', $text); + $text = Util::parseHtmlText($text); return Util::jsEscape($text); } diff --git a/includes/class.skill.php b/includes/types/skill.class.php similarity index 100% rename from includes/class.skill.php rename to includes/types/skill.class.php diff --git a/includes/class.spell.php b/includes/types/spell.class.php similarity index 89% rename from includes/class.spell.php rename to includes/types/spell.class.php index 9b093c31..864d543d 100644 --- a/includes/class.spell.php +++ b/includes/types/spell.class.php @@ -48,8 +48,8 @@ class SpellList extends BaseType foreach ($this->iterate() as &$_curTpl) { // required for globals - for ($i = 1; $i <= 3; $i++) - if ($this->canCreateItem()) + if ($idx = $this->canCreateItem()) + foreach ($idx as $i) $foo[] = (int)$_curTpl['effect'.$i.'CreateItemId']; for ($i = 1; $i <= 8; $i++) @@ -129,13 +129,24 @@ class SpellList extends BaseType for ($i = 1; $i <= 3; $i++) { - if (!in_array($this->curTpl["effect".$i."AuraId"], [8, 13, 22, 29, 34, 35, 83, 84, 85, 99, 124, 135, 143, 158, 161, 189, 230, 235, 240, 250])) + $mv = $this->curTpl['effect'.$i.'MiscValue']; + $bp = $this->curTpl['effect'.$i.'BasePoints'] + 1; + $au = $this->curTpl['effect'.$i.'AuraId']; + + // Enchant Item Permanent (53) / Temporary (54) + if (in_array($this->curTpl['effect'.$i.'Id'], [53, 54])) + { + if ($mv) + Util::arraySumByKey($stats, Util::parseItemEnchantment($mv, true)); + + continue; + } + + // Aura Effects + if (!in_array($au, [8, 13, 22, 29, 34, 35, 83, 84, 85, 99, 124, 135, 143, 158, 161, 189, 220, 230, 235, 240, 250])) continue; - $mv = $this->curTpl["effect".$i."MiscValue"]; - $bp = $this->curTpl["effect".$i."BasePoints"] + 1; - - switch ($this->curTpl["effect".$i."AuraId"]) + switch ($au) { case 29: // ModStat MiscVal:type { @@ -219,20 +230,9 @@ class SpellList extends BaseType break; } case 189: // CombatRating MiscVal:ratingMask - // special case: resilience - consists of 3 ratings strung together. MOD_CRIT_TAKEN_MELEE|RANGED|SPELL (14,15,16) - if (($mv & 0x1C000) == 0x1C000) - @$stats[ITEM_MOD_RESILIENCE_RATING] += $bp; - - for ($j = 0; $j < count(Util::$combatRatingToItemMod); $j++) - { - if (!Util::$combatRatingToItemMod[$j]) - continue; - - if (($mv & (1 << $j)) == 0) - continue; - - @$stats[Util::$combatRatingToItemMod[$j]] += $bp; - } + case 220: + if ($mod = Util::itemModByRatingMask($mv)) + @$stats[$mod] += $bp; break; case 143: // Resistance MiscVal:school case 83: @@ -304,7 +304,18 @@ class SpellList extends BaseType } // halper - private function getToolsForCurrent() + public function getReagentsForCurrent() + { + $data = []; + + for ($i = 1; $i <= 8; $i++) + if ($this->curTpl['reagent'.$i] > 0 && $this->curTpl['reagentCount'.$i]) + $data[$this->curTpl['reagent'.$i]] = [$this->curTpl['reagent'.$i], $this->curTpl['reagentCount'.$i]]; + + return $data; + } + + public function getToolsForCurrent() { if ($this->tools) return $this->tools; @@ -321,7 +332,7 @@ class SpellList extends BaseType if ($relId != $this->curTpl['tool'.$i]) continue; - $tools[$i-1] = array( + $tools[$i - 1] = array( 'itemId' => $relId, 'name' => $this->relItems->getField('name', true), 'quality' => $this->relItems->getField('quality') @@ -334,8 +345,8 @@ class SpellList extends BaseType if ($_ = $this->curTpl['toolCategory'.$i]) { $tc = DB::Aowow()->selectRow('SELECT * FROM ?_totemcategory WHERE id = ?d', $_); - $tools[$i+1] = array( - 'id' => $_, + $tools[$i + 1] = array( + 'id' => $_, 'name' => Util::localizedString($tc, 'name')); } } @@ -367,7 +378,7 @@ class SpellList extends BaseType return sprintf(Lang::$spell['range'], $this->curTpl['rangeMaxHostile']); } - private function createPowerCostForCurrent() + public function createPowerCostForCurrent() { $str = ''; @@ -403,7 +414,7 @@ class SpellList extends BaseType return $str; } - private function createCastTimeForCurrent($short = true, $noInstant = true) + public function createCastTimeForCurrent($short = true, $noInstant = true) { if ($this->curTpl['interruptFlagsChannel']) return Lang::$spell['channeled']; @@ -462,12 +473,28 @@ class SpellList extends BaseType public function canCreateItem() { - // 24: createItem; 34: changeItem; 59: randomItem; 66: createManaGem; 157: createitem2; 86: channelDeathItem + $idx = []; + // effect - 24: createItem; 34: changeItem; 59: randomItem; 66: createManaGem; 157: createItem2 + // aura - 86: channelDeathItem for ($i = 1; $i < 4; $i++) - if (in_array($this->curTpl['effect'.$i.'Id'], [24, 34, 59, 66, 157]) || $this->curTpl['effect'.$i.'AuraId'] == 86) - return true; + if (in_array($this->curTpl['effect'.$i.'Id'], [24, 34, 59, 66, 157]) || in_array($this->curTpl['effect'.$i.'AuraId'], [86])) + if ($this->curTpl['effect'.$i.'CreateItemId'] > 0) + $idx[] = $i; - return false; + return $idx; + } + + public function canTriggerSpell() + { + $idx = []; + // effect - 3: dummy; 32: trigger missile; 36: learn spell; 57: learn pet spell; 64/151: trigger spell (2); 101: feed pet; 133: unlearn specialization; 140/142: force cast (with value); 148/152/160: unk; 164: remove aura + // aura - 4: dummy; 23/227: periodic trigger spell (with value); 42/231: proc trigger spell (with value); 48: unk; 109: add target trigger; 226: periodic dummy; 236: control vehicle; 284: linked + for ($i = 1; $i < 4; $i++) + if (in_array($this->curTpl['effect'.$i.'Id'], [3, 32, 36, 57, 64, 101, 133, 142, 148, 151, 152, 160, 164]) || in_array($this->curTpl['effect'.$i.'AuraId'], [4, 23, 42, 48, 109, 226, 227, 231, 236, 284])) + if ($this->curTpl['effect'.$i.'TriggerSpell'] > 0) + $idx[] = $i; + + return $idx; } // description-, buff-parsing component @@ -547,7 +574,7 @@ class SpellList extends BaseType } // description-, buff-parsing component - private function resolveVariableString($variable) + private function resolveVariableString($variable, &$usesScalingRating) { $signs = ['+', '-', '/', '*', '%', '^']; @@ -684,20 +711,9 @@ class SpellList extends BaseType // Aura giving combat ratings $rType = 0; - if ($aura == 189) - { - for ($j = 0; $j < count(Util::$combatRatingToItemMod); $j++) - { - if (!Util::$combatRatingToItemMod[$j]) - continue; - - if (($mv & (1 << $j)) == 0) - continue; - - $rType = Util::$combatRatingToItemMod[$j]; - break; - } - } + if (in_array($aura, [189, 220])) + if ($rType = Util::itemModByRatingMask($mv)) + $usesScalingRating = true; // Aura end if ($rType && $this->interactive) @@ -794,20 +810,9 @@ class SpellList extends BaseType // Aura giving combat ratings $rType = 0; - if ($aura == 189) - { - for ($j = 0; $j < count(Util::$combatRatingToItemMod); $j++) - { - if (!Util::$combatRatingToItemMod[$j]) - continue; - - if (($mv & (1 << $j)) == 0) - continue; - - $rType = Util::$combatRatingToItemMod[$j]; - break; - } - } + if (in_array($aura, [189, 220])) + if ($rType = Util::itemModByRatingMask($mv)) + $usesScalingRating = true; // Aura end if ($rType && $equal && $this->interactive) @@ -868,7 +873,7 @@ class SpellList extends BaseType } // description-, buff-parsing component - private function resolveFormulaString($formula, $precision = 0) + private function resolveFormulaString($formula, $precision = 0, &$scaling) { // step 1: formula unpacking redux while (($formStartPos = strpos($formula, '${')) !== false) @@ -904,7 +909,7 @@ class SpellList extends BaseType ++$formCurPos; // for some odd reason the precision decimal survives if wo dont increment further.. } - $formOutStr = $this->resolveFormulaString($formOutStr, $formPrecision); + $formOutStr = $this->resolveFormulaString($formOutStr, $formPrecision, $scaling); $formula = substr_replace($formula, $formOutStr, $formStartPos, ($formCurPos - $formStartPos)); } @@ -930,7 +935,7 @@ class SpellList extends BaseType } $pos += strlen($result[0]); - $var = $this->resolveVariableString($result); + $var = $this->resolveVariableString($result, $scaling); if (is_array($var)) { $str .= $var[0]; @@ -951,7 +956,7 @@ class SpellList extends BaseType // should probably used only once to create ?_spell. come to think of it, it yields the same results every time.. it absolutely has to! // although it seems to be pretty fast, even on those pesky test-spells with extra complex tooltips (Ron Test Spell X)) - public function parseText($type = 'description', $level = MAX_LEVEL, $interactive = false) + public function parseText($type = 'description', $level = MAX_LEVEL, $interactive = false, &$scaling = false) { // oooo..kaaayy.. parsing text in 6 or 7 easy steps // we don't use the internal iterator here. This func has to be called for the individual template. @@ -1028,8 +1033,8 @@ class SpellList extends BaseType $max(a, b) - max() */ - $this->interactive = $interactive; - $this->charLevel = $level; + $this->interactive = $interactive; + $this->charLevel = $level; // step 0: get text $data = $this->getField($type, true); @@ -1096,8 +1101,8 @@ Turns the Shaman into a Ghost Wolf, increasing speed by $s2%$?s59289[ and regene Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.] */ - else if (!empty($matches[2])) // aura/spell-condition .. use false; TODO (low): catch cases and port "know"-param for tooltips from 5.0 - { // tooltip_enus: Charge to an enemy, stunning it for 1 sec.; spells_enus: {"58377": [["", "and 2 additional nearby targets "]], "103828": [["1 sec", "3 sec"]]}; + else if (!empty($matches[2])) + { $condStartPos = strpos($data, $matches[2]) - 2; $condCurPos = $condStartPos; } @@ -1191,7 +1196,7 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.] $formPrecision = $data[$formCurPos + 1]; $formCurPos += 2; } - $formOutStr = $this->resolveFormulaString($formOutStr, $formPrecision); + $formOutStr = $this->resolveFormulaString($formOutStr, $formPrecision, $scaling); $data = substr_replace($data, $formOutStr, $formStartPos, ($formCurPos - $formStartPos)); } @@ -1218,7 +1223,7 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.] $pos += strlen($result[0]); - $var = $this->resolveVariableString($result); + $var = $this->resolveVariableString($result, $scaling); $resolved = is_array($var) ? $var[0] : $var; $str .= is_numeric($resolved) ? abs($resolved) : $resolved; if (is_array($var)) @@ -1227,7 +1232,7 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.] $str .= substr($data, $pos); $str = str_replace('#', '$', $str); // reset marker - // step 5: variable-depentant variable-text + // step 5: variable-dependant variable-text // special case $lONE:ELSE; // todo (low): russian uses THREE (wtf?! oO) cases ($l[singular]:[plural1]:[plural2]) .. explode() chooses always the first plural option :/ while (preg_match('/([\d\.]+)([^\d]*)(\$l:*)([^:]*):([^;]*);/i', $str, $m)) @@ -1271,7 +1276,7 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.] $x .= '
'; // parse Buff-Text - $btt = $this->parseText('buff', $level, $this->interactive); + $btt = $this->parseText('buff', $level, $this->interactive, $scaling); $x .= $btt[0].'
'; // duration @@ -1280,6 +1285,9 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.] $x .= '
'; + // scaling information - spellId:min:max:curr + $x .= ''; + $this->buffs[$this->id] = array($x, $btt[1]); return $this->buffs[$this->id]; @@ -1298,7 +1306,7 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.] // fetch needed texts $name = $this->getField('name', true); $rank = $this->getField('rank', true); - $desc = $this->parseText('description', $level, $this->interactive); + $desc = $this->parseText('description', $level, $this->interactive, $scaling); $tools = $this->getToolsForCurrent(); $cool = $this->createCooldownForCurrent(); $cast = $this->createCastTimeForCurrent(); @@ -1306,18 +1314,10 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.] $range = $this->createRangesForCurrent(); // get reagents - $reagents = []; - for ($j = 1; $j <= 8; $j++) - { - if($this->curTpl['reagent'.$j] <= 0) - continue; + $reagents = $this->getReagentsForCurrent(); + foreach ($reagents as &$r) + $r[2] = ItemList::getName($r[0]); - $reagents[] = array( - 'id' => $this->curTpl['reagent'.$j], - 'name' => ItemList::getName($this->curTpl['reagent'.$j]), - 'count' => $this->curTpl['reagentCount'.$j] // if < 0 : require, but don't use - ); - } $reagents = array_reverse($reagents); // get stances (check: SPELL_ATTR2_NOT_NEED_SHAPESHIFT) @@ -1414,9 +1414,9 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.] $_ = Lang::$spell['reagents'].':
'; while ($reagent = array_pop($reagents)) { - $_ .= ''.$reagent['name'].''; - if ($reagent['count'] > 1) - $_ .= ' ('.$reagent['count'].')'; + $_ .= ''.$reagent[2].''; + if ($reagent[1] > 1) + $_ .= ' ('.$reagent[1].')'; if(!empty($reagents)) $_ .= ', '; @@ -1439,6 +1439,9 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.] if ($xTmp) $x .= '
'.implode('
', $xTmp).'
'; + // scaling information - spellId:min:max:curr + $x .= ''; + $this->tooltips[$this->id] = array($x, $desc ? $desc[1] : null); return $this->tooltips[$this->id]; @@ -1517,7 +1520,7 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.] 'cat' => $this->curTpl['typeCat'], 'trainingcost' => $this->curTpl['trainingCost'], 'skill' => count($this->curTpl['skillLines']) > 4 ? array_merge(array_splice($this->curTpl['skillLines'], 0, 4), [-1]): $this->curTpl['skillLines'], // display max 4 skillLines (fills max three lines in listview) - 'reagents' => [], + 'reagents' => $this->getReagentsForCurrent(), 'source' => [] ); @@ -1555,11 +1558,6 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.] $data[$this->id]['colors'] = $this->getColorsForCurrent(); } - // reagents - for ($i = 1; $i <= 8; $i++) - if ($this->curTpl['reagent'.$i] > 0 && $this->curTpl['reagentCount'.$i] > 0) - $data[$this->id]['reagents'][] = [$this->curTpl['reagent'.$i], $this->curTpl['reagentCount'.$i]]; - // glyph if ($this->curTpl['typeCat'] == -13) $data[$this->id]['glyphtype'] = $this->curTpl['cuFlags'] & SPELL_CU_GLYPH_MAJOR ? 1 : 2; @@ -1577,86 +1575,12 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.] return $data; } - public function getDetailPageData() - { - $result = array( - 'id' => $this->id, - 'name' => $this->getField('name', true), - 'icon' => $this->curTpl['iconString'], - 'stack' => $this->curTpl['stackAmount'], - 'powerCost' => $this->createPowerCostForCurrent(), - 'level' => $this->curTpl['spellLevel'], - 'rangeName' => $this->getField('rangeText', true), - 'range' => $this->curTpl['rangeMaxHostile'], - 'castTime' => $this->createCastTimeForCurrent(false, false), - 'cooldown' => $this->curTpl['recoveryTime'] > 0 ? Util::formatTime($this->curTpl['recoveryTime']) : ''.Lang::$main['n_a'].'', - 'gcd' => Util::formatTime($this->curTpl['startRecoveryTime']), - 'gcdCat' => "[NYI]", - 'duration' => $this->curTpl['duration'] > 0 ? Util::formatTime($this->curTpl['duration']) : ''.Lang::$main['n_a'].'', - 'school' => sprintf(Util::$dfnString, Util::asHex($this->getField('schoolMask')), Lang::getMagicSchools($this->getField('schoolMask'))), - 'dispel' => isset(Lang::$game['dt'][$this->curTpl['dispelType']]) ? Lang::$game['dt'][$this->curTpl['dispelType']] : ''.Lang::$main['n_a'].'', - 'mechanic' => isset(Lang::$game['me'][$this->curTpl['mechanic']]) ? Lang::$game['me'][$this->curTpl['mechanic']] : ''.Lang::$main['n_a'].'', - 'stances' => $this->curTpl['attributes2'] & 0x80000 ? '' : Lang::getStances($this->curTpl['stanceMask']), - 'tools' => $this->getToolsForCurrent(), - 'reagents' => [], - 'items' => [] - ); - - // minRange exists.. prepend - if ($_ = $this->curTpl['rangeMinHostile']) - $result['range'] = $_.' - '.$result['range']; - - // fill reagents - for ($i = 1; $i < 9; $i++) - if ($this->curTpl['reagent'.$i] > 0 && $this->curTpl['reagentCount'.$i] > 0) - $result['reagents'][$this->curTpl['reagent'.$i]] = $this->curTpl['reagentCount'.$i]; - - // parse itemClass & itemSubClassMask - $class = $this->getField('equippedItemClass'); - $subClass = $this->getField('equippedItemSubClassMask'); - - if ($class > 0 && $subClass > 0) - { - $title = ['CLASS: '.$class, 'SUBCLASS: '.Util::asHex($subClass)]; - $text = Lang::getRequiredItems($class, $subClass, false); - - if ($invType = $this->getField('equippedItemInventoryTypeMask')) - { - // remap some duplicated strings 'Off Hand' and 'Shield' are never used simultaneously - if ($invType & (1 << INVTYPE_ROBE)) // Robe => Chest - { - $invType &= ~(1 << INVTYPE_ROBE); - $invType &= (1 << INVTYPE_CHEST); - } - - if ($invType & (1 << INVTYPE_RANGEDRIGHT)) // Ranged2 => Ranged - { - $invType &= ~(1 << INVTYPE_RANGEDRIGHT); - $invType &= (1 << INVTYPE_RANGED); - } - - $_ = []; - $strs = Lang::$item['inventoryType']; - foreach ($strs as $k => $str) - if ($invType & 1 << $k && $str) - $_[] = $str; - - $title[] = 'INVENTORYTYPE: '.Util::asHex($invType); - $text .= ' '.Lang::$spell['_inSlot'].': '.implode(', ', $_); - } - - $result['items'] = sprintf(Util::$dfnString, implode(' - ', $title), $text); - } - - return $result; - } - - public function addGlobalsToJScript(&$template, $addMask = GLOBALINFO_ANY) + public function addGlobalsToJScript(&$template, $addMask = GLOBALINFO_SELF) { if ($this->relItems && ($addMask & GLOBALINFO_RELATED)) $this->relItems->addGlobalsToJscript($template); - foreach ($this->iterate() as $__) + foreach ($this->iterate() as $id => $__) { if ($addMask & GLOBALINFO_RELATED) { @@ -1671,15 +1595,42 @@ Lasts 5 min. $?$gte($pl,68)[][Cannot be used on items level 138 and higher.] $template->extendGlobalIds(TYPE_RACE, $i + 1); } + $data = null; + $extra = null; if ($addMask & GLOBALINFO_SELF) { $iconString = $this->curTpl['iconStringAlt'] ? 'iconStringAlt' : 'iconString'; - $template->extendGlobalData(self::$type, [$this->id => array( - 'icon' => $this->curTpl[$iconString], - 'name' => $this->getField('name', true), - )]); + $data = array( + $id => array( + 'icon' => $this->curTpl[$iconString], + 'name' => $this->getField('name', true), + ) + ); } + + if ($addMask & GLOBALINFO_EXTRA) + { +/* +spells / buffspells = { + "58377": [["", "and 2 additional nearby targets "]], + "103828": [["stunning", "rooting"], ["1 sec", "4 sec and reducing movement speed by 50% for 15 sec"]] +}; +*/ + $buff = $this->renderBuff(MAX_LEVEL, true); + $tTip = $this->renderTooltip(MAX_LEVEL, true); + + $extra = array( + 'id' => $id, + 'tooltip' => Util::jsEscape($tTip[0]), + 'buff' => @Util::jsEscape($buff[0]), + 'spells' => $tTip[1], + 'buffspells' => @$buff[1] + ); + } + + if ($data || $extra) + $template->extendGlobalData(self::$type, $data, $extra); } } } @@ -1784,7 +1735,7 @@ class SpellListFilter extends Filter $parts[] = ['name_loc'.User::$localeId, $_v['na']]; } - // spellLevel min + // spellLevel min todo (low): talentSpells (typeCat -2) commonly have spellLevel 1 (and talentLevel >1) -> query is inaccurate if (isset($_v['minle'])) { if (is_int($_v['minle']) && $_v['minle'] > 0) diff --git a/includes/class.title.php b/includes/types/title.class.php similarity index 97% rename from includes/class.title.php rename to includes/types/title.class.php index ae941c9a..a2b4ff14 100644 --- a/includes/class.title.php +++ b/includes/types/title.class.php @@ -141,7 +141,7 @@ class TitleList extends BaseType public function getHtmlizedName($gender = GENDER_MALE) { $field = $gender == GENDER_FEMALE ? 'female' : 'male'; - return str_replace('%s', '<'.Lang::$main['name'].'>', $this->getField($field, true)); + return str_replace('%s', '<'.Util::ucFirst(Lang::$main['name']).'>', $this->getField($field, true)); } public function renderTooltip() { } diff --git a/includes/class.worldevent.php b/includes/types/worldevent.class.php similarity index 100% rename from includes/class.worldevent.php rename to includes/types/worldevent.class.php diff --git a/includes/class.zone.php b/includes/types/zone.class.php similarity index 100% rename from includes/class.zone.php rename to includes/types/zone.class.php diff --git a/includes/class.user.php b/includes/user.class.php similarity index 100% rename from includes/class.user.php rename to includes/user.class.php diff --git a/includes/utilities.php b/includes/utilities.php index 6660cc49..0fb09abc 100644 --- a/includes/utilities.php +++ b/includes/utilities.php @@ -5,6 +5,7 @@ if (!defined('AOWOW_REVISION')) class Lang { + public static $timeUnits; public static $main; public static $account; public static $game; @@ -54,10 +55,13 @@ class Lang $tmp = []; if ($flags & CUSTOM_DISABLED) - $tmp[] = ''.self::$main['disabled'].''; + $tmp[] = '[tooltip name=disabledHint]'.Util::jsEscape(self::$main['disabledHint']).'[/tooltip][span class=tip tooltip=disabledHint]'.Util::jsEscape(self::$main['disabled']).'[/span]'; if ($flags & CUSTOM_SERVERSIDE) - $tmp[] = ''.self::$main['serverside'].''; + $tmp[] = '[tooltip name=serversideHint]'.Util::jsEscape(self::$main['serversideHint']).'[/tooltip][span class=tip tooltip=serversideHint]'.Util::jsEscape(self::$main['serverside']).'[/span]'; + + if ($flags & CUSTOM_UNAVAILABLE) + $tmp[] = self::$main['unavailable']; return $tmp; } @@ -94,6 +98,21 @@ class Lang if (!$name) continue; + if ($interactive) + { + $skill = 0; + switch ($prop) + { + case 1: $skill = 633; break; // Lockpicking + case 2: $skill = 182; break; // Herbing + case 3: $skill = 186; break; // Mining + case 20: $skill = 773; break; // Scribing + } + + if ($skill) + $name = ''.$name.''; + } + if ($rnk > 0) $name .= ' ('.$rnk.')'; } @@ -125,10 +144,10 @@ class Lang // not checking weapon / armor here. It's highly unlikely that they overlap if ($short) { - if ($class == 15) // misc - Mounts + if ($class == ITEM_CLASS_MISC) // misc - Mounts return ''; - if ($class == 4 && $mask == 0x001E) // all basic armor classes + if ($class == ITEM_CLASS_ARMOR && $mask == 0x1E) // all basic armor classes return ''; foreach(Lang::$spell['subClassMasks'] as $m => $str) @@ -136,11 +155,11 @@ class Lang return $str; } - if ($class == 15) // yeah hardcoded.. sue me! + if ($class == ITEM_CLASS_MISC) // yeah hardcoded.. sue me! return Lang::$spell['cat'][-5]; - $tmp = []; - $strs = Lang::$spell[$class == 4 ? 'armorSubClass' : 'weaponSubClass']; + $tmp = []; + $strs = Lang::$spell[$class == ITEM_CLASS_ARMOR ? 'armorSubClass' : 'weaponSubClass']; foreach ($strs as $k => $str) if ($mask & 1 << $k && $str) $tmp[] = $str; @@ -371,14 +390,18 @@ class SmartyAoWoW extends Smarty return true; } - public function extendGlobalData($type, $data) + public function extendGlobalData($type, $data, $extra = null) { $this->initJSGlobal($type); - $_ = &$this->_tpl_vars['jsGlobals'][$type][1]; // shorthand + $_ = &$this->_tpl_vars['jsGlobals'][$type]; // shorthand - foreach ($data as $id => $set) - if (!isset($_[$id])) - $_[$id] = $set; + if (is_array($data) && $data) + foreach ($data as $id => $set) + if (!isset($_[1][$id])) + $_[1][$id] = $set; + + if (is_array($extra) && $extra) + $_[2] = $extra; } private function initJSGlobal($type) @@ -389,22 +412,22 @@ class SmartyAoWoW extends Smarty return; switch ($type) - { // [brickFile, [data]] - case TYPE_NPC: $jsg[TYPE_NPC] = ['creatures', []]; break; - case TYPE_OBJECT: $jsg[TYPE_OBJECT] = ['objects', []]; break; - case TYPE_ITEM: $jsg[TYPE_ITEM] = ['items', []]; break; - case TYPE_QUEST: $jsg[TYPE_QUEST] = ['quests', []]; break; - case TYPE_SPELL: $jsg[TYPE_SPELL] = ['spells', []]; break; - case TYPE_ZONE: $jsg[TYPE_ZONE] = ['zones', []]; break; - case TYPE_FACTION: $jsg[TYPE_FACTION] = ['factions', []]; break; - case TYPE_PET: $jsg[TYPE_PET] = ['pets', []]; break; - case TYPE_ACHIEVEMENT: $jsg[TYPE_ACHIEVEMENT] = ['achievements', []]; break; - case TYPE_TITLE: $jsg[TYPE_TITLE] = ['titles', []]; break; - case TYPE_WORLDEVENT: $jsg[TYPE_WORLDEVENT] = ['holidays', []]; break; - case TYPE_CLASS: $jsg[TYPE_CLASS] = ['classes', []]; break; - case TYPE_RACE: $jsg[TYPE_RACE] = ['races', []]; break; - case TYPE_SKILL: $jsg[TYPE_SKILL] = ['skills', []]; break; - case TYPE_CURRENCY: $jsg[TYPE_CURRENCY] = ['currencies', []]; break; + { // [brickFile, [data], [extra]] + case TYPE_NPC: $jsg[TYPE_NPC] = ['creatures', [], []]; break; + case TYPE_OBJECT: $jsg[TYPE_OBJECT] = ['objects', [], []]; break; + case TYPE_ITEM: $jsg[TYPE_ITEM] = ['items', [], []]; break; + case TYPE_QUEST: $jsg[TYPE_QUEST] = ['quests', [], []]; break; + case TYPE_SPELL: $jsg[TYPE_SPELL] = ['spells', [], []]; break; + case TYPE_ZONE: $jsg[TYPE_ZONE] = ['zones', [], []]; break; + case TYPE_FACTION: $jsg[TYPE_FACTION] = ['factions', [], []]; break; + case TYPE_PET: $jsg[TYPE_PET] = ['pets', [], []]; break; + case TYPE_ACHIEVEMENT: $jsg[TYPE_ACHIEVEMENT] = ['achievements', [], []]; break; + case TYPE_TITLE: $jsg[TYPE_TITLE] = ['titles', [], []]; break; + case TYPE_WORLDEVENT: $jsg[TYPE_WORLDEVENT] = ['holidays', [], []]; break; + case TYPE_CLASS: $jsg[TYPE_CLASS] = ['classes', [], []]; break; + case TYPE_RACE: $jsg[TYPE_RACE] = ['races', [], []]; break; + case TYPE_SKILL: $jsg[TYPE_SKILL] = ['skills', [], []]; break; + case TYPE_CURRENCY: $jsg[TYPE_CURRENCY] = ['currencies', [], []]; break; } } @@ -418,8 +441,8 @@ class SmartyAoWoW extends Smarty if (!$ids) continue; - $this->initJSGlobal($type); + $ids = array_unique($ids, SORT_NUMERIC); switch ($type) { @@ -447,7 +470,7 @@ class SmartyAoWoW extends Smarty $this->updatePageVars(array( 'subject' => Util::ucFirst($subject), 'id' => intVal($this->_tpl_vars['query'][1]), - 'notFound' => sprintf(Lang::$main['pageNotFound'], $subject), + 'notFound' => sprintf(Lang::$main['pageNotFound'], $subject) )); $this->assign('lang', Lang::$main); @@ -664,6 +687,7 @@ class Util public static $dateFormatLong = "Y/m/d H:i:s"; public static $changeLevelString = '%s'; + public static $setRatingLevelString = '%s'; public static $filterResultString = '$$WH.sprintf(LANG.lvnote_filterresults, \'%s\')'; @@ -682,6 +706,11 @@ class Util null, 4, 10, 9, 8, 6, 15, 11, 3, 5, null, 7 ); + // from DurabilityQuality.dbc + public static $itemDurabilityQualityMod = array( + null, 1.0, 0.6, 1.0, 0.8, 1.0, 1.0, 1.2, 1.25, 1.44, 2.5, 1.728, 3.0, 0.0, 0.0, 1.2, 1.25 + ); + // todo: translate and move to Lang public static $spellModOp = array( 0 => 'DAMAGE', @@ -997,7 +1026,7 @@ class Util 45 => 'Track Resources', 46 => 'Mod Parry Skill', 47 => 'Mod Parry Percent', - 48 => 'Mod Dodge Skill', + 48 => 'Unknown Aura', 49 => 'Mod Dodge Percent', 50 => 'Mod Critical Healing Amount', 51 => 'Mod Block Percent', @@ -1297,6 +1326,16 @@ class Util return self::formatTime($tDiff * 1000, true); } + public static function getBuyoutForItem($itemId) + { + if (!$itemId) + return 0; + + // try, when having filled char-DB at hand + // return DB::Characters()->selectCell('SELECT SUM(a.buyoutprice) / SUM(ii.count) FROM auctionhouse a JOIN item_instance ii ON ii.guid = a.itemguid WHERE ii.itemEntry = ?d', $itemId); + return 0; + } + public static function formatMoney($qty) { $money = ''; @@ -1362,50 +1401,58 @@ class Util if ($short) { - if ($s['d']) - return round($s['d'])." ".Lang::$main['daysAbbr']; - if ($s['h']) - return round($s['h'])." ".Lang::$main['hoursAbbr']; - if ($s['m']) - return round($s['m'])." ".Lang::$main['minutesAbbr']; - if ($s['s']) - return round($s['s'] + $s['ms'] / 1000, 2)." ".Lang::$main['secondsAbbr']; + if ($_ = round($s['d'])) + return $_." ".Lang::$timeUnits['ab'][3]; + if ($_ = round($s['h'])) + return $_." ".Lang::$timeUnits['ab'][4]; + if ($_ = round($s['m'])) + return $_." ".Lang::$timeUnits['ab'][5]; + if ($_ = round($s['s'] + $s['ms'] / 1000, 2)) + return $_." ".Lang::$timeUnits['ab'][6]; if ($s['ms']) - return $s['ms']." ".Lang::$main['millisecsAbbr']; + return $s['ms']." ".Lang::$timeUnits['ab'][7]; - return '0 '.Lang::$main['secondsAbbr']; + return '0 '.Lang::$timeUnits['ab'][6]; } else { if ($s['d']) - return round($s['d'] + $s['h'] / 24, 2)." ".Lang::$main['days']; + return round($s['d'] + $s['h'] / 24, 2)." ".Lang::$timeUnits[$s['d'] == 1 && !$s['h'] ? 'sg' : 'pl'][3]; if ($s['h']) - return round($s['h'] + $s['m'] / 60, 2)." ".Lang::$main['hours']; + return round($s['h'] + $s['m'] / 60, 2)." ".Lang::$timeUnits[$s['h'] == 1 && !$s['m'] ? 'sg' : 'pl'][4]; if ($s['m']) - return round($s['m'] + $s['s'] / 60, 2)." ".Lang::$main['minutes']; + return round($s['m'] + $s['s'] / 60, 2)." ".Lang::$timeUnits[$s['m'] == 1 && !$s['s'] ? 'sg' : 'pl'][5]; if ($s['s']) - return round($s['s'] + $s['ms'] / 1000, 2)." ".Lang::$main['seconds']; + return round($s['s'] + $s['ms'] / 1000, 2)." ".Lang::$timeUnits[$s['s'] == 1 && !$s['ms'] ? 'sg' : 'pl'][6]; if ($s['ms']) - return $s['ms']." ".Lang::$main['millisecs']; + return $s['ms']." ".Lang::$timeUnits[$s['ms'] == 1 ? 'sg' : 'pl'][7]; - return '0 '.Lang::$main['seconds']; -/* kept for reference - if (isset($s['d'])) - $fmt[] = $s['d']." ".Lang::$main['days']; - if (isset($s['h'])) - $fmt[] = $s['h']." ".Lang::$main['hours']; - if (isset($s['m'])) - $fmt[] = $s['m']." ".Lang::$main['minutes']; - if (isset($s['s'])) - $fmt[] = $s['s']." ".Lang::$main['seconds']; - if (isset($s['ms'])) - $fmt[] = $s['ms']." ".Lang::$main['millisecs']; - - // return implode(' ', $fmt); -*/ + return '0 '.Lang::$timeUnits['pl'][6]; } } + public static function itemModByRatingMask($mask) + { + if (($mask & 0x1C000) == 0x1C000) // special case resilience + return ITEM_MOD_RESILIENCE_RATING; + + if (($mask & 0x00E0) == 0x00E0) // special case hit rating + return ITEM_MOD_HIT_RATING; + + for ($j = 0; $j < count(self::$combatRatingToItemMod); $j++) + { + if (!self::$combatRatingToItemMod[$j]) + continue; + + if (!($mask & (1 << $j))) + continue; + + return self::$combatRatingToItemMod[$j]; + } + + return 0; + } + public static function sideByRaceMask($race) { // Any @@ -1423,6 +1470,52 @@ class Util return 3; } + // pageText for Books (Item or GO) and questText + public static function parseHtmlText($text) + { + if (stristr($text, '')) // text is basicly a html-document with weird linebreak-syntax + { + $pairs = array( + '' => '', + '' => '', + '' => '', + '' => '', + '

' => '
', + "\n" => '', + "\r" => '' + ); + + // html may contain images + $text = preg_replace('/"Interface\\\Pictures\\\([\w_\-]+)"/i', '"images/interface/Pictures/\1.jpg"', strtr($text, $pairs)); + } + else + $text = strtr($text, ["\n" => '
', "\r" => '']); + + // gender switch + // ok, directed gender-reference: ($g:male:female:ref) where 'ref' is the variable (see $pairs) forward in the text determining the gender + $text = preg_replace('/\$g\s*([^:;]+)\s*:\s*([^:;]+)\s*(:?[^:;]*);/ui', '<\1/\2>', $text); + + // nonesense, that the client apparently ignores + $text = preg_replace('/\$t([^;]+);/ui', '', $text); + + // and another modifier for something russian |3-6($r) .. jesus christ <_< + $text = preg_replace('/\|\d\-?\d?\((\$\w)\)/ui', '\1', $text); + + $pairs = array( + '$c' => '<'.Lang::$game['class'].'>', + '$C' => '<'.Lang::$game['class'].'>', + '$r' => '<'.Lang::$game['race'].'>', + '$R' => '<'.Lang::$game['race'].'>', + '$n' => '<'.Lang::$main['name'].'>', + '$N' => '<'.Lang::$main['name'].'>', + '$b' => '
', + '$B' => '
', + '|n' => '' // what .. the fuck .. another type of line terminator? (only in spanish though) + ); + + return strtr($text, $pairs); + } + public static function asHex($val) { $_ = decHex($val); @@ -1568,19 +1661,21 @@ class Util // 6 => TYPE_TOTEM Rockbiter AmountX as Damage (ignore) // 7 => TYPE_USE_SPELL Engineering gadgets // 8 => TYPE_PRISMATIC_SOCKET Extra Sockets AmountX as socketCount (ignore) - public static function parseItemEnchantment($enchant, $amountOverride = null) + public static function parseItemEnchantment($eId, $raw = false, &$name = null) { - if (empty($enchant)) - return false; + $enchant = DB::Aowow()->selectRow('SELECT *, Id AS ARRAY_KEY FROM ?_itemenchantment WHERE Id = ?d', $eId); + if (!$enchant) + return []; + $name = self::localizedString($enchant, 'text'); + + + // parse stats $jsonStats = []; for ($h = 1; $h <= 3; $h++) { - $obj = $enchant['object'.$h]; - $val = $enchant['amount'.$h]; - - if (isset($amountOverride)) // itemSuffixes have dynamic amount - $val = $amountOverride; + $obj = (int)$enchant['object'.$h]; + $val = (int)$enchant['amount'.$h]; switch ($enchant['type'.$h]) { @@ -1589,7 +1684,10 @@ class Util break; case 3: case 7: - $spl = new SpellList(array(['s.id', (int)$obj])); + $spl = new SpellList(array(['s.id', $obj])); + if ($spl->error) + break; + $gains = $spl->getStatGain(); foreach ($gains as $gain) @@ -1623,14 +1721,14 @@ class Util } break; case 5: - if ($obj == ITEM_MOD_ATTACK_POWER) - @$jsonStats[ITEM_MOD_RANGED_ATTACK_POWER] += $val; - @$jsonStats[$obj] += $val; break; } } + if ($raw) + return $jsonStats; + // check if we use these mods $return = []; foreach ($jsonStats as $k => $v) @@ -1654,7 +1752,10 @@ class Util if (!isset($struct[$keys[0]])) return false; - return in_array($keys[1], $struct[$keys[0]]) || isset($struct[$keys[0]][$keys[1]]); + if (count($struct[$keys[0]]) == count($struct[$keys[0]], COUNT_RECURSIVE)) + return in_array($keys[1], $struct[$keys[0]]); + else + return isset($struct[$keys[0]][$keys[1]]); case 3: return isset($struct[$keys[0]][$keys[1]]) && in_array($keys[2], $struct[$keys[0]][$keys[1]]); } @@ -1672,6 +1773,11 @@ class Util return mb_strtoupper($first, 'UTF-8') . $rest; } + public static function ucWords($str) + { + return mb_convert_case($str, MB_CASE_TITLE, 'UTF-8'); + } + public static function checkNumeric(&$data) { if ($data === null) @@ -1703,6 +1809,249 @@ class Util return false; // always false for passed arrays } + + public function arraySumByKey(&$ref) + { + $nArgs = func_num_args(); + if (!is_array($ref) || $nArgs < 2) + return; + + for ($i = 1; $i < $nArgs; $i++) + { + $arr = func_get_arg($i); + if (!is_array($arr)) + continue; + + foreach ($arr as $k => $v) + { + if (!isset($ref[$k])) + $ref[$k] = 0; + + $ref[$k] += $v; + } + } + } + + /* from TC wiki + fishing_loot_template no relation entry is linked with ID of the fishing zone or area + creature_loot_template entry many <- many creature_template lootid + gameobject_loot_template entry many <- many gameobject_template data1 Only GO type 3 (CHEST) or 25 (FISHINGHOLE) + item_loot_template entry many <- one item_template entry + disenchant_loot_template entry many <- many item_template DisenchantID + prospecting_loot_template entry many <- one item_template entry + milling_loot_template entry many <- one item_template entry + pickpocketing_loot_template entry many <- many creature_template pickpocketloot + skinning_loot_template entry many <- many creature_template skinloot Can also store minable/herbable items gathered from creatures + quest_mail_loot_template entry quest_template RewMailTemplateId + reference_loot_template entry many <- many _loot_template -mincountOrRef In case of negative mincountOrRef + */ + private static function getLootByItem($tableName, $itemId) + { + return; + } + + private static function getLootByEntry($tableName, $lootId, $groupId = 0, $baseChance = 1.0) + { + $loot = []; + $rawItems = []; + + if (!$tableName || !$lootId) + return null; + + $rows = DB::Aowow()->select('SELECT * FROM ?# WHERE entry = ?d {AND groupid = ?d}', $tableName, abs($lootId), $groupId ? $groupId : DBSIMPLE_SKIP); + if (!$rows) + return null; + + $groupChances = []; + $nGroupEquals = []; + foreach ($rows as $entry) + { + $set = array( + 'quest' => $entry['ChanceOrQuestChance'] < 0, + 'group' => $entry['groupid'], + 'reference' => $lootId < 0 ? abs($lootId) : 0, + 'realChanceMod' => $baseChance + ); + + if ($entry['lootmode'] > 1) + { + $buff = []; + for ($i = 0; $i < 8; $i++) + if ($entry['lootmode'] & (1 << $i)) + $buff[] = $i; + + $set['mode'] = implode(', ', $buff); + } + else + $set['mode'] = 0; + + /* + modes:{"mode":8,"4":{"count":7173,"outof":17619},"8":{"count":7173,"outof":10684}} + ignore lootmodes from sharedDefines.h use different creatures/GOs from each template + modes.mode = b6543210 + ||||||'dungeon heroic + |||||'dungeon normal + ||||' + |||'10man normal + ||'25man normal + |'10man heroic + '25man heroic + */ + + if ($entry['mincountOrRef'] < 0) + { + list($data, $raw) = self::getLootByEntry(LOOT_REFERENCE, $entry['mincountOrRef'], $entry['groupid'], abs($entry['ChanceOrQuestChance'] / 100)); + + $loot = array_merge($loot, $data); + $rawItems = array_merge($rawItems, $raw); + + $set['content'] = $entry['mincountOrRef']; + $set['multiplier'] = $entry['maxcount']; + } + else + { + $rawItems[] = $entry['item']; + $set['content'] = $entry['item']; + $set['min'] = $entry['mincountOrRef']; + $set['max'] = $entry['maxcount']; + } + + if ($set['quest'] || !$set['group']) + $set['groupChance'] = abs($entry['ChanceOrQuestChance']); + else if ($entry['groupid'] && !$entry['ChanceOrQuestChance']) + { + @$nGroupEquals[$entry['groupid']]++; + $set['groupChance'] = &$groupChances[$entry['groupid']]; + } + else if ($entry['groupid'] && $entry['ChanceOrQuestChance']) + { + @$groupChances[$entry['groupid']] += $entry['ChanceOrQuestChance']; + $set['groupChance'] = abs($entry['ChanceOrQuestChance']); + } + else + continue; // shouldn't happen + + $loot[] = $set; + } + + foreach (array_keys($nGroupEquals) as $k) + { + $sum = $groupChances[$k]; + if (!$sum) + $sum = 0; + elseif ($sum > 100) // group has > 100% dropchance .. hmm, display some kind of error..? + $sum = 100; + + $cnt = empty($nGroupEquals[$k]) ? 1 : $nGroupEquals[$k]; + + $groupChances[$k] = (100 - $sum) / $cnt; // is applied as backReference to items with 0-chance + } + + return [$loot, array_unique($rawItems)]; + } + + // v this is bullshit, but as long as there is no integral template class.. + public static function handleLoot($table, $entry, &$pageTemplate, $debug = false) + { + $lv = []; + $loot = null; + + if (!$table || !$entry) + return null; + + /* + todo (high): implement conditions on loot (and conditions in general) + + also + + // if (is_array($entry) && in_array($table, [LOOT_CREATURE, LOOT_GAMEOBJECT]) + // iterate over the 4 available difficulties and assign modes + */ + + if ($entry > 0) + $struct = self::getLootByEntry($table, $entry); + else if ($entry < 0) + $struct = self::getLootByItem($table, -$entry); + + if (!$struct) + return $lv; + + $items = new ItemList(array(['i.id', $struct[1]])); + $items->addGlobalsToJscript($pageTemplate, GLOBALINFO_SELF | GLOBALINFO_RELATED); + $foo = $items->getListviewData(); + + // assign listview LV rows to loot rows, not the other way round! The same item may be contained multiple times + foreach ($struct[0] as $loot) + { + $base = array( + 'percent' => round($loot['groupChance'] * $loot['realChanceMod'], 3), + 'group' => $loot['group'], + 'count' => 1 // satisfies the sort-script + ); + + if ($_ = $loot['mode']) + $base['mode'] = $_; + + if ($_ = $loot['reference']) + $base['reference'] = $_; + + $buff = []; // equal distribution between min/max .. not blizzlike, but hey, TC-issue + if (isset($loot['max']) && isset($loot['min']) && ($loot['max'] > $loot['min'])) + for ($i = $loot['min']; $i <= $loot['max']; $i++) + $buff[] = $i.':'.(round(100 / (1 + $loot['max'] - $loot['min']), 3)); + + if ($buff) // yes, it wants a string .. how weired is that.. + $base['pctstack'] = '{'.implode(',',$buff).'}'; + + if ($loot['content'] > 0) // regular drop + { + if (!$debug) + { + if (!isset($lv[$loot['content']])) + $lv[$loot['content']] = array_merge($foo[$loot['content']], $base, ['stack' => [$loot['min'], $loot['max']]]); + else + $lv[$loot['content']]['percent'] += $base['percent']; + } + else + $lv[] = array_merge($foo[$loot['content']], $base, ['stack' => [$loot['min'], $loot['max']]]); + } + else if ($debug) // create dummy for ref-drop + { + $data = array( + 'id' => $loot['content'], + 'name' => '@REFERENCE: '.abs($loot['content']), + 'icon' => 'trade_engineering', + 'stack' => [$loot['multiplier'], $loot['multiplier']] + ); + $lv[] = array_merge($base, $data); + + $pageTemplate->extendGlobalData(TYPE_ITEM, [$loot['content'] => $data]); + } + } + + // move excessive % to extra loot + if (!$debug) + { + foreach ($lv as &$_) + { + if ($_['percent'] <= 100) + continue; + + while ($_['percent'] > 200) + { + $_['stack'][0]++; + $_['stack'][1]++; + $_['percent'] -= 100; + } + + $_['stack'][1]++; + $_['percent'] = 100; + } + } + + + return $lv; + } } ?> diff --git a/index.php b/index.php index 83a77240..37f2eab5 100644 --- a/index.php +++ b/index.php @@ -15,6 +15,7 @@ require 'includes/kernel.php'; if ($AoWoWconf['maintenance'] && !User::isInGroup(U_GROUP_EMPLOYEE)) $smarty->brb(); + switch ($pageCall) { /* called by user */ diff --git a/localization/locale_dede.php b/localization/locale_dede.php index 23a6a874..67aad8e9 100644 --- a/localization/locale_dede.php +++ b/localization/locale_dede.php @@ -11,6 +11,11 @@ if (!defined('AOWOW_REVISION')) $lang = array( // page variables + 'timeUnits' => array( + 'sg' => ["Jahr", "Monat", "Woche", "Tag", "Stunde", "Minute", "Sekunde", "Millisekunde"], + 'pl' => ["Jahre", "Monate", "Wochen", "Tage", "Stunden", "Minuten", "Sekunden", "Millisekunden"], + 'ab' => ["J.", "M.", "W.", "Tag", "Std.", "Min.", "Sek.", "Ms."], + ), 'main' => array( 'help' => "Hilfe", 'name' => "Name", @@ -39,17 +44,6 @@ $lang = array( 'gains' => "Belohnungen", 'login' => "Login", 'forum' => "Forum", - 'days' => "Tage", - 'hours' => "Stunden", - 'minutes' => "Minuten", - 'seconds' => "Sekunden", - 'millisecs' => "Millisekunden", - 'daysAbbr' => "T", - 'hoursAbbr' => "Std.", - 'minutesAbbr' => "Min.", - 'secondsAbbr' => "Sek.", - 'millisecsAbbr' => "Ms", - 'n_a' => "n. v.", // err_title = Fehler in AoWoW @@ -497,6 +491,8 @@ $lang = array( 'randEnchant' => "<Zufällige Verzauberung>", 'readClick' => "<Zum Lesen rechtsklicken>", 'set' => "Set", + '_rndEnchants' => "Zufällige Verzauberungen", + '_chance' => "(Chance von %s%%)", '_reqLevel' => "Mindeststufe", 'slot' => "Platz", '_quality' => "Qualität", @@ -516,7 +512,7 @@ $lang = array( ), 'bonding' => array ( "Accountgebunden", "Wird beim Aufheben gebunden", "Wird beim Anlegen gebunden", - "Wird bei Benutzung gebunden", "Seelengebunden", "Questgegenstand" + "Wird bei Benutzung gebunden", "Questgegenstand", "Questgegenstand" ), 'bagFamily' => array( "Tasche", "Köcher", "Munitionsbeutel", "Seelentasche", "Lederertasche", diff --git a/localization/locale_enus.php b/localization/locale_enus.php index 7f07e283..918db33e 100644 --- a/localization/locale_enus.php +++ b/localization/locale_enus.php @@ -6,9 +6,14 @@ if (!defined('AOWOW_REVISION')) $lang = array( // page variables + 'timeUnits' => array( + 'sg' => ["year", "month", "week", "day", "hour", "minute", "second", "millisecond"], + 'pl' => ["years", "months", "weeks", "days", "hours", "minutes", "seconds", "milliseconds"], + 'ab' => ["yr", "mo", "wk", "day", "hr", "min", "sec", "ms"] + ), 'main' => array( 'help' => "Help", - 'name' => "Name", + 'name' => "name", 'link' => "Link", 'signIn' => "Sign in", 'jsError' => "Please make sure you have javascript enabled.", @@ -34,17 +39,6 @@ $lang = array( 'gains' => "Gains", 'login' => "Login", 'forum' => "Forum", - 'days' => "days", - 'hours' => "hours", - 'minutes' => "minutes", - 'seconds' => "seconds", - 'millisecs' => "milliseconds", - 'daysAbbr' => "d", - 'hoursAbbr' => "hr", - 'minutesAbbr' => "min", - 'secondsAbbr' => "sec", - 'millisecsAbbr' => "ms", - 'n_a' => "n/a", // err_title = An error in AoWoW @@ -68,7 +62,7 @@ $lang = array( 'exactMatch' => "Exact match", // infobox - 'unavailable' => "Not available to players", + 'unavailable' => "Not available to players", // alternative wording found: "No longer available to players" ... aw screw it <_< 'disabled' => "Disabled", 'disabledHint' => "Cannot be attained or completed", 'serverside' => "Serverside", @@ -404,7 +398,7 @@ $lang = array( 'base' => "Show %s related to %s", 'link' => " or ", 'recipes' => "recipe items", - 'crafted' => "crafted items" + 'crafted' => "crafted items" ), 'cat' => array( 7 => "Class Skills", // classList @@ -451,7 +445,7 @@ $lang = array( 15 => "Daggers", 13 => "Fist Weapons", 0 => "One-Handed Axes", 4 => "One-Handed Maces", 7 => "One-Handed Swords", 6 => "Polearms", 10 => "Staves", 1 => "Two-Handed Axes", 5 => "Two-Handed Maces", 8 => "Two-Handed Swords", 2 => "Bows", 18 => "Crossbows", 3 => "Guns", 16 => "Thrown", 19 => "Wands", - 10 => "Fishing Poles", 14 => "Miscellaneous" + 20 => "Fishing Poles", 14 => "Miscellaneous" ), 'subClassMasks' => array( 0x02A5F3 => 'Melee Weapon', 0x0060 => 'Shield', 0x04000C => 'Ranged Weapon', 0xA091 => 'One-Handed Melee Weapon' @@ -489,11 +483,40 @@ $lang = array( 'itemLevel' => "Item Level", 'randEnchant' => "<Random enchantment>", 'readClick' => "<Right Click To Read>", +'openClick' => "<Right Click To Open>", 'set' => "Set", -'_reqLevel' => "Required level", +'partyLoot' => "Party loot", +'smartLoot' => "Smart loot", +'indestructible' => "Cannot be destroyed", +'deprecated' => "Deprecated", +'useInShape' => "Usable when shapeshifted", +'useInArena' => "Usable in arenas", +'refundable' => "Refundable", +'noNeedRoll' => "Cannot roll Need", +'atKeyring' => "Can be placed in the keyring", +'worth' => "Worth", +'consumable' => "Consumable", +'nonConsumable' => "Non-consumable", +'accountWide' => "Account-wide", +'millable' => "Millable", +'noEquipCD' => "No equip cooldown", +'prospectable' => "Prospectable", +'disenchantable' => "Disenchantable", +'cantDisenchant' => "Cannot be disenchanted", +'repairCost' => "Repair cost", +'tool' => "Tool", +'cost' => "Cost", +'content' => "Content", +'_transfer' => 'This item will be converted to %s if you transfer to %s.', +'_unavailable' => "This item is not available to players.", +'_rndEnchants' => "Random Enchantments", +'_chance' => "(%s%% chance)", +'_reqLevel' => "Required level", 'slot' => "Slot", '_quality' => "Quality", 'usableBy' => "Usable by", +'buyout' => "Buyout price", +'each' => "each", 'gems' => "Gems", 'socketBonus' => "Socket Bonus", 'socket' => array( @@ -509,7 +532,7 @@ $lang = array( ), 'bonding' => array ( "Binds to account", "Binds when picked up", "Binds when equipped", - "Binds when used", "Soulbound", "Quest Item" + "Binds when used", "Quest Item", "Quest Item" ), "bagFamily" => array( "Bag", "Quiver", "Ammo Pouch", "Soul Bag", "Leatherworking Bag", diff --git a/localization/locale_eses.php b/localization/locale_eses.php index 6cf088a9..1f3e4424 100644 --- a/localization/locale_eses.php +++ b/localization/locale_eses.php @@ -11,9 +11,14 @@ if (!defined('AOWOW_REVISION')) $lang = array( // page variables + 'timeUnits' => array( + 'sg' => ["año", "mes", "semana", "día", "hora", "minuto", "segundo", "milisegundo"], + 'pl' => ["años", "meses", "semanas", "dias", "horas", "minutos", "segundos", "milisegundos"], + 'ab' => ["año", "mes", "sem", "", "h", "min", "seg", "ms"], + ), 'main' => array( 'help' => "Ayuda", - 'name' => "Nombre", + 'name' => "nombre", 'link' => "Enlace", 'signIn' => "Iniciar sesión", 'jsError' => "Por favor, asegúrese de que ha habilitado javascript.", @@ -39,17 +44,6 @@ $lang = array( 'gains' => "Ganancias", 'login' => "[Login]", 'forum' => "Foro", - 'days' => "dias", - 'hours' => "horas", - 'minutes' => "minutos", - 'seconds' => "segundos", - 'millisecs' => "[milliseconds]", - 'daysAbbr' => "", // ??? - 'hoursAbbr' => "h", - 'minutesAbbr' => "min", - 'secondsAbbr' => "seg", - 'millisecsAbbr' => "[ms]", - 'n_a' => "n/d", // filter @@ -450,6 +444,8 @@ $lang = array( 'randEnchant' => "<Encantamiento aleatorio>", 'readClick' => "<Click derecho para leer>", 'set' => "Conjunto", + '_rndEnchants' => "Encantamientos aleatorios", + '_chance' => "(probabilidad %s%%)", '_reqLevel' => "Nivel requerido", 'slot' => "Casilla", '_quality' => "Calidad", @@ -469,7 +465,7 @@ $lang = array( ), 'bonding' => array ( "Se liga a la cuenta", "Se liga al recogerlo", "Se liga al equiparlo", - "Se liga al usarlo", "[ligados al alma]", /* google :( */ "Objeto de misión" + "Se liga al usarlo", "Objeto de misión", "Objeto de misión" ), "bagFamily" => array( "Bolsa", "Carcaj", "Bolsa de municiones", "Bolsa de almas", "Bolsa de peletería", diff --git a/localization/locale_frfr.php b/localization/locale_frfr.php index 46fb1336..c8db1afe 100644 --- a/localization/locale_frfr.php +++ b/localization/locale_frfr.php @@ -11,9 +11,14 @@ if (!defined('AOWOW_REVISION')) $lang = array( // page variables + 'timeUnits' => array( + 'sg' => ["année", "mois", "semaine", "jour", "heure", "minute", "seconde", "milliseconde"], + 'pl' => ["années", "mois", "semaines", "jours", "heures", "minutes", "secondes", "millisecondes"], + 'ab' => ["an", "mo", "sem", "jour", "h", "min", "s", "ms"] + ), 'main' => array( 'help' => "Aide", - 'name' => "Nom", + 'name' => "nom", 'link' => "Lien", 'signIn' => "S'enregistrer", 'jsError' => "S'il vous plait, assurez vous d'avoir le javascript autorisé.", @@ -39,17 +44,6 @@ $lang = array( 'gains' => "Gains", 'login' => "[Login]", 'forum' => "Forum", - 'days' => "jours", - 'hours' => "heures", - 'minutes' => "minutes", - 'seconds' => "secondes", - 'millisecs' => "[milliseconds]", - 'daysAbbr' => "jour", - 'hoursAbbr' => "h", - 'minutesAbbr' => "min", - 'secondsAbbr' => "s", - 'millisecsAbbr' => "[ms]", - 'n_a' => "n/d", // filter @@ -449,6 +443,8 @@ $lang = array( 'randEnchant' => "<Enchantement aléatoire>", 'readClick' => "<Clique Droit pour Lire>", 'set' => "Set", + '_rndEnchants' => "Enchantements aléatoires", + '_chance' => "(%s%% de chance)", '_reqLevel' => "Niveau requis", 'slot' => "Emplacement", '_quality' => "Qualité", @@ -468,7 +464,7 @@ $lang = array( ), 'bonding' => array ( "Lié au compte", "Lié quand ramassé", "Lié quand équipé", - "Lié quand utilisé", "[Soulbound]", "Objet de quête" + "Lié quand utilisé", "Objet de quête", "Objet de quête" ), "bagFamily" => array( "Sac", "Carquois", "Giberne", "Sac d'âmes", "Sac de travailleur du cuir", diff --git a/localization/locale_ruru.php b/localization/locale_ruru.php index 46533e9a..c14b3654 100644 --- a/localization/locale_ruru.php +++ b/localization/locale_ruru.php @@ -11,9 +11,14 @@ if (!defined('AOWOW_REVISION')) $lang = array( // page variables + 'timeUnits' => array( + 'sg' => ["год", "месяц", "неделя", "день", "час", "минута", "секунда", "миллисекунда"], + 'pl' => ["годы", "месяцы", "недели", "дн.", "часы", "мин", "секунды", "миллисекундах"], + 'ab' => ["г.", "мес.", "нед.", "дн", "ч.", "мин", "сек.", "мс"] + ), 'main' => array( 'help' => "Справка", - 'name' => "Название", + 'name' => "название", 'link' => "Ссылка", 'signIn' => "Войти", 'jsError' => "Для работы этого сайта необходим JavaScript.", @@ -39,17 +44,6 @@ $lang = array( 'gains' => "Бонус", 'login' => "[Login]", 'forum' => "Форум", - 'days' => "дн", - 'hours' => "часы", - 'minutes' => "мин", - 'seconds' => "секунды", - 'millisecs' => "[milliseconds]", - 'daysAbbr' => "дн", - 'hoursAbbr' => "ч.", - 'minutesAbbr' => "мин", - 'secondsAbbr' => "сек.", - 'millisecsAbbr' => "[ms]", - 'n_a' => "нет", // filter @@ -449,6 +443,8 @@ $lang = array( 'randEnchant' => "<Случайное зачарование>", 'readClick' => "<Щелкните правой кнопкой мыши, чтобы прочитать.>", 'set' => "Набор", + '_rndEnchants' => "Случайные улучшения", + '_chance' => "(шанс %s%%)", '_reqLevel' => "Требуется уровень", 'slot' => "Слот", '_quality' => "Качество", @@ -468,7 +464,7 @@ $lang = array( ), 'bonding' => array ( "Привязано к учетной записи", "Персональный при поднятии", "Становится персональным при надевании", - "Персональный при использовании", "[Персональными]", /*google translate*/ "Предмет, необходимый для задания" + "Персональный при использовании", "Предмет, необходимый для задания", "Предмет, необходимый для задания" ), "bagFamily" => array( "Сумка", "Колчан", "Подсумок", "Сумка душ", "Сумка кожевника", diff --git a/pages/achievement.php b/pages/achievement.php index fbebcd5b..189b16e3 100644 --- a/pages/achievement.php +++ b/pages/achievement.php @@ -19,7 +19,7 @@ if (!defined('AOWOW_REVISION')) * } */ -require 'includes/class.community.php'; +require 'includes/community.class.php'; $_id = intVal($pageParam); diff --git a/pages/class.php b/pages/class.php index 865e9a70..6263b577 100644 --- a/pages/class.php +++ b/pages/class.php @@ -4,7 +4,7 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -require 'includes/class.community.php'; +require 'includes/community.class.php'; $_id = intVal($pageParam); $_mask = 1 << ($_id - 1); diff --git a/pages/item.php b/pages/item.php index 0a37daec..d93f1aa9 100644 --- a/pages/item.php +++ b/pages/item.php @@ -7,7 +7,7 @@ if (!defined('AOWOW_REVISION')) if (isset($_GET['xml'])) die('unsupported, as i do not see the point'); -require 'includes/class.community.php'; +require 'includes/community.class.php'; $_id = intVal($pageParam); @@ -73,53 +73,223 @@ if (!$smarty->loadCache($cacheKeyPage, $item)) if ($item->error) $smarty->notFound(Lang::$game['item']); + $item->addGlobalsToJscript($smarty, GLOBALINFO_EXTRA | GLOBALINFO_SELF); + + $_flags = $item->getField('flags'); + $_slot = $item->getField('slot'); + $_subClass = $item->getField('subClass'); + $_class = $item->getField('class'); + + /***********/ + /* Infobox */ + /***********/ + + $quickInfo = Lang::getInfoBoxForFlags($item->getField('cuFlags')); + + if ($_slot) // itemlevel + $quickInfo[] = Lang::$game['level'].Lang::$colon.$item->getField('itemLevel'); + + if ($_flags & ITEM_FLAG_ACCOUNTBOUND ) // account-wide + $quickInfo[] = Lang::$item['accountWide']; + + if ($si = $item->json[$_id]['side']) // side + if ($si != 3) + $quickInfo[] = Lang::$main['side'].Lang::$colon.'[span class='.($si == 1 ? 'alliance' : 'horde').'-icon]'.Lang::$game['si'][$si].'[/span]'; + + // consumable / not consumable + if (!$_slot) + { + $hasUse = false; + for ($i = 1; $i < 6; $i++) + { + if ($item->getField('spellId'.$i) <= 0 || in_array($item->getField('spellTrigger'.$i), [1, 2])) + continue; + + $hasUse = true; + + if ($item->getField('spellCharges'.$i) >= 0) + continue; + + $tt = '[tooltip=tooltip_consumedonuse]'.Lang::$item['consumable'].'[/tooltip]'; // 2:Consommable 3:Verbrauchbar 6:Consumible 8:Расходуется + break; + } + + if ($hasUse) + $quickInfo[] = isset($tt) ? $tt : '[tooltip=tooltip_notconsumedonuse]'.Lang::$item['nonConsumable'].'[/tooltip]'; + } + + if ($hId = $item->getField('holidayId')) // 3:Werkzeug 6:Herramienta 8:Инструмент 2:Outil + if ($hName = DB::Aowow()->selectRow('SELECT * FROM ?_holidays WHERE id = ?d', $hId)) + $quickInfo[] = Lang::$game['eventShort'].Lang::$colon.'[url=?event='.$hId.']'.Util::localizedString($hName, 'name').'[/url]'; + + if ($tId = $item->getField('totemCategory')) // 3:Werkzeug 6:Herramienta 8:Инструмент 2:Outil + if ($tName = DB::Aowow()->selectRow('SELECT * FROM ?_totemCategory WHERE id = ?d', $tId)) + $quickInfo[] = Lang::$item['tool'].Lang::$colon.'[url=?items&filter=cr=91;crs='.$tId.';crv=0]'.Util::localizedString($tName, 'name').'[/url]'; + + $cost = ''; + if ($_ = $item->getField('buyPrice')) + $cost .= '[money='.$_.']'; + + if ($_ = $item->getExtendedCost()) + foreach ($_ as $c => $qty) + $cost .= '[currency='.$c.' amount='.$qty.']'; + + if ($cost) + $quickInfo[] = Lang::$item['cost'].Lang::$colon.$cost.'[color=q0] ('.Lang::$item['each'].')[/color]'; // 2:Coût 3:Preis 6:Coste 8:Цена + + if ($_ = $item->getField('repairPrice')) // 3:Reparaturkosten 8:Цена починки 2:Cout de réparation 6:Coste de reparación + $quickInfo[] = Lang::$item['repairCost'].Lang::$colon.'[money='.$_.']'; + + if (in_array($item->getField('bonding'), [0, 2, 3])) // avg auction buyout + if ($_ = Util::getBuyoutForItem($_id)) + $quickInfo[] = '[tooltip=tooltip_buyoutprice]'.Lang::$item['buyout.'].'[/tooltip]'.Lang::$colon.'[money='.$_.'][color=q0] ('.Lang::$item['each'].')[/color]'; + + if ($_flags & ITEM_FLAG_OPENABLE) // avg money contained // 2:Vaut 8:Деньги 6:Valor 3:Wert + if ($_ = intVal(($item->getField('minMoneyLoot') + $item->getField('maxMoneyLoot')) / 2)) + $quickInfo[] = Lang::$item['worth'].Lang::$colon.'[tooltip=tooltip_avgmoneycontained][money='.$_.'][/tooltip]'; + + if ($_slot) // if it goes into a slot it may be disenchanted + { + if ($item->getField('disenchantId')) + { + $_ = $item->getField('requiredDisenchantSkill'); + if ($_ < 1) // these are some items, that never went live .. extremely rough emulation here + $_ = intVal($item->getField('itemLevel') / 7.5) * 25; + + $quickInfo[] = Lang::$item['disenchantable'].' ([tooltip=tooltip_reqenchanting]'.$_.'[/tooltip])'; // 35002 + } + else + $quickInfo[] = Lang::$item['cantDisenchant']; // 27978 + } + + if (($_flags & ITEM_FLAG_MILLABLE) && $item->getField('requiredSkill') == 773) + $quickInfo[] = Lang::$item['millable'].' ([tooltip=tooltip_reqinscription]'.$item->getField('requiredSkillRank').'[/tooltip])'; // 8:Можно растолочь 2:Pilable 6:Se puede moler 3:Mahlbar + + if (($_flags & ITEM_FLAG_PROSPECTABLE) && $item->getField('requiredSkill') == 755) + $quickInfo[] = Lang::$item['prospectable'].' ([tooltip=tooltip_reqjewelcrafting]'.$item->getField('requiredSkillRank').'[/tooltip])'; // 3:Sondierbar 8:Просеиваемое 2:Prospectable 6:Prospectable + + if ($_flags & ITEM_FLAG_DEPRECATED) + $quickInfo[] = '[tooltip=tooltip_deprecated]'.Lang::$item['deprecated'].'[/tooltip]'; // 3:Nicht benutzt 6:Depreciado 8:Устарело 2:Désuet + + if ($_flags & ITEM_FLAG_NO_EQUIPCD) + $quickInfo[] = '[tooltip=tooltip_noequipcooldown]'.Lang::$item['noEquipCD'].'[/tooltip]'; // 3:Keine Anlegabklingzeit 6:No tiene tiempo de reutilización al equipar 8:Нет отката при надевании 2:Aucun temps de recharge lorsqu'équipé + + if ($_flags & ITEM_FLAG_PARTYLOOT) + $quickInfo[] = '[tooltip=tooltip_partyloot]'.Lang::$item['partyLoot'].'[/tooltip]'; // 3:Gruppenloot 6:Despojo de grupo 8:Добыча группы 2:Butin de groupe + + if ($_flags & ITEM_FLAG_REFUNDABLE) + $quickInfo[] = '[tooltip=tooltip_refundable]'.Lang::$item['refundable'].'[/tooltip]'; // 3:Rückzahlbar 6:Se puede devolver 8:Подлежит возврату 2:Remboursable + + if ($_flags & ITEM_FLAG_SMARTLOOT) + $quickInfo[] = '[tooltip=tooltip_smartloot]'.Lang::$item['smartLoot'].'[/tooltip]'; // 3:Intelligente Beuteverteilung 6:Botín inteligente 8:Умное распределение добычи 2:Butin intelligent + + if ($_flags & ITEM_FLAG_INDESTRUCTIBLE) + $quickInfo[] = Lang::$item['indestructible']; // 3:Kann nicht zerstört werden 6:No puede ser destruido 8:Невозможно выбросить 2:Ne peut être détruit + + if ($_flags & ITEM_FLAG_USABLE_ARENA) + $quickInfo[] = Lang::$item['useInArena']; // 3: Benutzbar in Arenen 2:Utilisable en Aréna 6:Se puede usar en arenas 8:Используется на аренах + + if ($_flags & ITEM_FLAG_USABLE_SHAPED) + $quickInfo[] = Lang::$item['useInShape']; // 2:Utilisable lorsque transformé 3:Benutzbar in Gestaltwandlung 6:Se puede usar con cambio de forma 8:Используется в формах + + if ($item->getField('flagsExtra') & 0x0100) // cant roll need + $quickInfo[] = '[tooltip=tooltip_cannotrollneed]'.Lang::$item['noNeedRoll'].'[/tooltip]'; // 3:Kann nicht für Bedarf werfen 6:No se puede hacer una tirada por Necesidad 2:Ne peut pas faire un jet de Besoin 8:Нельзя говорить "Мне это нужно" + + if ($item->getField('bagFamily') & 0x0100) // fits into keyring + $quickInfo[] = Lang::$item['atKeyring']; // 2:(Va dans le trousseau de clés) 8:(Может быть помещён в связку для ключей) 6:(Se puede poner en el llavero) 3:(Passt in den Schlüsselbund) + + + /****************/ + /* Main Content */ + /****************/ + $pageData = array( - 'infobox' => [], + 'infobox' => $quickInfo ? '[ul][li]'.implode('[/li][li]', $quickInfo).'[/li][/ul]' : null, 'relTabs' => [], - 'tooltip' => $item->renderTooltip([], false), - 'page' => $item->getDetailPageData(), - 'path' => [0, 0, $item->getField('classs'), $item->getField('subClass')], - 'title' => [Lang::$game['item'], $item->getField('name', true)], - 'pagetext' => false, // Books - 'buttons' => in_array($item->getField('class'), [ITEM_CLASS_WEAPON, ITEM_CLASS_GEM, ITEM_CLASS_ARMOR]), + 'tooltip' => $item->renderTooltip([], true), + 'path' => [0, 0], + 'title' => [$item->getField('name', true), Util::ucFirst(Lang::$game['item'])], + 'pageText' => [], + 'buttons' => in_array($_class, [ITEM_CLASS_WEAPON, ITEM_CLASS_GEM, ITEM_CLASS_ARMOR]), + 'page' => array( + 'color' => Util::$rarityColorStings[$item->getField('quality')], + 'quality' => $item->getField('quality'), + 'icon' => $item->getField('iconString'), + 'name' => $item->getField('name', true), + 'displayId' => $item->getField('displayId'), + 'slot' => $_slot, + 'stack' => $item->getField('stackable'), + 'class' => $_class + ) ); + // path + if (in_array($_class, [5, 8, 14])) + { + $pageData['path'][] = 15; // misc. + + if ($_class == 5) // reagent + $pageData['path'][] = 1; + else + $pageData['path'][] = 4; // other + } + else + { + $pageData['path'][] = $_class; + + if (!in_array($_class, [ITEM_CLASS_MONEY, ITEM_CLASS_QUEST, ITEM_CLASS_KEY])) + $pageData['path'][] = $_subClass; + + if ($_class == ITEM_CLASS_ARMOR && in_array($_subClass, [1, 2, 3, 4])) + { + if ($_ = $_slot); + $pageData['path'][] = $_; + } + else if (($_class == ITEM_CLASS_CONSUMABLE && $_subClass == 2) || $_class == ITEM_CLASS_GLYPH) + $pageData['path'][] = $item->getField('subSubClass'); + } + + // pageText + if ($next = $item->getField('pageTextId')) + { + while ($next) + { + $row = DB::Aowow()->selectRow('SELECT *, text as Text_loc0 FROM page_text pt LEFT JOIN locales_page_text lpt ON pt.entry = lpt.entry WHERE pt.entry = ?d', $next); + $next = $row['next_page']; + $pageData['pageText'][] = Util::parseHtmlText(Util::localizedString($row, 'Text')); + } + } + + // subItems + $item->initSubItems(); + if (!empty($item->subItems[$_id])) + { + uaSort($item->subItems[$_id], function($a, $b) { return strcmp($a['name'], $b['name']); }); + $pageData['page']['subItems'] = array_values($item->subItems[$_id]); + } + + // factionchange-equivalent + $pendant = DB::Aowow()->selectCell('SELECT IF(horde_id = ?d, alliance_id, -horde_id) FROM player_factionchange_items WHERE alliance_id = ?d OR horde_id = ?d', $_id, $_id, $_id); + if ($pendant) + { + $altItem = new ItemList(array(['id', abs($pendant)])); // todo (med): include this item in tab: "see also" + if (!$altItem->error) + { + $pageData['page']['transfer'] = array( + 'id' => $altItem->id, + 'quality' => $altItem->getField('quality'), + 'icon' => $altItem->getField('iconString'), + 'name' => $altItem->getField('name', true), + 'facInt' => $pendant > 0 ? 'alliance' : 'horde', + 'facName' => $pendant > 0 ? Lang::$game['si'][1] : Lang::$game['si'][2] + ); + } + } /* - - - -
{#Quick_Facts#}
-
-
    - {* Уровень вещи *} - {if $item.level}
  • {#level#}: {$item.level}
  • {/if} - {* Стоимость вещи *} - {if $item.buygold or $item.buysilver or $item.buycopper} -
  • - {#Buy_for#}: - {if $item.buygold}{$item.buygold}{/if} - {if $item.buysilver}{$item.buysilver}{/if} - {if $item.buycopper}{$item.buycopper}{/if} -
  • - {/if} - {if $item.sellgold or $item.sellsilver or $item.sellcopper} -
  • - {#Sells_for#}: - {if $item.sellgold}{$item.sellgold}{/if} - {if $item.sellsilver}{$item.sellsilver}{/if} - {if $item.sellcopper}{$item.sellcopper}{/if} -
  • - {/if} - {if isset($item.disenchantskill)}
  • {#Disenchantable#} ({$item.disenchantskill})
  • {/if} - {if isset($item.key)}
  • {#Can_be_placed_in_the_keyring#}
  • {/if} -
-
-*/ - - /********/ - /* TABS */ - /********/ + /**************/ + /* Extra Tabs */ + /**************/ // dropped by creature @@ -151,6 +321,30 @@ if (!$smarty->loadCache($cacheKeyPage, $item)) // contained in (item) [item_loot] // contains [item_loot] + $itemLoot = Util::handleLoot(LOOT_ITEM, $item->id, $smarty, User::isInGroup(U_GROUP_STAFF)); + if ($itemLoot) + { + $extraCols = ['Listview.extraCols.percent']; + + if (User::isInGroup(U_GROUP_STAFF)) + { + $extraCols[] = "Listview.funcBox.createSimpleCol('group', 'group', '10%', 'group')"; + $extraCols[] = "Listview.funcBox.createSimpleCol('mode', LANG.compose_mode, '10%', 'mode')"; + $extraCols[] = "Listview.funcBox.createSimpleCol('reference', LANG.finpcs.seploot + ' ' + LANG.button_link, '10%', 'reference')"; + } + + $pageData['relTabs'][] = array( + 'file' => 'item', + 'data' => $itemLoot, + 'params' => [ + 'tabs' => '$tabsRelated', + 'name' => '$LANG.tab_contains', + 'id' => 'contains', + 'hiddenCols' => "$['side', 'slot', 'source', 'reqlevel']", + 'extraCols' => "$[".implode(', ', $extraCols)."]", + ] + ); + } // pickpocketed from @@ -183,6 +377,8 @@ if (!$smarty->loadCache($cacheKeyPage, $item)) // teaches + // Same model as + // unlocks // $locks_row = $DB->selectCol(' // SELECT lockID @@ -200,21 +396,23 @@ if (!$smarty->loadCache($cacheKeyPage, $item)) $smarty->saveCache($cacheKeyPage, $pageData); } - // menuId 0: Item g_initPath() // tabId 0: Database g_initHeader() $smarty->updatePageVars(array( - 'book' => $pageData['pagetext'] ? true : false, 'title' => implode(" - ", $pageData['title']), 'path' => json_encode($pageData['path'], JSON_NUMERIC_CHECK), 'tab' => 0, 'type' => TYPE_ITEM, 'typeId' => $_id, 'reqJS' => array( + $pageData['pageText'] ? 'template/js/Book.js' : null, 'template/js/swfobject.js', 'template/js/profile.js', 'template/js/filters.js', '?data=weight-presets' + ), + 'reqCSS' => array( + $pageData['pageText'] ? ['path' => 'template/css/Book.css'] : null, ) )); $smarty->assign('community', CommunityContent::getAll(TYPE_ITEM, $_id)); // comments, screenshots, videos diff --git a/pages/items.php b/pages/items.php index f27ff100..1fd8445f 100644 --- a/pages/items.php +++ b/pages/items.php @@ -136,13 +136,16 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) asort($slot[0]); break; - case 3: case 16: + if (!isset($cats[2])) + $visibleCols[] = 'glyph'; + case 3: if (!isset($cats[1])) asort($catList[1]); case 1: case 7: case 9: + $hiddenCols[] = 'slot'; case 15: if (!isset($cats[1])) $type = [$catList[1], null]; @@ -181,13 +184,19 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) $filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : NULL; $filter['fi'] = $items->filterGetForm(); + $xCols = $items->filterGetForm('extraCols', true); + // if slot-dropdown is available && Armor && $path points to Armor-Class if (count($path) == 4 && $cats[0] == 4 && isset($filter['sl']) && !is_array($filter['sl'])) $path[] = $filter['sl']; + $infoMask = ITEMINFO_JSON; + if (array_intersect([63, 64], $xCols)) // 63:buyPrice; 64:sellPrice + $infoMask |= ITEMINFO_VENDOR; + $pageData = array( 'page' => [], - 'data' => $items->getListviewData(ITEMINFO_JSON), + 'data' => $items->getListviewData($infoMask), 'title' => $title, 'path' => $path, 'params' => [] @@ -206,7 +215,7 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) if (!$upgItem->error) { $upgItem->addGlobalsToJScript($smarty); - $pageData['data'][$filter['upg']] = $upgItem->getListviewData(ITEMINFO_JSON)[$filter['upg']]; + $pageData['data'][$filter['upg']] = $upgItem->getListviewData($infoMask)[$filter['upg']]; } } @@ -217,7 +226,11 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) } if (!empty($filter['fi']['extraCols'])) - $pageData['params']['extraCols'] = '$fi_getExtraCols(fi_extraCols, '.(empty($filter['gm']) ? 0 : $filter['gm']).', 0)'; + { + $gem = empty($filter['gm']) ? 0 : $filter['gm']; + $cost = array_intersect([63], $xCols) ? 1 : 0; + $pageData['params']['extraCols'] = '$fi_getExtraCols(fi_extraCols, '.$gem.', '.$cost.')'; + } if (!empty($filter['fi']['setWeights'])) { @@ -259,9 +272,9 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) $pageData['params']['sort'] = "$['-score', 'name']"; if ($items->hasSetFields(['armor'])) - $pageData['params']['visibleCols'] = "$['armor']"; + $visibleCols[] = 'armor'; - $pageData['params']['hiddenCols'] = "$['type', 'source']"; + array_push($hiddenCols, 'type', 'source'); } // create note if search limit was exceeded; overwriting 'note' is intentional @@ -271,6 +284,12 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) $pageData['params']['_truncated'] = 1; } + if ($hiddenCols) + $pageData['params']['hiddenCols'] = '$'.json_encode($hiddenCols); + + if ($visibleCols) + $pageData['params']['visibleCols'] = '$'.json_encode($visibleCols); + $smarty->saveCache($cacheKey, $pageData, $filter); } diff --git a/pages/itemset.php b/pages/itemset.php index 45bef0aa..e46243c2 100644 --- a/pages/itemset.php +++ b/pages/itemset.php @@ -4,7 +4,7 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -require 'includes/class.community.php'; +require 'includes/community.class.php'; $_id = intVal($pageParam); $path = [0, 2]; @@ -76,7 +76,13 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) $pieces = []; $eqList = []; $compare = []; - $iList = new ItemList(array(['i.id', array_keys($iSet->pieceToSet)])); + + if (!$iSet->pieceToSet) + $cnd = [0]; + else + $cnd = ['i.id', array_keys($iSet->pieceToSet)]; + + $iList = new ItemList(array($cnd)); $data = $iList->getListviewData(ITEMINFO_SUBITEMS | ITEMINFO_JSON); foreach ($iList->iterate() as $itemId => $__) { @@ -183,7 +189,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) ) ); - $iSet->addGlobalsToJscript($smarty, GLOBALINFO_RELATED); + $iSet->addGlobalsToJscript($smarty, GLOBALINFO_SELF); // related sets (priority: 1: similar tag + class; 2: has event; 3: no tag + similar type, 4: similar type + profession) $rel = []; diff --git a/pages/miscTools.php b/pages/miscTools.php index aee65089..2f125d0e 100644 --- a/pages/miscTools.php +++ b/pages/miscTools.php @@ -4,7 +4,7 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -// require 'includes/class.community.php'; +// require 'includes/community.class.php'; $_path = [1, 8]; $subMenu = $h1Links = null; diff --git a/pages/npc.php b/pages/npc.php index f8b0b8ff..079f5603 100644 --- a/pages/npc.php +++ b/pages/npc.php @@ -4,7 +4,7 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -require 'includes/class.community.php'; +require 'includes/community.class.php'; $_id = intVal($pageParam); diff --git a/pages/pet.php b/pages/pet.php index c9f57128..02aa54e4 100644 --- a/pages/pet.php +++ b/pages/pet.php @@ -4,7 +4,7 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -require 'includes/class.community.php'; +require 'includes/community.class.php'; $_id = intVal($pageParam); diff --git a/pages/quest.php b/pages/quest.php index 9ba5991d..ee0ad388 100644 --- a/pages/quest.php +++ b/pages/quest.php @@ -4,7 +4,7 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -require 'includes/class.community.php'; +require 'includes/community.class.php'; $_id = intVal($pageParam); diff --git a/pages/race.php b/pages/race.php index 4fe96b4d..f0bb4f50 100644 --- a/pages/race.php +++ b/pages/race.php @@ -4,7 +4,7 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -require 'includes/class.community.php'; +require 'includes/community.class.php'; $_id = intVal($pageParam); $_mask = 1 << ($_id - 1); diff --git a/pages/skill.php b/pages/skill.php index 2f46424b..c98a6c0b 100644 --- a/pages/skill.php +++ b/pages/skill.php @@ -4,7 +4,7 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -require 'includes/class.community.php'; +require 'includes/community.class.php'; $_id = intVal($pageParam); @@ -85,10 +85,9 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) // 3 crafted items [items] $created = []; foreach ($recipes->iterate() as $__) - if ($recipes->canCreateItem()) - for ($i = 1; $i < 4; $i++) - if ($_ = $recipes->getField('effect'.$i.'CreateItemId')) - $created[] = $_; + if ($idx = $this->canCreateItem()) + foreach ($idx as $i) + $created[] = $recipes->getField('effect'.$i.'CreateItemId'); if ($created) { diff --git a/pages/spell.php b/pages/spell.php index 62059bb1..4b21f63a 100644 --- a/pages/spell.php +++ b/pages/spell.php @@ -4,7 +4,7 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -require 'includes/class.community.php'; +require 'includes/community.class.php'; $_id = intVal($pageParam); @@ -55,9 +55,10 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) if ($spell->error) $smarty->notFound(Lang::$game['spell']); + $spell->addGlobalsToJScript($smarty, GLOBALINFO_ANY); + $_cat = $spell->getField('typeCat'); $path = [0, 1, $_cat]; - $l = [null, 'A', 'B', 'C']; // reconstruct path / title @@ -109,7 +110,11 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) $path[] = 410; // Cunning } - // infobox + + /***********/ + /* Infobox */ + /***********/ + $infobox = []; if (!in_array($_cat, [-5, -6])) // not mount or vanity pet @@ -181,29 +186,87 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) if ($cost = DB::Aowow()->selectCell('SELECT spellcost FROM npc_trainer WHERE spell = ?d', $spell->id)) $infobox[] = '[li]'.Lang::$spell['trainingCost'].Lang::$colon.'[money='.$cost.'][/li]'; + + /****************/ + /* Main Content */ + /****************/ + $pageData = array( 'title' => $spell->getField('name', true), 'path' => json_encode($path, JSON_NUMERIC_CHECK), 'infobox' => $infobox, 'relTabs' => [], 'view3D' => 0, - 'page' => $spell->getDetailPageData() + 'page' => array( + 'powerCost' => $spell->createPowerCostForCurrent(), + 'castTime' => $spell->createCastTimeForCurrent(false, false), + 'tools' => $spell->getToolsForCurrent(), + 'reagents' => $spell->getReagentsForCurrent(), + 'name' => $spell->getField('name', true), + 'icon' => $spell->getField('iconString'), + 'stack' => $spell->getField('stackAmount'), + 'level' => $spell->getField('spellLevel'), + 'rangeName' => $spell->getField('rangeText', true), + 'range' => $spell->getField('rangeMaxHostile'), + 'gcd' => Util::formatTime($spell->getField('startRecoveryTime')), + 'gcdCat' => "[NYI]", + 'school' => sprintf(Util::$dfnString, Util::asHex($spell->getField('schoolMask')), Lang::getMagicSchools($spell->getField('schoolMask'))), + 'dispel' => Lang::$game['dt'][$spell->getField('dispelType')], + 'mechanic' => Lang::$game['me'][$spell->getField('mechanic')], + ) ); - // description - @list( - $pageData['page']['info'], - $pageData['page']['spells'] - ) = $spell->renderTooltip(MAX_LEVEL, true); + if ($spell->getField('attributes2') & 0x80000) + $pageData['page']['stances'] = Lang::getStances($spell->getField('stanceMask')); - // buff - @list( - $pageData['page']['buff'], - $pageData['page']['buffspells'] - ) = $spell->renderBuff(MAX_LEVEL, true); + if (($_ = $spell->getField('recoveryTime')) && $_ > 0) + $pageData['page']['cooldown'] = Util::formatTime($_); + + if (($_ = $spell->getField('duration')) && $_ > 0) + $pageData['page']['duration'] = Util::formatTime($_); + + // minRange exists.. prepend + if ($_ = $spell->getField('rangeMinHostile')) + $pageData['page']['range'] = $_.' - '.$pageData['page']['range']; + + // parse itemClass & itemSubClassMask + $class = $spell->getField('equippedItemClass'); + $subClass = $spell->getField('equippedItemSubClassMask'); + $invType = $spell->getField('equippedItemInventoryTypeMask'); + + if ($class > 0 && $subClass > 0) + { + $title = ['Class: '.$class, 'SubClass: '.Util::asHex($subClass)]; + $text = Lang::getRequiredItems($class, $subClass, false); + + if ($invType) + { + // remap some duplicated strings 'Off Hand' and 'Shield' are never used simultaneously + if ($invType & (1 << INVTYPE_ROBE)) // Robe => Chest + { + $invType &= ~(1 << INVTYPE_ROBE); + $invType &= (1 << INVTYPE_CHEST); + } + + if ($invType & (1 << INVTYPE_RANGEDRIGHT)) // Ranged2 => Ranged + { + $invType &= ~(1 << INVTYPE_RANGEDRIGHT); + $invType &= (1 << INVTYPE_RANGED); + } + + $_ = []; + $strs = Lang::$item['inventoryType']; + foreach ($strs as $k => $str) + if ($invType & 1 << $k && $str) + $_[] = $str; + + $title[] = Lang::$item['slot'].Lang::$colon.Util::asHex($invType); + $text .= ' '.Lang::$spell['_inSlot'].': '.implode(', ', $_); + } + + $pageData['page']['items'] = sprintf(Util::$dfnString, implode(' | ', $title), $text); + } - // js-globals - $spell->addGlobalsToJScript($smarty); // prepare Tools foreach ($pageData['page']['tools'] as $k => $tool) @@ -232,7 +295,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) 'name' => $spell->relItems->getField('name', true), 'quality' => $spell->relItems->getField('quality'), 'entry' => $itemId, - 'count' => $_[$itemId], + 'count' => $_[$itemId][1], ); unset($_[$itemId]); @@ -245,6 +308,9 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) // Iterate through all effects: $pageData['page']['effect'] = []; + $triggerIdx = $spell->canTriggerSpell(); + $itemIdx = $spell->canCreateItem(); + for ($i = 1; $i < 4; $i++) { if ($spell->getField('effect'.$i.'Id') <= 0) @@ -260,8 +326,9 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) // Icons: // .. from item - if ($spell->canCreateItem() && ($_ = $spell->getField('effect'.$i.'CreateItemId')) && $_ > 0) + if (in_array($i, $itemIdx)) { + $_ = $spell->getField('effect'.$i.'CreateItemId'); foreach ($spell->relItems->iterate() as $itemId => $__) { if ($itemId != $_) @@ -280,8 +347,9 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) $foo['icon']['count'] = "'".($effBP + 1).'-'.$foo['icon']['count']."'"; } // .. from spell - else if (($_ = $spell->getField('effect'.$i.'TriggerSpell')) && $_ > 0) + else if (in_array($i, $triggerIdx)) { + $_ = $spell->getField('effect'.$i.'TriggerSpell'); $trig = new SpellList(array(['s.id', (int)$_])); $foo['icon'] = array( @@ -291,7 +359,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) 'count' => 0 ); - $trig->addGlobalsToJScript($smarty); + $trig->addGlobalsToJScript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); } // Effect Name @@ -300,14 +368,17 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) if ($spell->getField('effect'.$i.'RadiusMax') > 0) $foo['radius'] = $spell->getField('effect'.$i.'RadiusMax'); - if (($effBP + $effDS) && !($spell->canCreateItem() && $spell->relItems && !$spell->relItems->error) && (!$spell->getField('effect'.$i.'TriggerSpell') || in_array($effAura, [225, 227]))) + if (($effBP + $effDS) && !($itemIdx && $spell->relItems && !$spell->relItems->error) && (!in_array($i, $triggerIdx) || in_array($effAura, [225, 227]))) $foo['value'] = ($effDS != 1 ? ($effBP + 1).Lang::$game['valueDelim'] : null).($effBP + $effDS); if ($effRPPL != 0) $foo['value'] = (isset($foo['value']) ? $foo['value'] : '0') . sprintf(Lang::$spell['costPerLevel'], $effRPPL); - if($spell->getField('effect'.$i.'Periode') > 0) - $foo['interval'] = $spell->getField('effect'.$i.'Periode') / 1000; + if ($spell->getField('effect'.$i.'Periode') > 0) + $foo['interval'] = Util::formatTime($spell->getField('effect'.$i.'Periode')); + + if ($_ = $spell->getField('effect'.$i.'Mechanic')) + $foo['mechanic'] = Lang::$game['me'][$_]; // parse masks and indizes switch ($effId) @@ -523,7 +594,12 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) break; case 189: // Mod Rating case 220: // Combat Rating From Stat - $foo['name'] .= Lang::$colon.Util::$spellAuraStrings[$effAura].' ('.sprintf(Util::$dfnString, Util::$combatRating[log($effMV, 2)], Util::asHex($effMV)).')'; + $bar = []; + foreach (Util::$combatRating as $k => $str) + if ((1 << $k) & $effMV) + $bar[] = $str; + + $foo['name'] .= Lang::$colon.Util::$spellAuraStrings[$effAura].' ('.sprintf(Util::$dfnString, implode(', ', $bar), Util::asHex($effMV)).')'; break; case 168: // Mod Damage Done Versus case 59: // Mod Damage Done Versus Creature @@ -579,9 +655,10 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) unset($foo); // clear reference - /******* - * extra tabs - *******/ + + /**************/ + /* Extra Tabs */ + /**************/ // tab: modifies $this $sub = ['OR']; @@ -630,7 +707,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) ] ); - $modSpells->addGlobalsToJScript($smarty); + $modSpells->addGlobalsToJScript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); } } @@ -682,7 +759,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) ] ); - $modsSpell->addGlobalsToJScript($smarty); + $modsSpell->addGlobalsToJScript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); } } @@ -715,7 +792,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) ] ); - $saSpells->addGlobalsToJScript($smarty); + $saSpells->addGlobalsToJScript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); } // tab: used by - itemset @@ -738,7 +815,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) ] ); - $ubSets->addGlobalsToJScript($smarty); + $ubSets->addGlobalsToJScript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); } @@ -765,7 +842,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) ] ); - $ubItems->addGlobalsToJScript($smarty); + $ubItems->addGlobalsToJScript($smarty, GLOBALINFO_SELF); } // tab: criteria of @@ -776,6 +853,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) if (!$coAchievemnts->error) { $pageData['relTabs'][] = array( + 'file' => 'achievement', 'data' => $coAchievemnts->getListviewData(), 'params' => [ 'tabs' => '$tabsRelated', @@ -784,49 +862,28 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) ] ); - $coAchievemnts->addGlobalsToJScript($smarty); + $coAchievemnts->addGlobalsToJScript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); } } // tab: contains // spell_loot_template & skill_extra_item_template $extraItem = DB::Aowow()->selectRow('SELECT * FROM skill_extra_item_template WHERE spellid = ?d', $spell->id); - $spellLoot = DB::Aowow()->select('SELECT *, item as ARRAY_KEY FROM spell_loot_template WHERE entry = ?d', $spell->id); + $spellLoot = Util::handleLoot(LOOT_SPELL, $spell->id, $smarty, User::isInGroup(U_GROUP_STAFF)); + if ($extraItem || $spellLoot) { - $ids = []; - $lv = []; $extraCols = ['Listview.extraCols.percent']; - foreach ($spellLoot as $row) - $ids[] = (int)$row['item']; - if ($ids) + if ($spellLoot && User::isInGroup(U_GROUP_STAFF)) { - // todo (high): generic loot-processing function - $slItems = new ItemList(array(['i.id', $ids])); - $slItems->addGlobalsToJscript($smarty); - $lv += $slItems->getListviewData(); - - $equal = true; - foreach ($lv as $k => $v) - { - $chance = $spellLoot[$k]['ChanceOrQuestChance']; - if ($chance) - $equal = false; - - $lv[$k]['percent'] = $chance; - if ($spellLoot[$k]['maxcount'] > 1) - { - $lv[$k]['maxcount'] = $spellLoot[$k]['maxcount']; - $lv[$k]['mincount'] = $spellLoot[$k]['mincountOrRef'] > 0 ? $spellLoot[$k]['mincountOrRef'] : 1; - } - } - - if ($equal) - foreach ($lv as &$_) - $_['percent'] = number_format(100 / count($lv), 2); + $extraCols[] = "Listview.funcBox.createSimpleCol('group', 'group', '10%', 'group')"; + $extraCols[] = "Listview.funcBox.createSimpleCol('mode', LANG.compose_mode, '10%', 'mode')"; + $extraCols[] = "Listview.funcBox.createSimpleCol('reference', LANG.finpcs.seploot + ' ' + LANG.button_link, '10%', 'reference')"; } + $lv = $spellLoot; + if ($extraItem && $spell->canCreateItem()) { $foo = $spell->relItems->getListviewData(); @@ -870,7 +927,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) 'SELECT IF(s1.rankId <> 1 AND s2.id, s2.id, s1.id) FROM ?_spell s1 LEFT JOIN ?_spell s2 - ON s1.SpellFamilyId = s2.SpelLFamilyId AND + ON s1.SpellFamilyId = s2.SpelLFamilyId AND s1.SpellFamilyFlags1 = s2.SpelLFamilyFlags1 AND s1.SpellFamilyFlags2 = s2.SpellFamilyFlags2 AND s1.SpellFamilyFlags3 = s2.SpellFamilyFlags3 AND @@ -891,6 +948,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) WHERE sg1.spell_id = ?d', $firstRank ); + if ($linkedSpells) { $extraSpells = []; @@ -938,7 +996,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) ] ); - $stacks->addGlobalsToJScript($smarty); + $stacks->addGlobalsToJScript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); } } } @@ -991,7 +1049,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) ] ); - $linked->addGlobalsToJScript($smarty); + $linked->addGlobalsToJScript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); } diff --git a/pages/spells.php b/pages/spells.php index 30583bfe..9eb06784 100644 --- a/pages/spells.php +++ b/pages/spells.php @@ -379,7 +379,7 @@ if (!$smarty->loadCache($cacheKey, $pageData, $filter)) $pageData['data'] = $spells->getListviewData(); - $spells->addGlobalsToJscript($smarty); + $spells->addGlobalsToJscript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); // create note if search limit was exceeded; overwriting 'note' is intentional if ($spells->getMatches() > $AoWoWconf['sqlLimit']) diff --git a/pages/title.php b/pages/title.php index e6e70606..b7c94e9a 100644 --- a/pages/title.php +++ b/pages/title.php @@ -4,7 +4,7 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -require 'includes/class.community.php'; +require 'includes/community.class.php'; $_id = intVal($pageParam); diff --git a/search.php b/search.php index d5e823cf..40fdb0a9 100644 --- a/search.php +++ b/search.php @@ -51,7 +51,7 @@ todo 26: Listview - template: 'profile', id: 'characters', name: LANG. */ $search = urlDecode(trim($pageParam)); -$query = Util::sqlEscape(str_replace('?', '_', str_replace('*', '%', ($search)))); +$query = Util::sqlEscape(str_replace('?', '_', str_replace('*', '%', ($search))), true); $type = @intVal($_GET['type']); $searchMask = 0x0; $found = []; @@ -563,7 +563,7 @@ if ($searchMask & 0x800) if ($data = $prof->getListviewData()) { - $prof->addGlobalsToJscript($smarty); + $prof->addGlobalsToJscript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); foreach ($prof->iterate() as $__) $data[$prof->id]['param1'] = '"'.strToLower($prof->getField('iconString')).'"'; @@ -712,7 +712,7 @@ if ($searchMask & 0x8000) { $conditions = array( // [['cuFlags', MASK, '&'], 0], // todo (med): identify disabled quests - [User::$localeId ? 'Title_loc'.User::$localeId : 'Title', $query], // todo (high): unify name-fields + [User::$localeId ? 'lq.Title_loc'.User::$localeId : 'Title', $query], // todo (high): unify name-fields $maxResults ); diff --git a/setup/tools/sql/_item.php b/setup/tools/sql/_item.php index 4f2de1bc..0052e31e 100644 --- a/setup/tools/sql/_item.php +++ b/setup/tools/sql/_item.php @@ -114,7 +114,8 @@ CREATE TABLE `aowow_item_stats` ( DROP COLUMN `sheath`, DROP COLUMN `WDBVerified`, CHANGE COLUMN `entry` `id` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 FIRST , - CHANGE COLUMN `subclass` `subClass` tinyint(3) NOT NULL DEFAULT 0 AFTER `class`, + ADD COLUMN `classBak` tinyint(3) NOT NULL AFTER `class`, + CHANGE COLUMN `subclass` `subClass` tinyint(3) NOT NULL DEFAULT 0 AFTER `classBak`, ADD COLUMN `subClassBak` tinyint(3) NOT NULL AFTER `subClass`, ADD COLUMN `subSubClass` tinyint(3) NOT NULL AFTER `subClassBak`, CHANGE COLUMN `name` `name_loc0` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' AFTER `subSubClass`, @@ -127,10 +128,12 @@ CREATE TABLE `aowow_item_stats` ( CHANGE COLUMN `Quality` `quality` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `displayId`, CHANGE COLUMN `Flags` `flags` bigint(20) NOT NULL DEFAULT 0 AFTER `quality`, CHANGE COLUMN `FlagsExtra` `flagsExtra` int(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `flags`, + ADD COLUMN `cuFlags` int(10) NOT NULL AFTER `flagsExtra`, CHANGE COLUMN `BuyCount` `buyCount` tinyint(3) UNSIGNED NOT NULL DEFAULT 1 AFTER `flagsExtra`, CHANGE COLUMN `BuyPrice` `buyPrice` bigint(20) NOT NULL DEFAULT 0 AFTER `buyCount`, CHANGE COLUMN `SellPrice` `sellPrice` int(10) UNSIGNED NOT NULL DEFAULT 0 AFTER `buyPrice`, - ADD COLUMN `slot` tinyint(3) NOT NULL AFTER `sellPrice`, + ADD COLUMN `repairPrice` int(10) UNSIGNED NOT NULL AFTER `sellPrice`, + ADD COLUMN `slot` tinyint(3) NOT NULL AFTER `repairPrice`, CHANGE COLUMN `InventoryType` `slotBak` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `slot`, CHANGE COLUMN `AllowableClass` `requiredClass` int(11) NOT NULL DEFAULT '-1' AFTER `slotBak`, CHANGE COLUMN `AllowableRace` `requiredRace` int(11) NOT NULL DEFAULT '-1' AFTER `requiredClass`, @@ -230,8 +233,7 @@ CREATE TABLE `aowow_item_stats` ( CHANGE COLUMN `PageMaterial` `pageMaterial` tinyint(3) UNSIGNED NOT NULL DEFAULT 0 AFTER `languageId`, CHANGE COLUMN `startquest` `startQuest` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `pageMaterial`, CHANGE COLUMN `lockid` `lockId` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `startQuest`, - CHANGE COLUMN `RandomProperty` `randomProperty` mediumint(8) NOT NULL DEFAULT 0 AFTER `lockId`, - CHANGE COLUMN `RandomSuffix` `randomSuffix` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `randomProperty`, + CHANGE COLUMN `RandomProperty` `randomEnchant` mediumint(8) NOT NULL DEFAULT 0 AFTER `lockId`; MODIFY COLUMN `itemset` mediumint(8) UNSIGNED NOT NULL DEFAULT 0 AFTER `randomSuffix`, CHANGE COLUMN `MaxDurability` `durability` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `itemset`, CHANGE COLUMN `Map` `map` smallint(6) NOT NULL DEFAULT 0 AFTER `area`, @@ -255,6 +257,10 @@ CREATE TABLE `aowow_item_stats` ( DROP PRIMARY KEY, ADD PRIMARY KEY (`id`); + -- random Attribs + UPDATE aowow_items SET randomEnchant = -RandomSuffix WHERE RandomSuffix <> 0; + ALTER TABLE `aowow_items` DROP COLUMN `RandomSuffix`, + -- localization UPDATE aowow_items a, locales_item b SET a.name_loc2 = b.name_loc2, @@ -283,7 +289,7 @@ CREATE TABLE `aowow_item_stats` ( UPDATE aowow_items SET slot = 5 WHERE slotbak = 20; -- custom sub-classes - UPDATE aowow_items SET subClassBak = subClass, slot = slotBak; + UPDATE aowow_items SET subClassBak = subClass, classBak = class, slot = slotBak; UPDATE aowow_items SET subclass = IF( slot = 4, -8, IF( -- shirt slot = 19, -7, IF( -- tabard @@ -301,6 +307,42 @@ CREATE TABLE `aowow_item_stats` ( ) WHERE class = 4; + // move alchemist stones to trinkets (Armor) + UPDATE aowow_items SET class = 4, subClass = -4 WHERE classBak = 7 AND subClassBak = 11 AND slotBak = 12; + + // mark keys as key (if not quest items) + UPDATE aowow_items SET class = 13, subClass = 0 WHERE classBak IN (0, 15) AND bagFamily & 0x100; + + // set subSubClass for Glyphs (major/minor (requires spells to be set up)) + UPDATE aowow_items i, dbc.spell s, dbc.glyphProperties gp SET i.subSubClass = IF(gp.typeFlags & 0x1, 2, 1) WHERE i.spellId1 = s.id AND s.effectMiscValue1 = gp.id AND i.classBak = 16; + + // elixir-subClasses - spell_group.id = item.subSubClass (1:battle; 2:guardian) + // query takes ~1min + UPDATE aowow_items i, world.spell_group sg SET i.subSubClass = sg.id WHERE sg.spell_id = i.spellId1 AND i.classBak = 0 AND i.subClassBak = 2; + + + // filter misc(class:15) junk(subclass:0) to appropriate categories + + // assign pets and mounts to category + UPDATE aowow_items i, dbc.spell s SET + subClass = IF(effectAuraId1 <> 78, 2, IF(effectAuraId2 = 207 OR effectAuraId3 = 207 OR (s.id <> 65917 AND effectAuraId2 = 4 AND effectId3 = 77), -7, 5)) + WHERE + s.id = spellId2 AND class = 15 AND spellId1 IN (483, 55884); -- misc items with learn-effect + + // more corner cases (mounts that are not actualy learned) + UPDATE aowow_items i, dbc.spell s SET i.subClass = -7 WHERE + (effectId1 = 64 OR (effectAuraId1 = 78 AND effectAuraId2 = 4 AND effectId3 = 77) OR effectAuraId1 = 207 OR effectAuraId2 = 207 OR effectAuraId3 = 207) + AND s.id = i.spellId1 AND i.class = 15 AND i.subClass = 5; + + UPDATE aowow_items i, dbc.spell s SET i.subClass = 5 WHERE s.effectAuraId1 = 78 AND s.id = i.spellId1 AND i.class = 15 AND i.subClass = 0; + + UPDATE aowow_items i, dbc.spell s SET i.class = 0, i.subClass = 6 WHERE s.effectId1 = 53 AND s.id = i.spellId1 AND i.class = 15 AND i.subClassBak = 0; + UPDATE aowow_items i, dbc.spell s SET i.subClass = -3 WHERE s.effectId1 = 54 AND s.id = i.spellId1 AND i.class = 0 AND i.subClassBak = 8; + + // one stray enchanting recipe .. with a strange icon + UPDATE aowow_items SET class = 9, subClass = 8 WHERE id = 33147; + + UPDATE aowow_items SET subClass = -2 WHERE quality = 4 AND class = 15 AND subClassBak = 0 AND requiredClass AND (requiredClass & 0x5FF) <> 0x5FF; */ @@ -308,7 +350,7 @@ class ItemSetup extends ItemList { private $cols = []; - public function __construct($start, $end) // i suggest steps of 5k at max (12 steps (0 - 60k)); otherwise eats your ram for breakfast + public function __construct($start, $end) // i suggest steps of 3k at max (20 steps (0 - 60k)); otherwise eats your ram for breakfast { $this->cols = DB::Aowow()->selectCol('SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA`="world" AND `TABLE_NAME`="aowow_item_stats"'); set_time_limit(300); @@ -316,13 +358,41 @@ class ItemSetup extends ItemList $conditions = array( ['i.id', $start, '>'], ['i.id', $end, '<='], - ['class', [ITEM_CLASS_WEAPON, ITEM_CLASS_GEM, ITEM_CLASS_ARMOR]], + ['class', [ITEM_CLASS_WEAPON, ITEM_CLASS_GEM, ITEM_CLASS_ARMOR, ITEM_CLASS_CONSUMABLE]], 0 ); parent::__construct($conditions); } + public function calcRepairCost() + { + foreach ($this->iterate() as $id => $__) + { + $cls = $this->curTpl['class']; + $scb = $this->curTpl['subClassBak']; + $dur = $this->curTpl['durability']; + $qu = $this->curTpl['quality']; + + // has no durability + if (!in_array($cls, [ITEM_CLASS_WEAPON, ITEM_CLASS_ARMOR]) || $dur <= 0) + continue; + + // is relic, misc or obsolete + if ($cls == ITEM_CLASS_ARMOR && !in_array($scb, [1, 2, 3, 4, 6])) + continue; + + $cost = DB::Aowow()->selectCell('SELECT ?# FROM ?_durabilityCost WHERE itemLevel = ?', + 'class'.$cls.'Sub'.$scb, + $this->curTpl['itemLevel'] + ); + + $qMod = Util::$itemDurabilityQualityMod[(($qu + 1) * 2)]; + + DB::Aowow()->query('UPDATE ?_items SET repairPrice = ?d WHERE id = ?d', intVal($dur * $cost * $qMod), $id); + } + } + public function writeStatsTable() { foreach ($this->iterate() as $__) diff --git a/template/achievements.tpl b/template/achievements.tpl index fec317da..3ba0fb5d 100644 --- a/template/achievements.tpl +++ b/template/achievements.tpl @@ -21,7 +21,7 @@
- + - + @@ -103,11 +84,11 @@ - + - + @@ -130,19 +111,19 @@ - + -{if $lvData.page.stances} +{if !empty($lvData.page.stances)} {/if} -{if $lvData.page.items} +{if !empty($lvData.page.items)} @@ -157,7 +138,8 @@ {if isset($lvData.page.effect[i].value)}
{$lang._value}{$lang.colon}{$lvData.page.effect[i].value}{/if} {if isset($lvData.page.effect[i].radius)}
{$lang._radius}{$lang.colon}{$lvData.page.effect[i].radius} {$lang._distUnit}{/if} - {if isset($lvData.page.effect[i].interval)}
{$lang._interval}{$lang.colon}{$lvData.page.effect[i].interval} {$lang.seconds}{/if} + {if isset($lvData.page.effect[i].interval)}
{$lang._interval}{$lang.colon}{$lvData.page.effect[i].interval}{/if} + {if isset($lvData.page.effect[i].mechanic)}
{$lang.mechanic}{$lang.colon}{$lvData.page.effect[i].mechanic}{/if}
{if isset($lvData.page.effect[i].icon)}
{$lang.name}{$lang.colon}{$lang.name|ucFirst}{$lang.colon} diff --git a/template/bricks/globals/items.tpl b/template/bricks/globals/items.tpl index 5bb5859b..f3ae7426 100644 --- a/template/bricks/globals/items.tpl +++ b/template/bricks/globals/items.tpl @@ -7,4 +7,10 @@ var _ = g_items; {if isset($item.quality)}, quality:'{$item.quality}'{/if} {rdelim}; {/foreach} + +{if $extra} + _[{$extra.id}].tooltip_{$user.language} = '{$extra.tooltip}'; + _[{$extra.id}].spells_{$user.language} = {$extra.spells|@json_encode:$smarty.const.JSON_NUMERIC_CHECK}; +{/if} + {/strip} diff --git a/template/bricks/globals/spells.tpl b/template/bricks/globals/spells.tpl index 23b163ee..713a4ec6 100644 --- a/template/bricks/globals/spells.tpl +++ b/template/bricks/globals/spells.tpl @@ -6,4 +6,12 @@ var _ = g_spells; icon:'{$item.icon|escape:"javascript"}' {rdelim}; {/foreach} + +{if $extra} + _[{$extra.id}].tooltip_{$user.language} = '{$extra.tooltip}'; + _[{$extra.id}].buff_{$user.language} = '{$extra.buff}'; + _[{$extra.id}].spells_{$user.language} = {$extra.spells|@json_encode:$smarty.const.JSON_NUMERIC_CHECK}; + _[{$extra.id}].buffspells_{$user.language} = {$extra.buffspells|@json_encode:$smarty.const.JSON_NUMERIC_CHECK}; +{/if} + {/strip} diff --git a/template/bricks/listviews/item.tpl b/template/bricks/listviews/item.tpl index bcdfdb73..6c69d337 100644 --- a/template/bricks/listviews/item.tpl +++ b/template/bricks/listviews/item.tpl @@ -15,43 +15,14 @@ {foreach name=i from=$data item=curr} {ldelim} {foreach from=$curr key='name' item=val} - {if $name != 'id' && $name != 'name' && $name != 'heroic' && $name != 'mincount' && $name != 'maxcount' && $name != 'group' && $name != 'groupcount' && $name != 'cost'} + {if $name != 'id' && $name != 'name' && $name != 'heroic'} {$name}:{$val|@json_encode:$smarty.const.JSON_NUMERIC_CHECK}, {/if} {/foreach} name:'{$curr.name|escape:"quotes"}', - {if isset($curr.heroic)} heroic:1, {/if} - {if isset($curr.maxcount)} - {if $curr.maxcount > 1} - stack:[{$curr.mincount},{$curr.maxcount}], - {/if} - {/if} - {if isset($curr.group) and isset($curr.groupcount)} - group:'({$curr.group}){if $curr.groupcount!=1} x{$curr.groupcount}{/if}', - {/if} - {if isset($curr.cost.money) || isset($curr.cost.honor) ||isset($curr.cost.arena) || isset($curr.cost.items)} - stock:-1, - cost:[ - {if isset($curr.cost.money)}{$curr.cost.money}{/if} - {if isset($curr.cost.honor) or isset($curr.cost.arena) or isset($curr.cost.items)} - ,{if isset($curr.cost.honor)}{$curr.cost.honor}{/if} - {if isset($curr.cost.arena) or isset($curr.cost.items)} - ,{if isset($curr.cost.arena)}{$curr.cost.arena}{/if} - {if isset($curr.cost.items)} - ,[ - {foreach from=$curr.cost.items item=curitem name=c} - [{$curitem.item},{$curitem.count}] - {if $smarty.foreach.c.last}{else},{/if} - {/foreach} - ] - {/if} - {/if} - {/if} - ], - {/if} id:{$curr.id} {rdelim} {if $smarty.foreach.i.last}{else},{/if} @@ -89,7 +60,7 @@ }, count:363318, stack:[1,1], /* [min, max] */ - pctstack:'{1: 50.0123,2: 49.9877}' /* {dropCount: relChanceForThisStack} */ + pctstack:'{1: 50.0123, 2: 49.9877}' /* {dropCount: relChanceForThisStack} */ } ] }); diff --git a/template/bricks/listviews/spell.tpl b/template/bricks/listviews/spell.tpl index 2d901ccd..31d7a75d 100644 --- a/template/bricks/listviews/spell.tpl +++ b/template/bricks/listviews/spell.tpl @@ -49,10 +49,10 @@ {/if} {if !empty($curr.reagents)} reagents:[ - {section name=j loop=$curr.reagents} - [{$curr.reagents[j][0]},{$curr.reagents[j][1]}] - {if $smarty.section.j.last}{else},{/if} - {/section} + {foreach name=j from=$curr.reagents item=r} + [{$r[0]},{$r[1]}] + {if $smarty.foreach.j.last}{else},{/if} + {/foreach} ], {/if} {if isset($curr.creates)} diff --git a/template/css/global.css b/template/css/global.css index 78552e0c..e37a3347 100644 --- a/template/css/global.css +++ b/template/css/global.css @@ -2410,6 +2410,147 @@ td.checked .listview-cb:hover font-weight: bold; } +.slider-x, .slider-y { + position: relative; +} + +.slider-x { + width: 100%; + height: 25px; +} + +.slider-y { + width: 25px; + height: 100%; +} + +.slider-x.has-labels { + height: 40px; +} + +.slider-x .track, .slider-y .track { + position: absolute; + display: block; + width: 100%; + height: 100%; + z-index: 8; +} + +.slider-x .track { + height: 25px; +} + +.slider-y .track { + width: 25px; +} + +.slider-x .handle, .slider-y .handle { + position: absolute; + top: 0; + left: 0; + z-index: 10; +} + +.slider-x .handle { + background: url(../images/ui/misc/slider.gif) no-repeat top left; + cursor: e-resize; + height: 22px; + width: 9px; +} + +.slider-y .handle { + background: url(../images/ui/misc/slider.gif) no-repeat top right; + cursor: n-resize; + height: 9px; + width: 22px; +} + +.slider-x .handle:hover { + background-position: bottom left; +} + +.slider-y .handle:hover { + background-position: bottom right; +} + +.slider-x span, .slider-y span { + position: absolute; + background: #7e7e7e; + border: 1px solid #404040; + z-index: 5; +} + +.slider-x span { + top: 9px; + left: 0; + width: 100%; + height: 2px; +} + +.slider-y span { + top: 0; + left: 9px; + width: 2px; + height: 100%; +} + +.slider-x .label { + font-size: 11px; + left: 0; + position: absolute; + top: 22px; +} + +.slider-x .label.max { + left: auto; + right: 0; +} + +.slider-y .label { + font-size: 11px; + left: 22px; + position: absolute; + top: 0; +} + +.slider-y .label.max { + top: auto; + bottom: 0; +} + +.slider-x input, .slider-y input { + background: none; + border: 1px solid transparent; + font-weight: bold; + color: #fff; + display: block; + font-size: 11px; + margin: 0 auto; + position: relative; + text-align: center; + top: 22px; + width: 50px; + z-index: 9; +} + +.slider-y input { + margin: 0 0 0 21px; + position: relative; + text-align: left; + top: 45%; + width: 30px; +} + +.slider-x input:hover, .slider-y input:hover, .slider-x input:focus, .slider-y input:focus { + background: #101010; + border-color: #303030; + outline: none; +} + +.tooltip-slider table { + width: 100%; +} + .pet-model { position: relative; diff --git a/template/header.tpl b/template/header.tpl index eee17924..32bd5875 100644 --- a/template/header.tpl +++ b/template/header.tpl @@ -32,6 +32,6 @@ g_initHeader({$page.tab}); LiveSearch.attach($WH.ge('livesearch-generic')); {foreach from=$jsGlobals item="glob"} - {include file="bricks/globals/`$glob[0]`.tpl" data=$glob[1]} + {include file="bricks/globals/`$glob[0]`.tpl" data=$glob[1] extra=$glob[2]} {/foreach} {/strip} diff --git a/template/item.tpl b/template/item.tpl index 426aab29..0f91536f 100644 --- a/template/item.tpl +++ b/template/item.tpl @@ -19,7 +19,7 @@ {include file='bricks/infobox.tpl' info=$lvData.infobox}
- {$lang.links}{$lang.links} + {$lang.links}{$lang.links} {$lang.view3D}{$lang.view3D} {$lang.compare}{$lang.compare} {$lang.findUpgrades}{$lang.findUpgrades} @@ -27,33 +27,62 @@ {*
what the heck.. this div has neither data nor style or script associated with *}

{$lvData.page.name}

-
-
-
 
{$lvData.tooltip}
+{include file='bricks/tooltip.tpl'} + +{if !empty($lvData.page.disabled)} +
+ {$lang._unavailable} +{/if} +{if !empty($lvData.page.transfer)} +
+ {$lang._transfer|sprintf:$lvData.page.transfer.id:$lvData.page.transfer.quality:$lvData.page.transfer.icon:$lvData.page.transfer.name:$lvData.page.transfer.facInt:$lvData.page.transfer.facName} +{/if} +{if !empty($lvData.page.subItems)} +
+

{$lang._rndEnchants}

+ +
+
    + {foreach from=$lvData.page.subItems item=i key=k}{if $k < (count($lvData.page.subItems) / 2)} +
  • + ...{$i.name} + {$lang._chance|@sprintf:$i.chance} +
    {$i.enchantment} +
  • + {/if}{/foreach} +
+ {if count($lvData.page.subItems) > 1} +
+
    + {foreach from=$lvData.page.subItems item=i key=k}{if $k >= (count($lvData.page.subItems) / 2)} +
  • + ...{$i.name} + {$lang._chance|@sprintf:$i.chance} +
    {$i.enchantment} +
  • + {/if}{/foreach} +
+
+ {/if} +{/if} +{if !empty($lvData.pageText)} +
+

{$lang.content}

+
+ + +{/if} +
- - - - {if !empty($lvData.page.pagetext)} -

Content

-
- {strip} - - {/strip} - {/if} -

{$lang.related}

diff --git a/template/items.tpl b/template/items.tpl index 92bdda1e..aaca9446 100644 --- a/template/items.tpl +++ b/template/items.tpl @@ -59,7 +59,7 @@ - + diff --git a/template/itemsets.tpl b/template/itemsets.tpl index c6c89598..47438ab4 100644 --- a/template/itemsets.tpl +++ b/template/itemsets.tpl @@ -43,7 +43,7 @@
{$lang.name}{$lang.colon}{$lang.name|ucFirst}{$lang.colon}  
- + diff --git a/template/js/basic.js b/template/js/basic.js index ecf4d7e7..e240fe00 100644 --- a/template/js/basic.js +++ b/template/js/basic.js @@ -68,7 +68,7 @@ $WH.bindfunc = function() { var object = args.shift(); return function() { - return __method.apply(object, args.concat($WH.$A(arguments))); + return __method.apply(object, args.concat($WH.$A(arguments))); }; }; @@ -239,11 +239,11 @@ $WH.rs = function () { var c = $WH.rs.random; var r = ''; for (var i = 0; i < 16; i++) { - var n = Math.floor(Math.random() * c.length); - if (i == 0 && n < 11) { + var n = Math.floor(Math.random() * c.length); + if (i == 0 && n < 11) { n += 10; - } - r += c.substring(n, n + 1); + } + r += c.substring(n, n + 1); } return r; @@ -278,9 +278,9 @@ $WH.array_apply = function(a, f, ud) { $WH.array_filter = function(a, f) { var res = []; for (var i = 0, len = a.length; i < len; ++i) { - if (f(a[i])) { + if (f(a[i])) { res.push(a[i]); - } + } } return res; @@ -292,14 +292,14 @@ $WH.array_index = function(a, r, f, z) { } if (!a.__R || z) { - a.__R = {}; - if (!f) { + a.__R = {}; + if (!f) { f = function(x) { return x; }; - } + } - for (var i = 0, len = a.length; i < len; ++i) { + for (var i = 0, len = a.length; i < len; ++i) { a.__R[f(a[i])] = i; - } + } } return (r == null ? a.__R : !isNaN(a.__R[r])); @@ -307,19 +307,19 @@ $WH.array_index = function(a, r, f, z) { $WH.array_compare = function(a, b) { if (a.length != b.length) { - return false; + return false; } var o = {}; for (var i = a.length; i >= 0; --i) { - o[a[i]] = true; + o[a[i]] = true; } var match = true; for (var i = b.length; i >= 0; --i) { - if (o[b[i]] === undefined) { + if (o[b[i]] === undefined) { match = false; - } + } } return match; @@ -330,11 +330,11 @@ $WH.array_unique = function(a) { var tmp = {}; for (var i = a.length-1; i >= 0; --i) { - tmp[a[i]] = 1; + tmp[a[i]] = 1; } for (var i in tmp) { - out.push(i); + out.push(i); } return out; @@ -994,6 +994,24 @@ $WH.g_intersectRect = function(a, b) { //****************************************************************************// //****************************************************************************// +// sarjuuk: this function should be obsolete by now :x +$WH.g_setRatingLevel = function(sp, level, rating, value) { + var newLvl = prompt($WH.sprintf(LANG.prompt_ratinglevel, 1, 80), level); + if (newLvl != null) { + newLvl |= 0; + if (newLvl != level && newLvl >= 1 && newLvl <= 80) { + level = newLvl; + var a = $WH.g_convertRatingToPercent(level, rating, value); + a = (Math.round(a * 100) / 100); + if (rating != 12 && rating != 37) { + a += "%" + } + sp.innerHTML = $WH.sprintf(LANG.tooltip_combatrating, a, level); + sp.onclick = $WH.g_setRatingLevel.bind(0, sp, level, rating, value); + } + } +} + $WH.g_convertRatingToPercent = function(level, rating, value, classs) { var ratingBases = $WH.g_convertRatingToPercent.RB; @@ -1136,36 +1154,36 @@ $WH.g_individualToGlobalStat = { }; $WH.g_convertScalingFactor = function(level, factor, dist, stat, json) { - var scalingValues = $WH.g_convertScalingFactor.SV; - var scalingDistributions = $WH.g_convertScalingFactor.SD; + var scalingValues = $WH.g_convertScalingFactor.SV; + var scalingDistributions = $WH.g_convertScalingFactor.SD; - if(!scalingValues[level]) { - if (g_user.roles & U_GROUP_ADMIN) { - alert('There are no item scaling values for level ' + level); + if(!scalingValues[level]) { + if (g_user.roles & U_GROUP_ADMIN) { + alert('There are no item scaling values for level ' + level); } - return (json ? {} : 0); - } - - var - result = {}, - scaleValue = scalingValues[level], - scaleDistribution = scalingDistributions[dist]; - - if (!scaleDistribution || !(stat >= 0 && stat <= 9)) { - result.v = scaleValue[factor]; + return (json ? {} : 0); } - else { - result.n = $WH.g_statToJson[scaleDistribution[stat]]; - result.s = scaleDistribution[stat]; - result.v = Math.floor(scaleValue[factor] * scaleDistribution[stat + 10] / 10000.0); - } - return (json ? result : result.v); + var + result = {}, + scaleValue = scalingValues[level], + scaleDistribution = scalingDistributions[dist]; + + if (!scaleDistribution || !(stat >= 0 && stat <= 9)) { + result.v = scaleValue[factor]; + } + else { + result.n = $WH.g_statToJson[scaleDistribution[stat]]; + result.s = scaleDistribution[stat]; + result.v = Math.floor(scaleValue[factor] * scaleDistribution[stat + 10] / 10000.0); + } + + return (json ? result : result.v); } if (!$WH.wowheadRemote) { - $WH.g_ajaxIshRequest('?data=item-scaling'); + $WH.g_ajaxIshRequest('?data=item-scaling'); } $WH.g_getDataSource = function() { @@ -1383,14 +1401,6 @@ $WH.g_setTooltipLevel = function(tooltip, level) { return '' + prefix + '' + value + suffix + '' + br; }); } - else { - var json = { - scadist: scaDist - }; - - $WH.g_setJsonSpellLevel(json, level); - // just check for known spells - } } // Points per level @@ -1460,7 +1470,10 @@ $WH.g_setTooltipSpells = function(tooltip, spells, spellData, position) { } $WH.g_enhanceTooltip = function(tooltip, isStatic, useGets, showSlider, buff, knownSpells, chooseSpells) { - var _ = typeof tooltip, spellJson; + var + _ = typeof tooltip, + spellJson; + if (_ == 'number') { var arr = $WH.g_getDataSource(), @@ -1599,6 +1612,38 @@ $WH.g_staticTooltipLevelClick = function (div, level, noSlider, buff) { } } +$WH.g_tooltipSliderMove = function(e, slider, position) { + $WH.g_staticTooltipLevelClick(this, position.value, 1); + + if (this.bufftip) { + $WH.g_staticTooltipLevelClick(this.bufftip, position.value, 1, 1); + } + + $WH.Tooltip.hide(); +} + +$WH.g_tooltipSpellsChange = function() { + if (!this.modified) { + return; + } + + var + chooseSpells = this.modified[0], + spellJson = this.modified[1], + knownSpells = []; + + $.each($('input:checked', chooseSpells), function(i, s) { + knownSpells.push(parseInt(s.id.replace('known-', ''))); + }); + + this.modified[2] = knownSpells; + this.innerHTML = $WH.g_setTooltipSpells(this.innerHTML, knownSpells, spellJson); + + if (this.bufftip) { + ($WH.g_tooltipSpellsChange.bind(this.bufftip))(); + } +} + //****************************************************************************// //****************************************************************************// //****************************************************************************// @@ -1665,13 +1710,13 @@ $WH.Tooltip = { td = $WH.gE(table, 'td')[0], c = td.childNodes; - tooltip.className = $WH.trim(tooltip.className.replace('tooltip-slider', '')); + tooltip.className = $WH.trim(tooltip.className.replace('tooltip-slider', '')); if (c.length >= 2 && c[0].nodeName == 'TABLE' && c[1].nodeName == 'TABLE') { c[0].style.whiteSpace = 'nowrap'; var m = parseInt(tooltip.style.width); - if(!tooltip.slider || !m) { + if(!tooltip.slider || !m) { if (c[1].offsetWidth > 300) { m = Math.max(300, c[0].offsetWidth) + 20; } @@ -1686,10 +1731,10 @@ $WH.Tooltip = { tooltip.style.width = m + 'px'; c[0].style.width = c[1].style.width = '100%'; - if(tooltip.slider) { - Slider.setSize(tooltip.slider, m - 6); - tooltip.className += ' tooltip-slider'; - } + if(tooltip.slider) { + Slider.setSize(tooltip.slider, m - 6); + tooltip.className += ' tooltip-slider'; + } if (!noShrink && tooltip.offsetHeight > document.body.clientHeight) { table.className = 'shrink'; @@ -2008,30 +2053,30 @@ $WH.Tooltip = { }; if ($WH.isset('$WowheadPower')) { - $WowheadPower.init(); + $WowheadPower.init(); } $WH.g_getProfileIcon = function(raceId, classId, gender, level, icon, size) { var raceXclass = { - 10: {6:1, 3:1, 8:1, 2:1, 5:1, 4:1, 9:1}, // bloodelf - 11: {6:1, 3:1, 8:1, 2:1, 5:1, 7:1, 1:1}, // draenei - 3: {6:1, 3:1, 2:1, 5:1, 4:1, 1:1 }, // dwarf - 7: {6:1, 8:1, 4:1, 9:1, 1:1 }, // gnome - 1: {6:1, 8:1, 2:1, 5:1, 4:1, 9:1, 1:1}, // human - 4: {6:1, 11:1, 3:1, 5:1, 4:1, 1:1 }, // nightelf - 2: {6:1, 3:1, 4:1, 7:1, 9:1, 1:1 }, // orc - 6: {6:1, 11:1, 3:1, 7:1, 1:1 }, // tauren - 8: {6:1, 3:1, 8:1, 5:1, 4:1, 7:1, 1:1}, // troll - 5: {6:1, 8:1, 5:1, 4:1, 9:1, 1:1 } // scourge + 10: {6:1, 3:1, 8:1, 2:1, 5:1, 4:1, 9:1}, // bloodelf + 11: {6:1, 3:1, 8:1, 2:1, 5:1, 7:1, 1:1}, // draenei + 3: {6:1, 3:1, 2:1, 5:1, 4:1, 1:1 }, // dwarf + 7: {6:1, 8:1, 4:1, 9:1, 1:1 }, // gnome + 1: {6:1, 8:1, 2:1, 5:1, 4:1, 9:1, 1:1}, // human + 4: {6:1, 11:1, 3:1, 5:1, 4:1, 1:1 }, // nightelf + 2: {6:1, 3:1, 4:1, 7:1, 9:1, 1:1 }, // orc + 6: {6:1, 11:1, 3:1, 7:1, 1:1 }, // tauren + 8: {6:1, 3:1, 8:1, 5:1, 4:1, 7:1, 1:1}, // troll + 5: {6:1, 8:1, 5:1, 4:1, 9:1, 1:1 } // scourge }; if (icon) { - return isNaN(icon) ? icon : '?profile=avatar' + (size ? '&size=' + size : '') + '&id=' + icon + (size == 'tiny' ? '.gif' : '.jpg'); + return isNaN(icon) ? icon : '?profile=avatar' + (size ? '&size=' + size : '') + '&id=' + icon + (size == 'tiny' ? '.gif' : '.jpg'); } if (!g_file_races[raceId] || !g_file_classes[classId] || !g_file_genders[gender] || !raceXclass[raceId] || !raceXclass[raceId][classId] || (classId == 6 && level < 55)) { - return 'inv_misc_questionmark'; + return 'inv_misc_questionmark'; } return 'chr_' + g_file_races[raceId] + '_' + g_file_genders[gender] + '_' + g_file_classes[classId] + '0' + (level > 59 ? (Math.floor((level - 60) / 10) + 2) : 1); diff --git a/template/js/filters.js b/template/js/filters.js index 7c75a3a9..f3b2ce2d 100644 --- a/template/js/filters.js +++ b/template/js/filters.js @@ -1649,7 +1649,7 @@ function fi_getExtraCols(wt, gm, pu) { for (var i = 0; i < wt.length && i < nColsMax; ++i) { var a = fi_Lookup(wt[i]); - if (a && a.name && a.type == 'num') { + if (a && a.name && a.type == 'num' && a.name != 'buyprice') { var b = { id: a.name, value: a.name, @@ -1659,14 +1659,14 @@ function fi_getExtraCols(wt, gm, pu) { }; // Fix display of decimal columns - if (a.name.indexOf('dps') != -1 || a.name.indexOf('speed') != -1) { + if (/dps|speed/i.test(a.name)) { b.compute = function (item, td) { return (item[a.name] || 0).toFixed(2); } } // Fix display of money columns - if (a.name.indexOf('money') != -1) { + if (/money|price|cost/i.test(a.name)) { b.compute = function (item, td) { td.innerHTML = g_getMoneyHtml(item[a.name] || 0); } diff --git a/template/js/global.js b/template/js/global.js index 1982d780..369a1999 100644 --- a/template/js/global.js +++ b/template/js/global.js @@ -952,22 +952,6 @@ function g_createAchievementBar(b, d, a) { }; return g_createProgressBar(c) } -function g_setRatingLevel(f, e, b, c) { - var d = prompt($WH.sprintf(LANG.prompt_ratinglevel, 1, 80), e); - if (d != null) { - d |= 0; - if (d != e && d >= 1 && d <= 80) { - e = d; - var a = $WH.g_convertRatingToPercent(e, b, c); - a = (Math.round(a * 100) / 100); - if (b != 12 && b != 37) { - a += "%" - } - f.innerHTML = $WH.sprintf(LANG.tooltip_combatrating, a, e); - f.onclick = g_setRatingLevel.bind(0, f, e, b, c) - } - } -} function g_getMoneyHtml(c) { var b = 0, @@ -2013,6 +1997,305 @@ var VideoViewer = new function() { DomContentLoaded.addEvent(this.checkPound) }; + +var Slider = new function() { + var + start, + handleObj, + timer; + + function onMouseDown(e) { + e = $WH.$E(e); + + handleObj = this; + start = $WH.g_getCursorPos(e); + + $WH.aE(document, 'mousemove', onMouseMove); + $WH.aE(document, 'mouseup', onMouseUp); + + return false; + } + + function onMouseMove(e) { + e = $WH.$E(e); + + if (!start || !handleObj) { + return; + } + + var + cursor = $WH.g_getCursorPos(e), + delta = cursor[handleObj._dir] - start[handleObj._dir], + outside = setPosition(handleObj, handleObj._pos + delta), + current = getCurrentPosition(handleObj); + + if (current && handleObj.input) { + handleObj.input.value = current.value; + } + + if (!outside) { + start = cursor; + } + + if (handleObj.onMove) { + handleObj.onMove(e, handleObj, current); + } + } + + function onMouseUp(e) { + e = $WH.$E(e); + + if (handleObj.onMove) { + handleObj.onMove(e, handleObj, getCurrentPosition(handleObj)); + } + + handleObj = null; + start = null; + + $WH.dE(document, 'mousemove', onMouseMove); + $WH.dE(document, 'mouseup', onMouseUp); + + return false; + } + + function onClick(obj, e) { + e = $WH.$E(e); + + handleObj = obj; + start = $WH.g_getCursorPos(e); + + var + offset = $WH.ac(handleObj.parentNode), + center = Math.floor(getHandleWidth(handleObj) / 2); + + setPosition(handleObj, start[handleObj._dir] - offset[handleObj._dir] - center); + + var current = getCurrentPosition(handleObj); + + if (current && handleObj.input) { + handleObj.input.value = current.value; + } + + if (handleObj.onMove) { + handleObj.onMove(e, handleObj, current); + } + + $WH.aE(document, 'mousemove', onMouseMove); + $WH.aE(document, 'mouseup', onMouseUp); + + return false; + } + + function onKeyPress(obj, e) { + if (timer) { + clearTimeout(timer); + } + + if (e.type == 'change' || e.type == 'keypress' && e.which == 13) { + onInput(obj, e); + } + else { + timer = setTimeout(onInput.bind(0, obj, e), 1000); + } + } + + function onInput(obj, e) { + var + value = obj.input.value, + current = getCurrentPosition(obj); + + if (isNaN(value)) { + value = current.value; + } + if (value > obj._max) { + value = obj._max; + } + if (value < obj._min) { + value = obj._min; + } + + Slider.setValue(obj, value); + + if (obj.onMove) { + obj.onMove(e, obj, getCurrentPosition(obj)); + } + } + + function setPosition(obj, offset) { + var outside = false; + + if (offset < 0) { + offset = 0; + outside = true; + } + else if (offset > getMaxPosition(obj)) { + offset = getMaxPosition(obj); + outside = true; + } + + obj.style[(obj._dir == 'y' ? 'top' : 'left')] = offset + 'px'; + obj._pos = offset; + + return outside; + } + + function getMaxPosition(obj) { + return getTrackerWidth(obj) - getHandleWidth(obj) + 2; + } + + function getCurrentPosition(obj) { + var + percent = obj._pos / getMaxPosition(obj), + value = Math.round((percent * (obj._max - obj._min)) + obj._min), + result = [percent, value]; + + result.percent = percent; + result.value = value; + return result; + } + + function getTrackerWidth(obj) { + if (obj._tsz > 0) { + return obj._tsz; + } + + if (obj._dir == 'y') { + return obj.parentNode.offsetHeight; + } + + return obj.parentNode.offsetWidth; + } + + function getHandleWidth(obj) { + if (obj._hsz > 0) { + return obj._hsz; + } + + if (obj._dir == 'y') { + return obj.offsetHeight; + } + + return obj.offsetWidth; + } + + this.setPercent = function(obj, percent) { + setPosition(obj, parseInt(percent * getMaxPosition(obj))); + }; + + this.setValue = function(obj, value) { + if (value < obj._min) { + value = obj._min; + } + else if (value > obj._max) { + value = obj._max; + } + + if (obj.input) { + obj.input.value = value; + } + + this.setPercent(obj, (value - obj._min) / (obj._max - obj._min)); + }; + + this.setSize = function(obj, length) { + var + current = getCurrentPosition(obj), + resized = getMaxPosition(obj); + + obj.parentNode.style[(obj._dir == 'y' ? 'height' : 'width')] = length + 'px'; + + if (resized != getMaxPosition(obj)) { + this.setValue(obj, current.value); + } + }; + + this.init = function(container, opt) { + var obj = $WH.ce('a'); + obj.href = 'javascript:;'; + obj.onmousedown = onMouseDown; + obj.className = 'handle'; + + var track = $WH.ce('a'); + track.href = 'javascript:;'; + track.onmousedown = onClick.bind(0, obj); + track.className = 'track'; + + $WH.ae(container, $WH.ce('span')); + $WH.ae(container, track); + $WH.ae(container, obj); + + obj._dir = 'x'; + obj._min = 1; + obj._max = 100; + obj._pos = 0; + obj._tsz = 0; + obj._hsz = 0; + + if (opt != null) { + // Orientation + if (opt.direction == 'y') { + obj._dir = 'y'; + } + + // Values + if (opt.minValue) { + obj._min = opt.minValue; + } + if (opt.maxValue) { + obj._max = opt.maxValue; + } + + // Functions + if (opt.onMove) { + obj.onMove = opt.onMove; + } + + if (opt.trackSize) { + obj._tsz = opt.trackSize; + } + + if (opt.handleSize) { + obj._hsz = opt.handleSize; + } + + // Labels + if (opt.showLabels !== false) { + var label = $WH.ce('div'); + + label.innerHTML = obj._min; + label.className = 'label min'; + $WH.ae(container, label); + + label = $WH.ce('div'); + label.innerHTML = obj._max; + label.className = 'label max'; + $WH.ae(container, label); + + obj.input = $WH.ce('input'); + $(obj.input).attr({ value: obj._max, type: 'text' } + ).bind('click', function () { this.select(); } + ).keypress(function (e) { + var allowed = []; + var usedKey = e.which; + for (i = 48; i < 58; i++) { + allowed.push(i); + } + if (!($WH.in_array(allowed, usedKey) >= 0) && usedKey != 13) { + e.preventDefault(); + } + }).bind('keyup keydown change', onKeyPress.bind(0, obj)); + + obj.input.className = 'input'; + $WH.ae(container, obj.input); + } + } + + container.className = 'slider-' + obj._dir + (opt == null || opt.showLabels !== false ? ' has-labels' : ''); + + return obj; + } +}; + var suDialog; function su_addToSaved(c, d, a, e) { if (!c) { @@ -4946,7 +5229,7 @@ Listview.extraCols = { var sp = $WH.ce('span'); sp.className += ' tip'; $WH.ae(sp, $WH.ct(value)); - $WH.ae(b, sp); + $WH.ae(td, sp); } else { return value; @@ -5367,53 +5650,400 @@ Listview.extraCols = { }; Listview.funcBox = { - assocBinFlags: function(f, arr) { - var res = []; - for (var i in arr) { - if (!isNaN(i) && (f & 1 << i - 1)) { - res.push(i); - } - } - res.sort(function(a, b) { - return $WH.strcmp(arr[a], arr[b]); - }); - - return res; + createSimpleCol: function(i, n, w, v) { + return { + id: i, + name: (LANG[n] !== undefined ? LANG[n] : n), + width: w, + value: v + }; }, - createSimpleCol: function(i, n, w, v) { - return { - id: i, - name: (LANG[n] !== undefined ? LANG[n] : n), - width: w, - value: v - }; - }, + initLootTable: function(row) { + var divider; - initLootTable: function(row) { - var divider; - - if (this._totalCount != null) { - divider = this._totalCount; - } + if (this._totalCount != null) { + divider = this._totalCount; + } else { - divider = row.outof; - } + divider = row.outof; + } - if (divider == 0) { - if (row.count != -1) { - row.percent = row.count; - } + if (divider == 0) { + if (row.count != -1) { + row.percent = row.count; + } else { - row.percent = 0; - } - } + row.percent = 0; + } + } else { - row.percent = row.count / divider * 100; - } + row.percent = row.count / divider * 100; + } (Listview.funcBox.initModeFilter.bind(this, row))(); - }, + }, + +// // subtabs here // + + initModeFilter: function(row) + { + if(this._lootModes == null) + this._lootModes = { 99: 0 }; + + if(this._distinctModes == null) + this._distinctModes = { 99: 0 }; + + if((!row.modes || row.modes.mode == 4) && row.classs != 12 && row.commondrop) + { + this._lootModes[99]++; // Trash + this._distinctModes[99]++; + } + else if(row.modes) + { + for(var i = -2; i <= 5; ++i) + { + if(this._lootModes[i] == null) + this._lootModes[i] = 0; + + if(row.modes.mode & 1 << parseInt(i) + 2) + this._lootModes[i]++; + } + + if(this._distinctModes[row.modes.mode] == null) + this._distinctModes[row.modes.mode] = 0; + this._distinctModes[row.modes.mode]++; + } + }, + + addModeIndicator: function() + { + var nModes = 0; + for(var i in this._distinctModes) + { + if(this._distinctModes[i]) + nModes++; + } + + if(nModes < 2) + return; + + var pm = location.hash.match(/:mode=([^:]+)/), + order = [0,-1,-2,1,3,2,4,5,99], + langref = { + "-2": LANG.tab_heroic, + "-1": LANG.tab_normal, + 0: LANG.tab_noteworthy, + 1: $WH.sprintf(LANG.tab_normalX, 10), + 2: $WH.sprintf(LANG.tab_normalX, 25), + 3: $WH.sprintf(LANG.tab_heroicX, 10), + 4: $WH.sprintf(LANG.tab_heroicX, 25), + 5: LANG.tab_raidfinder, + 99: '' // No indicator for trash + }; + + var f = function(mode, dm, updatePound) + { + g_setSelectedLink(this, 'lootmode'); + + lv.customPound = lv.id + (dm != null ? ':mode=' + g_urlize(langref[dm].replace(' ', '')) : ''); + lv.customFilter = function(item) { return Listview.funcBox.filterMode(item, lv._totalCount, mode) }; + + lv.updateFilters(1); + lv.applySort(); + lv.refreshRows(); + if(updatePound) + lv.updatePound(1); + }; + + var lv = this, + modes = [], + a; + + a = $('' + LANG.pr_note_all + ''); + a[0].f = f.bind(a[0], null, null, 1); + a.click(a[0].f); + var firstCallback = f.bind(a[0], null, null, 0); + firstCallback(); + + modes.push($('').append(a).append($('' + LANG.pr_note_all + ''))); + + for(var j = 0, len = order.length; j < len; ++j) + { + var i = order[j]; + if(!this._lootModes[i]) + continue; + + a = $('' + langref[i] + ' (' + this._lootModes[i] + ')'); + a[0].f = f.bind(a[0], 1 << i + 2, i, 1); + a.click(a[0].f); + + if(i == 0) + firstCallback = f.bind(a[0], 1 << i + 2, i, 0); + + if((i < -1 || i > 2) && i != 5) + a.addClass('icon-heroic'); + + modes.push($('').append(a).append($(' 2 ? ' class="icon-heroic"' : '') + '>' + langref[i] + ' (' + this._lootModes[i] + ')'))); // jQuery is dumb + + if(pm && pm[1] == g_urlize(langref[i].replace(' ', ''))) + (a[0].f)(); + } + + var showNoteworthy = false; + for(var i = 0, len = modes.length; i < len; ++i) + { + a = $('a', modes[i]); + if(!$('span', a).html() && modes.length == 3) + showNoteworthy = true; + else + this.createIndicator(modes[i], null, a[0].f); + } + + if(showNoteworthy) + firstCallback(); + + $(this.noteTop).append($('
')); + }, + + filterMode: function(row, total, mode) + { + if(total != null && row.count != null) + { + if(row._count == null) + row._count = row.count; + + var count = row._count; + + if(mode != null && row.modes[mode]) + { + count = row.modes[mode].count; + total = row.modes[mode].outof; + } + + row.__tr = null; + row.count = count; + row.outof = total; + if(total) + row.percent = count / total * 100; + else + row.percent = count; + } + + return (mode != null ? ((!row.modes || row.modes.mode == 4) && row.classs != 12 && row.commondrop ? (mode == 32) : (row.modes && (row.modes.mode & mode))) : true); + }, + + initSubclassFilter: function(row) + { + var i = row.classs || 0; + if(this._itemClasses == null) + this._itemClasses = {}; + if(this._itemClasses[i] == null) + this._itemClasses[i] = 0; + this._itemClasses[i]++; + }, + + addSubclassIndicator: function() + { + var it = location.hash.match(/:type=([^:]+)/), + order = []; + + for(var i in g_item_classes) + order.push({ i: i, n: g_item_classes[i] }); + order.sort(function(a, b) { return $WH.strcmp(a.n, b.n) }); + + var f = function(itemClass, updatePound) + { + g_setSelectedLink(this, 'itemclass'); + + lv.customPound = lv.id + (itemClass != null ? ':type=' + itemClass : ''); + lv.customFilter = function(item) { return itemClass == null || itemClass == item.classs }; + + lv.updateFilters(1); + lv.applySort(); + lv.refreshRows(); + if(updatePound) + lv.updatePound(1); + } + + var lv = this, + classes = [], + a; + + a = $('' + LANG.pr_note_all + ''); + a[0].f = f.bind(a[0], null, 1); + a.click(a[0].f); + var firstCallback = f.bind(a[0], null, 0); + firstCallback(); + + classes.push($('').append(a).append($('' + LANG.pr_note_all + ''))); + + for(var j = 0, len = order.length; j < len; ++j) + { + var i = order[j].i; + if(!this._itemClasses[i]) + continue; + + a = $('' + g_item_classes[i] + ' (' + this._itemClasses[i] + ')'); + a[0].f = f.bind(a[0], i, 1); + a.click(a[0].f); + + classes.push($('').append(a).append($('' + g_item_classes[i] + ' (' + this._itemClasses[i] + ')'))); + + if(it && it[1] == g_urlize(i)) + (a[0].f)(); + } + + if(classes.length > 2) + { + for(var i = 0, len = classes.length; i < len; ++i) + this.createIndicator(classes[i], null, $('a', classes[i])[0].f); + + $(this.noteTop).css('padding-bottom', '12px'); + $(this.noteIndicators).append($('
')).insertAfter($(this.navTop)); + } + }, + + initStatisticFilter: function(row) + { + if(this._achievTypes == null) + this._achievTypes = {}; + if(this._achievTypes[row.type] == null) + this._achievTypes[row.type] = 0; + this._achievTypes[row.type]++; + }, + + addStatisticIndicator: function() + { + var it = location.hash.match(/:type=([^:]+)/), + order = []; + + for(var i in g_achievement_types) + order.push({ i: i, n: g_achievement_types[i] }); + order.sort(function(a, b) { return $WH.strcmp(a.n, b.n) }); + + var f = function(achievType, updatePound) + { + g_setSelectedLink(this, 'achievType'); + + lv.customPound = lv.id + (achievType != null ? ':type=' + achievType : ''); + lv.customFilter = function(achievement) { return achievType == null || achievType == achievement.type }; + + lv.updateFilters(1); + lv.applySort(); + lv.refreshRows(); + if(updatePound) + lv.updatePound(1); + }; + + var lv = this, + types = [], + a; + + a = $('' + LANG.pr_note_all + ''); + a[0].f = f.bind(a[0], null, 1); + a.click(a[0].f); + var firstCallback = f.bind(a[0], null, 0); + firstCallback(); + + types.push($('').append(a).append($('' + LANG.pr_note_all + ''))); + + for(var j = 0, len = order.length; j < len; ++j) + { + var i = order[j].i; + if(!this._achievTypes[i]) + continue; + + a = $('' + g_achievement_types[i] + ' (' + this._achievTypes[i] + ')'); + a[0].f = f.bind(a[0], i, 1); + a.click(a[0].f); + + types.push($('').append(a).append($('' + g_achievement_types[i] + ' (' + this._achievTypes[i] + ')'))); + + if(it && it[1] == i) + (a[0].f)(); + } + + if(types.length > 2) + { + for(var i = 0, len = types.length; i < len; ++i) + this.createIndicator(types[i], null, $('a', types[i])[0].f); + + $(this.noteTop).append($('
')); + } + }, + + initQuestFilter: function(row) + { + if(this._questTypes == null) + this._questTypes = {}; + + for(var i = 1; i <= 4; ++i) + { + if(this._questTypes[i] == null) + this._questTypes[i] = 0; + + if(row._type && (row._type & 1 << i - 1)) + this._questTypes[i]++; + } + }, + + addQuestIndicator: function() + { + var it = location.hash.match(/:type=([^:]+)/); + + var f = function(questType, updatePound) + { + g_setSelectedLink(this, 'questType'); + + lv.customPound = lv.id + (questType != null ? ':type=' + questType : ''); + lv.customFilter = function(quest) { return questType == null || (quest._type & 1 << questType - 1) }; + + lv.updateFilters(1); + lv.applySort(); + lv.refreshRows(); + if(updatePound) + lv.updatePound(1); + }; + + var lv = this, + types = [], + a; + + a = $('' + LANG.pr_note_all + ''); + a[0].f = f.bind(a[0], null, 1); + a.click(a[0].f); + var firstCallback = f.bind(a[0], null, 0); + firstCallback(); + + types.push($('').append(a).append($('' + LANG.pr_note_all + ''))); + + for(var i = 1; i <= 4; ++i) + { + if(!this._questTypes[i]) + continue; + + a = $('' + g_quest_indicators[i] + ' (' + this._questTypes[i] + ')'); + a[0].f = f.bind(a[0], i, 1); + a.click(a[0].f); + + types.push($('').append(a).append($('' + g_quest_indicators[i] + ' (' + this._questTypes[i] + ')'))); + + if(it && it[1] == i) + (a[0].f)(); + } + + if(types.length > 2) + { + for(var i = 0, len = types.length; i < len; ++i) + this.createIndicator(types[i], null, $('a', types[i])[0].f); + + $(this.noteTop).css('padding-bottom', '12px'); + $(this.noteIndicators).append($('
')).insertAfter($(this.navTop)); + } + }, + +// \\ subtabs here \\ assocArrCmp: function(a, b, arr) { if (a == null) { @@ -5441,29 +6071,43 @@ Listview.funcBox = { return 0 }, - location: function(row, td) { - if (row.location == null) { - return -1; - } + assocBinFlags: function(f, arr) { + var res = []; + for (var i in arr) { + if (!isNaN(i) && (f & 1 << i - 1)) { + res.push(i); + } + } + res.sort(function(a, b) { + return $WH.strcmp(arr[a], arr[b]); + }); - for (var i = 0, len = row.location.length; i < len; ++i) { - if (i > 0) { - $WH.ae(td, $WH.ct(LANG.comma)); - } + return res; + }, - var zoneId = row.location[i]; - if (zoneId == -1) { - $WH.ae(td, $WH.ct(LANG.ellipsis)); - } + location: function(row, td) { + if (row.location == null) { + return -1; + } + + for (var i = 0, len = row.location.length; i < len; ++i) { + if (i > 0) { + $WH.ae(td, $WH.ct(LANG.comma)); + } + + var zoneId = row.location[i]; + if (zoneId == -1) { + $WH.ae(td, $WH.ct(LANG.ellipsis)); + } else { - var a = $WH.ce('a'); - a.className = 'q1'; - a.href = '?zone=' + zoneId; - $WH.ae(a, $WH.ct(g_zones[zoneId])); - $WH.ae(td, a); - } - } - }, + var a = $WH.ce('a'); + a.className = 'q1'; + a.href = '?zone=' + zoneId; + $WH.ae(a, $WH.ct(g_zones[zoneId])); + $WH.ae(td, a); + } + } + }, arrayText: function(arr, lookup) { if (arr == null) { @@ -5601,53 +6245,53 @@ Listview.funcBox = { }, createSocketedIcons: function(sockets, td, gems, match, text) { - var + var nMatch = 0, d = $WH.ce('div'), d2 = $WH.ce('div'); for (var i = 0, len = sockets.length; i < len; ++i) { - var + var icon, gemId = gems[i]; - if (g_items && g_items[gemId]) { - icon = g_items.createIcon(gemId, 0); - } + if (g_items && g_items[gemId]) { + icon = g_items.createIcon(gemId, 0); + } else if ($WH.isset('g_gems') && g_gems && g_gems[gemId]) { - icon = Icon.create(g_gems[gemId].icon, 0, null, '?item=' + gemId); + icon = Icon.create(g_gems[gemId].icon, 0, null, '?item=' + gemId); } else { icon = Icon.create(null, 0, null, 'javascript:;'); - } + } icon.className += ' iconsmall-socket-' + g_file_gems[sockets[i]] + (!gems || !gemId ? '-empty': ''); - icon.style.cssFloat = icon.style.styleFloat = 'left'; + icon.style.cssFloat = icon.style.styleFloat = 'left'; - if (match && match[i]) { - icon.insertBefore($WH.ce('var'), icon.childNodes[1]); + if (match && match[i]) { + icon.insertBefore($WH.ce('var'), icon.childNodes[1]); ++nMatch; - } + } - $WH.ae(d, icon); - } + $WH.ae(d, icon); + } - d.style.margin = '0 auto'; - d.style.textAlign = 'left'; + d.style.margin = '0 auto'; + d.style.textAlign = 'left'; - d.style.width = (26 * sockets.length) + 'px'; - d2.className = 'clear'; + d.style.width = (26 * sockets.length) + 'px'; + d2.className = 'clear'; - $WH.ae(td, d); - $WH.ae(td, d2); + $WH.ae(td, d); + $WH.ae(td, d2); - if (text && nMatch == sockets.length) { - d = $WH.ce('div'); - d.style.paddingTop = '4px'; - $WH.ae(d, $WH.ct(text)); - $WH.ae(td, d); - } - }, + if (text && nMatch == sockets.length) { + d = $WH.ce('div'); + d.style.paddingTop = '4px'; + $WH.ae(d, $WH.ct(text)); + $WH.ae(td, d); + } + }, getItemType: function(itemClass, itemSubclass, itemSubsubclass) { if (itemSubsubclass != null && g_item_subsubclasses[itemClass] != null && g_item_subsubclasses[itemClass][itemSubclass] != null) { @@ -5674,66 +6318,15 @@ Listview.funcBox = { return g_quest_sorts[category]; }, - getQuestReputation: function(faction, quest) { - if (quest.reprewards) { - for (var c = 0, a = quest.reprewards.length; c < a; ++c) { - if (quest.reprewards[c][0] == faction) { - return quest.reprewards[c][1]; - } - } - } - }, - - getEventNextDates: function(startDate, endDate, recurrence, fromWhen) { - if (typeof startDate != 'string' || typeof endDate != 'string') { - return [null, null]; - } - - startDate = new Date(startDate.replace(/-/g, '/')); - endDate = new Date(endDate.replace(/-/g, '/')); - - if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) { - return [null, null]; - } - - if (fromWhen == null) { - fromWhen = g_serverTime; - } - - var offset = 0; - if (recurrence == -1) { // Once by month using day of the week of startDate - var nextEvent = new Date(fromWhen.getFullYear(), fromWhen.getMonth(), 1, startDate.getHours(), startDate.getMinutes(), startDate.getSeconds()); // counts as next until it ends - for (var i = 0; i < 2; ++i) { - nextEvent.setDate(1); - nextEvent.setMonth(nextEvent.getMonth() + i); // + 0 = try current month, else try next month - var day = nextEvent.getDay(); - var tolerance = 1; - if (nextEvent.getYear() == 2009) { - tolerance = 0; - } - if (day > tolerance) { - nextEvent.setDate(nextEvent.getDate() + (7 - day)); // first sunday - } - - var eventEnd = new Date(nextEvent); - eventEnd.setDate(eventEnd.getDate() + (7 - tolerance)); // 2010, length of 6. tolerance is 1 if it isnt 2009 - if (fromWhen.getTime() < eventEnd.getTime()) { - break; // event hasnt ended yet, so this is still the current one - } - } - - offset = nextEvent.getTime() - startDate.getTime(); - } - else if (recurrence > 0) { - recurrence *= 1000; // sec -> ms - offset = Math.ceil((fromWhen.getTime() - endDate.getTime()) / recurrence) * recurrence; + getQuestReputation: function(faction, quest) { + if (quest.reprewards) { + for (var c = 0, a = quest.reprewards.length; c < a; ++c) { + if (quest.reprewards[c][0] == faction) { + return quest.reprewards[c][1]; + } + } } - - startDate.setTime(startDate.getTime() + offset); - endDate.setTime(endDate.getTime() + offset); - - return [startDate, endDate]; - }, + }, getFactionCategory: function(category, category2) { if (category) { @@ -5744,6 +6337,57 @@ Listview.funcBox = { } }, + getEventNextDates: function(startDate, endDate, recurrence, fromWhen) { + if (typeof startDate != 'string' || typeof endDate != 'string') { + return [null, null]; + } + + startDate = new Date(startDate.replace(/-/g, '/')); + endDate = new Date(endDate.replace(/-/g, '/')); + + if (isNaN(startDate.getTime()) || isNaN(endDate.getTime())) { + return [null, null]; + } + + if (fromWhen == null) { + fromWhen = g_serverTime; + } + + var offset = 0; + if (recurrence == -1) { // Once by month using day of the week of startDate + var nextEvent = new Date(fromWhen.getFullYear(), fromWhen.getMonth(), 1, startDate.getHours(), startDate.getMinutes(), startDate.getSeconds()); // counts as next until it ends + for (var i = 0; i < 2; ++i) { + nextEvent.setDate(1); + nextEvent.setMonth(nextEvent.getMonth() + i); // + 0 = try current month, else try next month + var day = nextEvent.getDay(); + var tolerance = 1; + if (nextEvent.getYear() == 2009) { + tolerance = 0; + } + if (day > tolerance) { + nextEvent.setDate(nextEvent.getDate() + (7 - day)); // first sunday + } + + var eventEnd = new Date(nextEvent); + eventEnd.setDate(eventEnd.getDate() + (7 - tolerance)); // 2010, length of 6. tolerance is 1 if it isnt 2009 + if (fromWhen.getTime() < eventEnd.getTime()) { + break; // event hasnt ended yet, so this is still the current one + } + } + + offset = nextEvent.getTime() - startDate.getTime(); + } + else if (recurrence > 0) { + recurrence *= 1000; // sec -> ms + offset = Math.ceil((fromWhen.getTime() - endDate.getTime()) / recurrence) * recurrence; + } + + startDate.setTime(startDate.getTime() + offset); + endDate.setTime(endDate.getTime() + offset); + + return [startDate, endDate]; + }, + createTextRange: function(min, max) { min |= 0; max |= 0; @@ -5759,195 +6403,195 @@ Listview.funcBox = { return null; }, - coReport: function(d, b, f) { - if (!g_user.id || !g_report_reasons[f]) { - return - } - var a = ""; - if (f == 4 || f == 7) { - a = prompt(LANG.prompt_details, "") - } else { - if (d == 2) { - if (!confirm((f == 5 ? LANG.confirm_report3: LANG.confirm_report4))) { - return - } - } else { - if (!confirm($WH.sprintf((d == 0 ? LANG.confirm_report: LANG.confirm_report2), g_report_reasons[f]))) { - return - } - } - } - if (a != null) { - var e = "?report&type=" + d + "&typeid=" + b + "&reason=" + f; - if (a) { - e += "&reasonmore=" + $WH.urlencode(a) - } - new Ajax(e); - var c = $WH.ce("span"); - $WH.ae(c, $WH.ct(LANG.lvcomment_reported)); - this.parentNode.replaceChild(c, this) - } - }, - coReportClick: function(b, a, c) { - this.menu = [ + coReport: function(d, b, f) { + if (!g_user.id || !g_report_reasons[f]) { + return + } + var a = ""; + if (f == 4 || f == 7) { + a = prompt(LANG.prompt_details, "") + } else { + if (d == 2) { + if (!confirm((f == 5 ? LANG.confirm_report3: LANG.confirm_report4))) { + return + } + } else { + if (!confirm($WH.sprintf((d == 0 ? LANG.confirm_report: LANG.confirm_report2), g_report_reasons[f]))) { + return + } + } + } + if (a != null) { + var e = "?report&type=" + d + "&typeid=" + b + "&reason=" + f; + if (a) { + e += "&reasonmore=" + $WH.urlencode(a) + } + new Ajax(e); + var c = $WH.ce("span"); + $WH.ae(c, $WH.ct(LANG.lvcomment_reported)); + this.parentNode.replaceChild(c, this) + } + }, + coReportClick: function(b, a, c) { + this.menu = [ [2, g_report_reasons[2], Listview.funcBox.coReport.bind(this, a, b.id, 2)], [1, g_report_reasons[1], Listview.funcBox.coReport.bind(this, a, b.id, 1)], [3, g_report_reasons[3], Listview.funcBox.coReport.bind(this, a, b.id, 3)], [4, g_report_reasons[4], Listview.funcBox.coReport.bind(this, a, b.id, 4)] ]; - if (a == 1 && b.op && typeof g_pageInfo != "undefined" && !g_pageInfo.sticky) { - this.menu.splice(3, 0, [0, g_report_reasons[0], Listview.funcBox.coReport.bind(this, a, b.id, 0)]) - } - if (a == 1 && g_users[b.user].avatar == 2) { - this.menu.push([5, g_report_reasons[5], Listview.funcBox.coReport.bind(this, 2, g_users[b.user].avatarmore, 5)]) - } (Menu.showAtCursor.bind(this, c))() - }, - coGetColor: function(c, a, d) { - switch (a) { - case -1 : + if (a == 1 && b.op && typeof g_pageInfo != "undefined" && !g_pageInfo.sticky) { + this.menu.splice(3, 0, [0, g_report_reasons[0], Listview.funcBox.coReport.bind(this, a, b.id, 0)]) + } + if (a == 1 && g_users[b.user].avatar == 2) { + this.menu.push([5, g_report_reasons[5], Listview.funcBox.coReport.bind(this, 2, g_users[b.user].avatarmore, 5)]) + } (Menu.showAtCursor.bind(this, c))() + }, + coGetColor: function(c, a, d) { + switch (a) { + case -1 : var b = null; if (!d) { b = c.divPost.childNodes[1].className.match(/comment-([a-z]+)/); - } else { + } else { b = c.divBody[0].className.match(/comment-([a-z]+)/) } if (b != null) { - return " comment-" + b[1] - } - break; - case 3: - case 4: - if (c.roles & (U_GROUP_ADMIN | U_GROUP_BUREAU)) { - return " comment-blue" - } - if (c.roles & U_GROUP_GREEN_TEXT) { - return " comment-green" - } else { - if (c.roles & U_GROUP_VIP) { - return " comment-gold" - } - } - break - } - if (c.roles & (U_GROUP_ADMIN | U_GROUP_BUREAU)) { - return " comment-blue" - } else { - if (c.rating >= 10) { - return " comment-green" - } else { - if (c.rating < 0) { - return " comment-bt" - } - } - } - return "" - }, - coToggleVis: function(b) { + return " comment-" + b[1] + } + break; + case 3: + case 4: + if (c.roles & (U_GROUP_ADMIN | U_GROUP_BUREAU)) { + return " comment-blue" + } + if (c.roles & U_GROUP_GREEN_TEXT) { + return " comment-green" + } else { + if (c.roles & U_GROUP_VIP) { + return " comment-gold" + } + } + break + } + if (c.roles & (U_GROUP_ADMIN | U_GROUP_BUREAU)) { + return " comment-blue" + } else { + if (c.rating >= 10) { + return " comment-green" + } else { + if (c.rating < 0) { + return " comment-bt" + } + } + } + return "" + }, + coToggleVis: function(b) { var c = g_toggleDisplay(b.divBody); - this.firstChild.nodeValue = (c ? LANG.lvcomment_hide: LANG.lvcomment_show); - b.__div.className = $WH.trim(b.__div.className.replace("comment-collapsed", "")) + (c ? "": " comment-collapsed"); - var a = b.divHeader.firstChild.lastChild; - if (b.ratable) { - a.style.display = "" - } else { - if (b.deleted || b.purged) { - a.style.fontWeight = "normal"; - a.className = "q10"; - a.innerHTML = (b.deleted ? LANG.lvcomment_deleted: LANG.lvcomment_purged); - a.style.display = "" - } - } - g_toggleDisplay(b.divLinks); - if (b.lastEdit != null) { - g_toggleDisplay(b.divLastEdit) - } - }, - coDisplayRating: function(d, c) { - if (typeof(d._ratingMode) == "undefined") { - d._ratingMode = 0 - } - if (typeof(Listview._ratings) == "undefined") { - Listview._ratings = {} - } - var a = c; - var e = d._ratingMode; - if (e == 0) { - if (d.rating < 0) { - a.innerHTML = d.rating - } else { - a.innerHTML = "+" + d.rating - } - } - if (e == 1) { - if (Listview._ratings[d.id] !== undefined) { - var b = Listview._ratings[d.id]; - a.innerHTML = "+" + b.up + " / -" + b.down - } else { - new Ajax("?comment=rating&id=" + d.id, { - method: "get", - onSuccess: function(i, g) { + this.firstChild.nodeValue = (c ? LANG.lvcomment_hide: LANG.lvcomment_show); + b.__div.className = $WH.trim(b.__div.className.replace("comment-collapsed", "")) + (c ? "": " comment-collapsed"); + var a = b.divHeader.firstChild.lastChild; + if (b.ratable) { + a.style.display = "" + } else { + if (b.deleted || b.purged) { + a.style.fontWeight = "normal"; + a.className = "q10"; + a.innerHTML = (b.deleted ? LANG.lvcomment_deleted: LANG.lvcomment_purged); + a.style.display = "" + } + } + g_toggleDisplay(b.divLinks); + if (b.lastEdit != null) { + g_toggleDisplay(b.divLastEdit) + } + }, + coDisplayRating: function(d, c) { + if (typeof(d._ratingMode) == "undefined") { + d._ratingMode = 0 + } + if (typeof(Listview._ratings) == "undefined") { + Listview._ratings = {} + } + var a = c; + var e = d._ratingMode; + if (e == 0) { + if (d.rating < 0) { + a.innerHTML = d.rating + } else { + a.innerHTML = "+" + d.rating + } + } + if (e == 1) { + if (Listview._ratings[d.id] !== undefined) { + var b = Listview._ratings[d.id]; + a.innerHTML = "+" + b.up + " / -" + b.down + } else { + new Ajax("?comment=rating&id=" + d.id, { + method: "get", + onSuccess: function(i, g) { var f = JSON.parse(g.responseText); - if (f.success) { - Listview._ratings[i] = f; - this.innerHTML = "+" + f.up + " / -" + f.down - } else { - this.innerHTML = "Error!" - } - }.bind(a, d.id) - }); - a.innerHTML = ''; - } - } - }, - coToggleRating: function(b, a) { - if (typeof(b._ratingMode) == "undefined") { - b._ratingMode = 0 - } - if (++b._ratingMode > 1) { - b._ratingMode = 0 - } - Listview.funcBox.coDisplayRating(b, a) - }, - coRate: function(e, a) { - if (a == 0) { - var c = 5; - if (g_user.roles & U_GROUP_ADMIN) { - c = 25 - } else { - if (g_user.roles & U_GROUP_BUREAU) { - c = 15 - } - } - var d = prompt($WH.sprintf(LANG.prompt_customrating, c, c), 0); - if (d == null) { - return - } else { - d |= 0; - if (d != 0 && Math.abs(d) <= c) { - a = d - } - } - if (a == 0) { - return - } - } else { - if (g_user.roles & U_GROUP_COMMENTS_MODERATOR) { - a *= 5 - } - } - e.rating += a; - e.raters.push([g_user.id, a]); - var b = e.divHeader.firstChild; - $WH.Tooltip.hide(); - b = b.childNodes[b.childNodes.length - 3]; + if (f.success) { + Listview._ratings[i] = f; + this.innerHTML = "+" + f.up + " / -" + f.down + } else { + this.innerHTML = "Error!" + } + }.bind(a, d.id) + }); + a.innerHTML = ''; + } + } + }, + coToggleRating: function(b, a) { + if (typeof(b._ratingMode) == "undefined") { + b._ratingMode = 0 + } + if (++b._ratingMode > 1) { + b._ratingMode = 0 + } + Listview.funcBox.coDisplayRating(b, a) + }, + coRate: function(e, a) { + if (a == 0) { + var c = 5; + if (g_user.roles & U_GROUP_ADMIN) { + c = 25 + } else { + if (g_user.roles & U_GROUP_BUREAU) { + c = 15 + } + } + var d = prompt($WH.sprintf(LANG.prompt_customrating, c, c), 0); + if (d == null) { + return + } else { + d |= 0; + if (d != 0 && Math.abs(d) <= c) { + a = d + } + } + if (a == 0) { + return + } + } else { + if (g_user.roles & U_GROUP_COMMENTS_MODERATOR) { + a *= 5 + } + } + e.rating += a; + e.raters.push([g_user.id, a]); + var b = e.divHeader.firstChild; + $WH.Tooltip.hide(); + b = b.childNodes[b.childNodes.length - 3]; var f = $WH.ge("commentrating" + e.id); Listview.funcBox.coDisplayRating(e, f); - $WH.de(b.nextSibling); - $WH.de(b.nextSibling); - new Ajax("?comment=rate&id=" + e.id + "&rating=" + a, { - method: "get", - onSuccess: function(e) { + $WH.de(b.nextSibling); + $WH.de(b.nextSibling); + new Ajax("?comment=rate&id=" + e.id + "&rating=" + a, { + method: "get", + onSuccess: function(e) { if (e.responseText == "0") {} else { if (e.responseText == "1") { b.innerHTML = LANG.tooltip_banned_rating; @@ -5959,255 +6603,255 @@ Listview.funcBox = { } } } - } + } }); - }, - coDelete: function(a) { - if (a.purged) { - alert(LANG.message_cantdeletecomment) - } else { - if (confirm(LANG.confirm_deletecomment)) { - new Ajax("?comment=delete&id=" + a.id); - this.deleteRows([a]) - } - } - }, - coDetach: function(a) { - if (a.replyTo == 0) { - alert(LANG.message_cantdetachcomment) - } else { - if (confirm(LANG.confirm_detachcomment)) { - new Ajax("?comment=detach&id=" + a.id); - a.replyTo = 0; - alert(LANG.message_commentdetached) - } - } - }, - coEdit: function(g, e, c) { - if (!c) { - g.divBody.style.display = "none"; - g.divResponse.style.display = "none"; - g.divLinks.firstChild.style.display = "none" - } else { - g.divBody.hide(); - g.divResponse.hide() - } - var f = $WH.ce("div"); - f.className = "comment-edit"; - g.divEdit = f; - if (e == -1) { - if (g_users[g.user] != null) { - g.roles = g_users[g.user].roles - } - } - var a = Listview.funcBox.coEditAppend(f, g, e, c); - var b = $WH.ce("div"); - b.className = "comment-edit-buttons"; - var d = $WH.ce("input"); - d.type = "button"; - d.value = LANG.compose_save; - d.onclick = Listview.funcBox.coEditButton.bind(d, g, true, e, c); - $WH.ae(b, d); - $WH.ae(b, $WH.ct(" ")); - d = $WH.ce("input"); - d.type = "button"; - d.value = LANG.compose_cancel; - d.onclick = Listview.funcBox.coEditButton.bind(d, g, false, e, c); - $WH.ae(b, d); - $WH.ae(f, b); - var c = f; - if ($WH.Browser.ie6) { - c = $WH.ce("div"); - c.style.width = "99%"; - $WH.ae(c, f) - } + }, + coDelete: function(a) { + if (a.purged) { + alert(LANG.message_cantdeletecomment) + } else { + if (confirm(LANG.confirm_deletecomment)) { + new Ajax("?comment=delete&id=" + a.id); + this.deleteRows([a]) + } + } + }, + coDetach: function(a) { + if (a.replyTo == 0) { + alert(LANG.message_cantdetachcomment) + } else { + if (confirm(LANG.confirm_detachcomment)) { + new Ajax("?comment=detach&id=" + a.id); + a.replyTo = 0; + alert(LANG.message_commentdetached) + } + } + }, + coEdit: function(g, e, c) { + if (!c) { + g.divBody.style.display = "none"; + g.divResponse.style.display = "none"; + g.divLinks.firstChild.style.display = "none" + } else { + g.divBody.hide(); + g.divResponse.hide() + } + var f = $WH.ce("div"); + f.className = "comment-edit"; + g.divEdit = f; + if (e == -1) { + if (g_users[g.user] != null) { + g.roles = g_users[g.user].roles + } + } + var a = Listview.funcBox.coEditAppend(f, g, e, c); + var b = $WH.ce("div"); + b.className = "comment-edit-buttons"; + var d = $WH.ce("input"); + d.type = "button"; + d.value = LANG.compose_save; + d.onclick = Listview.funcBox.coEditButton.bind(d, g, true, e, c); + $WH.ae(b, d); + $WH.ae(b, $WH.ct(" ")); + d = $WH.ce("input"); + d.type = "button"; + d.value = LANG.compose_cancel; + d.onclick = Listview.funcBox.coEditButton.bind(d, g, false, e, c); + $WH.ae(b, d); + $WH.ae(f, b); + var c = f; + if ($WH.Browser.ie6) { + c = $WH.ce("div"); + c.style.width = "99%"; + $WH.ae(c, f) + } $WH.ae(g.divBody.parentNode, f) - a.focus() - }, - coEditAppend: function(m, b, l, X, x) { - var f = Listview.funcBox.coGetCharLimit(l); - if (l == 1 || l == 3 || l == 4) { - b.user = g_user.name; - b.roles = g_user.roles; - b.rating = 1 - } else { - if (l == 2) { - b.roles = g_user.roles; - b.rating = 1 - } - } - if (x) { - b.roles &= ~U_GROUP_PENDING - } - if (l == -1 || l == 0) { - var j = $WH.ce("div"); - j.className = "comment-edit-modes"; - $WH.ae(j, $WH.ct(LANG.compose_mode)); - var p = $WH.ce("a"); - p.className = "selected"; - p.onclick = Listview.funcBox.coModeLink.bind(p, 1, l, b); - p.href = "javascript:;"; - $WH.ae(p, $WH.ct(LANG.compose_edit)); - $WH.ae(j, p); - $WH.ae(j, $WH.ct("|")); - var w = $WH.ce("a"); - w.onclick = Listview.funcBox.coModeLink.bind(w, 2, l, b); - w.href = "javascript:;"; - $WH.ae(w, $WH.ct(LANG.compose_preview)); - $WH.ae(j, w); - $WH.ae(m, j) - } - var a = $WH.ce("div"); - a.style.display = "none"; - a.className = "comment-body" + Listview.funcBox.coGetColor(b, l); - $WH.ae(m, a); - var h = $WH.ce("div"); - h.className = "comment-edit-body"; - var e = $WH.ce("div"); - e.className = "toolbar"; + a.focus() + }, + coEditAppend: function(m, b, l, X, x) { + var f = Listview.funcBox.coGetCharLimit(l); + if (l == 1 || l == 3 || l == 4) { + b.user = g_user.name; + b.roles = g_user.roles; + b.rating = 1 + } else { + if (l == 2) { + b.roles = g_user.roles; + b.rating = 1 + } + } + if (x) { + b.roles &= ~U_GROUP_PENDING + } + if (l == -1 || l == 0) { + var j = $WH.ce("div"); + j.className = "comment-edit-modes"; + $WH.ae(j, $WH.ct(LANG.compose_mode)); + var p = $WH.ce("a"); + p.className = "selected"; + p.onclick = Listview.funcBox.coModeLink.bind(p, 1, l, b); + p.href = "javascript:;"; + $WH.ae(p, $WH.ct(LANG.compose_edit)); + $WH.ae(j, p); + $WH.ae(j, $WH.ct("|")); + var w = $WH.ce("a"); + w.onclick = Listview.funcBox.coModeLink.bind(w, 2, l, b); + w.href = "javascript:;"; + $WH.ae(w, $WH.ct(LANG.compose_preview)); + $WH.ae(j, w); + $WH.ae(m, j) + } + var a = $WH.ce("div"); + a.style.display = "none"; + a.className = "comment-body" + Listview.funcBox.coGetColor(b, l); + $WH.ae(m, a); + var h = $WH.ce("div"); + h.className = "comment-edit-body"; + var e = $WH.ce("div"); + e.className = "toolbar"; e.style.cssFloat = "left"; - var i = $WH.ce("div"); - i.className = "menu-buttons"; + var i = $WH.ce("div"); + i.className = "menu-buttons"; i.style.cssFloat = "left"; - var g = $WH.ce("textarea"); - g.className = "comment-editbox"; - g.rows = 10; + var g = $WH.ce("textarea"); + g.className = "comment-editbox"; + g.rows = 10; g.style.clear = "left"; - g.value = b.body; - switch (l) { - case 1: - g.name = "commentbody"; - break; - case 2: - g.name = "desc"; - g.originalValue = b.body; - break; - case 3: - g.name = "body"; - break; - case 4: - g.name = "sig"; - g.originalValue = b.body; - g.rows = ($WH.Browser.firefox ? 2 : 3); - g.style.height = "auto"; - break - } - if (l != -1 && l != 0) { - var d = $WH.ce("h3"), - y = $WH.ce("a"), - v = $WH.ce("div"), - u = $WH.ce("div"); - var c = Listview.funcBox.coLivePreview.bind(g, b, l, v); - if (b.body) { - y.className = "disclosure-off"; - v.style.display = "none" - } else { - y.className = "disclosure-on" - } - $WH.ae(y, $WH.ct(LANG.compose_livepreview)); - $WH.ae(d, y); - y.href = "javascript:;"; - y.onclick = function() { - c(1); - y.className = "disclosure-" + (g_toggleDisplay(v) ? "on": "off") - }; - $WH.ns(y); - d.className = "first"; - u.className = "pad"; - $WH.ae(a, d); - $WH.ae(a, v); - $WH.ae(a, u); - g_onAfterTyping(g, c, 50); - $WH.aE(g, "focus", function() { - c(); - a.style.display = ""; - if (l != 4) { - g.style.height = "22em" - } - }) - } else { - if (l != 4) { - $WH.aE(g, "focus", function() { - g.style.height = "22em" - }) - } - } - var t = [{ - id: "b", - title: LANG.markup_b, - pre: "[b]", - post: "[/b]" - }, - { - id: "i", - title: LANG.markup_i, - pre: "[i]", - post: "[/i]" - }, - { - id: "u", - title: LANG.markup_u, - pre: "[u]", - post: "[/u]" - }, - { - id: "s", - title: LANG.markup_s, - pre: "[s]", - post: "[/s]" - }, - { - id: "small", - title: LANG.markup_small, - pre: "[small]", - post: "[/small]" - }, - { - id: "url", - title: LANG.markup_url, - onclick: function() { - var i = prompt(LANG.prompt_linkurl, "http://"); - if (i) { - g_insertTag(g, "[url=" + i + "]", "[/url]") - } - } - }, - { - id: "quote", - title: LANG.markup_quote, - pre: "[quote]", - post: "[/quote]" - }, - { - id: "code", - title: LANG.markup_code, - pre: "[code]", - post: "[/code]" - }, - { - id: "ul", - title: LANG.markup_ul, - pre: "[ul]\n[li]", - post: "[/li]\n[/ul]", - rep: function(i) { - return i.replace(/\n/g, "[/li]\n[li]") - } - }, - { - id: "ol", - title: LANG.markup_ol, - pre: "[ol]\n[li]", - post: "[/li]\n[/ol]", - rep: function(i) { - return i.replace(/\n/g, "[/li]\n[li]") - } - }, - { - id: "li", - title: LANG.markup_li, - pre: "[li]", - post: "[/li]" - }]; + g.value = b.body; + switch (l) { + case 1: + g.name = "commentbody"; + break; + case 2: + g.name = "desc"; + g.originalValue = b.body; + break; + case 3: + g.name = "body"; + break; + case 4: + g.name = "sig"; + g.originalValue = b.body; + g.rows = ($WH.Browser.firefox ? 2 : 3); + g.style.height = "auto"; + break + } + if (l != -1 && l != 0) { + var d = $WH.ce("h3"), + y = $WH.ce("a"), + v = $WH.ce("div"), + u = $WH.ce("div"); + var c = Listview.funcBox.coLivePreview.bind(g, b, l, v); + if (b.body) { + y.className = "disclosure-off"; + v.style.display = "none" + } else { + y.className = "disclosure-on" + } + $WH.ae(y, $WH.ct(LANG.compose_livepreview)); + $WH.ae(d, y); + y.href = "javascript:;"; + y.onclick = function() { + c(1); + y.className = "disclosure-" + (g_toggleDisplay(v) ? "on": "off") + }; + $WH.ns(y); + d.className = "first"; + u.className = "pad"; + $WH.ae(a, d); + $WH.ae(a, v); + $WH.ae(a, u); + g_onAfterTyping(g, c, 50); + $WH.aE(g, "focus", function() { + c(); + a.style.display = ""; + if (l != 4) { + g.style.height = "22em" + } + }) + } else { + if (l != 4) { + $WH.aE(g, "focus", function() { + g.style.height = "22em" + }) + } + } + var t = [{ + id: "b", + title: LANG.markup_b, + pre: "[b]", + post: "[/b]" + }, + { + id: "i", + title: LANG.markup_i, + pre: "[i]", + post: "[/i]" + }, + { + id: "u", + title: LANG.markup_u, + pre: "[u]", + post: "[/u]" + }, + { + id: "s", + title: LANG.markup_s, + pre: "[s]", + post: "[/s]" + }, + { + id: "small", + title: LANG.markup_small, + pre: "[small]", + post: "[/small]" + }, + { + id: "url", + title: LANG.markup_url, + onclick: function() { + var i = prompt(LANG.prompt_linkurl, "http://"); + if (i) { + g_insertTag(g, "[url=" + i + "]", "[/url]") + } + } + }, + { + id: "quote", + title: LANG.markup_quote, + pre: "[quote]", + post: "[/quote]" + }, + { + id: "code", + title: LANG.markup_code, + pre: "[code]", + post: "[/code]" + }, + { + id: "ul", + title: LANG.markup_ul, + pre: "[ul]\n[li]", + post: "[/li]\n[/ul]", + rep: function(i) { + return i.replace(/\n/g, "[/li]\n[li]") + } + }, + { + id: "ol", + title: LANG.markup_ol, + pre: "[ol]\n[li]", + post: "[/li]\n[/ol]", + rep: function(i) { + return i.replace(/\n/g, "[/li]\n[li]") + } + }, + { + id: "li", + title: LANG.markup_li, + pre: "[li]", + post: "[/li]" + }]; if (!X) { for (var q = 0, r = t.length; q < r; ++q) { var k = t[q]; @@ -6233,33 +6877,33 @@ Listview.funcBox = { $WH.ae(e, o) } } else { - for (var B = 0, C = t.length; B < C; ++B) { - var q = t[B]; - if ((g_user.rolls & U_GROUP_PENDING) && q.nopending) { - continue - } - var H = "tb-" + q.id; - var V = $WH.ce('button'); - V.onclick = function(i, L) { + for (var B = 0, C = t.length; B < C; ++B) { + var q = t[B]; + if ((g_user.rolls & U_GROUP_PENDING) && q.nopending) { + continue + } + var H = "tb-" + q.id; + var V = $WH.ce('button'); + V.onclick = function(i, L) { L.preventDefault(); (i.onclick != null ? i.onclick: g_insertTag.bind(0, g, i.pre, i.post, i.rep))() }; V.bind(null, q); - V.className = H; - V.title = q.title; - V[0].setAttribute("type", "button"); - $WH.ae(V, $WH.ce('ins')); - $WH.ae(e, V); - } - e.className += " formatting button sm"; - } - var r = function(L, i) { - var M = prompt($WH.sprintf(LANG.markup_prompt, L), ""); - if (M != null) { - g_insertTag(g, "[" + i + "=" + (parseInt(M) || 0) + "]", "") - } - }; - var A = [[0, LANG.markup_links, , [ + V.className = H; + V.title = q.title; + V[0].setAttribute("type", "button"); + $WH.ae(V, $WH.ce('ins')); + $WH.ae(e, V); + } + e.className += " formatting button sm"; + } + var r = function(L, i) { + var M = prompt($WH.sprintf(LANG.markup_prompt, L), ""); + if (M != null) { + g_insertTag(g, "[" + i + "=" + (parseInt(M) || 0) + "]", "") + } + }; + var A = [[0, LANG.markup_links, , [ [9, LANG.types[10][0] + "...", r.bind(null, LANG.types[10][1], "achievement")], [11, LANG.types[13][0] + "...", r.bind(null, LANG.types[13][1], "class")], [7, LANG.types[8][0] + "...", r.bind(null, LANG.types[8][1], "faction")], @@ -6278,730 +6922,762 @@ Listview.funcBox = { $WH.ae(di, e); $WH.ae(di, i); $WH.ae(h, di); - $WH.ae(h, $WH.ce("div")); - $WH.ae(h, g); - $WH.ae(h, $WH.ce("br")); - Menu.addButtons(i, A); - if (l == 4) { - $WH.ae(h, $WH.ct($WH.sprintf(LANG.compose_limit2, f, 3))) - } else { - $WH.ae(h, $WH.ct($WH.sprintf(LANG.compose_limit, f))) - } + $WH.ae(h, $WH.ce("div")); + $WH.ae(h, g); + $WH.ae(h, $WH.ce("br")); + Menu.addButtons(i, A); + if (l == 4) { + $WH.ae(h, $WH.ct($WH.sprintf(LANG.compose_limit2, f, 3))) + } else { + $WH.ae(h, $WH.ct($WH.sprintf(LANG.compose_limit, f))) + } var A = $WH.ce('span'); A.className = "comment-remaining"; $WH.ae(A, $WH.ct($WH.sprintf(LANG.compose_remaining, l - b.body.length))); $WH.ae(h, A); - g.onkeyup = Listview.funcBox.coUpdateCharLimit.bind(0, g, A, f); - g.onkeydown = Listview.funcBox.coUpdateCharLimit.bind(0, g, A, f); - if ((l == -1 || l == 0) && g_user.roles & U_GROUP_MODERATOR) { - var B = $WH.ce("div"); + g.onkeyup = Listview.funcBox.coUpdateCharLimit.bind(0, g, A, f); + g.onkeydown = Listview.funcBox.coUpdateCharLimit.bind(0, g, A, f); + if ((l == -1 || l == 0) && g_user.roles & U_GROUP_MODERATOR) { + var B = $WH.ce("div"); B.classname = "pad"; - var W = $WH.ce("div"); - $WH.ae(W, $WH.ct((g_user.roles & U_GROUP_ADMIN ? "Admin": "Moderator") + " response")); - var p = $WH.ce("textarea"); + var W = $WH.ce("div"); + $WH.ae(W, $WH.ct((g_user.roles & U_GROUP_ADMIN ? "Admin": "Moderator") + " response")); + var p = $WH.ce("textarea"); p.value = b.response; p.rows = 3; - p.style.height = "6em"; - $WH.ae(h, B); - $WH.ae(h, w); - $WH.ae(h, p) - } - $WH.ae(m, h); - $WH.ae(m, $WH.ce('div')); - $WH.ae(m, a); + p.style.height = "6em"; + $WH.ae(h, B); + $WH.ae(h, w); + $WH.ae(h, p) + } + $WH.ae(m, h); + $WH.ae(m, $WH.ce('div')); + $WH.ae(m, a); - return g - }, + return g + }, /* - coEditAppend: function(m, b, l) { - var f = Listview.funcBox.coGetCharLimit(l); - if (l == 1 || l == 3 || l == 4) { - b.user = g_user.name; - b.roles = g_user.roles; - b.rating = 1 - } else { - if (l == 2) { - b.roles = g_user.roles; - b.rating = 1 - } - } - if (l == -1 || l == 0) { - var j = $WH.ce("div"); - j.className = "comment-edit-modes"; - $WH.ae(j, $WH.ct(LANG.compose_mode)); - var p = $WH.ce("a"); - p.className = "selected"; - p.onclick = Listview.funcBox.coModeLink.bind(p, 1, l, b); - p.href = "javascript:;"; - $WH.ae(p, $WH.ct(LANG.compose_edit)); - $WH.ae(j, p); - $WH.ae(j, $WH.ct("|")); - var w = $WH.ce("a"); - w.onclick = Listview.funcBox.coModeLink.bind(w, 2, l, b); - w.href = "javascript:;"; - $WH.ae(w, $WH.ct(LANG.compose_preview)); - $WH.ae(j, w); - $WH.ae(m, j) - } - var a = $WH.ce("div"); - a.style.display = "none"; - a.className = "comment-body" + Listview.funcBox.coGetColor(b, l); - $WH.ae(m, a); - var h = $WH.ce("div"); - h.className = "comment-edit-body"; - var e = $WH.ce("div"); - e.className = "toolbar"; - var g = $WH.ce("textarea"); - g.className = "comment-editbox"; - g.rows = 10; - g.value = b.body; - switch (l) { - case 1: - g.name = "commentbody"; - g.onfocus = g_revealCaptcha; - break; - case 2: - g.name = "desc"; - g.originalValue = b.body; - break; - case 3: - g.name = "body"; - g.onfocus = g_revealCaptcha; - break; - case 4: - g.name = "sig"; - g.originalValue = b.body; - g.rows = ($WH.Browser(gecko ? 2 : 3); - g.style.height = "auto"; - break - } - if (l != -1 && l != 0) { - var d = $WH.ce("h3"), - y = $WH.ce("a"), - v = $WH.ce("div"), - u = $WH.ce("div"); - var c = Listview.funcBox.coLivePreview.bind(g, b, l, v); - if (b.body) { - y.className = "disclosure-off"; - v.style.display = "none" - } else { - y.className = "disclosure-on" - } - $WH.ae(y, $WH.ct(LANG.compose_livepreview)); - $WH.ae(d, y); - y.href = "javascript:;"; - y.onclick = function() { - c(1); - y.className = "disclosure-" + (g_toggleDisplay(v) ? "on": "off") - }; - $WH.ns(y); - d.className = "first"; - u.className = "pad"; - $WH.ae(a, d); - $WH.ae(a, v); - $WH.ae(a, u); - g_onAfterTyping(g, c, 50); - $WH.aE(g, "focus", function() { - c(); - a.style.display = ""; - if (l != 4) { - g.style.height = "22em" - } - }) - } else { - if (l != 4) { - $WH.aE(g, "focus", function() { - g.style.height = "22em" - }) - } - } - var t = [{ - id: "b", - title: LANG.markup_b, - pre: "[b]", - post: "[/b]" - }, - { - id: "i", - title: LANG.markup_i, - pre: "[i]", - post: "[/i]" - }, - { - id: "u", - title: LANG.markup_u, - pre: "[u]", - post: "[/u]" - }, - { - id: "s", - title: LANG.markup_s, - pre: "[s]", - post: "[/s]" - }, - { - id: "small", - title: LANG.markup_small, - pre: "[small]", - post: "[/small]" - }, - { - id: "url", - title: LANG.markup_url, - onclick: function() { - var i = prompt(LANG.prompt_linkurl, "http://"); - if (i) { - g_insertTag(g, "[url=" + i + "]", "[/url]") - } - } - }, - { - id: "quote", - title: LANG.markup_quote, - pre: "[quote]", - post: "[/quote]" - }, - { - id: "code", - title: LANG.markup_code, - pre: "[code]", - post: "[/code]" - }, - { - id: "ul", - title: LANG.markup_ul, - pre: "[ul]\n[li]", - post: "[/li]\n[/ul]", - rep: function(i) { - return i.replace(/\n/g, "[/li]\n[li]") - } - }, - { - id: "ol", - title: LANG.markup_ol, - pre: "[ol]\n[li]", - post: "[/li]\n[/ol]", - rep: function(i) { - return i.replace(/\n/g, "[/li]\n[li]") - } - }, - { - id: "li", - title: LANG.markup_li, - pre: "[li]", - post: "[/li]" - }]; - for (var q = 0, r = t.length; q < r; ++q) { - var k = t[q]; - if (l == 4 && k.id == "quote") { - break - } - var o = $WH.ce("button"); - var z = $WH.ce("img"); - o.setAttribute("type", "button"); - o.title = k.title; - if (k.onclick != null) { - o.onclick = k.onclick - } else { - o.onclick = g_insertTag.bind(0, g, k.pre, k.post, k.rep) - } - z.src = "template/images/pixel.gif"; - z.className = "toolbar-" + k.id; - $WH.ae(o, z); - $WH.ae(e, o) - } - $WH.ae(h, e); - $WH.ae(h, g); - $WH.ae(h, $WH.ce("br")); - if (l == 4) { - $WH.ae(h, $WH.ct($WH.sprintf(LANG.compose_limit2, f, 3))) - } else { - $WH.ae(h, $WH.ct($WH.sprintf(LANG.compose_limit, f))) - } - $WH.ae(m, h); - return g - }, + coEditAppend: function(m, b, l) { + var f = Listview.funcBox.coGetCharLimit(l); + if (l == 1 || l == 3 || l == 4) { + b.user = g_user.name; + b.roles = g_user.roles; + b.rating = 1 + } else { + if (l == 2) { + b.roles = g_user.roles; + b.rating = 1 + } + } + if (l == -1 || l == 0) { + var j = $WH.ce("div"); + j.className = "comment-edit-modes"; + $WH.ae(j, $WH.ct(LANG.compose_mode)); + var p = $WH.ce("a"); + p.className = "selected"; + p.onclick = Listview.funcBox.coModeLink.bind(p, 1, l, b); + p.href = "javascript:;"; + $WH.ae(p, $WH.ct(LANG.compose_edit)); + $WH.ae(j, p); + $WH.ae(j, $WH.ct("|")); + var w = $WH.ce("a"); + w.onclick = Listview.funcBox.coModeLink.bind(w, 2, l, b); + w.href = "javascript:;"; + $WH.ae(w, $WH.ct(LANG.compose_preview)); + $WH.ae(j, w); + $WH.ae(m, j) + } + var a = $WH.ce("div"); + a.style.display = "none"; + a.className = "comment-body" + Listview.funcBox.coGetColor(b, l); + $WH.ae(m, a); + var h = $WH.ce("div"); + h.className = "comment-edit-body"; + var e = $WH.ce("div"); + e.className = "toolbar"; + var g = $WH.ce("textarea"); + g.className = "comment-editbox"; + g.rows = 10; + g.value = b.body; + switch (l) { + case 1: + g.name = "commentbody"; + g.onfocus = g_revealCaptcha; + break; + case 2: + g.name = "desc"; + g.originalValue = b.body; + break; + case 3: + g.name = "body"; + g.onfocus = g_revealCaptcha; + break; + case 4: + g.name = "sig"; + g.originalValue = b.body; + g.rows = ($WH.Browser(gecko ? 2 : 3); + g.style.height = "auto"; + break + } + if (l != -1 && l != 0) { + var d = $WH.ce("h3"), + y = $WH.ce("a"), + v = $WH.ce("div"), + u = $WH.ce("div"); + var c = Listview.funcBox.coLivePreview.bind(g, b, l, v); + if (b.body) { + y.className = "disclosure-off"; + v.style.display = "none" + } else { + y.className = "disclosure-on" + } + $WH.ae(y, $WH.ct(LANG.compose_livepreview)); + $WH.ae(d, y); + y.href = "javascript:;"; + y.onclick = function() { + c(1); + y.className = "disclosure-" + (g_toggleDisplay(v) ? "on": "off") + }; + $WH.ns(y); + d.className = "first"; + u.className = "pad"; + $WH.ae(a, d); + $WH.ae(a, v); + $WH.ae(a, u); + g_onAfterTyping(g, c, 50); + $WH.aE(g, "focus", function() { + c(); + a.style.display = ""; + if (l != 4) { + g.style.height = "22em" + } + }) + } else { + if (l != 4) { + $WH.aE(g, "focus", function() { + g.style.height = "22em" + }) + } + } + var t = [{ + id: "b", + title: LANG.markup_b, + pre: "[b]", + post: "[/b]" + }, + { + id: "i", + title: LANG.markup_i, + pre: "[i]", + post: "[/i]" + }, + { + id: "u", + title: LANG.markup_u, + pre: "[u]", + post: "[/u]" + }, + { + id: "s", + title: LANG.markup_s, + pre: "[s]", + post: "[/s]" + }, + { + id: "small", + title: LANG.markup_small, + pre: "[small]", + post: "[/small]" + }, + { + id: "url", + title: LANG.markup_url, + onclick: function() { + var i = prompt(LANG.prompt_linkurl, "http://"); + if (i) { + g_insertTag(g, "[url=" + i + "]", "[/url]") + } + } + }, + { + id: "quote", + title: LANG.markup_quote, + pre: "[quote]", + post: "[/quote]" + }, + { + id: "code", + title: LANG.markup_code, + pre: "[code]", + post: "[/code]" + }, + { + id: "ul", + title: LANG.markup_ul, + pre: "[ul]\n[li]", + post: "[/li]\n[/ul]", + rep: function(i) { + return i.replace(/\n/g, "[/li]\n[li]") + } + }, + { + id: "ol", + title: LANG.markup_ol, + pre: "[ol]\n[li]", + post: "[/li]\n[/ol]", + rep: function(i) { + return i.replace(/\n/g, "[/li]\n[li]") + } + }, + { + id: "li", + title: LANG.markup_li, + pre: "[li]", + post: "[/li]" + }]; + for (var q = 0, r = t.length; q < r; ++q) { + var k = t[q]; + if (l == 4 && k.id == "quote") { + break + } + var o = $WH.ce("button"); + var z = $WH.ce("img"); + o.setAttribute("type", "button"); + o.title = k.title; + if (k.onclick != null) { + o.onclick = k.onclick + } else { + o.onclick = g_insertTag.bind(0, g, k.pre, k.post, k.rep) + } + z.src = "template/images/pixel.gif"; + z.className = "toolbar-" + k.id; + $WH.ae(o, z); + $WH.ae(e, o) + } + $WH.ae(h, e); + $WH.ae(h, g); + $WH.ae(h, $WH.ce("br")); + if (l == 4) { + $WH.ae(h, $WH.ct($WH.sprintf(LANG.compose_limit2, f, 3))) + } else { + $WH.ae(h, $WH.ct($WH.sprintf(LANG.compose_limit, f))) + } + $WH.ae(m, h); + return g + }, */ - coLivePreview: function(f, e, a, b) { + coLivePreview: function(f, e, a, b) { if (b != 1 && a.style.display == "none") { - return - } - var c = this, - i = Listview.funcBox.coGetCharLimit(e), - g = (c.value.length > i ? c.value.substring(0, i) : c.value); - if (e == 4) { - var h; - if ((h = g.indexOf("\n")) != -1 && (h = g.indexOf("\n", h + 1)) != -1 && (h = g.indexOf("\n", h + 1)) != -1) { - g = g.substring(0, h) - } - } - var d = Markup.toHtml(g, { - mode: Markup.MODE_COMMENT, - roles: f.roles - }); - if (d) { - a.innerHTML = d - } else { - a.innerHTML = '...' - } - }, - coEditButton: function(f, d, e, k) { - if (d) { - var a = $WH.gE(f.divEdit, "textarea"); + return + } + var c = this, + i = Listview.funcBox.coGetCharLimit(e), + g = (c.value.length > i ? c.value.substring(0, i) : c.value); + if (e == 4) { + var h; + if ((h = g.indexOf("\n")) != -1 && (h = g.indexOf("\n", h + 1)) != -1 && (h = g.indexOf("\n", h + 1)) != -1) { + g = g.substring(0, h) + } + } + var d = Markup.toHtml(g, { + mode: Markup.MODE_COMMENT, + roles: f.roles + }); + if (d) { + a.innerHTML = d + } else { + a.innerHTML = '...' + } + }, + coEditButton: function(f, d, e, k) { + if (d) { + var a = $WH.gE(f.divEdit, "textarea"); var g = a[0]; - if (!Listview.funcBox.coValidate(a, e)) { - return - } - if (g.value != f.body || (a[1] && a[1].value != f.response)) { - var c = 0; - if (f.lastEdit != null) { - c = f.lastEdit[1] - }++c; - f.lastEdit = [g_serverTime, c, g_user.name]; - Listview.funcBox.coUpdateLastEdit(f); - var b = Listview.funcBox.coGetCharLimit(e); - var i = Markup.toHtml((g.value.length > b ? g.value.substring(0, b) : g.value), { - mode: Markup.MODE_COMMENT, - roles: f.roles - }); - var h = ((a[1] && a[1].value.length > 0) ? Markup.toHtml("[div][/div][wowheadresponse=" + g_user.name + " roles=" + g_user.roles + "]" + a[1].value + "[/wowheadresponse]", { - mode: Markup.MODE_COMMENT, - roles: g_user.roles - }) : ""); - if (!k) { - f.divBody.innerHTML = i; - f.divResponse.innerHTML = h - } else { - f.divBody.html(i); - f.divResponse.html(h) - } - f.body = g.value; - if (g_user.roles & U_GROUP_MODERATOR && e[1]) { - f.response = e[1].value - } - var j = "body=" + $WH.urlencode(f.body); - if (f.response !== undefined) { - j += "&response=" + $WH.urlencode(f.response) - } - if (e == -1) { - new Ajax("?forums=editpost&id=" + f.id, { - method: "POST", - params: j - }) - } else { - new Ajax("?comment=edit&id=" + f.id, { - method: "POST", - params: j - }) - } - } - } - if (!k) { + if (!Listview.funcBox.coValidate(a, e)) { + return + } + if (g.value != f.body || (a[1] && a[1].value != f.response)) { + var c = 0; + if (f.lastEdit != null) { + c = f.lastEdit[1] + }++c; + f.lastEdit = [g_serverTime, c, g_user.name]; + Listview.funcBox.coUpdateLastEdit(f); + var b = Listview.funcBox.coGetCharLimit(e); + var i = Markup.toHtml((g.value.length > b ? g.value.substring(0, b) : g.value), { + mode: Markup.MODE_COMMENT, + roles: f.roles + }); + var h = ((a[1] && a[1].value.length > 0) ? Markup.toHtml("[div][/div][wowheadresponse=" + g_user.name + " roles=" + g_user.roles + "]" + a[1].value + "[/wowheadresponse]", { + mode: Markup.MODE_COMMENT, + roles: g_user.roles + }) : ""); + if (!k) { + f.divBody.innerHTML = i; + f.divResponse.innerHTML = h + } else { + f.divBody.html(i); + f.divResponse.html(h) + } + f.body = g.value; + if (g_user.roles & U_GROUP_MODERATOR && e[1]) { + f.response = e[1].value + } + var j = "body=" + $WH.urlencode(f.body); + if (f.response !== undefined) { + j += "&response=" + $WH.urlencode(f.response) + } + if (e == -1) { + new Ajax("?forums=editpost&id=" + f.id, { + method: "POST", + params: j + }) + } else { + new Ajax("?comment=edit&id=" + f.id, { + method: "POST", + params: j + }) + } + } + } + if (!k) { f.divBody.style.display = ""; f.divResponse.style.display = ""; f.divLinks.firstChild.style.display = ""; - } else { - f.divBody.show(); - f.divResponse.show() - } - $WH.de(f.divEdit); - f.divEdit = null + } else { + f.divBody.show(); + f.divResponse.show() + } + $WH.de(f.divEdit); + f.divEdit = null }, - coGetCharLimit: function(a) { - if (a == 2) { - return 7500 - } - if (a == 4) { - return 250 - } - if (g_user.roles & U_GROUP_STAFF) { - return 16000000 - } - var b = 1; - if (g_user.premium) { - b = 3 - } - switch (a) { - case 0: - case 1: - return 7500 * b; - case -1 : case 3: - return 15000 * b - } - }, - coUpdateCharLimit: function(a, b, c) { - var d = a.value; - if (d.length > c) { - a.value = d.substring(0, c); - } else { - b.innerHTML = (" " + $WH.sprintf(LANG.compose_remaining, c - d.length)) + coGetCharLimit: function(a) { + if (a == 2) { + return 7500 + } + if (a == 4) { + return 250 + } + if (g_user.roles & U_GROUP_STAFF) { + return 16000000 + } + var b = 1; + if (g_user.premium) { + b = 3 + } + switch (a) { + case 0: + case 1: + return 7500 * b; + case -1 : case 3: + return 15000 * b + } + }, + coUpdateCharLimit: function(a, b, c) { + var d = a.value; + if (d.length > c) { + a.value = d.substring(0, c); + } else { + b.innerHTML = (" " + $WH.sprintf(LANG.compose_remaining, c - d.length)) b.className.replace(/(?:^|\s)q10(?!\S)/g , ''); - if (d.length == c) { - b.className += " q10"; - } - } - }, - coModeLink: function(e, b, f) { + if (d.length == c) { + b.className += " q10"; + } + } + }, + coModeLink: function(e, b, f) { var j = Listview.funcBox.coGetCharLimit(b); - var c = Markup.MODE_COMMENT; - $WH.array_walk($WH.gE(this.parentNode, "a"), function(k) { - k.className = "" - }); - this.className = "selected"; - var d = $WH.gE(this.parentNode.parentNode, "textarea"), + var c = Markup.MODE_COMMENT; + $WH.array_walk($WH.gE(this.parentNode, "a"), function(k) { + k.className = "" + }); + this.className = "selected"; + var d = $WH.gE(this.parentNode.parentNode, "textarea"), k = d[0], - i = k, - a = i.previousSibling; - if (b == 4) { - c = Markup.MODE_SIGNATURE - } - switch (e) { - case 1: - i.style.display = ""; - a.style.display = "none"; - a.previousSibling.style.display = ""; - i.focus(); - break; - case 2: - i.style.display = "none"; - var g = (k.value.length > j ? k.value.substring(0, j) : k.value); - if (b == 4) { - var h; - if ((h = g.indexOf("\n")) != -1 && (h = g.indexOf("\n", h + 1)) != -1 && (h = g.indexOf("\n", h + 1)) != -1) { - g = g.substring(0, h) - } - } - var l = Markup.toHtml(g, { - mode: c, - roles: f.roles - }); - if (d[1] && d[1].value.length > 0) { - l += Markup.toHtml("[div][/div][wowheadresponse=" + g_user.name + " roles=" + g_user.roles + "]" + f[1].value + "[/wowheadresponse]", { - mode: c, - roles: g_user.roles - }) - } - a.innerHTML = l; - a.style.display = ""; - a.previousSibling.style.display = "none"; - break - } - }, - coReply: function(b) { - document.forms.addcomment.elements.replyto.value = b.replyTo; - var a = $WH.ge("replybox-generic"); - $WH.gE(a, "span")[0].innerHTML = b.user; - a.style.display = ""; - co_addYourComment() - }, - coValidate: function(a, c) { - c |= 0; - if (c == 1 || c == -1) { - if ($WH.trim(a.value).length < 1) { - alert(LANG.message_forumposttooshort); - return false - } - } else { - if ($WH.trim(a.value).length < 10) { - alert(LANG.message_commenttooshort); - return false - } - } - var b = Listview.funcBox.coGetCharLimit(c); - if (a.value.length > b) { - if (!confirm($WH.sprintf(c == 1 ? LANG.confirm_forumposttoolong: LANG.confirm_commenttoolong, b, a.value.substring(b - 30, b)))) { - return false - } - } - return true - }, - coCustomRatingOver: function(a) { - $WH.Tooltip.showAtCursor(a, LANG.tooltip_customrating, 0, 0, "q") - }, - coPlusRatingOver: function(a) { - $WH.Tooltip.showAtCursor(a, LANG.tooltip_uprate, 0, 0, "q2") - }, - coMinusRatingOver: function(a) { - $WH.Tooltip.showAtCursor(a, LANG.tooltip_downrate, 0, 0, "q10") - }, - coSortDate: function(a) { - a.nextSibling.nextSibling.className = ""; - a.className = "selected"; - this.mainDiv.className += " listview-aci"; - this.setSort([1], true, false) - $WH.sc("temp_comment_sort", 1) - }, - coSortHighestRatedFirst: function(a) { - a.previousSibling.previousSibling.className = ""; - a.className = "selected"; - this.mainDiv.className = this.mainDiv.className.replace("listview-aci", ""); - this.setSort([ - 3, 2], true, false) - $WH.sc("temp_comment_sort", 2) - }, - coFilterByPatchVersion: function(a) { - this.minPatchVersion = a.value; - this.refreshRows() - }, - coUpdateLastEdit: function(f) { - var b = f.divLastEdit; - if (!b) { - return - } - if (f.lastEdit != null) { - var e = f.lastEdit; - b.childNodes[1].firstChild.nodeValue = e[2]; - b.childNodes[1].href = "?user=" + e[2]; - var c = new Date(e[0]); - var d = (g_serverTime - c) / 1000; - if (b.childNodes[3].firstChild) { - $WH.de(b.childNodes[3].firstChild) - } - Listview.funcBox.coFormatDate(b.childNodes[3], d, c); - var a = ""; - if (f.rating != null) { - a += $WH.ct($WH.sprintf(LANG.lvcomment_patch, g_getPatchVersion(c))) - } - if (e[1] > 1) { - a += LANG.dash + $WH.sprintf(LANG.lvcomment_nedits, e[1]) - } - b.childNodes[4].nodeValue = a; - b.style.display = "" - } else { - b.style.display = "none" - } - }, - coFormatDate: function(f, e, b, g, h) { - var d; - if (e < 2592000) { - var a = $WH.sprintf(LANG.date_ago, g_formatTimeElapsed(e)); - var c = new Date(); - c.setTime(b.getTime() + (g_localTime - g_serverTime)); - f.style.cursor = "help"; - f.title = c.toLocaleString() - } else { - a = LANG.date_on + g_formatDateSimple(b, g) - } - if (h == 1) { - a = a.substr(0, 1).toUpperCase() + a.substr(1) - } - d = $WH.ct(a); - $WH.ae(f, d) - }, - coFormatFileSize: function(c) { - var b = -1; - var a = "KMGTPEZY"; - while (c >= 1024 && b < 7) { - c /= 1024; ++b - } - if (b < 0) { - return c + " byte" + (c > 1 ? "s": "") - } else { - return c.toFixed(1) + " " + a[b] + "B" - } - }, + i = k, + a = i.previousSibling; + if (b == 4) { + c = Markup.MODE_SIGNATURE + } + switch (e) { + case 1: + i.style.display = ""; + a.style.display = "none"; + a.previousSibling.style.display = ""; + i.focus(); + break; + case 2: + i.style.display = "none"; + var g = (k.value.length > j ? k.value.substring(0, j) : k.value); + if (b == 4) { + var h; + if ((h = g.indexOf("\n")) != -1 && (h = g.indexOf("\n", h + 1)) != -1 && (h = g.indexOf("\n", h + 1)) != -1) { + g = g.substring(0, h) + } + } + var l = Markup.toHtml(g, { + mode: c, + roles: f.roles + }); + if (d[1] && d[1].value.length > 0) { + l += Markup.toHtml("[div][/div][wowheadresponse=" + g_user.name + " roles=" + g_user.roles + "]" + f[1].value + "[/wowheadresponse]", { + mode: c, + roles: g_user.roles + }) + } + a.innerHTML = l; + a.style.display = ""; + a.previousSibling.style.display = "none"; + break + } + }, + coReply: function(b) { + document.forms.addcomment.elements.replyto.value = b.replyTo; + var a = $WH.ge("replybox-generic"); + $WH.gE(a, "span")[0].innerHTML = b.user; + a.style.display = ""; + co_addYourComment() + }, + coValidate: function(a, c) { + c |= 0; + if (c == 1 || c == -1) { + if ($WH.trim(a.value).length < 1) { + alert(LANG.message_forumposttooshort); + return false + } + } else { + if ($WH.trim(a.value).length < 10) { + alert(LANG.message_commenttooshort); + return false + } + } + var b = Listview.funcBox.coGetCharLimit(c); + if (a.value.length > b) { + if (!confirm($WH.sprintf(c == 1 ? LANG.confirm_forumposttoolong: LANG.confirm_commenttoolong, b, a.value.substring(b - 30, b)))) { + return false + } + } + return true + }, + coCustomRatingOver: function(a) { + $WH.Tooltip.showAtCursor(a, LANG.tooltip_customrating, 0, 0, "q") + }, + coPlusRatingOver: function(a) { + $WH.Tooltip.showAtCursor(a, LANG.tooltip_uprate, 0, 0, "q2") + }, + coMinusRatingOver: function(a) { + $WH.Tooltip.showAtCursor(a, LANG.tooltip_downrate, 0, 0, "q10") + }, + coSortDate: function(a) { + a.nextSibling.nextSibling.className = ""; + a.className = "selected"; + this.mainDiv.className += " listview-aci"; + this.setSort([1], true, false) + $WH.sc("temp_comment_sort", 1) + }, + coSortHighestRatedFirst: function(a) { + a.previousSibling.previousSibling.className = ""; + a.className = "selected"; + this.mainDiv.className = this.mainDiv.className.replace("listview-aci", ""); + this.setSort([ - 3, 2], true, false) + $WH.sc("temp_comment_sort", 2) + }, + coFilterByPatchVersion: function(a) { + this.minPatchVersion = a.value; + this.refreshRows() + }, + coUpdateLastEdit: function(f) { + var b = f.divLastEdit; + if (!b) { + return + } + if (f.lastEdit != null) { + var e = f.lastEdit; + b.childNodes[1].firstChild.nodeValue = e[2]; + b.childNodes[1].href = "?user=" + e[2]; + var c = new Date(e[0]); + var d = (g_serverTime - c) / 1000; + if (b.childNodes[3].firstChild) { + $WH.de(b.childNodes[3].firstChild) + } + Listview.funcBox.coFormatDate(b.childNodes[3], d, c); + var a = ""; + if (f.rating != null) { + a += $WH.ct($WH.sprintf(LANG.lvcomment_patch, g_getPatchVersion(c))) + } + if (e[1] > 1) { + a += LANG.dash + $WH.sprintf(LANG.lvcomment_nedits, e[1]) + } + b.childNodes[4].nodeValue = a; + b.style.display = "" + } else { + b.style.display = "none" + } + }, + coFormatDate: function(f, e, b, g, h) { + var d; + if (e < 2592000) { + var a = $WH.sprintf(LANG.date_ago, g_formatTimeElapsed(e)); + var c = new Date(); + c.setTime(b.getTime() + (g_localTime - g_serverTime)); + f.style.cursor = "help"; + f.title = c.toLocaleString() + } else { + a = LANG.date_on + g_formatDateSimple(b, g) + } + if (h == 1) { + a = a.substr(0, 1).toUpperCase() + a.substr(1) + } + d = $WH.ct(a); + $WH.ae(f, d) + }, + coFormatFileSize: function(c) { + var b = -1; + var a = "KMGTPEZY"; + while (c >= 1024 && b < 7) { + c /= 1024; ++b + } + if (b < 0) { + return c + " byte" + (c > 1 ? "s": "") + } else { + return c.toFixed(1) + " " + a[b] + "B" + } + }, - dateEventOver: function(date, event, e) { - var dates = Listview.funcBox.getEventNextDates(event.startDate, event.endDate, event.rec || 0, date), - buff = ''; + dateEventOver: function(date, event, e) { + var dates = Listview.funcBox.getEventNextDates(event.startDate, event.endDate, event.rec || 0, date), + buff = ''; - if (dates[0] && dates[1]) { - var + if (dates[0] && dates[1]) { + var t1 = new Date(event.startDate.replace(/-/g, '/')), - t2 = new Date(event.endDate.replace(/-/g, '/')), - first, - last; + t2 = new Date(event.endDate.replace(/-/g, '/')), + first, + last; - t1.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); - t2.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); + t1.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); + t2.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); - if (date.getFullYear() == dates[0].getFullYear() && date.getMonth() == dates[0].getMonth() && date.getDate() == dates[0].getDate()) { - first = true; - } + if (date.getFullYear() == dates[0].getFullYear() && date.getMonth() == dates[0].getMonth() && date.getDate() == dates[0].getDate()) { + first = true; + } - if (date.getFullYear() == dates[1].getFullYear() && date.getMonth() == dates[1].getMonth() && date.getDate() == dates[1].getDate()) { - last = true; - } + if (date.getFullYear() == dates[1].getFullYear() && date.getMonth() == dates[1].getMonth() && date.getDate() == dates[1].getDate()) { + last = true; + } - if (first && last) - buff = g_formatTimeSimple(t1, LANG.lvscreenshot_from, 1) + ' ' + g_formatTimeSimple(t2, LANG.date_to, 1); - else if (first) - buff = g_formatTimeSimple(t1, LANG.tab_starts); - else if (last) - buff = g_formatTimeSimple(t2, LANG.tab_ends); - else - buff = LANG.allday; + if (first && last) + buff = g_formatTimeSimple(t1, LANG.lvscreenshot_from, 1) + ' ' + g_formatTimeSimple(t2, LANG.date_to, 1); + else if (first) + buff = g_formatTimeSimple(t1, LANG.tab_starts); + else if (last) + buff = g_formatTimeSimple(t2, LANG.tab_ends); + else + buff = LANG.allday; } - $WH.Tooltip.showAtCursor(e, '' + event.name + '
' + buff, 0, 0, 'q'); - }, + $WH.Tooltip.showAtCursor(e, '' + event.name + '
' + buff, 0, 0, 'q'); + }, - ssCellOver: function() { - this.className = 'screenshot-caption-over'; - }, + ssCellOver: function() { + this.className = 'screenshot-caption-over'; + }, - ssCellOut: function() { - this.className = 'screenshot-caption'; - }, + ssCellOut: function() { + this.className = 'screenshot-caption'; + }, - ssCellClick: function(i, e) { - e = $WH.$E(e); + ssCellClick: function(i, e) { + e = $WH.$E(e); - if (e.shiftKey || e.ctrlKey) { - return; - } + if (e.shiftKey || e.ctrlKey) { + return; + } - var + var j = 0, el = e._target; while (el && j < 3) { - if (el.nodeName == 'A') { - return; - } - if (el.nodeName == 'IMG') { - break; - } - el = el.parentNode; - } + if (el.nodeName == 'A') { + return; + } + if (el.nodeName == 'IMG') { + break; + } + el = el.parentNode; + } - ScreenshotViewer.show({ - screenshots: this.data, - pos: i - }); - }, + ScreenshotViewer.show({ + screenshots: this.data, + pos: i + }); + }, - viCellClick: function(i, e) { - e = $WH.$E(e); + ssCreateCb: function(td, row) { + if (row.__nochk) { + return; + } - if (e.shiftKey || e.ctrlKey) { - return; - } + var div = $WH.ce('div'); + div.className = 'listview-cb'; + div.onclick = Listview.cbCellClick; - var + var cb = $WH.ce('input'); + cb.type = 'checkbox'; + cb.onclick = Listview.cbClick; + $WH.ns(cb); + + if (row.__chk) { + cb.checked = true; + } + + row.__cb = cb; + + $WH.ae(div, cb); + $WH.ae(td, div); + }, + + viCellClick: function(i, e) { + e = $WH.$E(e); + + if (e.shiftKey || e.ctrlKey) { + return; + } + + var j = 0, el = e._target; - while (el && j < 3) { - if (el.nodeName == 'A') { - return; - } - if (el.nodeName == 'IMG') { - break; - } - el = el.parentNode; - } + while (el && j < 3) { + if (el.nodeName == 'A') { + return; + } + if (el.nodeName == 'IMG') { + break; + } + el = el.parentNode; + } - VideoViewer.show({ - videos: this.data, - pos: i - }) - }, + VideoViewer.show({ + videos: this.data, + pos: i + }) + }, - moneyHonorOver: function(e) { - $WH.Tooltip.showAtCursor(e, '' + LANG.tooltip_honorpoints + '', 0, 0, 'q1'); - }, + moneyHonorOver: function(e) { + $WH.Tooltip.showAtCursor(e, '' + LANG.tooltip_honorpoints + '', 0, 0, 'q1'); + }, - moneyArenaOver: function(e) { - $WH.Tooltip.showAtCursor(e, '' + LANG.tooltip_arenapoints + '', 0, 0, 'q1'); - }, + moneyArenaOver: function(e) { + $WH.Tooltip.showAtCursor(e, '' + LANG.tooltip_arenapoints + '', 0, 0, 'q1'); + }, - moneyAchievementOver: function(e) { - $WH.Tooltip.showAtCursor(e, '' + LANG.tooltip_achievementpoints + '', 0, 0, 'q1'); - }, + moneyAchievementOver: function(e) { + $WH.Tooltip.showAtCursor(e, '' + LANG.tooltip_achievementpoints + '', 0, 0, 'q1'); + }, - appendMoney: function(g, a, f, m, j, c, l) { // todo: understand and adapt - var k, h = 0; - if (a >= 10000) { - h = 1; - k = $WH.ce("span"); - k.className = "moneygold"; - $WH.ae(k, $WH.ct(Math.floor(a / 10000))); - $WH.ae(g, k); - a %= 10000 - } - if (a >= 100) { - if (h) { - $WH.ae(g, $WH.ct(" ")) - } else { - h = 1 - } - k = $WH.ce("span"); - k.className = "moneysilver"; - $WH.ae(k, $WH.ct(Math.floor(a / 100))); - $WH.ae(g, k); - a %= 100 - } - if (a >= 1 || f != null) { - if (h) { - $WH.ae(g, $WH.ct(" ")) - } else { - h = 1 - } - k = $WH.ce("span"); - k.className = "moneycopper"; - $WH.ae(k, $WH.ct(a)); - $WH.ae(g, k) - } - if (m != null && m != 0) { - if (h) { - $WH.ae(g, $WH.ct(" ")) - } else { - h = 1 - } - k = $WH.ce("span"); - k.className = "money" + (m < 0 ? "horde": "alliance") + " tip"; - k.onmouseover = Listview.funcBox.moneyHonorOver; - k.onmousemove = $WH.Tooltip.cursorUpdate; - k.onmouseout = $WH.Tooltip.hide; - $WH.ae(k, $WH.ct($WH.number_format(Math.abs(m)))); - $WH.ae(g, k) - } - if (j >= 1) { - if (h) { - $WH.ae(g, $WH.ct(" ")) - } else { - h = 1 - } - k = $WH.ce("span"); - k.className = "moneyarena tip"; - k.onmouseover = Listview.funcBox.moneyArenaOver; - k.onmousemove = $WH.Tooltip.cursorUpdate; - k.onmouseout = $WH.Tooltip.hide; - $WH.ae(k, $WH.ct($WH.number_format(j))); - $WH.ae(g, k) - } - if (c != null) { - for (var b = 0; b < c.length; ++b) { - if (h) { - $WH.ae(g, $WH.ct(" ")) - } else { - h = 1 - } - var o = c[b][0]; - var e = c[b][1]; - k = $WH.ce("a"); - k.href = "?item=" + o; - k.className = "moneyitem"; - k.style.backgroundImage = "url(images/icons/tiny/" + g_items.getIcon(o).toLowerCase() + ".gif)"; - $WH.ae(k, $WH.ct(e)); - $WH.ae(g, k) - } - } - if (l != null) { - if (h) { - $WH.ae(g, $WH.ct(" ")) - } else { - h = 1 - } - k = $WH.ce("span"); - k.className = "moneyachievement tip"; - k.onmouseover = Listview.funcBox.moneyAchievementOver; - k.onmousemove = $WH.Tooltip.cursorUpdate; - k.onmouseout = $WH.Tooltip.hide; - $WH.ae(k, $WH.ct($WH.number_format(l))); - $WH.ae(g, k) - } - }, + moneyCurrencyOver: function(currencyId, count, e) { + var buff = g_gatheredcurrencies[currencyId]['name_' + Locale.getName()]; + + // justice / valor points handling removed + + $WH.Tooltip.showAtCursor(e, buff, 0, 0, 'q1'); + }, + + appendMoney: function(g, a, f, m, j, c, l) { // todo: understand and adapt + var k, h = 0; + if (a >= 10000) { + h = 1; + k = $WH.ce("span"); + k.className = "moneygold"; + $WH.ae(k, $WH.ct(Math.floor(a / 10000))); + $WH.ae(g, k); + a %= 10000 + } + if (a >= 100) { + if (h) { + $WH.ae(g, $WH.ct(" ")) + } else { + h = 1 + } + k = $WH.ce("span"); + k.className = "moneysilver"; + $WH.ae(k, $WH.ct(Math.floor(a / 100))); + $WH.ae(g, k); + a %= 100 + } + if (a >= 1 || f != null) { + if (h) { + $WH.ae(g, $WH.ct(" ")) + } else { + h = 1 + } + k = $WH.ce("span"); + k.className = "moneycopper"; + $WH.ae(k, $WH.ct(a)); + $WH.ae(g, k) + } + if (m != null && m != 0) { + if (h) { + $WH.ae(g, $WH.ct(" ")) + } else { + h = 1 + } + k = $WH.ce("span"); + k.className = "money" + (m < 0 ? "horde": "alliance") + " tip"; + k.onmouseover = Listview.funcBox.moneyHonorOver; + k.onmousemove = $WH.Tooltip.cursorUpdate; + k.onmouseout = $WH.Tooltip.hide; + $WH.ae(k, $WH.ct($WH.number_format(Math.abs(m)))); + $WH.ae(g, k) + } + if (j >= 1) { + if (h) { + $WH.ae(g, $WH.ct(" ")) + } else { + h = 1 + } + k = $WH.ce("span"); + k.className = "moneyarena tip"; + k.onmouseover = Listview.funcBox.moneyArenaOver; + k.onmousemove = $WH.Tooltip.cursorUpdate; + k.onmouseout = $WH.Tooltip.hide; + $WH.ae(k, $WH.ct($WH.number_format(j))); + $WH.ae(g, k) + } + if (c != null) { + for (var b = 0; b < c.length; ++b) { + if (h) { + $WH.ae(g, $WH.ct(" ")) + } else { + h = 1 + } + var o = c[b][0]; + var e = c[b][1]; + k = $WH.ce("a"); + k.href = "?item=" + o; + k.className = "moneyitem"; + k.style.backgroundImage = "url(images/icons/tiny/" + g_items.getIcon(o).toLowerCase() + ".gif)"; + $WH.ae(k, $WH.ct(e)); + $WH.ae(g, k) + } + } + if (l != null) { + if (h) { + $WH.ae(g, $WH.ct(" ")) + } else { + h = 1 + } + k = $WH.ce("span"); + k.className = "moneyachievement tip"; + k.onmouseover = Listview.funcBox.moneyAchievementOver; + k.onmousemove = $WH.Tooltip.cursorUpdate; + k.onmouseout = $WH.Tooltip.hide; + $WH.ae(k, $WH.ct($WH.number_format(l))); + $WH.ae(g, k) + } + }, getUpperSource: function(source, sm) { switch (source) { @@ -7701,6 +8377,10 @@ Listview.templates = { name: LANG.type, type: 'text', compute: function(item, td) { + if (item.classs == null) { + return; + } + td.className = 'small q1'; $WH.nw(td); var a = $WH.ce('a'); @@ -7722,7 +8402,7 @@ Listview.templates = { ], getItemLink: function(item) { - return '?item=' + item.id; + return item.id > 0 ? '?item=' + item.id : 'javascript:;'; }, onBeforeCreate: function() { @@ -7749,7 +8429,7 @@ Listview.templates = { if (!topBar && this._nComparable < 15) { return; } - + if (this.mode != Listview.MODE_CHECKBOX) { return; } diff --git a/template/js/locale_dede.js b/template/js/locale_dede.js index 644fc156..16b20352 100644 --- a/template/js/locale_dede.js +++ b/template/js/locale_dede.js @@ -3866,7 +3866,6 @@ var LANG = { tc_summary: "Zusammenfassung", tc_restore: "Wiederherstellen", tc_export: "Exportieren", - tc_link: "Link", tc_print: "Drucken", tc_glyphs: "Glyphen", diff --git a/template/js/locale_enus.js b/template/js/locale_enus.js index 49c6f85d..7a9521bd 100644 --- a/template/js/locale_enus.js +++ b/template/js/locale_enus.js @@ -1037,7 +1037,7 @@ var g_item_slots = { }; var g_item_classes = { - 0: 'Consommable', + 0: 'Consumable', 1: 'Container', 2: 'Weapon', 3: 'Gem', @@ -3911,7 +3911,6 @@ var LANG = { tc_export: "Export", tc_summary: "Summary", tc_restore: "Restore", - tc_link: "Link", tc_print: "Print", tc_glyphs: "Glyphs", diff --git a/template/js/locale_eses.js b/template/js/locale_eses.js index d97ace9d..a5646e20 100644 --- a/template/js/locale_eses.js +++ b/template/js/locale_eses.js @@ -4094,7 +4094,6 @@ var LANG = { tc_export: "Exportar", tc_summary: "Resúmen", tc_restore: "Restaurar", - tc_link: "Enlace", tc_print: "Imprimir", tc_glyphs: "Glifos", diff --git a/template/js/locale_frfr.js b/template/js/locale_frfr.js index e58c745b..76b88c1b 100644 --- a/template/js/locale_frfr.js +++ b/template/js/locale_frfr.js @@ -4083,7 +4083,6 @@ var LANG = { tc_export: "Exporter", tc_summary: "Résumé", tc_restore: "Restaurer", - tc_link: "Lien", tc_print: "Imprimer", tc_glyphs: "Glyphes", diff --git a/template/js/locale_ruru.js b/template/js/locale_ruru.js index a62c968c..51d20edb 100644 --- a/template/js/locale_ruru.js +++ b/template/js/locale_ruru.js @@ -4084,7 +4084,6 @@ var LANG = { tc_export: "Экспортировать", tc_summary: "Сводка", tc_restore: "Восстановить", - tc_link: "Ссылка", tc_print: "Печать", tc_glyphs: "Символы", diff --git a/template/spell.tpl b/template/spell.tpl index bff00b95..8d0aa26d 100644 --- a/template/spell.tpl +++ b/template/spell.tpl @@ -21,31 +21,12 @@ {include file='bricks/infobox.tpl' info=$lvData.infobox}
{$lang.name}{$lang.colon}{$lang.name|ucFirst}{$lang.colon}  
{$lang.level}{$lang.colon}
{$lvData.page.info}
- -
- - - - {if !empty($lvData.page.buff)} -

{$lang._aura}

-
-
{$lvData.page.buff}
-
- - {/if} +{include file='bricks/tooltip.tpl'} {if $lvData.page.reagents}{if $lvData.page.tools}
{/if}

{$lang.reagents}

@@ -95,7 +76,7 @@
{$lang.duration}{$lvData.page.duration}{if !empty($lvData.page.duration)}{$lvData.page.duration}{else}{$lang.n_a}{/if}
{$lang.school}
{$lang.mechanic}{$lvData.page.mechanic}{if $lvData.page.mechanic}{$lvData.page.mechanic}{else}{$lang.n_a}{/if}
{$lang.dispelType}{$lvData.page.dispel}{if $lvData.page.dispel}{$lvData.page.dispel}{else}{$lang.n_a}{/if}
{$lang._gcdCategory}
{$lang._cooldown}{$lvData.page.cooldown}{if !empty($lvData.page.cooldown)}{$lvData.page.cooldown}{else}{$lang.n_a}{/if}
{$lang._gcd} {$lvData.page.gcd}
{$lang._forms} {$lvData.page.stances}
{$lang.requires2} {$lvData.page.items}
diff --git a/template/spells.tpl b/template/spells.tpl index 78db27c0..7295c8b4 100644 --- a/template/spells.tpl +++ b/template/spells.tpl @@ -55,7 +55,7 @@ {/if}
- +
{$lang.name}{$lang.colon}{$lang.name|ucFirst}{$lang.colon}