нативки BuildList
Изначально, была только одна кнопка. Со временем возникло желанием сделать альтернативные списки. Короче, у рабочего может быть несколько меню, и значит и кнопок меню.
заведен такой тип как BuildList, являющим простым списком построенных здании. Кроме того, этот ранее как простой тип оброс множеством параметров. Проще говоря, этот тип помогает занести все данные меню: список, кнопка меню вызова и ее параметры, контейнер кнопок и ее параметры.
создать билд лист
создать билд лист с указанием параметров будущей кнопки вызова меню. На данный момент у билд листа еще нет никакой кнопки, ее нужно создать и привязать к билд листу.
--создать билд лист
--@ string build_list_id - идишник списка;
--@ table build_list - список;
--@ real position_x, @ real position_y - положение кнопки вызова меню на экране;
--@ real button_width,@ real button_height - размеры кнопки вызова меню
function CreateBuildList(build_list_id,build_list,position_x, position_y,button_width,button_height)
привязка билд лист к юниту или его типу
билд лист привязать к юниту или отвязать от юнита. Короче, таким образом мы будем знать у какого рабочего может быть билд лист (или меню).
Эта поможет при выборе рабочего отобразить кнопку меню от билд листа
еще не очень продуманы зависимости: если нужно отключить всем юнитам данного типа, но и одновременно, нужно включен у одного юнита
--включить определенному юниту билд лист
--@ unit worker - юнит-строитель, рабочий;
--@ string build_list_id - идишник списка
function AddBuildListForUnit(worker, build_list_id)

--включает у всех юнита данного типа
--@ integer unit_type - ид тип юнит-строителя;
--@ string build_list_id - идишник списка
function AddBuildListForUnitType(unit_type, build_list_id)

--выключает определенному юниту билд лист
--@ unit worker - юнит-строитель, рабочий;
--@ string build_list_id - идишник списка
function RemoveBuildListForUnit(worker, build_list_id)

--выключает у всех юнита данного типа
--@ integer unit_type - ид тип юнит-строителя;
--@ string build_list_id - идишник списка
function RemoveBuildListForUnitType(unit_type, build_list_id)
билд лист: работа со списком
можете редактировать список: установить новый, добавлять или удалять.
--задать билд листу список ид-здании
--@ string build_list_id - идишник списка;
--@ table build_list - список
function SetBuildList(build_list_id,build_list)

--добавить идишник здания в список билд листа
--@ string build_list_id - идишник списка;
--@ string type_building - ид здание
function AddBuildListTypeBuilding(build_list_id,type_building)

--удалить идишник здания из списка билд листа
--@ string build_list_id - идишник списка;
--@ string type_building - ид здание
function RemoveBuildListTypeBuilding(build_list_id,type_building)
билд лист: работа с кнопкой вызова меню
тут чисто параметры распространяются на кнопку меню: размеры, положение, видимость и др. Прежде всего необходимо создать эту кнопку, и привязать ее к билд листу.
билд лист: кнопка меню: создать и привязать кнопку меню
Эти две функции создают кнопки меню.
Вы можете инициировать в начале игры список билд листов.
пример списка
CreateBuildList('build menu human',{'htow','hhou','hbar','hbla','hwtw','halt','harm','hars','hlum','hgra','hvlt'},0.4, 0.3)
CreateBuildList('build menu orc',{'ogre','otrb','obar','ofor','oalt','obea','osld','otto','owtw','ovln'},0.4, 0.3)
CreateBuildList('build menu naga',{'nnfm','nntg','nntt','nnsg','nnsa','nnad'},0.4, 0.3)
CreateBuildList('build menu undead',{'unpl','uzig','usep','ugrv','uaod','utod','uslh','ubon','usap','ugol','utom'},0.4, 0.3)
CreateBuildList('build menu blood elf',{'oshy','ushp','eshy','nshp','hshy'},0.4, 0.3)
CreateBuildList('build menu blood elf-engineer',{'h00C'},0.4, 0.3)
нужно создать для каждого такого билд листа фрейм-кнопку, и привязать ее к билд листу. С этим хорошо справляется функция InitButtonsBuildMenu, которая берет все билд листы, и создает для каждого листа кнопку.
Если в течении игры вы создаете билд лист через CreateBuildList, вам потребуется для нее создать новую кнопку CreateBuildListButton
--создать билд листу кнопку (если конечно, у билд листа нет своей кнопки)
--короче, создание кнопки, и затем привязка кнопки к билд листу
--по факту: у каждого билд листа должна быть своя кнопка
--@ player PlAyer - игрок, которому создают кнопку меню;
--@ string build_list_id -  идишник списка
function CreateBuildListButton(PlAyer,build_list_id)

--инициировать массив кнопок вызова меню (это на старте)
--короче, это аналогия CreateBuildListButton, но для всех билд листов на старте
--берет все возможные билд листы, и каждому создает кнопку меню
--@ player PlAyer - игрок, которому создают контейнер;
--@ integer number_last_button - номер последней кнопки
function InitButtonsBuildMenu(PlAyer)
билд лист: кнопка меню: включить/выключить билд лист
работает так: если отключен билд лист, то у рабочих не отображается кнопка.
в основном при отключении не должна показываться кнопка, вот и все.
Вы можете воздействовать локально на игрока, можно отключить билд лист так у одного, так и у всех.
Также можно и обратно отобразить кнопки (даже если у раба их несколько).
очень помогает при отмене, не важна какая кнопка нажата.
--включить/выключить билд лист
--отключенный билд лист не отображается в игре
--@ string build_list_id - идишник списка;
--@ boolean flag - вкл/выкл true/false
function DisableBuildListAllPlayers(build_list_id, flag)

--включить/выключить билд лист конкретному игроку
--отключенный билд лист не отображается в игре
--@ player Player - игрок;
--@ string build_list_id - идишник списка;
--@ boolean flag - вкл/выкл true/false
function DisableBuildListForPlayer(Player,build_list_id, flag)
билд лист: кнопка меню: координаты
--задать билд листу положение кнопки вызова меню
--@ string build_list_id - идишник списка;
--@ real position_x, @ real position_y - положение кнопки вызова меню на экране
function SetBuildListPosition(build_list_id,position_x, position_y)
билд лист: кнопка меню: размеры
--задать билд листу размеры кнопки вызова меню
--@ string build_list_id - идишник списка;
--@ real button_width,@ real button_height - размеры кнопки вызова меню
function SetBuildListSizeButton(build_list_id,button_width,button_height)
билд лист: кнопка меню: заглавие
--установить заглавие кнопки меню для билд листа 
--@ string build_list_id - идишник списка;
--@ string name - название кнопки меню (заглавие)
function SetBuildingListName(build_list_id, name)
билд лист: кнопка меню: описание
--установить описание кнопки меню для билд листа
--@ string build_list_id - идишник списка;
--@ string desc - описание меню списка
function SetBuildingListDescription(build_list_id, desc)
билд лист: кнопка меню: указать иконку
--установить иконку кнопки меню для билд листа
--@ string build_list_id - идишник списка;
--@ string path_icon_menu - иконка кнопки меню
function SetBuildListIcon(build_list_id,path_icon_menu)
билд лист: кнопка меню: горячая клавиша
--установить горячую клавишу кнопки меню для билд листа
--@ string build_list_id - идишник списка;
--@ string hotkey - строчная горячая клавиша вызова (для описания tooltip);
--@ oskey Oskey - кнопка вызова (для работы триггера)
function SetBuildingListHotkey(build_list_id, Hotkey, Oskey)
билд лист: кнопка меню: получить номер кнопки меню и саму кнопку
--получить номер фрейм-кнопки по идишнику билд листа
--локально у разных игроков номера фрейм-кнопок могут отличаться, тк у разных игроков мб разные списки
--@ player PlaYer - игрок;
--@ string build_list_id - идишник списка;
--@@ return integer - номер кнопки
function GetBuildingListNumberButton(PlaYer,build_list_id)

--получить фрейм-кнопку билд листа
--@ player PlaYer - игрок;
--@ string build_list_id - идишник списка;
--@@ return button - кнопка
function GetBuildingListButton(PlaYer,build_list_id)
билд лист: задать параметры контейнера
--параметры билд листа: настройки контейнера кнопок меню (размеры кнопок,зазоры, координаты, итд)
--@ string build_list_id - идишник списка;
--@ real pos_x,@ real pos_y  - экранные координаты левого нижнего угла контейнера;
--@ integer rows - строки; @ integer columns - столбцы;
--@ real button_width, @ real button_height - размеры кнопок;
--@ real gap_between_buttons - зазор между кнопками;
--@ real offset_x, @ real offset_y - оффсеты рамки;
--@ string path_backdrop - изображение фона контейнера
function SettingBuildMenu(build_list_id,pos_x,pos_y,rows,columns,button_width,button_height,gap_between_buttons,offset_x,offset_y, path_backdrop)
билд лист: получить макс кол-во билд листов в игре
можно узнать сколько билд листов в игре. полезно для циклов при работе с кнопками меню
--показывает макс кол-во списков в игре
--удобнее циклом пробежаться по всем кнопкам меню, зная кол-во
--каждая кнопка вызова меню имеет нумеруется индексом
function GetMaxCountBuildList()
билд лист: получить кнопки рабочего
можем получить список build_list_id и его кол-во. Полезно узнать имеет ли юнит меню, или нет. А и позже поработать со билд листами.
--получить список возможных билд листов от выбранного юнита (если конечно они есть)
--Определяет есть ли у юнита несколько кнопок, например двойной список
--@ unit selected_unit - юнит, при котором проверяют наличие кнопок
--@@ return table возвращает список
function GetBuildListsForUnit(selected_unit)

--Получить кол-во билд листов у юнита
--Определяет есть ли у юнита несколько кнопок, например двойной список
--@ unit selected_unit - юнит, при котором проверяют наличие кнопок
--@@ return integer возвращает число
function GetCountBuildListsForUnit(selected_unit)
параметры ид-здания
отдельная категория, где нужна запись бд о зданиях. Тут итак все понятно.
BuildListBuilding: создать идишник здания
--создать данные для ид-здания
--@ string id_building - ид тип здания;
--@ string path_icon_building - иконка;
--@ integer button_position_x, @ integer button_position_y - положение иконки
function CreateBuildListBuilding(id_building,path_icon_building,button_position_x,button_position_y)
BuildListBuilding: задать модель
--добавить к данным ид-здания модель и ее параметры
--@ string id_building - ид тип здания;
--@ string path_model_building - модель здания;
--@ real scale - размер модели (процентный множитель)
function SetBuildListBuildingModel(id_building,path_model_building,scale)
BuildListBuilding: задать ресурсы
--указать для здания золото
--@ string id_building - ид тип здания;
--@ integer gold - золото
function SetBuildListBuildingGoldCost(id_building,gold)

--указать для здания древесину
--@ string id_building - ид тип здания;
--@ integer lumber - древесина
function SetBuildListBuildingLumberCost(id_building,lumber)

--указать для здания ресурсы
--@ string id_building - ид тип здания;
--@ integer gold - золото;
--@ integer lumber - древесина
function SetBuildListBuildingResourcesCost(id_building,gold,lumber)
BuildListBuilding: задать требования
для здании существует требования построить ряд здании - Buildings_requirements.
еще можно указать ряд исследовании, которые нужно изучить, чтобы построить - Tech_requirements.
указывают в них идишники здании или ид-технологии
Для чего это разделение нужно? чтобы разделять. Пример:
требуется построить:
  • кузницу
требуется изучить:
  • каменная укладка
  • цемент
--указать для здания требования
--@ string id_building - ид тип здания;
--@ table Buildings_requirements - требование: построить список указанных здании;
--@ table Tech_requirements - требование: изучить список указанных технологии
function AddBuildListTechRequirement(id_building,Buildings_requirements,Tech_requirements)
BuildListBuilding: заглавие, описание, горячая клавиша
--указание заглавие здания в подсказке
--@ string id_building - ид тип здания;
--@ string title - заглавие
function SetBuildListBuildingTitle(id_building,Title)

--указание описание здания в подсказке
--@ string id_building - ид тип здания;
--@ string desc - описание
function SetBuildListBuildingDescription(id_building,desc)

--указать для здания горячую клавишу
--@ string id_building - ид тип здания;
--@ string hotkey - строчная горячая клавиша вызова (для описания tooltip);
--@ oskey Oskey - кнопка вызова (для работы триггера)
function SetBuildListBuildingHotkey(id_building, Hotkey, Oskey)
BuildListBuilding: указать параметры паффинга
эти параметры нужно при размещении здания мышкой.
в качестве required_to_build и forbidden_to_build указывают:
ground = 1 --ground-pathable PATHING_TYPE_WALKABILITY
air = 2 --air-pathable PATHING_TYPE_FLYABILITY
buildable = 4 --buildable PATHING_TYPE_BUILDABILITY
unblighted = 8 --unblighted PATHING_TYPE_BLIGHTPATHING
sea = 16 --sea-pathable PATHING_TYPE_FLOATABILITY
amphibious = 32 --amphibious-pathable PATHING_TYPE_AMPHIBIOUSPATHING

можно ничего не указывать, по дефолту для здании и декора примет: buildable + ground
--указать параметры паффинга
--@ string id_building - ид тип здания;
--@ integer WidtH , @ integer HeighT - размеры площадки пример: клетки 4x4 (размеры 1 клетки 32x32);
--@ integer required_to_build - требование строить в определенных типах паффинга (флаги, биты)
--@ integer forbidden_to_build - запрещено строить в определенных типах паффинга (флаги, биты)
--@ real radius_water - требование строиться около воды для верфи (в указанном радиусе должна быть вода)
function SetBuildListBuildingPathing(id_building,WidtH,HeighT,Required_to_build,Forbidden_to_build,Radius_water)
декорациям тоже нужно указать размеры.
--декорации
--@ string id_destructable - ид тип декорации;
--@ integer type_pathing - карта путей (см. ниже): 
--@ integer WidtH, @ integer HeighT - размеры паффинга декора, пример: клетки 4x4 (размеры 1 клетки 32x32);
function SetBuildListDestructablePathing(id_destructable,type_pathing,WidtH,HeighT)
а это если здание имеет возможность разворачиваться колесом
--может ли здание поворачиваемым колесиком мыши в ркежиме выбора строительства
--@ string id_building - ид тип здания;
--@ boolean flag - может ли здание поворачиваться колесом мыши
function SetBuildListBuildingAbilityToTurn(id_building,flag)
функции фреймов
функции для работы с фреймами, облегчающие работу с билд меню. конечно, оно еще не полное
func main frames
--@ string - путь toc-file для подзагрузки ряда файлов
function LoadToc(s)

--инициируем общую таблицу меню строительства
--@ boolean Load - инициировать ли таблицу (этот параметр можно не указывать)
function InitBuildMenu(Load)

--инициируем таблицу игрока (локально у каждого будет свой набор фреймов и данные о них, записанные в эту таблицу)
--@ player PlAyer - игрок 
function CreateBuildMenuForPlayer(PlAyer)

--задаем дефолтные параметры флагов, отображающие тек статус меню
--обнуляет ряд параметров, фиксирующие статус меню. При сэйв/лоад помогает
--@ player PlAyer - игрок 
function InitParamBuildMenuForPlayer(PlAyer)

--создается главный фрейм всего меню строительства, и инициирует ряд важных таблиц данных
--у каждого игрока свои данные состояния меню, мыши итд
--@ player PlAyer - игрок;
--@ framehandle parent - родитель всего главного меню
function CreateMainBuildMenu(PlAyer,parent)
func frames conteiner buttons
--создается (инициируется) контейнер кнопок всего меню
--таблицы короче инициируются и фрейм-родитель интерфейса и контейнера, фон, DeadZoneMouse
--@ player PlAyer - игрок 
function CreateConteinerButtonsBuildMenu(PlAyer)

--создаем кнопку контейнера
--если такая кнопка существует, ее можно переиспользовать. иначе создаем новую
--@ player PlAyer - игрок, которому создают контейнер;
--@ integer number  - номер массива кнопки;
--@ real x,@ real y  - экранные координаты кнопки;
--@ real width, @ real height - размеры кнопки;
--@ string path_icon - изображение иконки;
--@ integer level_layer - уровень слоя (если он есть)
function CreateButtonConteinerOfBuildMenu(PlAyer,num,x,y,width,height,path_icon,level)

--создает контейнер кнопок
--по факту: у каждого игрока может быть только 1 контейнер кнопок
--может быть миллион разных билд листов, и кнопок вызова меню. Но контейнер кнопок всего один
--невозможно отобразить одновременно несколько контейнеров, только один.
--@ player PlAyer - игрок, которому создают контейнер;
--@ real x,@ real y  - экранные координаты левого нижнего угла контейнера;
--@ integer rows - строки; @ integer columns - столбцы;
--@ real width, @ real height - размеры кнопок;
--@ real gap - зазор между кнопками;
--@ real offset_x, @ real offset_y - оффсеты рамки;
--@ string path_backdrop - изображение фона контейнера
function SettingConteinerButtonsBuildMenu(PlAyer,x,y,rows,columns,width,height,gap,offset_x,offset_y, path_backdrop)

--обновить контейнер кнопок по билд листу (прорисовка кнопок)
--аналог SettingConteinerButtonsBuildMenu, только берет данные из билд листа
--@ player PlAyer - игрок, которому создают контейнер;
--@ string build_list_id - идишник списка 
function SettingConteinerButtonsBuildMenuEx(PlAyer,build_list_id)

--обновить контейнер кнопок по номеру фрейм-кнопки вызова (прорисовка кнопок)
--когда жмешь на кнопку вызова меню, то тут же сразу прорисовывается контейнер 
--@ player PlAyer - игрок, которому создают контейнер;
--@ integer num - num 
function SettingConteinerButtonsBuildMenuEx2(PlAyer,num)
func frames tooltip
--создаем подсказку
--на всю меню работает динамично 1 подсказка
--не нужно теперь на каждую кнопку создавать новый набор фреймов и привязывать
--@ player PlAyer - игрок;
--@  x, @ real y - экранные координаты левого нижнего угла текстовой подсказки
--@ real widht_text_frame - ширина текстового окошка (текста);
--@ real gap_between_frames - зазор между фреймами;
--@ real offset_x,@ real offset_y - оффсеты рамки от текста
function CreateTooltipForButtonsBuildMenu(PlAyer,x,y,widht_text_frame,gap_between_frames,offset_x, offset_y)
func frames button cancel
--закрываем меню строительства
--из разных участков приходилось вызовать один и тот же код, решено смоздать эту функцию
--@ integer n - номер игрока 
function CloseBuildMenu(n)

--создать кнопку отмены
--инициируем таблицы,фрейм-кнопку
--по факту: кнопка отмены у каждого игрока всего одна. нужно на старте игры создать ее
--@ player PlAyer - игрок, которому создают кнопку;
--@ integer number_last_button - номер последней кнопки
function CreateButtonCancel(PlAyer)

--задать параметры кнопки отмены
--задает размеры, и к какой кнопке крепить. У разных билд меню разное кол-во кнопок.
--@ player PlAyer - игрок, которому создают кнопку;
--@ integer number_last_button - номер последней кнопки;
--@ real width,@ real height - размеры кнопки отмены
function SettingButtonCancel(PlAyer,number_last_button, width,height)
func frames button menu
кнопки меню уже были созданы ранее функциями (из раздела BuildList):
CreateBuildListButton
InitButtonsBuildMenu
--Обновить показ кнопок для выбранного юнита
--@ player PlAyer - игрок, которому создают контейнер;
--@ integer number_last_button - номер последней кнопки;
--@ booleam flag - показать/скрыть true/false все кнопки вызова меню
function DisplayButtonsBuildMenu(PlAyer,selected_unit, flag)

--макс кол-во кнопок (не путать с BuildList с функцией GetMaxCountBuildList)
--удобнее циклом пробежаться по всем кнопкам меню, зная кол-во
--каждая кнопка вызова меню имеет нумеруется индексом
--@ player Player
function GetMaxCountButtonsBuildMenuForPlayer(Player)
полный код
func build list
    
    --для поворотов не забудьте дать это здание рабам в ро
    id_dummy_for_rotate = FourCC('h00D')
    
    default_path_icon = "ReplaceableTextures\\CommandButtons\\BTNSelectHeroOn"
	path_active_icon = "ReplaceableTextures\\CommandButtons\\BTN"
	path_disabled_icon = "ReplaceableTextures\\CommandButtonsDisabled\\DISBTN"
    path_icon_human_build = "ReplaceableTextures\\CommandButtons\\BTNHumanBuild"
    path_icon_orc_build = "ReplaceableTextures\\CommandButtons\\BTNBasicStruct"
    path_icon_undead_build = "ReplaceableTextures\\CommandButtons\\BTNScourgeBuild"
    path_icon_cancel = "Cancel"
    
    build_menu_text_tip = "Вызывает меню постройки"
    build_menu_text_ubertip = "Показывает весь список здании, который может построить выбранный юнит"
    cancel_text_tip = "Отмена"
    cancel_text_ubertip = "Отменяет выбранный приказ"
    
    
	ToolTipBackground="UI\\Widgets\\ToolTips\\Human\\human-tooltip-background"
	ToolTipBorder="UI\\Widgets\\ToolTips\\Human\\human-tooltip-border"
	ToolTipGoldIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipGoldIcon"
	ToolTipLumberIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipLumberIcon"
	ToolTipStonesIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipStonesIcon"
	ToolTipManaIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipManaIcon"
	ToolTipSupplyIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipSupplyIcon"
	ToolTipHorizontalSeparator="UI\\Widgets\\ToolTips\\Human\\HorizontalSeparator"
 

	ground = 1     --ground-pathable PATHING_TYPE_WALKABILITY   
    air = 2        --air-pathable PATHING_TYPE_FLYABILITY          
    buildable = 4  --buildable PATHING_TYPE_BUILDABILITY
    unblighted = 8 --unblighted PATHING_TYPE_BLIGHTPATHING 
    sea = 16        --sea-pathable PATHING_TYPE_FLOATABILITY
    amphibious = 32 --amphibious-pathable PATHING_TYPE_AMPHIBIOUSPATHING   

    
	BuildList = {}
	list_builder = {}
	list_builder_for_type = {}
	
	--@ string build_list_id - идишник списка;
	--@ table build_list - список;
	--@ real position_x, @ real position_y - положение кнопки вызова меню на экране;
    --@ real button_width,@ real button_height - размеры кнопки вызова меню
	function CreateBuildList(build_list_id,build_list,position_x, position_y,button_width,button_height)

		if type(build_list_id)~='string' then
			print('ошибка CreateBuildList: неверный 1-аргумент') return false
		end
		
		if not BuildList[build_list_id] then
			BuildList[build_list_id] = {}
		end
		BuildList[build_list_id] = build_list or {}
        BuildList[build_list_id].button_buid_menu_width = button_width or 0.039
        BuildList[build_list_id].button_buid_menu_height = button_height or 0.039
		BuildList[build_list_id].button_buid_menu_pos_x = position_x or 0
		BuildList[build_list_id].button_buid_menu_pos_y = position_y or 0
		
		--дефолтные параметры
		BuildList[build_list_id].button_buid_menu_path_icon = path_icon_orc_build
		BuildList[build_list_id].button_buid_menu_hotkey = "B"
		BuildList[build_list_id].button_buid_menu_oskey = OSKEY_B
	end
    
    --настройки контейнера кнопок меню (размеры кнопок,зазоры, координаты, итд)
    --@ string build_list_id - идишник списка;
    --@ real pos_x,@ real pos_y  - экранные координаты левого нижнего угла контейнера;
    --@ integer rows - строки; @ integer columns - столбцы;
    --@ real button_width, @ real button_height - размеры кнопок;
    --@ real gap_between_buttons - зазор между кнопками;
    --@ real offset_x, @ real offset_y - оффсеты рамки;
    --@ string path_backdrop - изображение фона контейнера
    function SettingBuildMenu(build_list_id,pos_x,pos_y,rows,columns,button_width,button_height,gap_between_buttons,offset_x,offset_y, path_backdrop)
		if type(build_list_id)~='string' or (not BuildList[build_list_id]) then
			print('ошибка SettingBuildMenu: неверный 1-аргумент') return false
		end
		BuildList[build_list_id].conteiner_pos_x = pos_x or 0
		BuildList[build_list_id].conteiner_pos_y = pos_y or 0
		BuildList[build_list_id].conteiner_rows = rows or 3
		BuildList[build_list_id].conteiner_columns = columns or 4
		BuildList[build_list_id].conteiner_button_width = button_width or 0.039
		BuildList[build_list_id].conteiner_button_height = button_height or 0.039
		BuildList[build_list_id].conteiner_gap_between_buttons = gap_between_buttons or 0
		BuildList[build_list_id].conteiner_backdrop_offset_x = offset_x or 0
		BuildList[build_list_id].conteiner_backdrop_offset_y = offset_y or 0
		BuildList[build_list_id].conteiner_path_backdrop = path_backdrop or ToolTipBackground
    end
	
	--@ string build_list_id - идишник списка;
	--@ string type_building - ид здание
	function AddBuildListTypeBuilding(build_list_id,type_building)
		
		if type(build_list_id)~='string' or (not BuildList[build_list_id]) then
			print('ошибка AddBuildListTypeBuilding: неверный 1-аргумент') return false
		end
		if type(type_building)~='string' then
			print('ошибка AddBuildListTypeBuilding: неверный 2-аргумент') return false
		end
		
		for k,v in pairs(BuildList[build_list_id]) do 
			if v== type_building then
				return false
			end
		end
		
		table.insert(BuildList[build_list_id],type_building)
	end
	
	--@ string build_list_id - идишник списка;
	--@ string type_building - ид здание
	function RemoveBuildListTypeBuilding(build_list_id,type_building)
		
		if type(build_list_id)~='string' or (not BuildList[build_list_id]) then
			print('ошибка RemoveBuildListTypeBuilding: неверный 1-аргумент') return false
		end
		if type(type_building)~='string' then
			print('ошибка RemoveBuildListTypeBuilding: неверный 2-аргумент') return false
		end
		
		for a=1, #BuildList[build_list_id] do 
			if BuildList[build_list_id][a]== type_building then
				table.remove(BuildList[build_list_id],a)
				break
			end
		end
	end
	
	--@ string build_list_id - идишник списка;
	--@ string path_icon_menu - иконка кнопки меню
	function SetBuildListIcon(build_list_id,path_icon_menu)
		if type(build_list_id)~='string' or (not BuildList[build_list_id]) then
			print('ошибка SetBuildListIcon: неверный 1-аргумент') return false
		end
		BuildList[build_list_id].button_buid_menu_path_icon = path_icon_menu or path_icon_orc_build
	end
	
	--@ string build_list_id - идишник списка;
	--@ string name - название кнопки меню (заглавие)
	function SetBuildingListName(build_list_id, name)
		if type(build_list_id)~='string' or (not BuildList[build_list_id]) then
			print('ошибка SetBuildingListName: неверный 1-аргумент') return false
		end
		BuildList[build_list_id].button_buid_menu_name = name or build_menu_text_tip
	end
	
	--@ string build_list_id - идишник списка;
	--@ string desc - описание меню списка
	function SetBuildingListDescription(build_list_id, desc)
		if type(build_list_id)~='string' or (not BuildList[build_list_id]) then
			print('ошибка SetBuildingListDescription: неверный 1-аргумент') return false
		end
		BuildList[build_list_id].button_buid_menu_desc = desc or build_menu_text_ubertip 
	end
	
	--@ string build_list_id - идишник списка;
	--@ string hotkey - строчная горячая клавиша вызова (для описания tooltip);
	--@ oskey Oskey - кнопка вызова (для работы триггера)
	function SetBuildingListHotkey(build_list_id, Hotkey, Oskey)
		if type(build_list_id)~='string' or (not BuildList[build_list_id]) then
			print('ошибка SetBuildingListHotkey: неверный 1-аргумент') return false
		end
		if type(Hotkey)~='string' then
			print('ошибка SetBuildingListHotkey: неверный 2-аргумент') return false
		end
		if not Oskey then
			print('ошибка SetBuildingListHotkey: неверный 3-аргумент') return false
		end
		BuildList[build_list_id].button_buid_menu_hotkey = Hotkey
		BuildList[build_list_id].button_buid_menu_oskey = Oskey
	end
    --@ player PlaYer - игрок;
    --@ string build_list_id - идишник списка;
    --@@ return integer - номер кнопки
	function GetBuildingListNumberButton(PlaYer,build_list_id)
        local n = GetPlayerId(PlaYer)
		
		if type(build_list_id)~='string' or (not BuildList[build_list_id]) then
			print('ошибка GetBuildingListNumberButton: неверный 1-аргумент') return 0
		end
		
		--у каждого игрока локально могут быть свои фреймы
		if not BuildList[build_list_id].number_of_button_buid_menu then
			BuildList[build_list_id].number_of_button_buid_menu = {}
		end
		
        BuildList[build_list_id].number_of_button_buid_menu[n] = type(BuildList[build_list_id].number_of_button_buid_menu[n])=='number' and BuildList[build_list_id].number_of_button_buid_menu[n] or 0
        return BuildList[build_list_id].number_of_button_buid_menu[n]
    end
    --@ player PlaYer - игрок;
    --@ string build_list_id - идишник списка;
    --@@ return button - кнопка
    function GetBuildingListButton(PlaYer,build_list_id)
        local n = GetPlayerId(PlaYer)
        if type(build_menu)~='table' then print('ошибка GetBuildingListButton: общая таблица build_menu не инициирована') return nil end
        if type(build_menu[n]) ~= 'table' then print('ошибка GetBuildingListButton: таблица игрока build_menu не инициирована') return nil end
        
        if type(build_list_id)~='string' or (not BuildList[build_list_id]) then
			print('ошибка GetBuildingListButton: неверный 1-аргумент') return nil
		end
        local num = GetBuildingListNumberButton(build_list_id)
        if num > 0 then
            return build_menu[n].button_build_menu[num]
        end
        return nil
    end
    
	--включить определенному юниту билд лист
	--@ unit worker - юнит-строитель, рабочий;
	--@ string build_list_id - идишник списка
	function EnableBuildList(worker, build_list_id)
		if GetUnitTypeId( worker ) < 1 then
			print('ошибка EnableBuildList: неверный 1-аргумент') return false
		end
		if type(build_list_id)~='string' or (not BuildList[build_list_id]) then
			print('ошибка EnableBuildList: неверный 2-аргумент') return false
		end
		
		local h = GetHandleId(worker)
		if not list_builder[h] then
			list_builder[h] = {}
		elseif #list_builder[h]>0 then
			for a=1,#list_builder[h] do
				if list_builder[h][a] == build_list_id then
					return false
				end
			end
		end
		
		table.insert(list_builder[h],build_list_id)
	end
	
	--включает у всех типов юнита
	--@ integer unit_type - ид тип юнит-строителя;
	--@ string build_list_id - идишник списка
	function EnableBuildListForUnitType(unit_type, build_list_id)
		if type(unit_type)~='number' or unit_type < 1 then
			print('ошибка EnableBuildListForUnitType: неверный 1-аргумент') return false
		end
		if type(build_list_id)~='string' or (not BuildList[build_list_id]) then
			print('ошибка EnableBuildListForUnitType: неверный 2-аргумент') return false
		end
		
		if not list_builder_for_type[unit_type] then
			list_builder_for_type[unit_type] = {}
		elseif #list_builder_for_type[unit_type]>0 then
			for a=1,#list_builder_for_type[unit_type] do
				if list_builder_for_type[unit_type][a] == build_list_id then
					return false
				end
			end
		end
		
		table.insert(list_builder_for_type[unit_type],build_list_id)
	end
	
	--показывает макс кол-во списков в игре, точно такое кол-во и кнопок в игре
	function GetMaxCountBuildList()
		local max = 0
		
		for k,v in pairs(BuildList) do 
            max = max + 1
		end
		
		return max
	end
    
	
	CreateBuildList('build menu human',{'htow','hhou','hbar','hbla','hwtw','halt','harm','hars','hlum','hgra','hvlt'},0.4, 0.3)
	CreateBuildList('build menu orc',{'ogre','otrb','obar','ofor','oalt','obea','osld','otto','owtw','ovln'},0.4, 0.3)
	CreateBuildList('build menu naga',{'nnfm','nntg','nntt','nnsg','nnsa','nnad'},0.4, 0.3)
	CreateBuildList('build menu undead',{'unpl','uzig','usep','ugrv','uaod','utod','uslh','ubon','usap','ugol','utom'},0.4, 0.3)
	CreateBuildList('build menu blood elf',{'oshy','ushp','eshy','nshp','hshy'},0.4, 0.3)
	CreateBuildList('build menu blood elf-engineer',{'h00C'},0.4, 0.3)
	
	EnableBuildListForUnitType(FourCC('hpea'), 'build menu human')
	EnableBuildListForUnitType(FourCC('opeo'), 'build menu orc')
	EnableBuildListForUnitType(FourCC('nmpe'), 'build menu naga')
	EnableBuildListForUnitType(FourCC('uaco'), 'build menu undead')
	EnableBuildListForUnitType(FourCC('nhew'), 'build menu blood elf')
	EnableBuildListForUnitType(FourCC('nbee'), 'build menu blood elf-engineer')
	
	SetBuildListIcon('build menu human',path_icon_human_build)
	SetBuildListIcon('build menu orc',path_icon_orc_build)
	SetBuildListIcon('build menu naga',path_icon_human_build)
	SetBuildListIcon('build menu undead',path_icon_undead_build)
	SetBuildListIcon('build menu blood elf',path_icon_human_build)
	SetBuildListIcon('build menu blood elf-engineer',path_icon_human_build)
	
	
	data_buildings = {}
	Destructable_Pathing = {}

	--@ string id_building - ид тип здания;
	--@ string path_icon_building - иконка;
	--@ integer button_position_x, @ integer button_position_y - положение иконки
	function CreateBuildListBuilding(id_building,path_icon_building,button_position_x,button_position_y)
		if type(id_building)~='string' then
			print('ошибка CreateBuildListBuilding: неверный 1-аргумент') return false
		end
		id_building = FourCC(id_building)
		
		if not data_buildings[id_building] then
			data_buildings[id_building] = {}
		end
		data_buildings[id_building].icon=path_icon_building or default_path_icon
		data_buildings[id_building].icon_pos_x=button_position_x or 0
		data_buildings[id_building].icon_pos_y=button_position_y or 0
		data_buildings[id_building].name_building=GetObjectName(id_building)
		data_buildings[id_building].gold_cost=0
		data_buildings[id_building].lumber_cost=0
	end
	
	--@ string id_building - ид тип здания;
	--@ string path_model_building - модель здания;
	--@ real scale - размер модели (процентный множитель)
	function SetBuildListBuildingModel(id_building,path_model_building,scale)
		
		local ID = FourCC(id_building)
		if type(id_building)~='string' or (not data_buildings[ID]) then
			print('ошибка SetBuildListBuildingModel: неверный 1-аргумент') return false
		end
		
		data_buildings[ID].model=path_model_building or nil
		data_buildings[ID].scale_model=scale or 1.00 --дефолт размер = 1.00
	end
	
	--@ string id_building - ид тип здания;
	--@ integer gold - золото
	function SetBuildListBuildingGoldCost(id_building,gold)
		local ID = FourCC(id_building)
		if type(id_building)~='string' or (not data_buildings[ID]) then
			print('ошибка SetBuildListBuildingGoldCost: неверный 1-аргумент') return false
		end
		data_buildings[ID].gold_cost=type(gold)=='number' and gold or 0
	end
	--@ string id_building - ид тип здания;
	--@ integer lumber - древесина
	function SetBuildListBuildingLumberCost(id_building,lumber)
		local ID = FourCC(id_building)
		if type(id_building)~='string' or (not data_buildings[ID]) then
			print('ошибка SetBuildListBuildingLumberCost: неверный 1-аргумент') return false
		end
		data_buildings[ID].lumber_cost=type(lumber)=='number' and lumber or 0
	end
	--@ string id_building - ид тип здания;
	--@ integer gold - золото;
	--@ integer lumber - древесина
	function SetBuildListBuildingResourcesCost(id_building,gold,lumber)
		SetBuildListBuildingGoldCost(id_building,gold)
		SetBuildListBuildingLumberCost(id_building,lumber)
	end
	--@ string id_building - ид тип здания;
	--@ table Buildings_requirements - требование: построить список указанных здании;
	--@ table Tech_requirements - требование: изучить список указанных технологии
	function AddBuildListTechRequirement(id_building,Buildings_requirements,Tech_requirements)
		local ID = FourCC(id_building)
		if type(id_building)~='string' or (not data_buildings[ID]) then
			print('ошибка AddBuildListTechRequirement: неверный 1-аргумент') return false
		end
		--если эти требования указаны, иначе ничего не делать
		if Buildings_requirements then
			data_buildings[ID].buildings_requirements=type(Buildings_requirements)=='table' and Buildings_requirements
		end
		if Tech_requirements then
			data_buildings[ID].tech_requirements=type(Tech_requirements)=='table' and Tech_requirements
		end
	end
	
	--@ string id_building - ид тип здания;
	--@ string hotkey - строчная горячая клавиша вызова (для описания tooltip);
	--@ oskey Oskey - кнопка вызова (для работы триггера)
	function SetBuildListBuildingHotkey(id_building, Hotkey, Oskey)
		local ID = FourCC(id_building)
		if type(id_building)~='string' or (not data_buildings[ID]) then
			print('ошибка SetBuildListBuildingHotkey: неверный 1-аргумент') return false
		end
		if type(Hotkey)~='string' then
			print('ошибка SetBuildListBuildingHotkey: неверный 2-аргумент') return false
		end
		if not Oskey then
			print('ошибка SetBuildListBuildingHotkey: неверный 3-аргумент') return false
		end
		data_buildings[ID].hotkey = Hotkey
		data_buildings[ID].oskey = Oskey
	end
	
	--@ string id_building - ид тип здания;
	--@ integer WidtH , @ integer HeighT - размеры площадки пример: клетки 4x4 (размеры 1 клетки 32x32);
	--@ integer required_to_build - требование строить в определенных типах паффинга (флаги, биты)
	--@ integer forbidden_to_build - запрещено строить в определенных типах паффинга (флаги, биты)
	--@ real radius_water - требование строиться около воды для верфи (в указанном радиусе должна быть вода)
	function SetBuildListBuildingPathing(id_building,WidtH,HeighT,Required_to_build,Forbidden_to_build,Radius_water)
		local ID = FourCC(id_building)
		if type(id_building)~='string' or (not data_buildings[ID]) then
			print('ошибка SetBuildListBuildingPathing: неверный 1-аргумент') return false
		end
		data_buildings[ID].width = type(WidtH) == 'number' and WidtH*32
		data_buildings[ID].height = type(HeighT) == 'number' and HeighT*32
		data_buildings[ID].required_to_build = type(Required_to_build) == 'number' and Required_to_build or 0
		data_buildings[ID].forbidden_to_build = type(Forbidden_to_build) == 'number' and Forbidden_to_build or 0
		data_buildings[ID].radius_water = type(Radius_water) == 'number' and Radius_water or 0
	end
	
	--@ string id_building - ид тип здания;
	--@ string title - заглавие
	function SetBuildListBuildingTitle(id_building,Title)
		local ID = FourCC(id_building)
		if type(id_building)~='string' or (not data_buildings[ID]) then
			print('ошибка SetBuildListBuildingTitle: неверный 1-аргумент') return false
		end
		data_buildings[ID].title = type(Title) == 'string' and Title or 'Привет'
	end
	
	
	--@ string id_building - ид тип здания;
	--@ string desc - описание
	function SetBuildListBuildingDescription(id_building,desc)
		local ID = FourCC(id_building)
		if type(id_building)~='string' or (not data_buildings[ID]) then
			print('ошибка SetBuildListBuildingDescription: неверный 1-аргумент') return false
		end
		data_buildings[ID].description = type(desc) == 'string' and desc or 'тут что-то должно было написано'
	end
	
	--@ string id_building - ид тип здания;
	--@ boolean flag - может ли здание поворачиваться колесом мыши
	function SetBuildListBuildingAbilityToTurn(id_building,flag)
		local ID = FourCC(id_building)
		if type(id_building)~='string' or (not data_buildings[ID]) then
			print('ошибка SetBuildListBuildingAbilityToTurn: неверный 1-аргумент') return false
		end
		data_buildings[ID].ability_to_rotate = flag
	end

	--@ string id_destructable - ид тип декорации;
	--@ integer type_pathing - карта путей (см. ниже): 
	--[[
		ground = 1     --ground-pathable PATHING_TYPE_WALKABILITY   
		air = 2        --air-pathable PATHING_TYPE_FLYABILITY          
		buildable = 4  --buildable PATHING_TYPE_BUILDABILITY
		unblighted = 8 --unblighted PATHING_TYPE_BLIGHTPATHING 
		sea = 16        --sea-pathable PATHING_TYPE_FLOATABILITY
		amphibious = 32 --amphibious-pathable PATHING_TYPE_AMPHIBIOUSPATHING
		
		можно ничего не указывать, по дефолту: buildable + ground
	]]
	--@ integer WidtH, @ integer HeighT - размеры паффинга декора, пример: клетки 4x4 (размеры 1 клетки 32x32);
	function SetBuildListDestructablePathing(id_destructable,type_pathing,WidtH,HeighT)
		local ID = FourCC(id_destructable)
		if type(id_destructable)~='string' or (not Destructable_Pathing[ID]) then
			print('ошибка SetBuildListDestructablePathing: неверный 1-аргумент') return false
		end
		if not Destructable_Pathing[id_destructable] then
			Destructable_Pathing[id_destructable] = {}
		end
		Destructable_Pathing[id_destructable].width = type(WidtH)=='number' and WidtH*32 or 128
		Destructable_Pathing[id_destructable].height = type(HeighT)=='number' and HeighT*32 or 128
		Destructable_Pathing[id_destructable].pathing = type(type_pathing)=='number' and type_pathing or (buildable+ground)
	end
	

	--здесь запись всех зданий, которые могут быть повернутыми
	SetBuildListBuildingAbilityToTurn('h00C',true)
	
    --peasant (human)
	CreateBuildListBuilding('htow',"TownHall",0,0)
	CreateBuildListBuilding('hhou',"Farm",0,1)
	CreateBuildListBuilding('hbar',"HumanBarracks",1,0)
	CreateBuildListBuilding('hbla',"Blacksmith",3,0)
	CreateBuildListBuilding('hwtw',"HumanWatchTower",0,2)
	CreateBuildListBuilding('halt',"AltarOfKings",1,1)
	CreateBuildListBuilding('harm',"Workshop",3,1)
	CreateBuildListBuilding('hars',"ArcaneSanctum",2,1)
	CreateBuildListBuilding('hlum',"HumanLumberMill",2,0)
	CreateBuildListBuilding('hgra',"GryphonAviary",1,2)
	CreateBuildListBuilding('hvlt',"ArcaneVault",2,2)
    --peon (orc)
	CreateBuildListBuilding('ogre',"Greathall",0,0)
	CreateBuildListBuilding('otrb',"TrollBurrow",0,1)
	CreateBuildListBuilding('obar',"Barracks",1,0)
	CreateBuildListBuilding('ofor',"Forge",2,0)
	CreateBuildListBuilding('oalt',"AltarOfStorms",1,1)
	CreateBuildListBuilding('obea',"Beastiary",3,1)
	CreateBuildListBuilding('osld',"SpiritLodge",2,1)
	CreateBuildListBuilding('otto',"TaurenTotem",0,2)
	CreateBuildListBuilding('owtw',"OrcTower",3,0)
	CreateBuildListBuilding('ovln',"VoodooLounge",1,2)
    --acolyte (undead)
	CreateBuildListBuilding('unpl',"Necropolis",0,0)
	CreateBuildListBuilding('uzig',"Ziggurat",0,1)
	CreateBuildListBuilding('usep',"Crypt",1,0)
	CreateBuildListBuilding('ugrv',"Graveyard",3,0)
	CreateBuildListBuilding('uaod',"AltarOfDarkness",1,1)
	CreateBuildListBuilding('utod',"TempleOfTheDamned",2,1)
	CreateBuildListBuilding('uslh',"Slaughterhouse",3,1)
	CreateBuildListBuilding('ubon',"Boneyard",1,2)
	CreateBuildListBuilding('usap',"SacrificialPit",0,2)
	CreateBuildListBuilding('ugol',"GoldMine",2,0)
	CreateBuildListBuilding('utom',"TombOfRelics",2,2)
    --worker (naga)
	CreateBuildListBuilding('nnad',"AltarOfDepths",0,0)
	CreateBuildListBuilding('nnfm',"CoralBed",2,0)
	CreateBuildListBuilding('nnsg',"SpawningGrounds",1,0)
	CreateBuildListBuilding('nnsa',"ShrineOfAszhara",0,1)
	CreateBuildListBuilding('nntt',"TempleOfTides",0,0)
	CreateBuildListBuilding('nntg',"TidalGuardian",3,0)
    --worker (blood elf)
	CreateBuildListBuilding('oshy',"GoblinShipyard")
	CreateBuildListBuilding('ushp',"UndeadShipyard")
	CreateBuildListBuilding('eshy',"NightElfShipyard")
	CreateBuildListBuilding('nshp',"GoblinShipyard")
	CreateBuildListBuilding('hshy',"HumanShipyard")
    --engineer (blood elf)
    CreateBuildListBuilding('h00C',"IceCrownObelisk")


	SetBuildListBuildingModel('htow',"buildings\\human\\TownHall\\TownHall")
	SetBuildListBuildingModel('hhou',"buildings\\human\\Farm\\Farm")
	SetBuildListBuildingModel('hbar',"buildings\\human\\HumanBarracks\\HumanBarracks")
	SetBuildListBuildingModel('hbla',"buildings\\human\\Blacksmith\\Blacksmith")
	SetBuildListBuildingModel('hwtw',"buildings\\human\\HumanTower\\HumanTower")
	SetBuildListBuildingModel('halt',"buildings\\human\\AltarofKings\\AltarofKings")
	SetBuildListBuildingModel('harm',"buildings\\human\\Workshop\\Workshop")
	SetBuildListBuildingModel('hars',"buildings\\human\\ArcaneSanctum\\ArcaneSanctum")
	SetBuildListBuildingModel('hlum',"buildings\\human\\HumanLumbermill\\HumanLumbermill")
	SetBuildListBuildingModel('hgra',"buildings\\human\\GryphonAviary\\GryphonAviary")
	SetBuildListBuildingModel('hvlt',"buildings\\human\\ArcaneVault\\ArcaneVault")
    
    --peon (orc)
	SetBuildListBuildingModel('ogre',"buildings\\orc\\GreatHall\\GreatHall")
	SetBuildListBuildingModel('otrb',"buildings\\orc\\TrollBurrow\\TrollBurrow")
	SetBuildListBuildingModel('obar',"buildings\\orc\\OrcBarracks\\OrcBarracks")
	SetBuildListBuildingModel('ofor',"buildings\\orc\\WarMill\\WarMill")
	SetBuildListBuildingModel('oalt',"buildings\\orc\\AltarofStorms\\AltarofStorms")
	SetBuildListBuildingModel('obea',"buildings\\orc\\Beastiary\\Beastiary")
	SetBuildListBuildingModel('osld',"buildings\\orc\\SpiritLodge\\SpiritLodge")
	SetBuildListBuildingModel('otto',"buildings\\orc\\TaurenTotem\\TaurenTotem")
	SetBuildListBuildingModel('owtw',"buildings\\orc\\WatchTower\\WatchTower")
	SetBuildListBuildingModel('ovln',"buildings\\orc\\VoodooLounge\\VoodooLounge")
    --acolyte (undead)
	SetBuildListBuildingModel('unpl',"buildings\\undead\\Necropolis\\Necropolis")
	SetBuildListBuildingModel('uzig',"buildings\\undead\\Ziggurat\\Ziggurat")
	SetBuildListBuildingModel('usep',"buildings\\undead\\Crypt\\Crypt")
	SetBuildListBuildingModel('ugrv',"buildings\\undead\\Graveyard\\Graveyard")
	SetBuildListBuildingModel('uaod',"buildings\\undead\\AltarOfDarkness\\AltarOfDarkness")
	SetBuildListBuildingModel('utod',"buildings\\undead\\TempleOfTheDamned\\TempleOfTheDamned")
	SetBuildListBuildingModel('uslh',"buildings\\undead\\Slaughterhouse\\Slaughterhouse")
	SetBuildListBuildingModel('ubon',"buildings\\undead\\BoneYard\\BoneYard")
	SetBuildListBuildingModel('usap',"buildings\\undead\\SacrificialPit\\SacrificialPit")
	SetBuildListBuildingModel('ugol',"buildings\\undead\\HauntedMine\\HauntedMine")
	SetBuildListBuildingModel('utom',"buildings\\undead\\TombOfRelics\\TombOfRelics")
    --worker (naga)
	SetBuildListBuildingModel('nnad',"buildings\\naga\\AltarOfDepths\\AltarOfDepths")
	SetBuildListBuildingModel('nnfm',"buildings\\naga\\CoralBed\\CoralBed")
	SetBuildListBuildingModel('nnsg',"buildings\\naga\\SpawningGrounds\\SpawningGrounds")
	SetBuildListBuildingModel('nnsa',"buildings\\naga\\ShrineOfAshjara\\ShrineOfAshjara")
	SetBuildListBuildingModel('nntt',"buildings\\naga\\TempleofTides\\TempleofTides")
	SetBuildListBuildingModel('nntg',"buildings\\naga\\TidalGuardian\\TidalGuardian")
    --worker (blood elf)
	SetBuildListBuildingModel('oshy',"buildings\\other\\GoblinShipyard\\GoblinShipyard")
	SetBuildListBuildingModel('ushp',"buildings\\undead\\UndeadShipyard\\UndeadShipyard")
	SetBuildListBuildingModel('eshy',"buildings\\NightElf\\NightElfShipyard\\NightElfShipyard")
	SetBuildListBuildingModel('nshp',"buildings\\other\\GoblinShipyard\\GoblinShipyard")
	SetBuildListBuildingModel('hshy',"buildings\\human\\HumanShipyard\\HumanShipyard")

    --ingeneer (blood elf)
	SetBuildListBuildingModel('h00C',"Leather Wall.mdl",0.6)
    
	--peasant (human)
	SetBuildListBuildingResourcesCost('htow',385,205)
	SetBuildListBuildingResourcesCost('hhou',80,20)
	SetBuildListBuildingResourcesCost('hbar',160,60)
	SetBuildListBuildingResourcesCost('hbla',140,60)
	SetBuildListBuildingResourcesCost('hwtw',30,20)
	SetBuildListBuildingResourcesCost('halt',180,50)
	SetBuildListBuildingResourcesCost('harm',140,140)
	SetBuildListBuildingResourcesCost('hars',150,140)
	SetBuildListBuildingResourcesCost('hlum',145,0)
	SetBuildListBuildingResourcesCost('hgra',120,240)
	SetBuildListBuildingResourcesCost('hvlt',130,30)
    --peon (orc)
	SetBuildListBuildingResourcesCost('ogre',385,185)
	SetBuildListBuildingResourcesCost('otrb',160,40)
	SetBuildListBuildingResourcesCost('obar',180,50)
	SetBuildListBuildingResourcesCost('ofor',205,0)
	SetBuildListBuildingResourcesCost('oalt',180,50)
	SetBuildListBuildingResourcesCost('obea',145,140)
	SetBuildListBuildingResourcesCost('osld',150,150)
	SetBuildListBuildingResourcesCost('otto',90,200)
	SetBuildListBuildingResourcesCost('owtw',110,80)
	SetBuildListBuildingResourcesCost('ovln',130,30)
    --acolyte (undead)
	SetBuildListBuildingResourcesCost('unpl',255,0)
	SetBuildListBuildingResourcesCost('uzig',150,50)
	SetBuildListBuildingResourcesCost('usep',200,50)
	SetBuildListBuildingResourcesCost('ugrv',215,0)
	SetBuildListBuildingResourcesCost('uaod',180,50)
	SetBuildListBuildingResourcesCost('utod',155,140)
	SetBuildListBuildingResourcesCost('uslh',140,135)
	SetBuildListBuildingResourcesCost('ubon',125,250)
	SetBuildListBuildingResourcesCost('usap',75,150)
	SetBuildListBuildingResourcesCost('ugol',255,220)
	SetBuildListBuildingResourcesCost('utom',130,30)
    --worker (naga)
	SetBuildListBuildingResourcesCost('nnad',255,100)
	SetBuildListBuildingResourcesCost('nnfm',115,40)
	SetBuildListBuildingResourcesCost('nnsg',205,60)
	SetBuildListBuildingResourcesCost('nnsa',180,70)
	SetBuildListBuildingResourcesCost('nntt',385,150)
	SetBuildListBuildingResourcesCost('nntg',130,80)
    --worker (blood elf) 
	SetBuildListBuildingResourcesCost('oshy',50,0)
	SetBuildListBuildingResourcesCost('ushp',50,0)
	SetBuildListBuildingResourcesCost('eshy',50,0)
	SetBuildListBuildingResourcesCost('nshp',50,0)
	SetBuildListBuildingResourcesCost('hshy',50,0)
	
    --peasant (human)
	AddBuildListTechRequirement('hbla',{'htow'})
	AddBuildListTechRequirement('harm',{'hkee','hbla'})
	AddBuildListTechRequirement('hars',{'hkee'})
	AddBuildListTechRequirement('hgra',{'hcas','hlum'})
    --peon (orc)
	AddBuildListTechRequirement('otto',{'htow'})
	AddBuildListTechRequirement('osld',{'ostr'})
	AddBuildListTechRequirement('obea',{'ostr'})
	AddBuildListTechRequirement('owtw',{'ofor'})
    --acolyte (undead)
	AddBuildListTechRequirement('utod',{'unp1','ugrv'})
	AddBuildListTechRequirement('uslh',{'unp1','ugrv'})
	AddBuildListTechRequirement('ubon',{'unp2','usap'})
	AddBuildListTechRequirement('usap',{'unp1'})

	--peasant (human)
	SetBuildListBuildingPathing('htow',16,16,buildable)
	SetBuildListBuildingPathing('hhou',4,4,buildable)
	SetBuildListBuildingPathing('hbar',12,12,buildable)
	SetBuildListBuildingPathing('hbla',8,8,buildable)
	SetBuildListBuildingPathing('hwtw',4,4,buildable)
	SetBuildListBuildingPathing('halt',10,10,buildable)
	SetBuildListBuildingPathing('harm',12,12,buildable)
	SetBuildListBuildingPathing('hars',12,12,buildable)
	SetBuildListBuildingPathing('hlum',10,10,buildable)
	SetBuildListBuildingPathing('hgra',8,8,buildable)
	SetBuildListBuildingPathing('hvlt',12,12,buildable)
	--peon (orc)
	SetBuildListBuildingPathing('ogre',16,16,buildable)
	SetBuildListBuildingPathing('otrb',6,6,buildable)
	SetBuildListBuildingPathing('obar',12,12,buildable)
	SetBuildListBuildingPathing('ofor',6,6,buildable)
	SetBuildListBuildingPathing('oalt',10,10,buildable)
	SetBuildListBuildingPathing('obea',12,12,buildable)
	SetBuildListBuildingPathing('osld',12,12,buildable)
	SetBuildListBuildingPathing('otto',12,12,buildable)
	SetBuildListBuildingPathing('owtw',4,4,buildable)
	SetBuildListBuildingPathing('ovln',12,12,buildable)
    --acolyte (undead)
	SetBuildListBuildingPathing('unpl',16,16,buildable)
    SetBuildListBuildingPathing('uzig',6,6,buildable,unblighted)
	SetBuildListBuildingPathing('usep',12,12,buildable,unblighted)
	SetBuildListBuildingPathing('ugrv',12,12,buildable,unblighted)
	SetBuildListBuildingPathing('uaod',10,10,buildable,unblighted)
	SetBuildListBuildingPathing('utod',12,12,buildable,unblighted)
	SetBuildListBuildingPathing('uslh',12,12,buildable,unblighted)
	SetBuildListBuildingPathing('ubon',12,12,buildable,unblighted)
	SetBuildListBuildingPathing('usap',12,12,buildable,unblighted)
	SetBuildListBuildingPathing('ugol',16,16)
	SetBuildListBuildingPathing('utom',12,12,buildable,unblighted)
    --worker (naga)
	SetBuildListBuildingPathing('nnad',10,10,ground)
	SetBuildListBuildingPathing('nnfm',6,6,ground)
	SetBuildListBuildingPathing('nnsg',12,12,ground)
	SetBuildListBuildingPathing('nnsa',12,12,ground)
	SetBuildListBuildingPathing('nntt',16,16,ground)
	SetBuildListBuildingPathing('nntg',4,4,ground)
    --worker (blood elf)
	SetBuildListBuildingPathing('oshy',8,8,ground,0,384.000)
	SetBuildListBuildingPathing('ushp',12,12,ground,0,384.000)
	SetBuildListBuildingPathing('eshy',6,6,ground,0,384.000)
	SetBuildListBuildingPathing('nshp',8,8,ground,0,384.000)
	SetBuildListBuildingPathing('hshy',6,6,ground,0,384.000)
    --neutral
	SetBuildListBuildingPathing('ngol',16,16,buildable)

    --engineer (blood elf)
	SetBuildListBuildingPathing('h00C',10,4,buildable)

	--peasant (human)
	SetBuildListBuildingTitle('htow',"Построить ратушу")
	SetBuildListBuildingTitle('hhou',"Построить ферму")
	SetBuildListBuildingTitle('hbar',"Построить казармы")
	SetBuildListBuildingTitle('hbla',"Построить кузницу")
	SetBuildListBuildingTitle('hwtw',"Построить дозорную башню")
	SetBuildListBuildingTitle('halt',"Построить алтарь королей")
	SetBuildListBuildingTitle('harm',"Построить мастерскую")
	SetBuildListBuildingTitle('hars',"Построить волшебное святилище")
	SetBuildListBuildingTitle('hlum',"Построить лесопилку")
	SetBuildListBuildingTitle('hgra',"Построить авиарий")
	SetBuildListBuildingTitle('hvlt',"Построить волшебное хранилище")
    --peon (orc)
	SetBuildListBuildingTitle('ogre',"Построить дом вождей")
	SetBuildListBuildingTitle('otrb',"Построить землянку")
	SetBuildListBuildingTitle('obar',"Построить казармы")
	SetBuildListBuildingTitle('ofor',"Построить лесопилку")
	SetBuildListBuildingTitle('oalt',"Построить алтарь бури")
	SetBuildListBuildingTitle('obea',"Построить зверинец")
	SetBuildListBuildingTitle('osld',"Построить обитель духов")
	SetBuildListBuildingTitle('otto',"Построить тауренский тотем")
	SetBuildListBuildingTitle('owtw',"Построить сторожевую башню")
	SetBuildListBuildingTitle('ovln',"Построить лавку вуду")
    --acolyte (undead)
	SetBuildListBuildingTitle('unpl',"Призвать некрополь")
	SetBuildListBuildingTitle('uzig',"Призвать зиккурат")
	SetBuildListBuildingTitle('usep',"Призвать склеп")
	SetBuildListBuildingTitle('ugrv',"Призвать кладбище")
	SetBuildListBuildingTitle('uaod',"Призвать алтарь тьмы")
	SetBuildListBuildingTitle('utod',"Призвать храм проклятых")
	SetBuildListBuildingTitle('uslh',"Призвать бойню")
	SetBuildListBuildingTitle('ubon',"Призвать костяной двор")
	SetBuildListBuildingTitle('usap',"Призвать жертвенную яму")
	SetBuildListBuildingTitle('ugol',"Проклясть рудник")
	SetBuildListBuildingTitle('utom',"Призвать реликварий")
    --worker (naga)
	SetBuildListBuildingTitle('nnad',"Построить алтарь глубин")
	SetBuildListBuildingTitle('nnfm',"Вырастить коралловый риф")
	SetBuildListBuildingTitle('nnsg',"Построить нерестилище")
	SetBuildListBuildingTitle('nnsa',"Построить святилище Азшары")
	SetBuildListBuildingTitle('nntt',"Построить храм пучины")
	SetBuildListBuildingTitle('nntg',"Построить приливный страж")
	--worker (blood elf)
	SetBuildListBuildingTitle('oshy',"Построить верфь Орды")
	SetBuildListBuildingTitle('ushp',"Построить верфь Нежити")
	SetBuildListBuildingTitle('eshy',"Построить верфь ночных эльфов")
	SetBuildListBuildingTitle('nshp',"Построить гоблинскую верфь (нейтрал)")
	SetBuildListBuildingTitle('hshy',"Построить верфь Альянса")
    --ingeneer (blood elf)
	SetBuildListBuildingTitle('h00C',"Построить поворачиваемые ворота")
    
    build_text_ubertip = {}
    --peasant (human)
	SetBuildListBuildingDescription('htow',"Базовое здание. Обучает работников и хранит добытые ресурсы. Можно улучшить до форта, а затем до замка, чтобы получить доступ к новым зданиям и типам войск.")
	SetBuildListBuildingDescription('hhou',"Предоставляет припасы, увеличивая максимальную численность армии.")
	SetBuildListBuildingDescription('hbar',"Здание для подготовки базовых войск. Обучает пехотинцев, стрелков и рыцарей. |nДает доступ к «Защите», «Длинноствольным мушкетам» и «Дрессировке животных».")
    SetBuildListBuildingDescription('hbla',"Позволяет улучшать доспехи, оружие и порох.")
	SetBuildListBuildingDescription('hwtw',"Базовая наблюдательная башня. Не может атаковать, но может быть улучшена до сторожевой, магической или орудийной башни. Можно оснастить «Магическим стражем».")
	SetBuildListBuildingDescription('halt',"Призывает новых и воскрешает павших героев.")
	SetBuildListBuildingDescription('harm',"Строит осадные машины и ветролеты, а также обучает мортирные расчеты. |nДает доступ к осветительным зарядам, картечи, залповому огню, авиабомбам и зенитным орудиям.")
	SetBuildListBuildingDescription('hars',"Обучает жрецов, волшебниц и разрушителей чар. |nДает доступ к улучшениям для жрецов и волшебниц, а также к «Магическому контролю» и «Магическому стражу».")
	SetBuildListBuildingDescription('hlum',"Хранит добытую древесину. |nДает доступ к новым технологиям добычи древесины и строительства.")
	SetBuildListBuildingDescription('hgra',"Обучает наездников на грифонах и дракондорах. |nДает доступ к «Грозовому молоту» и «Туману».")
	SetBuildListBuildingDescription('hvlt',"Позволяет покупать предметы. Ассортимент зависит от уровня главного здания базы (ратуша, форт или замок) и наличия других зданий.")
    --peon (orc)
	SetBuildListBuildingDescription('ogre',"Базовое здание. Обучает батраков и хранит добытые ресурсы. Можно улучшить до крепости, а затем – до цитадели, чтобы получить доступ к новым зданиям и типам войск.")
    SetBuildListBuildingDescription('otrb',"Предоставляет припасы, увеличивая максимальную численность армии. Батраки могут укрыться в землянке и атаковать врагов. Можно улучшить с помощью укрепленных стен. |n|n|cffffcc00Атакует наземные и воздушные цели.|r")
    SetBuildListBuildingDescription('obar',"Здание для подготовки базовых войск. Обучает рубак и охотников за головами, а также строит разрушители. |nДает доступ к «Грубой силе», «Берсерку», «Регенерации троллей» и «Горючей смеси».")
    SetBuildListBuildingDescription('ofor',"Хранит добытую древесину. |nДает доступ к улучшениям для доспехов и оружия, а также позволяет строить укрепления.")
    SetBuildListBuildingDescription('oalt',"Призывает новых и воскрешает павших героев.")
    SetBuildListBuildingDescription('obea',"Обучает налетчиков, кодо, а также наездников на нетопырях и ветрокрылах. |nДает доступ к «Опутыванию», «Отравленным копьям», «Жидкому огню» и «Боевым барабанам».")
    SetBuildListBuildingDescription('osld',"Здание для подготовки магов. Обучает шаманов и знахарей. |nДает доступ к улучшениям для шаманов и знахарей.")
    SetBuildListBuildingDescription('otto',"Обучает духостранников и тауренов. |nДает доступ к улучшениям для духостранников и тауренов.")
    SetBuildListBuildingDescription('owtw',"Оборонительное сооружение. Можно улучшить с помощью укрепленных стен. |n|n|cffffcc00Атакует наземные и воздушные цели.|r")
	SetBuildListBuildingDescription('ovln',"Позволяет покупать предметы. Ассортимент зависит от уровня главного здания базы (дом вождей, крепость или цитадель) и наличия других зданий.")
    --acolyte (undead)
	SetBuildListBuildingDescription('unpl',"Базовое здание. Обучает послушников и хранит древесину. Можно улучшить до чертогов мертвых, а затем – до темной цитадели, чтобы получить доступ к новым зданиям и типам войск.")
	SetBuildListBuildingDescription('uzig',"Предоставляет припасы, увеличивая максимальную численность армии. Можно улучшить до оборонительного здания, способного атаковать наземные и воздушные цели.")
	SetBuildListBuildingDescription('usep',"Базовое здание для подготовки войск. Призывает вурдалаков, некроарахнидов и горгулий. Дает доступ к «Ярости вурдалака», «Каннибализму», «Каменной форме», «Паутине» и «Закопаться».")
    SetBuildListBuildingDescription('ugrv',"Дает доступ к улучшениям для оружия и доспехов нежити. Производит трупы и хранит добытую древесину.")
    SetBuildListBuildingDescription('uaod',"Призывает новых и воскрешает павших героев.")
	SetBuildListBuildingDescription('utod',"Обучает некромантов и банши. |nДает доступ к улучшениям для некромантов и банши, а также к «Живучим скелетам» и «Искусному воскрешению».")
	SetBuildListBuildingDescription('uslh',"Создает поганищ и обсидиановые статуи, а также строит мясные фургоны. Дает доступ к «Болезнетворному облаку» и «Облику сфинкса».")
	SetBuildListBuildingDescription('ubon',"Создает ледяных змеев. Дает доступ к «Леденящему дыханию».")
	SetBuildListBuildingDescription('usap',"Позволяет совершать жертвоприношения, превращая послушников в невидимые тени. Тени обнаруживают невидимые войска, но не могут атаковать.")
	SetBuildListBuildingDescription('ugol',"Поражает рудник проклятием, после чего послушники могут добывать из него золото.")
	SetBuildListBuildingDescription('utom',"Позволяет покупать предметы. Ассортимент зависит от уровня главного здания базы (некрополь, чертоги мертвых или темная цитадель) и наличия других зданий.")
    --worker (naga)
	SetBuildListBuildingDescription('nnad',"Призывает новых и воскрешает павших героев.")
	SetBuildListBuildingDescription('nnfm',"Предоставляет припасы, увеличивая максимальную численность армии.")
	SetBuildListBuildingDescription('nnsg',"Обучает мирмидонов, морских варанов и наг-сирен. Дает доступ к «Опутыванию», коралловым клинкам и коралловой чешуе.")
	SetBuildListBuildingDescription('nnsa',"Обучает сирен и коатлей. Дает доступ к улучшениям для сирен и коатлей.")
	SetBuildListBuildingDescription('nntt',"Базовое здание. Обучает мурлоков-рабов и мурлоков-разорителей, а также хранит добытые ресурсы. Дает доступ к улучшениям для доспехов и оружия наг, а также к «Погружению».")
	SetBuildListBuildingDescription('nntg',"Базовое оборонительное сооружение.|n|n|cffffcc00Атакует наземные и воздушные цели.|r")
	
    --worker (blood elf)
	SetBuildListBuildingDescription('oshy',"Строит транспорты, фрегаты и линкоры Орды.")
	SetBuildListBuildingDescription('ushp',"Строит транспорт, фрегаты и линкоры нежити.")
	SetBuildListBuildingDescription('eshy',"Строит транспорты, фрегаты и линкоры ночных эльфов.")
	SetBuildListBuildingDescription('nshp',"Продает корабли")
	SetBuildListBuildingDescription('hshy',"Строит транспорты, фрегаты и линкоры Альянса.")
    --ingeneer (blood elf)
	SetBuildListBuildingDescription('h00C',"Базовые ворота, которые можно повернуть колесиком")

    --peasant (human)
	SetBuildListBuildingHotkey('htow', "H", OSKEY_H)
	SetBuildListBuildingHotkey('hhou', "F", OSKEY_F)
	SetBuildListBuildingHotkey('hbar', "B", OSKEY_B)
	SetBuildListBuildingHotkey('hbla', "S", OSKEY_S)
	SetBuildListBuildingHotkey('hwtw', "T", OSKEY_T)
	SetBuildListBuildingHotkey('halt', "A", OSKEY_A)
	SetBuildListBuildingHotkey('harm', "W", OSKEY_W)
	SetBuildListBuildingHotkey('hars', "R", OSKEY_R)
	SetBuildListBuildingHotkey('hlum', "L", OSKEY_L)
	SetBuildListBuildingHotkey('hgra', "G", OSKEY_G)
	SetBuildListBuildingHotkey('hvlt', "V", OSKEY_V)
    --peon (orc)
	SetBuildListBuildingHotkey('ogre', "H", OSKEY_H)
	SetBuildListBuildingHotkey('otrb', "O", OSKEY_O)
	SetBuildListBuildingHotkey('obar', "B", OSKEY_B)
	SetBuildListBuildingHotkey('ofor', "M", OSKEY_M)
	SetBuildListBuildingHotkey('oalt', "A", OSKEY_A)
	SetBuildListBuildingHotkey('obea', "E", OSKEY_E)
	SetBuildListBuildingHotkey('osld', "S", OSKEY_S)
	SetBuildListBuildingHotkey('otto', "T", OSKEY_T)
	SetBuildListBuildingHotkey('owtw', "W", OSKEY_W)
	SetBuildListBuildingHotkey('ovln', "V", OSKEY_V)
    --acolyte (undead)
	SetBuildListBuildingHotkey('unpl', "N", OSKEY_N)
	SetBuildListBuildingHotkey('uzig', "Z", OSKEY_Z)
	SetBuildListBuildingHotkey('usep', "C", OSKEY_C)
	SetBuildListBuildingHotkey('ugrv', "V", OSKEY_V)
	SetBuildListBuildingHotkey('uaod', "A", OSKEY_A)
	SetBuildListBuildingHotkey('utod', "T", OSKEY_T)
	SetBuildListBuildingHotkey('uslh', "H", OSKEY_H)
	SetBuildListBuildingHotkey('ubon', "B", OSKEY_B)
	SetBuildListBuildingHotkey('usap', "S", OSKEY_S)
	SetBuildListBuildingHotkey('ugol', "G", OSKEY_G)
	SetBuildListBuildingHotkey('utom', "R", OSKEY_R)
	
    --worker (naga)
	SetBuildListBuildingHotkey('nnad', "L", OSKEY_L)
	SetBuildListBuildingHotkey('nnfm', "C", OSKEY_C)
	SetBuildListBuildingHotkey('nnsg', "S", OSKEY_S)
	SetBuildListBuildingHotkey('nnsa', "A", OSKEY_A)
	SetBuildListBuildingHotkey('nntt', "T", OSKEY_T)
	SetBuildListBuildingHotkey('nntg', "D", OSKEY_D)
    
    --для декорации
	SetBuildListDestructablePathing('ATtr')
	SetBuildListDestructablePathing('ATtc')
	SetBuildListDestructablePathing('LTlt')
func frames
код не полный, тк идет переделка с голых таблиц на функции



do
    local real = MarkGameStarted
  function MarkGameStarted()
        real()

--@ string - путь toc-file для подзагрузки ряда файлов
function LoadToc(s)
    if BlzLoadTOCFile(s) then
        print("Loaded: "..s)
    else
        print("Failed to Load: "..s)
    end
end

--инициируем общую таблицу меню строительства
--@ boolean Load - инициировать ли таблицу (этот параметр можно не указывать)
function InitBuildMenu(Load)
	if (not Load) and type(build_menu) ~= 'table' then
		build_menu = {}
	end
end
--инициируем таблицу игрока (локально у каждого будет свой набор фреймов и данные о них, записанные в эту таблицу)
--@ player PlAyer - игрок 
function CreateBuildMenuForPlayer(PlAyer)
    local n = GetPlayerId(PlAyer)
	if type(build_menu)~='table' then print('ошибка CreateBuildMenuForPlayer: общая таблица build_menu не инициирована') return false end
    if (not build_menu[n]) then
        build_menu[n] = {}
    end
end
--задаем дефолтные параметры флагов, отображающие тек статус меню
--@ player PlAyer - игрок 
function InitParamBuildMenuForPlayer(PlAyer)
    local n = GetPlayerId(PlAyer)
	if type(build_menu)~='table' then print('ошибка InitParamBuildMenuForPlayer: общая таблица build_menu не инициирована') return false end
    if type(build_menu[n]) ~= 'table' then print('ошибка InitParamBuildMenuForPlayer: таблица игрока build_menu не инициирована') return false end
    
	--задаем дефолтные параметры
	build_menu[n].display_interface = false --вкл/откл полностью меню строительства
    build_menu[n].display_menu_builder = false --отображается ли меню у игрока
    build_menu[n].player_chooses_place = false --игрок выбирает место
    build_menu[n].mask_cursor_mouse_in_frame=false --флаг, который показывает находится ли курсор внутри маски. помогает при перетаскивании прятать ии снимать курсор
    build_menu[n].button_cancel_cursor_mouse_in_frame=false --флаг, который показывает находится ли курсор внутри кнопки "отмена"
    build_menu[n].button_menu_builder_cursor_mouse_in_frame=0 --флаг, который показывает находится ли курсор внутри кнопки "меню строительства"

end
--создается главный фрейм всего меню строительства, и инициирует ряд важных таблиц данных
--у каждого игрока свои данные состояния интерфейса, мыши итд
--@ player PlAyer - игрок;
--@ framehandle parent - родитель всего главного меню
function CreateMainBuildMenu(PlAyer,parent)
	local n = GetPlayerId(PlAyer)
	if type(build_menu)~='table' then print('ошибка CreateMainBuildMenu: общая таблица build_menu не инициирована') return false end
    if type(build_menu[n]) ~= 'table' then print('ошибка CreateMainBuildMenu: таблица игрока build_menu не инициирована') return false end
    
	build_menu[n].interface = BlzCreateFrameByType("FRAME","interface",parent,"",0)
	BlzFrameSetVisible(build_menu[n].interface, false)
	
	--динамичные параметры игрока
	--требуемые характеристики при выборе места строительства игроком
	build_menu[n].id=0 --ид тип здания
	build_menu[n].model=nil --спецэффект (модель здания)
	build_menu[n].image={} --images (изображения)
	build_menu[n].image_x={} --определяет координаты images
	build_menu[n].image_y={}
	build_menu[n].image_z={}
	build_menu[n].image_offset_x={}  --определяет оффсеты images относительного курсора мыши (при поворотах)
	build_menu[n].image_offset_y={}
	build_menu[n].flag={}
	build_menu[n].width=0 --размеры паффинга здания
	build_menu[n].height=0 
	build_menu[n].square_area = 0
	build_menu[n].count_images = 0
	build_menu[n].can_build=false --флаг, чекает местность на возможность строить
	build_menu[n].coord_x = 0 --координаты при выборе места для строительства
	build_menu[n].coord_y = 0
	build_menu[n].building_facing = 270.
	build_menu[n].building_can_be_rotated = false
	build_menu[n].building_update_rotate = false
	build_menu[n].offsets_rotate = {
		vx1=0,vy1=0,vx2=0,vy2=0,vx3=0,vy3=0,vx4=0,vy4=0
	}
	
	--маска экрана (не дает выделять и выбирать объекты на карте во время выбора участка)  
    build_menu[n].Mask=BlzCreateFrameByType("SLIDER","DeadZoneMouse",BlzGetFrameByName("ConsoleUIBackdrop",0),"",0)
    BlzFrameSetLevel(build_menu[n].Mask, 1)
    BlzFrameSetSize(build_menu[n].Mask, 0.6*2, 0.6*2)
    BlzFrameSetEnable(build_menu[n].Mask, false)
	BlzFrameClearAllPoints(build_menu[n].Mask)
    BlzFrameSetAbsPoint(build_menu[n].Mask, FRAMEPOINT_CENTER, 0.4, 0.3)

	
	--триггер фиксирует заход курсора мыши в фрейм-маску (помогает скрывать/отображать курсор)
	local trigger_mask_enter=createtrigger()
	blztriggerregisterframeevent(trigger_mask_enter, build_menu[n].mask, frameevent_mouse_enter)
	triggeraddaction(trigger_mask_enter,function()
		local n = getplayerid(gettriggerplayer())
		build_menu[n].mask_cursor_mouse_in_frame=true
	end)
	--триггер фиксирует покидание курсора мыши из фрейм-маски (помогает скрывать/отображать курсор)
	local trigger_mask_leave=createtrigger()
	blztriggerregisterframeevent(trigger_mask_leave, build_menu[n].mask, frameevent_mouse_leave)
	triggeraddaction(trigger_mask_leave,function()
		local n = getplayerid(gettriggerplayer())
		build_menu[n].mask_cursor_mouse_in_frame=false
	end)
end
--создается (инициируется) контейнер кнопок всего меню
--таблицы короче инициируются и фрейм-родитель контейнера, фон, DeadZoneMouse
--@ player PlAyer - игрок 
function CreateConteinerButtonsBuildMenu(PlAyer)
	local n = GetPlayerId(PlAyer)
	if type(build_menu)~='table' then print('ошибка CreateConteinerButtonsBuildMenu: общая таблица build_menu не инициирована') return false end
    if type(build_menu[n]) ~= 'table' then print('ошибка CreateConteinerButtonsBuildMenu: таблица игрока build_menu не инициирована') return false end
    
	--контейнер кнопок
    build_menu[n].conteiner = BlzCreateFrameByType("FRAME","conteiner",build_menu[n].interface,"",0)
    BlzFrameSetLevel(build_menu[n].conteiner, 5)
	
	--мертвая зона контейнера
    build_menu[n].DeadZoneMouse=BlzCreateFrameByType("SLIDER","DeadZoneMouse",build_menu[n].conteiner,"",0)
    BlzFrameSetLevel(build_menu[n].DeadZoneMouse, 1)
	--фон контейнера
	build_menu[n].backdrop=BlzCreateFrameByType("BACKDROP","backdrop",build_menu[n].conteiner,"",0)    
	
	--параметры контейнера
	build_menu[n].conteiner_x=0.4
	build_menu[n].conteiner_y=0.3
	build_menu[n].conteiner_gap_between_buttons=0
	build_menu[n].conteiner_width_button=0.035
	build_menu[n].conteiner_height_button=0.035
	build_menu[n].conteiner_row=3
	build_menu[n].conteiner_column=4
	build_menu[n].conteiner_offset_x=0.002
	build_menu[n].conteiner_offset_y=0.002
	
	--параметры кнопок контейнера
	build_menu[n].button={} --кнопка
	build_menu[n].IconTexture={} --иконка

	build_menu[n].Building_Id={} --ид тип здания
	build_menu[n].Trigger_click={} --триггер, фиксирующий нажатие по кнопке лкм
	build_menu[n].trigger_mouse_enter={} --триггер, фиксирующий вход курсора в фрейм-кнопку (для триггера build_menu[n].Trigger_click)
	build_menu[n].trigger_mouse_leave={} --триггер, фиксирующий покидание курсора в фрейм-кнопку (для триггера build_menu[n].Trigger_click)
	build_menu[n].cursor_mouse_in_frame={} --фиксирует, что курсор находит внутри кнопки (для триггера build_menu[n].Trigger_click)
	
	--данные кнопки (записываются из данных здания)
	build_menu[n].gold_required={} --кол-во требуемой золота
	build_menu[n].lumber_required={} --кол-во требуемой древесины
	build_menu[n].mana_required={} --кол-во требуемой маны (если она есть)
	build_menu[n].food_required={} --кол-во требуемой пищи (если она есть)
	build_menu[n].requirement_met={}--выполнено ли требования построить здания/изучить технологии	
end

--создаем подсказку
--на всю меню работает динамично 1 подсказка
--не нужно теперь на каждую кнопку создавать новый набор фреймов и привязывать
--@ player PlAyer - игрок;
--@  x, @ real y - экранные координаты левого нижнего угла текстовой подсказки
--@ real widht_text_frame - ширина текстового окошка (текста);
--@ real gap_between_frames - зазор между фреймами;
--@ real offset_x,@ real offset_y - оффсеты рамки от текста
function CreateTooltipForButtonsBuildMenu(PlAyer,x,y,widht_text_frame,gap_between_frames,offset_x, offset_y)
	local n = GetPlayerId(PlAyer)
	if type(build_menu)~='table' then print('ошибка CreateTooltipForButtonsBuildMenu: общая таблица build_menu не инициирована') return false end
    if type(build_menu[n]) ~= 'table' then print('ошибка CreateTooltipForButtonsBuildMenu: таблица игрока build_menu не инициирована') return false end
    
	--создаем главную подсказку (родителя всего tooltip)
	build_menu[n].Tooltip = BlzCreateFrameByType("FRAME","tooltip",build_menu[n].conteiner,"",0)
	BlzFrameSetVisible(build_menu[n].Tooltip, false)
	
	--создаем элементы подсказки
	build_menu[n].Tooltip_Backdrop = BlzCreateFrameByType("BACKDROP","backdrop tooltip",build_menu[n].Tooltip,"BoxedTextBackgroundTemplate",0)   
	build_menu[n].Tooltip_title =BlzCreateFrameByType("TEXT","title tooltip",build_menu[n].Tooltip,"BoxedTextTitle",0)
	build_menu[n].Tooltip_Text=BlzCreateFrameByType("TEXT","description tooltip",build_menu[n].Tooltip,"BoxedTextValue",0)
	build_menu[n].Tooltip_HorizontalSeparator=BlzCreateFrameByType("BACKDROP","Separator",build_menu[n].Tooltip,"",0)
	
	--настраиваем описание
	BlzFrameClearAllPoints(build_menu[n].Tooltip_Text)
	BlzFrameSetAbsPoint( build_menu[n].Tooltip_Text, FRAMEPOINT_BOTTOMLEFT, x or 0.55, y or 0.19)
	BlzFrameSetSize(build_menu[n].Tooltip_Text, widht_text_frame or 0.25, 0)
	BlzFrameSetEnable(build_menu[n].Tooltip_Text, false)
	BlzFrameSetText(build_menu[n].Tooltip_Text,'описание')

	--настраиваем горизонтальную линию (крепится к описанию)
	BlzFrameSetPoint(build_menu[n].Tooltip_HorizontalSeparator, FRAMEPOINT_BOTTOMLEFT, build_menu[n].Tooltip_Text, FRAMEPOINT_TOPLEFT, 0.0025, 0.0025)
	BlzFrameSetPoint(build_menu[n].Tooltip_HorizontalSeparator, FRAMEPOINT_BOTTOMRIGHT, build_menu[n].Tooltip_Text, FRAMEPOINT_TOPRIGHT, 0.0025, 0.0025)
	BlzFrameSetSize(build_menu[n].Tooltip_HorizontalSeparator, 0, 0.0015)
	BlzFrameSetTexture(build_menu[n].Tooltip_HorizontalSeparator, ToolTipHorizontalSeparator,0, true) 

	--настраиваем заглавие (крепится к горизонтальной линии)
	BlzFrameSetPoint(build_menu[n].Tooltip_title, FRAMEPOINT_BOTTOMLEFT, build_menu[n].Tooltip_HorizontalSeparator, FRAMEPOINT_TOPLEFT, -gap_between_frames or -0.005, gap_between_frames or 0.005)
	BlzFrameSetSize(build_menu[n].Tooltip_title, 0.25, 0)
	BlzFrameSetEnable(build_menu[n].Tooltip_title, false)
	BlzFrameSetText(build_menu[n].Tooltip_title,'заглавие')

	--настраиваем фон подсказки (настроек мало, тк часть лежит в fdf-file)
	BlzFrameSetPoint(build_menu[n].Tooltip_Backdrop, FRAMEPOINT_BOTTOMLEFT, build_menu[n].Tooltip_Text, FRAMEPOINT_BOTTOMLEFT, -gap_between_frames or -0.005, -gap_between_frames or -0.005)
	BlzFrameSetPoint(build_menu[n].Tooltip_Backdrop, FRAMEPOINT_TOPRIGHT, build_menu[n].Tooltip_title, FRAMEPOINT_TOPRIGHT, gap_between_frames or 0.005, gap_between_frames or 0.005)
	
	--далее идут требования к подсказке (их еще некуда крепить, тк неизвестны требования, поэтому просто создаем) 
	--Tooltip: resourse_bar
	build_menu[n].resourse_bar = BlzCreateFrameByType("FRAME","resourse_bar",build_menu[n].Tooltip,"",0)
	BlzFrameSetVisible(build_menu[n].resourse_bar, false)

	--Tooltip: resourse_bar: mana cost
	build_menu[n].icon_mana_cost = BlzCreateFrameByType("BACKDROP","icon_mana_cost",build_menu[n].resourse_bar,"",0)
	BlzFrameSetSize(build_menu[n].icon_mana_cost, 0.012, 0.012)
	BlzFrameSetTexture(build_menu[n].icon_mana_cost, ToolTipManaIcon, 0, true)
	BlzFrameSetVisible(build_menu[n].icon_mana_cost, false)
	
	build_menu[n].text_mana_cost = BlzCreateFrameByType("TEXT","text mana cost",build_menu[n].icon_mana_cost ,"BoxedTextValue",0)          
	BlzFrameSetEnable(build_menu[n].text_mana_cost, false)
	BlzFrameSetPoint(build_menu[n].text_mana_cost, FRAMEPOINT_LEFT, build_menu[n].icon_mana_cost, FRAMEPOINT_RIGHT, 0.0025, 0.0)
	BlzFrameSetSize(build_menu[n].text_mana_cost, 0, 0.012)

	--Tooltip: resourse_bar: gold cost
	build_menu[n].icon_gold_cost = BlzCreateFrameByType("BACKDROP","icon gold cost",build_menu[n].resourse_bar,"",0)
	BlzFrameSetSize(build_menu[n].icon_gold_cost, 0.012, 0.012)
	BlzFrameSetTexture(build_menu[n].icon_gold_cost, ToolTipGoldIcon, 0, true)
	BlzFrameSetVisible(build_menu[n].icon_gold_cost, false)
	
	build_menu[n].text_gold_cost = BlzCreateFrameByType("TEXT","text gold dcost",build_menu[n].icon_gold_cost ,"BoxedTextValue",0)          
	BlzFrameSetEnable(build_menu[n].text_gold_cost, false)
	BlzFrameSetPoint(build_menu[n].text_gold_cost, FRAMEPOINT_LEFT, build_menu[n].icon_gold_cost[num], FRAMEPOINT_RIGHT, 0.0025, 0.0)
	BlzFrameSetSize(build_menu[n].text_gold_cost, 0, 0.012)

	--Tooltip: resourse_bar: lumber cost
	build_menu[n].icon_lumber_cost = BlzCreateFrameByType("BACKDROP","icon lumber cost",build_menu[n].resourse_bar,"",0)
	BlzFrameSetSize(build_menu[n].icon_lumber_cost, 0.012, 0.012)
	BlzFrameSetTexture(build_menu[n].icon_lumber_cost, ToolTipLumberIcon, 0, true)
	BlzFrameSetVisible(build_menu[n].icon_lumber_cost, false)
	
	build_menu[n].text_lumber_cost = BlzCreateFrameByType("TEXT","text lumber cost",build_menu[n].icon_lumber_cost ,"BoxedTextValue",0)          
	BlzFrameSetEnable(build_menu[n].text_lumber_cost, false)
	BlzFrameSetPoint(build_menu[n].text_lumber_cost, FRAMEPOINT_LEFT, build_menu[n].icon_lumber_cost, FRAMEPOINT_RIGHT, 0.0025, 0.0)
	BlzFrameSetSize(build_menu[n].text_lumber_cost, 0, 0.012)

	--Tooltip: resourse_bar: food cost
	build_menu[n].icon_food_cost = BlzCreateFrameByType("BACKDROP","icon food cost",build_menu[n].resourse_bar,"",0)
	BlzFrameSetSize(build_menu[n].icon_food_cost, 0.012, 0.012)
	BlzFrameSetTexture(build_menu[n].icon_food_cost, ToolTipSupplyIcon, 0, true)
	BlzFrameSetVisible(build_menu[n].icon_food_cost, false)
	
	build_menu[n].text_food_cost = BlzCreateFrameByType("TEXT","text_food_cost",build_menu[n].icon_food_cost ,"BoxedTextValue",0)          
	BlzFrameSetEnable(build_menu[n].text_food_cost, false)
	BlzFrameSetPoint(build_menu[n].text_food_cost, FRAMEPOINT_LEFT, build_menu[n].icon_food_cost, FRAMEPOINT_RIGHT, 0.0025, 0.0)
	BlzFrameSetSize(build_menu[n].text_food_cost, 0, 0.012)
	
	--Tooltip: text_building_requirement
	build_menu[n].text_building_requirement = BlzCreateFrameByType("TEXT","text_building_requirement",build_menu[n].Tooltip,"BoxedTextValue",0)          
	BlzFrameSetEnable(build_menu[n].text_building_requirement, false)
	BlzFrameSetSize(build_menu[n].text_building_requirement, 0.25, 0)
	BlzFrameSetVisible(build_menu[n].text_building_requirement, false)
	
	--Tooltip: text_tech_requirement
	build_menu[n].text_tech_requirement = BlzCreateFrameByType("TEXT","text_tech_requirement",build_menu[n].Tooltip,"BoxedTextValue",0)          
	BlzFrameSetEnable(build_menu[n].text_tech_requirement, false)
	BlzFrameSetSize(build_menu[n].text_tech_requirement, 0.25, 0)
	BlzFrameSetVisible(build_menu[n].text_tech_requirement, false)
	
	--ресурс-полоса подсказки
	build_menu[n].text_gold_cost=0 --текст золота, отображающий стоимость
	build_menu[n].text_lumber_cost=0 --текст дерева, отображающий стоимость
	build_menu[n].text_mana_cost=0 --текст маны, отображающий стоимость
	build_menu[n].text_food_cost=0 --текст пищи, отображающий стоимость
	
	--требование подсказки
	build_menu[n].text_building_requirement=nil --текст, описывающий требование построить здания
	build_menu[n].text_tech_requirement=nil --текст, описывающий требование изучить технологию

	--создаем список, определяющий порядок в горизонтальном рядом ресурсов
	build_menu[n].frame_List = {}
end


--создаем кнопку контейнера
--если такая кнопка существует, ее можно переиспользовать. иначе создаем новую
--@ player PlAyer - игрок, которому создают контейнер;
--@ integer number  - номер массива кнопки;
--@ real x,@ real y  - экранные координаты кнопки;
--@ real width, @ real height - размеры кнопки;
--@ string path_icon - изображение иконки;
--@ integer level_layer - уровень слоя (если он есть)
function CreateButtonConteinerOfBuildMenu(PlAyer,num,x,y,width,height,path_icon,level)
	local n = GetPlayerId(PlAyer)
	if type(build_menu)~='table' then print('ошибка CreateButtonConteinerOfBuildMenu: общая таблица build_menu не инициирована') return false end
    if type(build_menu[n]) ~= 'table' then print('ошибка CreateButtonConteinerOfBuildMenu: таблица игрока build_menu не инициирована') return false end
    if type(build_menu[n].button) ~= 'table' then print('ошибка CreateButtonConteinerOfBuildMenu: таблица кнопки build_menu не инициирована') return false end

	local IsFrameCreated = false
	if not build_menu[n].button[num] then
		IsFrameCreated = true
		build_menu[n].button[num] = BlzCreateFrameByType("SLIDER","button",build_menu[n].conteiner,"",num)
		build_menu[n].IconTexture[num] = BlzCreateFrameByType("BACKDROP","IconTexture",build_menu[n].button[num],"",num)
    end
	
    --настройка кнопки и ее иконки
	BlzFrameClearAllPoints(build_menu[n].button[num])
	BlzFrameClearAllPoints(build_menu[n].IconTexture[num])
    BlzFrameSetAbsPoint(build_menu[n].button[num], FRAMEPOINT_CENTER, x,y)
	BlzFrameSetAllPoints(build_menu[n].IconTexture[num],build_menu[n].button[num])
    BlzFrameSetTexture(build_menu[n].IconTexture[num], path_icon or default_path_icon, 0, true)
    BlzFrameSetSize(build_menu[n].button[num], width, height)
	BlzFrameSetLevel(build_menu[n].button[num], level or 1)
	BlzFrameSetVisible(build_menu[n].button[num], true)
	
	build_menu[n].gold_required[num]=0
    build_menu[n].lumber_required[num]=0
    build_menu[n].mana_required[num]=0
    build_menu[n].food_required[num]=0
	
	--для кнопок контейнера задаем события
	if IsFrameCreated then
		--триггер фиксирует заход курсора мыши в фрейм-маску (помогает скрывать/отображать курсор)	
		build_menu[n].trigger_mouse_enter[num]=CreateTrigger()
		BlzTriggerRegisterFrameEvent(build_menu[n].trigger_mouse_enter[num], build_menu[n].button[num], FRAMEEVENT_MOUSE_ENTER)
		TriggerAddAction(build_menu[n].trigger_mouse_enter[num],function()
			local n = GetPlayerId(GetTriggerPlayer())
			print('курсор наведен на кнопку-'..tostring(num))
			build_menu[n].cursor_mouse_in_frame[num]=true
		end)
		--триггер фиксирует покидание курсора мыши из фрейм-маски (помогает скрывать/отображать курсор)	
		build_menu[n].trigger_mouse_leave[num]=CreateTrigger()
		BlzTriggerRegisterFrameEvent(build_menu[n].trigger_mouse_leave[num], build_menu[n].button[num], FRAMEEVENT_MOUSE_LEAVE)
		TriggerAddAction(build_menu[n].trigger_mouse_leave[num],function()
			local n = GetPlayerId(GetTriggerPlayer())
			print('курсор не наведен на кнопку-'..tostring(num))
			build_menu[n].cursor_mouse_in_frame[num]=false
		end)
		
		--триггер фиксирует нажатие на кнопку
		build_menu[n].Trigger_click[num]=CreateTrigger()
		--BlzTriggerRegisterFrameEvent(build_menu[n].Trigger_click[num], build_menu[n].button[num], FRAMEEVENT_MOUSE_UP)
		TriggerRegisterPlayerEvent(build_menu[n].Trigger_click[num], GetLocalPlayer(), EVENT_PLAYER_MOUSE_UP )
		TriggerAddAction(build_menu[n].Trigger_click[num],function()
			local n = GetPlayerId(GetTriggerPlayer())
			
			for a=1,#build_menu[n].button do
				--if BlzGetTriggerFrame()==build_menu[n].button[a] then --GetTriggeringTrigger
					if build_menu[n].cursor_mouse_in_frame[a] then
					--print('click button-'..tostring(a))
					
					if build_menu[n].requirement_met[a] then
						--print('требования выполнены')
		
						local Type_Building = build_menu[n].Building_Id[a]
						
						local gold,lumber,food,mana =0,0,0,0
						if Type_Building>0 then

							if build_gold_cost[Type_Building]then
								if build_gold_cost[Type_Building]> 0 then
									gold=build_gold_cost[Type_Building]
								end
							end
							if build_lumb_cost[Type_Building]then
								if build_lumb_cost[Type_Building]> 0 then
									lumber=build_lumb_cost[Type_Building]
								end
							end 
							if build_food_cost[Type_Building]then
								if build_food_cost[Type_Building]> 0 then
									food=build_food_cost[Type_Building]
								end
							end 
							if build_mana_cost[Type_Building]then
								if build_mana_cost[Type_Building]> 0 then
									mana=build_mana_cost[Type_Building]
								end
							end 
							local flag = true
							if (gold>GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_GOLD) and lumber>GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_LUMBER)) or gold>GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_GOLD)  then
								DisplayTimedTextToPlayer(GetTriggerPlayer(), 0.3, 0.21, 0.3, "|Cffffcc00Недостаточно золото|r")
								flag = false
							elseif lumber>GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_LUMBER) then
								DisplayTimedTextToPlayer(GetTriggerPlayer(), 0.3, 0.21, 0.3, "|Cffffcc00Недостаточно древесины|r")
								flag = false
							end
							if flag then
								--показываем кнопку отмены
								BlzFrameSetVisible(button_cancel, true)
								--скрываем кнопку меню
								BlzFrameSetVisible(button_build_menu, false)
								--скрываем контейнер 
								BlzFrameSetVisible(build_menu[n].conteiner, false)
								--меню раба закрыто
								build_menu[n].display_menu_builder = false
								--игрок выбирает участок
								build_menu[n].player_chooses_place = true
								BlzFrameSetEnable(build_menu[n].Mask, true)
								
								for b=1, 12 do
									build_menu[n].Building_Id[b]=0
									BlzFrameSetTexture(build_menu[n].IconTexture[b], path_icon, 0, true)
									BlzFrameSetText(build_menu[n].Tooltip_Text[b],'описание')
									BlzFrameSetText(build_menu[n].Tooltip_title[b],'заглавие')
								end
								
								local path_effect = GetTriggerPlayer()==GetLocalPlayer() and build_model[Type_Building] or nil
								
								build_menu[n].id=Type_Building
								build_menu[n].model=AddSpecialEffect(path_effect,build_menu[n].coord_x,build_menu[n].coord_y)
								BlzPlaySpecialEffect(build_menu[n].model,ANIM_TYPE_STAND)
								
								local scale = build_scale_model[Type_Building]
								--print('size_model: '..tostring(scale))
								if scale then
									--BlzSetSpecialEffectMatrixScale(build_menu[n].model,scale,scale,scale)
									BlzSetSpecialEffectScale(build_menu[n].model,scale)
								end
								
								
								--по дефолту 270.
								build_menu[n].building_facing = 270.
								
								BlzSetSpecialEffectYaw(build_menu[n].model, math.rad(build_menu[n].building_facing))
								BlzSetSpecialEffectColorByPlayer( build_menu[n].model,GetOwningPlayer(LastSelestedUnit[n]))
								
								if type(build_size_pathing[Type_Building]) == 'number' then
									build_menu[n].width=build_size_pathing[Type_Building]
									build_menu[n].height=build_size_pathing[Type_Building]
									build_menu[n].square_area = math.modf(build_menu[n].width/32) * math.modf(build_menu[n].height/32)
								else
									build_menu[n].width=build_size_pathing[Type_Building].width
									build_menu[n].height=build_size_pathing[Type_Building].height
									build_menu[n].square_area = math.modf(build_menu[n].width/32) * math.modf(build_menu[n].height/32)
								end
								build_menu[n].can_build=false
									
								local block = 32.
								local half_width,half_height = (build_menu[n].width/2),(build_menu[n].height/2)
								local cx,cy = build_menu[n].coord_x,build_menu[n].coord_y
								local minx,maxx,miny,maxy = cx-half_width,cx+half_width,cy-half_height,cy+half_height

								local x,y = minx,miny+(block/2)
								local num = 0
								for y=miny+(block/2),maxy,block do
									for x=minx+(block/2),maxx,block do
										num = num+1
										build_menu[n].image[num]=CreateSquareImageForPlayer(GetTriggerPlayer(),"war3mapImported\\block 32x32.TGA",block*2,x,y,2)
										--координаты image
										build_menu[n].image_x[num]=x
										build_menu[n].image_y[num]=y
										--оффсеты от центра
										build_menu[n].image_offset_x[num]=x-cx
										build_menu[n].image_offset_y[num]=y-cy
									end
								end
								build_menu[n].count_images = num
								
								--при повороте может меняться число images, статичное число изображении достаточно подвинуть
								--а динамичное число нужно пересоздавать
								if type_building_for_rotate[Type_Building] then
									build_menu[n].building_can_be_rotated = true
									build_menu[n].building_update_rotate = true
									build_menu[n].offsets_rotate.vx1=-half_width
									build_menu[n].offsets_rotate.vx2=-half_width
									build_menu[n].offsets_rotate.vx3=half_width
									build_menu[n].offsets_rotate.vx4=half_width
									build_menu[n].offsets_rotate.vy1=-half_height
									build_menu[n].offsets_rotate.vy2=half_height
									build_menu[n].offsets_rotate.vy3=half_height
									build_menu[n].offsets_rotate.vy4=-half_height
								else
									build_menu[n].building_can_be_rotated = false
								end
								
								UpdatePathingPlayer(cx,cy,half_width,half_height,block,GetTriggerPlayer())
								
							end
						
						end
					end
					--end
				end
			end
		end)
	end
end

--создает контейнер кнопок
--по факту: у каждого игрока может быть только 1 контейнер кнопок
--может быть миллион разных билд листов, и кнопок вызова меню. Но контейнер кнопок всего один
--невозможно отобразить одновременно несколько контейнеров, только один.
--@ player PlAyer - игрок, которому создают контейнер;
--@ real x,@ real y  - экранные координаты левого нижнего угла контейнера;
--@ integer rows - строки; @ integer columns - столбцы;
--@ real width, @ real height - размеры кнопок;
--@ real gap - зазор между кнопками;
--@ real offset_x, @ real offset_y - оффсеты рамки;
--@ string path_backdrop - изображение фона контейнера
function SettingConteinerButtonsBuildMenu(PlAyer,x,y,rows,columns,width,height,gap,offset_x,offset_y, path_backdrop)
	local n = GetPlayerId(PlAyer)
	if type(build_menu)~='table' then print('ошибка SettingConteinerButtonsBuildMenu: общая таблица build_menu не инициирована') return false end
    if type(build_menu[n]) ~= 'table' then print('ошибка SettingConteinerButtonsBuildMenu: таблица игрока build_menu не инициирована') return false end
    
	--параметры контейнера
	if build_menu[n].conteiner_offset_x~=offset_x or build_menu[n].conteiner_offset_y~=offset_Y then
		build_menu[n].conteiner_offset_x=offset_x or 0.002
		build_menu[n].conteiner_offset_y=offset_y or 0.002
	end
	
	local num = 0
    local size_button = 0.039
    
	local flag_1 = build_menu[n].conteiner_row ~= rows or build_menu[n].conteiner_column ~= columns
	local flag_2 = build_menu[n].conteiner_width_button ~= width or build_menu[n].conteiner_height_button ~= height
	local flag_3 = build_menu[n].conteiner_gap_between_buttons~=gap
	local flag_4 = build_menu[n].conteiner_x~=x or build_menu[n].conteiner_y~=y
	
	if flag_1 or flag_2 or flag_3 or flag_4 then
		x = x or 0.4; y = y or 0.3
		gap = gap or 0
		width = width or 0.035;	height = height or 0.035
		rows = rows or 3; columns=columns or 4
		
		build_menu[n].conteiner_x=x
		build_menu[n].conteiner_y=y
		build_menu[n].conteiner_gap_between_buttons=gap
		build_menu[n].conteiner_width_button=width
		build_menu[n].conteiner_height_button=height
		build_menu[n].conteiner_row=rows
		build_menu[n].conteiner_column=columns

		--скрываем
		for a=1, #build_menu[n].button do
			BlzFrameSetVisible(build_menu[n].button[a], true)
		end

		for b=rows, 1,-1 do
			for a=1, columns, 1 do
				num = num + 1
				local coord_x,coord_y=x+(width*(a-1))+gap, y+(height*(b-1))+gap
				CreateButtonConteinerOfBuildMenu(PlAyer,num,coord_x,coord_y,width,height,default_path_icon,level)
			end
		end
	end
end

--обновить контейнер кнопок по билд листу (прорисовка кнопок)
--аналог SettingConteinerButtonsBuildMenu, только берет данные из билд листа
--@ player PlAyer - игрок, которому создают контейнер;
--@ string build_list_id - идишник списка 
function SettingConteinerButtonsBuildMenuEx(PlAyer,build_list_id)
	local n = GetPlayerId(PlAyer)
	if type(build_menu)~='table' then print('ошибка SettingConteinerButtonsBuildMenuEx: общая таблица build_menu не инициирована') return false end
    if type(build_menu[n]) ~= 'table' then print('ошибка SettingConteinerButtonsBuildMenuEx: таблица игрока build_menu не инициирована') return false end

	local conteiner_coord_x = BuildList[build_list_id].conteiner_pos_x
	local conteiner_coord_y = BuildList[build_list_id].conteiner_pos_y
	local rows = BuildList[build_list_id].conteiner_rows
	local columns = BuildList[build_list_id].conteiner_columns
	local conteiner_button_w = BuildList[build_list_id].conteiner_button_width
	local conteiner_button_h = BuildList[build_list_id].conteiner_button_height
	local gap = BuildList[build_list_id].conteiner_gap_between_buttons
	local backdrop_offset_x = BuildList[build_list_id].conteiner_backdrop_offset_x
	local backdrop_offset_y = BuildList[build_list_id].conteiner_backdrop_offset_y
	local path_backdrop = BuildList[build_list_id].conteiner_path_backdrop
	
	SettingButtonCancel(PlAyer,rows*columns, conteiner_button_w,conteiner_button_h)
	SettingConteinerButtonsBuildMenu(PlAyer,x,y,rows,columns,width,height,gap,offset_x,offset_y, path_backdrop)
end

--обновить контейнер кнопок по номеру фрейм-кнопки вызова (прорисовка кнопок)
--когда жмешь на кнопку вызова меню, то тут же сразу прорисовывается контейнер 
--@ player PlAyer - игрок, которому создают контейнер;
--@ integer num - num 
function SettingConteinerButtonsBuildMenuEx2(PlAyer,num)
	local n = GetPlayerId(PlAyer)
	if type(build_menu)~='table' then print('ошибка SettingConteinerButtonsBuildMenuEx: общая таблица build_menu не инициирована') return false end
    if type(build_menu[n]) ~= 'table' then print('ошибка SettingConteinerButtonsBuildMenuEx: таблица игрока build_menu не инициирована') return false end
    
	local build_list_id = build_menu[n].build_list_id[num]
	SettingConteinerButtonsBuildMenuEx(PlAyer,build_list_id)
end
--закрываем меню строительства
--@ integer n - номер игрока 
function CloseBuildMenu(n)
	if build_menu[n].display_menu_builder then --отображается ли меню у игрока

		--скрываем кнопку отмены
		BlzFrameSetVisible(build_menu[n].button_cancel, false)
		--показываем кнопку меню
		for a=1, build_menu[n].max_buttons_build_menu do
			BlzFrameSetVisible(build_menu[n].button_build_menu[a], true)
		end
		--скрываем контейнер 
		BlzFrameSetVisible(build_menu[n].conteiner, false)
		--меню раба закрыто
		build_menu[n].display_menu_builder = false
		
		--обнуляем данные ячеек
		for a=1, #build_menu[n].button do
			build_menu[n].Building_Id[a]=0
			BlzFrameSetTexture(build_menu[n].IconTexture[a], default_path_icon, 0, true)
			build_menu[n].requirement_met[a]=false
		end
	elseif build_menu[n].player_chooses_place then --если игрок выбирает место строительства
		--скрываем кнопку отмены
		BlzFrameSetVisible(build_menu[n].button_cancel, false)
		--показываем кнопку меню
		for a=1, build_menu[n].max_buttons_build_menu do
			BlzFrameSetVisible(build_menu[n].button_build_menu[a], true)
		end
		--скрываем контейнер 
		BlzFrameSetVisible(build_menu[n].conteiner, false)
		--меню раба закрыто
		build_menu[n].display_menu_builder = false
		
		--обнуляем данные ячеек
		for a=1, #build_menu[n].button do
			build_menu[n].Building_Id[a]=0
			BlzFrameSetTexture(build_menu[n].IconTexture[a], default_path_icon, 0, true)
			build_menu[n].requirement_met[a]=false
			
		end
		
		--реим выбора закрыт
		build_menu[n].player_chooses_place = false
		BlzFrameSetEnable(build_menu[n].Mask, false)
		BlzEnableCursor(true)
		
		--двигаем в угол карты
		BlzSetSpecialEffectPosition( build_menu[n].model, GetRectMinX(GetWorldBounds()), GetRectMinY(GetWorldBounds()), 0 )
		--затем уничтожаем
		DestroyEffect(build_menu[n].model)
		for k, v in pairs(build_menu[n].image) do
			DestroyImage(v)
			build_menu[n].image[k]=nil
		end

	else
		--скрываем кнопку отмены
		BlzFrameSetVisible(build_menu[n].button_cancel, false)
		--показываем кнопку меню
		for a=1, build_menu[n].max_buttons_build_menu do
			BlzFrameSetVisible(build_menu[n].button_build_menu[a], true)
		end
		--скрываем контейнер 
		BlzFrameSetVisible(build_menu[n].conteiner, false)
	end
end

--создать кнопку отмены
--@ player PlAyer - игрок, которому создают кнопку;
--@ integer number_last_button - номер последней кнопки
function CreateButtonCancel(PlAyer, number_last_button, width,height)
	local n = GetPlayerId(PlAyer)
	if type(build_menu)~='table' then print('ошибка CreateButtonCancel: общая таблица build_menu не инициирована') return false end
    if type(build_menu[n]) ~= 'table' then print('ошибка CreateButtonCancel: таблица игрока build_menu не инициирована') return false end
    
	
	-- ========= кнопка отмены ===========================
	build_menu[n].button_cancel = BlzCreateFrameByType("SLIDER","button cancel",build_menu[n].interface,"",0)
	build_menu[n].icon_button_cancel = BlzCreateFrameByType("BACKDROP","IconTexture",build_menu[n].button_cancel,"",0)
	BlzFrameClearAllPoints(build_menu[n].button_cancel)
	BlzFrameClearAllPoints(build_menu[n].icon_button_cancel)
	BlzFrameSetAllPoints(build_menu[n].button_cancel,build_menu[n].button[number_last_button])
	BlzFrameSetAllPoints(build_menu[n].icon_button_cancel,build_menu[n].button_cancel)
	BlzFrameSetTexture(build_menu[n].icon_button_cancel, path_active_icon .. path_icon_cancel, 0, true)
	--BlzFrameSetSize(build_menu[n].button_cancel, width, height)
	BlzFrameSetVisible(build_menu[n].button_cancel, false)
	BlzFrameSetLevel(build_menu[n].button_cancel, 2)
	
	--триггер фиксирует вход курсора мыши в кнопку "отмена" (помогает отслеживать клик в триггере trigger_button_cancel_click)
	build_menu[n].trigger_button_cancel_enter=CreateTrigger()
	BlzTriggerRegisterFrameEvent(build_menu[n].trigger_button_cancel_enter, build_menu[n].button_cancel, FRAMEEVENT_MOUSE_ENTER)
	TriggerAddAction(build_menu[n].trigger_button_cancel_enter,function()
		local n = GetPlayerId(GetTriggerPlayer())
		build_menu[n].button_cancel_cursor_mouse_in_frame=TRUE
	end)
	--триггер фиксирует покидание курсора мыши из кнопки "отмена" (помогает отслеживать клик в триггере trigger_button_cancel_click)
	build_menu[n].trigger_button_cancel_leave=CreateTrigger()
	BlzTriggerRegisterFrameEvent(build_menu[n].trigger_button_cancel_leave, build_menu[n].button_cancel, FRAMEEVENT_MOUSE_LEAVE)
	TriggerAddAction(build_menu[n].trigger_button_cancel_leave,function()
		local n = GetPlayerId(GetTriggerPlayer())
		build_menu[n].button_cancel_cursor_mouse_in_frame=false
	end)
	--триггер фиксирует отмену
	build_menu[n].trigger_button_cancel_click=CreateTrigger()
	BlzTriggerRegisterFrameEvent(build_menu[n].trigger_button_cancel_click, build_menu[n].button_cancel, FRAMEEVENT_MOUSE_UP)
	TriggerRegisterPlayerEvent(build_menu[n].trigger_button_cancel_click, Player(0), EVENT_PLAYER_MOUSE_UP )
	TriggerRegisterPlayerEvent(build_menu[n].trigger_button_cancel_click, Player(0), EVENT_PLAYER_END_CINEMATIC )
	TriggerAddAction(build_menu[n].trigger_button_cancel_click,function()
		local n = GetPlayerId(GetTriggerPlayer())
		
		local b1 = GetTriggerEventId() == EVENT_PLAYER_END_CINEMATIC
		local b2 = GetTriggerEventId() == EVENT_PLAYER_MOUSE_UP and BlzGetTriggerPlayerMouseButton()==MOUSE_BUTTON_TYPE_LEFT and  build_menu[n].button_cancel_cursor_mouse_in_frame
		local b3 = GetTriggerEventId() == EVENT_PLAYER_MOUSE_UP and BlzGetTriggerPlayerMouseButton()==MOUSE_BUTTON_TYPE_RIGHT and  build_menu[n].player_chooses_place
		
		if b1 or b2 or b3 then
			print('click button "cancel"')
			CloseBuildMenu(n)
		end
	end)
	
end

--инициировать массив кнопок вызова меню (это на старте)
--@ player PlAyer - игрок, которому создают контейнер;
--@ integer number_last_button - номер последней кнопки
function InitButtonsBuildMenu(PlAyer)
	local n = GetPlayerId(PlAyer)
	if type(build_menu)~='table' then print('ошибка CreateButtonsBuildMenu: общая таблица build_menu не инициирована') return false end
    if type(build_menu[n]) ~= 'table' then print('ошибка CreateButtonsBuildMenu: таблица игрока build_menu не инициирована') return false end
    
	if not build_menu[n].button_build_menu then
		build_menu[n].button_build_menu = {}
		build_menu[n].icon_button_build_menu = {}
		build_menu[n].trigger_button_build_menu_enter = {}
		build_menu[n].trigger_button_build_menu_leave = {}
		build_menu[n].trigger_button_build_menu_click = {}
		build_menu[n].build_list_id = {}
		--эти для подсказки
		build_menu[n].build_path_texture = {} --иконка
		build_menu[n].build_button_title = {} --название кнопки вызова меню
		build_menu[n].build_button_desc = {} --описание кнопки вызова меню
		build_menu[n].build_button_hotkey = {} --строчная горячая клавиша вызова меню
		build_menu[n].build_button_oskey = {} --клавиша вызова меню
		build_menu[n].build_button_width = {} --ширина
		build_menu[n].build_button_height = {} --высота
		build_menu[n].build_button_visible = {} --кнопка в данный видима true/false
		build_menu[n].build_button_enable = {} --разрешен ли показ кнопки true/false
		
	end
	
	--макс кол-во возможных кнопок у юнитов
	local max = 0
	for k,v in pairs(BuildList) do 
		max = max + 1
		--button_build_menu (frame): запись ключа (идишника списка)
		build_menu[n].build_list_id[max]=k
		--build_list: запись номер кнопки
		BuildList[k].number_of_button_buid_menu[n] = max
	end
	build_menu[n].max_buttons_build_menu=max
	
	for a=max,1,-1 do
		build_menu[n].button_build_menu[a] = BlzCreateFrameByType("TEXT","button build menu",build_menu[n].interface,"",0)
        build_menu[n].icon_button_build_menu[a] = BlzCreateFrameByType("BACKDROP","IconTexture",build_menu[n].button_build_menu[a],"",0)
        
		local build_list_id = build_menu[n].build_list_id[a]
		local coord_x = BuildList[build_list_id].button_buid_menu_pos_x
		local coord_y = BuildList[build_list_id].button_buid_menu_pos_y
		local path_texture = BuildList[build_list_id].button_buid_menu_path_icon
		local str_button_name = BuildList[build_list_id].button_buid_menu_name
		local str_button_desc = BuildList[build_list_id].button_buid_menu_desc
		local str_hotkey = BuildList[build_list_id].button_buid_menu_hotkey
		local button_oskey = BuildList[build_list_id].button_buid_menu_oskey
		local w = BuildList[build_list_id].button_buid_menu_width
		local h = BuildList[build_list_id].button_buid_menu_height
		
		BlzFrameClearAllPoints(build_menu[n].button_build_menu[a])
		BlzFrameClearAllPoints(build_menu[n].icon_button_build_menu[a])
        BlzFrameSetAbsPoint(build_menu[n].button_build_menu[a], FRAMEPOINT_CENTER, coord_x, coord_y)
		BlzFrameSetAllPoints(build_menu[n].icon_button_build_menu[a],build_menu[n].button_build_menu[a])
		BlzFrameSetSize(build_menu[n].button_build_menu[a], w, h)
		BlzFrameSetTexture(build_menu[n].icon_button_build_menu[a], path_texture or path_icon_orc_build, 0, true)
        
		--в данный момент кнопка невидима
		build_menu[n].build_button_visible[a] = false
		BlzFrameSetVisible(build_menu[n].button_build_menu[a], build_menu[n].build_button_visible[a])
		
		--запоминаем ряд данных для подсказки tooltip
		build_menu[n].build_path_texture[a] = path_texture
		build_menu[n].build_button_title[a] = str_button_name --название кнопки вызова меню
		build_menu[n].build_button_desc[a] = str_button_desc --описание кнопки вызова меню
		build_menu[n].build_button_hotkey[a] = str_hotkey --строчная горячая клавиша вызова меню
		build_menu[n].build_button_oskey[a] = button_oskey --клавиша вызова меню
		build_menu[n].build_button_width[a] = w --ширина
		build_menu[n].build_button_height[a] = h --высота
		build_menu[n].build_button_enable[a] = true --кнопка включена к показу (можно спец нативкой отключить показ кнопки)
		
		--триггер фиксирует вход курсора мыши в кнопку "меню строительства" (помогает отслеживать клик в триггере trigger_button_build_menu_click)
		build_menu[n].trigger_button_build_menu_enter[a]=CreateTrigger()
		BlzTriggerRegisterFrameEvent(build_menu[n].trigger_button_build_menu_enter[a], build_menu[n].button_build_menu[a], FRAMEEVENT_MOUSE_ENTER)
		TriggerAddAction(build_menu[n].trigger_button_build_menu_enter[a],function()
			local n = GetPlayerId(GetTriggerPlayer())
			for a=1,build_menu[n].max_buttons_build_menu do
				if GetTriggeringTrigger()==build_menu[n].trigger_button_build_menu_enter[a] then
					build_menu[n].button_menu_builder_cursor_mouse_in_frame=a
					break
				end
			end	
		end)
		--триггер фиксирует покидание курсора мыши из кнопки "меню строительства" (помогает отслеживать клик в триггере trigger_button_build_menu_click)
		build_menu[n].trigger_button_build_menu_leave[a]=CreateTrigger()
		BlzTriggerRegisterFrameEvent(build_menu[n].trigger_button_build_menu_leave[a], build_menu[n].button_build_menu[a], FRAMEEVENT_MOUSE_LEAVE)
		TriggerAddAction(build_menu[n].trigger_button_build_menu_leave[a],function()
			local n = GetPlayerId(GetTriggerPlayer())
			for a=1,build_menu[n].max_buttons_build_menu do
				if GetTriggeringTrigger()==build_menu[n].trigger_button_build_menu_leave[a] then
					build_menu[n].button_menu_builder_cursor_mouse_in_frame=0
					break
				end
			end
		end)

		--триггер фиксирует нажатие на кнопку "меню строительства"
		build_menu[n].trigger_button_build_menu_click[a] =CreateTrigger()
		TriggerRegisterPlayerEvent(build_menu[n].trigger_button_build_menu_click[a], PlAyer, EVENT_PLAYER_MOUSE_UP )
		TriggerAddAction(build_menu[n].trigger_button_build_menu_click[a],function()
			local n = GetPlayerId(GetTriggerPlayer())
			
			if build_menu[n].button_menu_builder_cursor_mouse_in_frame>0 then
				if BlzGetTriggerPlayerMouseButton()==MOUSE_BUTTON_TYPE_LEFT  then
					print('click button "build menu"')
					
					--показываем кнопку отмены
					BlzFrameSetVisible(button_cancel, true)
					--скрываем кнопку меню
					for a=1, build_menu[n].max_buttons_build_menu do
						BlzFrameSetVisible(build_menu[n].button_build_menu[a], false)
					end
					--показываем контейнер 
					BlzFrameSetVisible(build_menu[n].conteiner, true)
					--скрываем последнюю кнопку
					BlzFrameSetVisible(build_menu[n].button[12], false)
					
					build_menu[n].display_menu_builder = true
					
					
					--тип раба-строителя
					local Type_builder = GetUnitTypeId(LastSelestedUnit[n])
					if Type_builder==FourCC('hpea') or Type_builder==FourCC('opeo') or Type_builder==FourCC('nmpe') or Type_builder==FourCC('nhew') or Type_builder==FourCC('nbee') or Type_builder==FourCC('uaco') then
					
						local new_list_builder = AddBoxs(LastSelestedUnit[n],3,2)
					
						local num = 1
						for a=1, #new_list_builder do
							--тип постройки
							local Type_building = new_list_builder[a]
							--записываем тип здания в ячейку
							build_menu[n].Building_Id[num]=Type_building
							
							--эти три переменные текста просто защита, мало ли в таблице мб не указаны тексты
							local text_hotkey = ''
							local text_title = ''
							local text_descript = ''
							--если в базе данных присутствует заглавие, то показываем. Иначе, пустая строка
							if build_text_tip[Type_building] then
								text_title = tostring(build_text_tip[Type_building])
							end
							--если в базе данных присутствует горячая клавиша, то показываем. Иначе, пустая строка
							if build_text_hotkey[Type_building] then
								BlzFrameSetText(build_menu[n].Tooltip_title[num],text_title..' (|cffffcc00'..tostring(build_text_hotkey[Type_building])..'|r)')
							else
								BlzFrameSetText(build_menu[n].Tooltip_title[num],text_title)
							end
							--если в базе данных присутствует описание, то показываем. Иначе, пустая строка
							if build_text_ubertip[Type_building] then
								text_descript = tostring(build_text_ubertip[Type_building])
							end
							BlzFrameSetText(build_menu[n].Tooltip_Text[num],text_descript)

							update_Tooltip_for_menu_builder(num, GetTriggerPlayer())
							num = num + 1
						end
					end
				end
			end

		end)
	end
	
end

--создать билд листу кнопку (если конечно, у билд листа нет своей кнопки)
--@ player PlAyer - игрок, которому создают кнопку меню;
--@ string build_list_id -  идишник списка
function CreateBuildListButton(PlAyer,build_list_id)
	local n = GetPlayerId(PlAyer)
	if type(build_menu)~='table' then print('ошибка CreateBuildListButton: общая таблица build_menu не инициирована') return false end
    if type(build_menu[n]) ~= 'table' then print('ошибка CreateBuildListButton: таблица игрока build_menu не инициирована') return false end
	if type(build_list_id)~='string' or (not BuildList[build_list_id]) then
		print('ошибка CreateBuildListButton: неверный 2-аргумент') return false
	end
	if (not BuildList[build_list_id].) then
		print('ошибка CreateBuildListButton: неверный 2-аргумент') return false
	end
	
	local num = BuildList[build_list_id].number_of_button_buid_menu[n]
	
	--если инициирована кнопка, то отменяем
	if type(num)=='number' and num>0 then
		return false
	end
	
	if not build_menu[n].button_build_menu then
		build_menu[n].button_build_menu = {}
		build_menu[n].icon_button_build_menu = {}
		build_menu[n].trigger_button_build_menu_enter = {}
		build_menu[n].trigger_button_build_menu_leave = {}
		build_menu[n].trigger_button_build_menu_click = {}
		build_menu[n].build_list_id = {}
		build_menu[n].build_button_title = {} --название кнопки вызова меню
		build_menu[n].build_button_desc = {} --описание кнопки вызова меню
		build_menu[n].build_button_hotkey = {} --строчная горячая клавиша вызова меню
		build_menu[n].build_button_oskey = {} --клавиша вызова меню
		build_menu[n].build_button_width = {} --ширина
		build_menu[n].build_button_height = {} --высота
		build_menu[n].build_button_visible = {} --кнопка в данный видима true/false
		build_menu[n].build_button_enable = {} --разрешен ли показ кнопки true/false
	end
	
	
	local num = GetMaxCountBuildList()+1
	--button_build_menu (frame): запись ключа
	build_menu[n].build_list_id[num]=build_list_id
	--build_list: запись номер кнопки
	BuildList[build_list_id].number_of_button_buid_menu[n] = num 
	
	build_menu[n].button_build_menu[num] = BlzCreateFrameByType("TEXT","button build menu",build_menu[n].interface,"",0)
	build_menu[n].icon_button_build_menu[num] = BlzCreateFrameByType("BACKDROP","IconTexture",build_menu[n].button_build_menu[num],"",0)
	
	local coord_x = BuildList[build_list_id].button_buid_menu_pos_x
	local coord_y = BuildList[build_list_id].button_buid_menu_pos_y
	local path_texture = BuildList[build_list_id].button_buid_menu_path_icon
	local str_button_name = BuildList[build_list_id].button_buid_menu_name
	local str_button_desc = BuildList[build_list_id].button_buid_menu_desc
	local str_hotkey = BuildList[build_list_id].button_buid_menu_hotkey
	local button_oskey = BuildList[build_list_id].button_buid_menu_oskey
	local w = BuildList[build_list_id].button_buid_menu_width
    local h = BuildList[build_list_id].button_buid_menu_height

	BlzFrameClearAllPoints(build_menu[n].button_build_menu[num])
	BlzFrameClearAllPoints(build_menu[n].icon_button_build_menu[num])
    BlzFrameSetAbsPoint(build_menu[n].button_build_menu[num], FRAMEPOINT_CENTER, coord_x, coord_y)
	BlzFrameSetAllPoints(build_menu[n].icon_button_build_menu[num],build_menu[n].button_build_menu[num])
	BlzFrameSetSize(build_menu[n].button_build_menu[num], w, h)
	BlzFrameSetTexture(build_menu[n].icon_button_build_menu[num], path_texture or path_icon_orc_build, 0, true)
    
	--в данный момент кнопка невидима
	build_menu[n].build_button_visible[num] = false
	BlzFrameSetVisible(build_menu[n].button_build_menu[num], build_menu[n].build_button_visible[num])
	
	--запоминаем ряд данных для подсказки tooltip
	build_menu[n].build_path_texture[num] = path_texture
	build_menu[n].build_button_title[num] = str_button_name --название кнопки вызова меню
	build_menu[n].build_button_desc[num] = str_button_desc --описание кнопки вызова меню
	build_menu[n].build_button_hotkey[num] = str_hotkey --строчная горячая клавиша вызова меню
	build_menu[n].build_button_oskey[num] = button_oskey --клавиша вызова меню
	build_menu[n].build_button_width[num] = w --ширина
	build_menu[n].build_button_height[num] = h --высота
	build_menu[n].build_button_enable[num] = true --кнопка включена к показу (можно нативкой отключить показ)
		
	--триггер фиксирует вход курсора мыши в кнопку "меню строительства" (помогает отслеживать клик в триггере trigger_button_build_menu_click)
	build_menu[n].trigger_button_build_menu_enter[num]=CreateTrigger()
	BlzTriggerRegisterFrameEvent(build_menu[n].trigger_button_build_menu_enter[num], build_menu[n].button_build_menu[num], FRAMEEVENT_MOUSE_ENTER)
	TriggerAddAction(build_menu[n].trigger_button_build_menu_enter[num],function()
		local n = GetPlayerId(GetTriggerPlayer())
		for a=1,build_menu[n].max_buttons_build_menu do
			if GetTriggeringTrigger()==build_menu[n].trigger_button_build_menu_enter[a] then
				build_menu[n].button_menu_builder_cursor_mouse_in_frame=a
				break
			end
		end	
	end)
	--триггер фиксирует покидание курсора мыши из кнопки "меню строительства" (помогает отслеживать клик в триггере trigger_button_build_menu_click)
	build_menu[n].trigger_button_build_menu_leave[num]=CreateTrigger()
	BlzTriggerRegisterFrameEvent(build_menu[n].trigger_button_build_menu_leave[num], build_menu[n].button_build_menu[a], FRAMEEVENT_MOUSE_LEAVE)
	TriggerAddAction(build_menu[n].trigger_button_build_menu_leave[num],function()
		local n = GetPlayerId(GetTriggerPlayer())
		for a=1,build_menu[n].max_buttons_build_menu do
			if GetTriggeringTrigger()==build_menu[n].trigger_button_build_menu_leave[a] then
				build_menu[n].button_menu_builder_cursor_mouse_in_frame=0
				break
			end
		end
	end)

	--триггер фиксирует нажатие на кнопку "меню строительства"
	build_menu[n].trigger_button_build_menu_click[num] =CreateTrigger()
	TriggerRegisterPlayerEvent(build_menu[n].trigger_button_build_menu_click[num], PlAyer, EVENT_PLAYER_MOUSE_UP )
	TriggerAddAction(build_menu[n].trigger_button_build_menu_click[num],function()
		local n = GetPlayerId(GetTriggerPlayer())
		
		if build_menu[n].button_menu_builder_cursor_mouse_in_frame>0 then
			if BlzGetTriggerPlayerMouseButton()==MOUSE_BUTTON_TYPE_LEFT  then
				print('click button "build menu"')
				
				--показываем кнопку отмены
				BlzFrameSetVisible(button_cancel, true)
				--скрываем кнопку меню
				for a=1, build_menu[n].max_buttons_build_menu do
					BlzFrameSetVisible(build_menu[n].button_build_menu[a], false)
				end
				--показываем контейнер 
				BlzFrameSetVisible(build_menu[n].conteiner, true)
				--скрываем последнюю кнопку
				BlzFrameSetVisible(build_menu[n].button[12], false)
				
				build_menu[n].display_menu_builder = true
				
				
				--тип раба-строителя
				local Type_builder = GetUnitTypeId(LastSelestedUnit[n])
				if Type_builder==FourCC('hpea') or Type_builder==FourCC('opeo') or Type_builder==FourCC('nmpe') or Type_builder==FourCC('nhew') or Type_builder==FourCC('nbee') or Type_builder==FourCC('uaco') then
				
					local new_list_builder = AddBoxs(LastSelestedUnit[n],3,2)
				
					local num = 1
					for a=1, #new_list_builder do
						--тип постройки
						local Type_building = new_list_builder[a]
						--записываем тип здания в ячейку
						build_menu[n].Building_Id[num]=Type_building
						
						--эти три переменные текста просто защита, мало ли в таблице мб не указаны тексты
						local text_hotkey = ''
						local text_title = ''
						local text_descript = ''
						--если в базе данных присутствует заглавие, то показываем. Иначе, пустая строка
						if build_text_tip[Type_building] then
							text_title = tostring(build_text_tip[Type_building])
						end
						--если в базе данных присутствует горячая клавиша, то показываем. Иначе, пустая строка
						if build_text_hotkey[Type_building] then
							BlzFrameSetText(build_menu[n].Tooltip_title[num],text_title..' (|cffffcc00'..tostring(build_text_hotkey[Type_building])..'|r)')
						else
							BlzFrameSetText(build_menu[n].Tooltip_title[num],text_title)
						end
						--если в базе данных присутствует описание, то показываем. Иначе, пустая строка
						if build_text_ubertip[Type_building] then
							text_descript = tostring(build_text_ubertip[Type_building])
						end
						BlzFrameSetText(build_menu[n].Tooltip_Text[num],text_descript)

						update_Tooltip_for_menu_builder(num, GetTriggerPlayer())
						num = num + 1
					end
				end
			end
		end

	end)
	
end

--Обновить показ кнопок для выбранного юнита
--@ player PlAyer - игрок, которому создают контейнер;
--@ integer number_last_button - номер последней кнопки
function DisplayButtonsBuildMenu(PlAyer,selected_unit)
	local n = GetPlayerId(PlAyer)
	if type(build_menu)~='table' then print('ошибка UpdateDataButtons: общая таблица build_menu не инициирована') return false end
    if type(build_menu[n]) ~= 'table' then print('ошибка UpdateDataButtons: таблица игрока build_menu не инициирована') return false end
	
	local TypeBuilder = GetUnitTypeId( selected_unit )
	if TypeBuilder < 1 then
		print('ошибка UpdateDataButtonsBuildMenu: неверный 2-аргумент') return false
	end
	
	local num = {}
	local h = GetHandleId(selected_unit)
	
	--записываем все возможные списки, которые могут быть у selected_unit
	local check_table = {}
	if #list_builder[h]>0 then
		for a=1, #list_builder[h] do
			local build_list_id = list_builder[h][a]
			check_table[build_list_id] = build_list_id
		end
	end
	if #list_builder_for_type[TypeBuilder]>0 then
		for a=1, #list_builder[TypeBuilder] do
			local build_list_id = list_builder[TypeBuilder][a]
			check_table[build_list_id] = build_list_id
		end
	end
	
	--прячем все кнопки
	for a=1,#build_menu[n].button_build_menu do
		build_menu[n].build_button_visible[a] = false
		BlzFrameSetVisible(build_menu[n].button_build_menu[a], false)
	end
		
	--теперь отображаем нужные кнопки вызова меню
	for k, v in pairs(check_table) do
		local num = BuildList[k].number_of_button_buid_menu[n]
		build_menu[n].build_button_visible[a] = build_menu[n].build_button_enable[num] and true
		BlzFrameSetVisible(build_menu[n].button_build_menu[num], build_menu[n].build_button_visible[num])
	end
end
	


function InitFramesBuildMenu(Load,rows,columns,offsets,gap_between_buttons)
	local n = GetPlayerId(GetLocalPlayer())
	
	if not Load then
		TimerForSelectedPlayer = CreateTimer()
		InitBuildMenu(Load)
		CreateBuildMenuForPlayer(GetLocalPlayer())
        --иницируем флаги
        InitParamBuildMenuForPlayer(GetLocalPlayer())
	else
		--обнуляем флаги
        InitParamBuildMenuForPlayer(GetLocalPlayer())
	end
	
	
		
	BlzLoadTOCFile("war3mapImported\\MySimpleButton.toc")
	gameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)
    --создать главное меню для игрока
	CreateMainBuildMenu(GetLocalPlayer(),gameUI)
	--создать общую динамичную подсказку
	CreateTooltipForButtonsBuildMenu(GetLocalPlayer())
	--создать контейнер кнопок
	CreateConteinerButtonsBuildMenu(GetLocalPlayer())
	--создать кнопку отмены
	CreateButtonCancel(PlAyer,number_last_button)
	--инициировать кнопки меню
	InitButtonsBuildMenu(PlAyer)
	--настройка контейнера
	SettingConteinerButtonsBuildMenu(PlAyer,x,y,rows,columns,width,height,gap,offset_x,offset_y, path_backdrop)

--доделать функции
SettingBuildMenu 
SettingConteinerButtonsBuildMenu



    
	

    --=========== функции ==================
        
        
        function UpdateResourseBarTooltip(num,plaYer) --
            local n = GetPlayerId(plaYer)
            local Type_building = build_menu[n].Building_Id[num]
            build_menu[n].frame_List = {} --пересоздаем локалку
            
            BlzFrameClearAllPoints(build_menu[n].icon_mana_cost[num])
            BlzFrameClearAllPoints(build_menu[n].icon_gold_cost[num])
            BlzFrameClearAllPoints(build_menu[n].icon_lumber_cost[num])
            BlzFrameClearAllPoints(build_menu[n].icon_food_cost[num])

                build_menu[n].gold_required[num]=0
                build_menu[n].lumber_required[num]=0
                build_menu[n].mana_required[num]=0
                build_menu[n].food_required[num]=0
            
            if build_gold_cost[Type_building] then
                if build_gold_cost[Type_building]>0 then
                    build_menu[n].frame_List[#build_menu[n].frame_List+1]=build_menu[n].icon_gold_cost[num]
                    build_menu[n].frame_List[#build_menu[n].frame_List+1]=build_menu[n].text_gold_cost[num]
                    build_menu[n].gold_required[num]=build_gold_cost[Type_building]
                    BlzFrameSetVisible(build_menu[n].icon_gold_cost[num], true)
                    BlzFrameSetText(build_menu[n].text_gold_cost[num],'|cffffcc00'..build_menu[n].gold_required[num]..'|r')

                else
                    BlzFrameSetVisible(build_menu[n].icon_gold_cost[num], false)
                end
            else
                BlzFrameSetVisible(build_menu[n].icon_gold_cost[num], false)
            end
            if build_lumb_cost[Type_building] then
                if build_lumb_cost[Type_building]>0 then
                    build_menu[n].frame_List[#build_menu[n].frame_List+1]=build_menu[n].icon_lumber_cost[num]
                    build_menu[n].frame_List[#build_menu[n].frame_List+1]=build_menu[n].text_lumber_cost[num]
                    build_menu[n].lumber_required[num]=build_lumb_cost[Type_building]

                    BlzFrameSetVisible(build_menu[n].icon_lumber_cost[num], true)
                    BlzFrameSetText(build_menu[n].text_lumber_cost[num],'|cffffcc00'..build_menu[n].lumber_required[num]..'|r')
                else
                    BlzFrameSetVisible(build_menu[n].icon_lumber_cost[num], false)
                end
            else
                BlzFrameSetVisible(build_menu[n].icon_lumber_cost[num], false)
            end
            if build_mana_cost[Type_building] then
                if build_mana_cost[Type_building]>0 then
                    build_menu[n].frame_List[#build_menu[n].frame_List+1]=build_menu[n].icon_mana_cost[num]
                    build_menu[n].frame_List[#build_menu[n].frame_List+1]=build_menu[n].text_mana_cost[num]
                    build_menu[n].mana_required[num]=build_mana_cost[Type_building]
                    BlzFrameSetText(build_menu[n].text_mana_cost[num],'|cffffcc00'..build_menu[n].mana_required[num]..'|r')
                    
                    BlzFrameSetVisible(build_menu[n].icon_mana_cost[num], true)
                else
                    BlzFrameSetVisible(build_menu[n].icon_mana_cost[num], false)
                end 
            else
                BlzFrameSetVisible(build_menu[n].icon_mana_cost[num], false)
            end
            if build_food_cost[Type_building] then
                if build_food_cost[Type_building]>0 then
                    build_menu[n].frame_List[#build_menu[n].frame_List+1]=build_menu[n].icon_food_cost[num]
                    build_menu[n].frame_List[#build_menu[n].frame_List+1]=build_menu[n].text_food_cost[num]
                    build_menu[n].food_required[num]=build_food_cost[Type_building]
                    
                    BlzFrameSetVisible(build_menu[n].icon_food_cost[num], true)
                    BlzFrameSetText(build_menu[n].text_food_cost[num],build_menu[n].food_required[num])
                else
                    BlzFrameSetVisible(build_menu[n].icon_food_cost[num], false)
                end 
            else
                BlzFrameSetVisible(build_menu[n].icon_food_cost[num], false)
            end
            --порядок определен, теперь прикрепляем звенья горизонтального ряда друг с другом
            for a=#build_menu[n].frame_List-1, 1, -2 do 
                --у каждого ресурса 2 фрейма: иконка и текст.
                --фреймы между ресурсами крепим друг к другу, иконка одного реса креится к тексту другого реса
                if a>1 then 
                    BlzFrameSetPoint(build_menu[n].frame_List[a], FRAMEPOINT_LEFT, build_menu[n].frame_List[a-1], FRAMEPOINT_RIGHT, 0.005, 0.0)
                end
            end
            
        end

        function update_building_requirement(key_frame, playeR)
           --если что-то указано, значит, проверяем на требование?
            if buildings_required_for_construction[key_frame] then
                if #buildings_required_for_construction[key_frame]>0 then
                    local co,str =  0,"Требуется:"
                    for a=1, #buildings_required_for_construction[key_frame] do
                        local Type = FourCC(buildings_required_for_construction[key_frame][a])
                        local count = BlzCountLivingPlayerUnitsOfTypeId(Type, playeR)
                        --print('кол-во '..GetObjectName(Type)..' = '..count)
                        if count==0 then
                            co =co+1
                            str=str.."|n-"..GetObjectName(Type)
                        end
                    end 
                    return co,str
                else
                    return 0
                end
            else
                return 0
            end
        end
        function update_tech_requirement(key_frame, playeR)
            local count,str =  0,"Требуется изучить:"
            if tech_required_for_construction[key_frame] then
                local table = tech_required_for_construction[key_frame]

                for techId, value in pairs(table) do
                    local lv = GetPlayerTechCount(playeR,FourCC(techId),true) --текущий уровень технологии
                    
                    --если текущий уровень lv не достиг требуемого уровня value
                    --значит, не изучен еще, записываем список технологии
                    if value > lv then
                        count = count + 1
                        str=str.."|n-"..GetObjectName(FourCC(techId))
                    end                    
                end
                return count,str
            else
                return 0
            end
        end
        function update_Tooltip_for_menu_builder(num, playeR)
            local n = GetPlayerId(playeR)
            local Type_building = build_menu[n].Building_Id[num]
            
            --кол-во требуемых здании, и список
            local count_1,str_1 = update_building_requirement(Type_building, playeR) 
            --кол-во требуемых технологии, и список
            local count_2,str_2 = update_tech_requirement(Type_building, playeR)
            local list_frame = {}

            --требования построить здания не выполнено, значит, добавляем фрейм подсказку
            if count_1 > 0  then
                --оставляем только требование на постройку
                BlzFrameSetVisible(build_menu[n].text_building_requirement[num], true)
                BlzFrameSetText(build_menu[n].text_building_requirement[num],'|cffffcc00'..str_1..'|r')
                list_frame[#list_frame+1]=build_menu[n].text_building_requirement[num]
            else
                BlzFrameSetVisible(build_menu[n].text_building_requirement[num], false)
            end
            --требования изучить технологию не выполнено, значит, добавляем фрейм подсказку
            if count_2 > 0  then
                --оставляем только требование на изучение технологии
                BlzFrameSetVisible(build_menu[n].text_tech_requirement[num], true)
                BlzFrameSetText(build_menu[n].text_tech_requirement[num],'|cffffcc00'..str_2..'|r')
                list_frame[#list_frame+1]=build_menu[n].text_tech_requirement[num]
            else
                BlzFrameSetVisible(build_menu[n].text_tech_requirement[num], false)
            end

            BlzFrameClearAllPoints(build_menu[n].Tooltip_title[num])
            BlzFrameClearAllPoints(build_menu[n].text_tech_requirement[num])
            BlzFrameClearAllPoints(build_menu[n].text_building_requirement[num])

               
            if count_1>0 or count_2>0 then 
                --заменяем иконку на не активную
                local icon = build_icon[Type_building]
                BlzFrameSetTexture(build_menu[n].IconTexture[num], path_disabled_icon .. icon, 0, true)
                build_menu[n].requirement_met[num]=false
                --убираем /прячем лишние фреймы
                BlzFrameSetVisible(build_menu[n].resourse_bar[num], false)
                
                if #list_frame>1 then
                    BlzFrameSetPoint(build_menu[n].Tooltip_title[num], FRAMEPOINT_BOTTOMLEFT, build_menu[n].text_building_requirement[num], FRAMEPOINT_TOPLEFT, -0.005, 0.005)
                    BlzFrameSetPoint(build_menu[n].text_building_requirement[num], FRAMEPOINT_BOTTOMLEFT, build_menu[n].Tooltip_HorizontalSeparator[num], FRAMEPOINT_TOPLEFT, -0.005, 0.005)
                    BlzFrameSetPoint(build_menu[n].text_tech_requirement[num], FRAMEPOINT_BOTTOMLEFT, build_menu[n].text_building_requirement[num], FRAMEPOINT_TOPLEFT, -0.005, 0.005)
                    
                    
                elseif #list_frame==1 then
                    BlzFrameSetPoint(build_menu[n].Tooltip_title[num], FRAMEPOINT_BOTTOMLEFT, list_frame[1], FRAMEPOINT_TOPLEFT, -0.005, 0.005)
                    BlzFrameSetPoint(list_frame[1], FRAMEPOINT_BOTTOMLEFT, build_menu[n].Tooltip_HorizontalSeparator[num], FRAMEPOINT_TOPLEFT, -0.005, 0.005)
                end  
            elseif count_1+count_2==0 then
                --заменяем иконку на активную
                local icon = build_icon[Type_building]
                BlzFrameSetTexture(build_menu[n].IconTexture[num], path_active_icon .. icon, 0, true)
                build_menu[n].requirement_met[num]=true
                
                UpdateResourseBarTooltip(num,playeR)
                if #build_menu[n].frame_List>0 then
                    BlzFrameSetVisible(build_menu[n].resourse_bar[num], true)
                    
                    BlzFrameClearAllPoints(build_menu[n].frame_List[1])
                    BlzFrameClearAllPoints(build_menu[n].Tooltip_title[num])
                        
                    BlzFrameSetPoint(build_menu[n].frame_List[1], FRAMEPOINT_BOTTOMLEFT, build_menu[n].Tooltip_HorizontalSeparator[num], FRAMEPOINT_TOPLEFT, -0.0018, 0.0025)
                    BlzFrameSetPoint(build_menu[n].Tooltip_title[num], FRAMEPOINT_BOTTOMLEFT, build_menu[n].frame_List[1]~=nil and build_menu[n].frame_List[1] or build_menu[n].Tooltip_HorizontalSeparator[num], FRAMEPOINT_TOPLEFT, 0.00025, 0.0025)
                else
                    BlzFrameSetVisible(build_menu[n].resourse_bar[num], false)
                    
                    BlzFrameClearAllPoints(build_menu[n].Tooltip_title[num])
                    BlzFrameSetPoint(build_menu[n].Tooltip_title[num], FRAMEPOINT_BOTTOMLEFT, build_menu[n].Tooltip_HorizontalSeparator[num], FRAMEPOINT_TOPLEFT, -0.005, 0.005)
                end
            end      
        end

        
        function AddBoxs(builder,column,row)
            local button_xy = {}
            for x=0, column do
				if not button_xy[x] then
					button_xy[x]={}
				end
            end
            local button_busy = {}
            local type_builder = GetUnitTypeId(builder)
            
            for a=1,#list_builder[type_builder] do
                local Type_building = list_builder[type_builder][a]
                
                local button_data = ButtonList[Type_building] or ButtonList['default']
                local x, y = button_data.pos_x or 0, button_data.pos_y or 0
                
                if not button_xy[x][y] then
                    button_xy[x][y]=FourCC(Type_building)
                    button_busy[a]=true
                end
            end
            for a=1,#list_builder[type_builder] do
                local Type_building = list_builder[type_builder][a]
                if not button_busy[a] then
                    
                    local exit = false
                    for y=0, row do
                        if exit then
                            break
                        end
                        for x=0, column do
                            if not button_xy[x][y] then
                                button_xy[x][y]=FourCC(Type_building)
                                button_busy[a]=true
                                print(a..') '..x..'-'..y..' '..GetObjectName(button_xy[x][y]))
                                exit = true
                                break 
                            end
                        end
                    end
                end
            end
            
            local tt = {}
            local exit = false
            for y=0, row do
                if exit then
                    break
                end
                
                for x=0, column do
                    if button_xy[x][y] then
                        tt[#tt+1]=button_xy[x][y]
                        --print(#tt..') '..GetObjectName(button_xy[x][y]))
                    end
                    if #list_builder[type_builder]==#tt then
                        exit = true
                        break
                    end
                end
            end
            
            return tt
        end
        
        

    
    
    --========== триггеры фреймов ====================
    


            
        --триггер фиксирует отпускание горячей кнопки во время отображения списка меню строительства
            local trigger_up_key = CreateTrigger()

            local hpea = FourCC('hpea')
            for a=1, #list_builder[hpea] do
                local Type_building = FourCC(list_builder[hpea][a])
                local oskey = build_text_oskey[Type_building]
                BlzTriggerRegisterPlayerKeyEvent(trigger_up_key, Player(0), oskey, 0, false)
            end
            local opeo = FourCC('opeo')
            for a=1, #list_builder[opeo] do
                local Type_building = FourCC(list_builder[opeo][a])
                local oskey = build_text_oskey[Type_building]
                BlzTriggerRegisterPlayerKeyEvent(trigger_up_key, Player(0), oskey, 0, false)
            end
            local nmpe = FourCC('nmpe')
            for a=1, #list_builder[nmpe] do
                local Type_building = FourCC(list_builder[nmpe][a])
                local oskey = build_text_oskey[Type_building]
                BlzTriggerRegisterPlayerKeyEvent(trigger_up_key, Player(0), oskey, 0, false)
            end
			local nhew = FourCC('nhew')
            for a=1, #list_builder[nhew] do
                local Type_building = FourCC(list_builder[nhew][a])
                local oskey = build_text_oskey[Type_building]
                BlzTriggerRegisterPlayerKeyEvent(trigger_up_key, Player(0), oskey, 0, false)
            end
			local uaco = FourCC('uaco')
            for a=1, #list_builder[uaco] do
                local Type_building = FourCC(list_builder[uaco][a])
                local oskey = build_text_oskey[Type_building]
                BlzTriggerRegisterPlayerKeyEvent(trigger_up_key, Player(0), oskey, 0, false)
            end
			
            
            TriggerAddAction(trigger_up_key,function()
                local n = GetPlayerId(GetTriggerPlayer())
                
                --проверка: отображено ли панель меню строительства
                if build_menu[n].display_menu_builder then
                    local Type_builder = GetUnitTypeId(LastSelestedUnit[n])
                    print('нажата кнопка')
                    
                    --перебираем индекс кнопки
                    for a=1,#list_builder[Type_builder] do
                        local Type_Building = FourCC(list_builder[Type_builder][a])
                        local oskey = build_text_oskey[Type_Building]
                    
                        if BlzGetTriggerPlayerKey()==oskey then
                            print('click button-'..tostring(a))
                            
                            --проверяем требования выполнены ли	игроком		
                            if build_menu[n].requirement_met[a] then
                                print('требования выполнены')
                                
                                --далее проверяем достаточно ли игроку ресурсов
                                local gold,lumber,food,mana =0,0,0,0
                                if Type_Building>0 then --если указан какой либо тип
                                    --проверяем есть ли в требовании золото (если указана)
                                    if build_gold_cost[Type_Building] then
                                        if build_gold_cost[Type_Building]> 0 then
                                            gold=build_gold_cost[Type_Building]
                                        end
                                    end
                                    --проверяем есть ли в требовании древесина (если указана)
                                    if build_lumb_cost[Type_Building]then
                                        if build_lumb_cost[Type_Building]> 0 then
                                            lumber=build_lumb_cost[Type_Building]
                                        end
                                    end 
                                    --проверяем указана ли в требовании пища (если указана)
                                    if build_food_cost[Type_Building]then
                                        if build_food_cost[Type_Building]> 0 then
                                            food=build_food_cost[Type_Building]
                                        end
                                    end 
                                    --проверяем есть ли в требовании мана (если указана)
                                    if build_mana_cost[Type_Building]then
                                        if build_mana_cost[Type_Building]> 0 then
                                            mana=build_mana_cost[Type_Building]
                                        end
                                    end
                                    --далее сравниваем
                                    local flag = true
                                    if (gold>GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_GOLD) and lumber>GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_LUMBER)) or gold>GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_GOLD)  then
                                        DisplayTimedTextToPlayer(GetTriggerPlayer(), 0.3, 0.21, 0.3, "|Cffffcc00Недостаточно золото|r")
                                        flag = false
                                    elseif lumber>GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_LUMBER) then
                                        DisplayTimedTextToPlayer(GetTriggerPlayer(), 0.3, 0.21, 0.3, "|Cffffcc00Недостаточно древесины|r")
                                        flag = false
                                    end
                                    
                                    --если требование на ресурсы выполнимы, то отображаем панель выбора
                                    if flag then
                                        --показываем кнопку отмены
                                        BlzFrameSetVisible(button_cancel, true)
                                        --скрываем кнопку меню
                                        BlzFrameSetVisible(button_build_menu, false)
                                        --скрываем контейнер 
                                        BlzFrameSetVisible(build_menu[n].conteiner, false)
                                        --меню раба закрыто
                                        build_menu[n].display_menu_builder = false
                                        --игрок выбирает участок
                                        build_menu[n].player_chooses_place = true
                                        BlzFrameSetEnable(build_menu[n].Mask, true)
                                        
                                        for b=1, 12 do
                                            build_menu[n].Building_Id[b]=0
                                            BlzFrameSetTexture(build_menu[n].IconTexture[b], path_icon, 0, true)
                                            BlzFrameSetText(build_menu[n].Tooltip_Text[b],'описание')
                                            BlzFrameSetText(build_menu[n].Tooltip_title[b],'заглавие')
                                        end
                                        
                                        local path_effect = GetTriggerPlayer()==GetLocalPlayer() and build_model[Type_Building] or nil
                                        
                                        build_menu[n].id=Type_Building
                                        build_menu[n].model=AddSpecialEffect(path_effect,build_menu[n].coord_x,build_menu[n].coord_y)
                                        BlzPlaySpecialEffect(build_menu[n].model,ANIM_TYPE_STAND)
										
										local scale = build_scale_model[Type_Building]
										--print('size_model: '..tostring(scale))
										if scale then
											--BlzSetSpecialEffectMatrixScale(build_menu[n].model,scale,scale,scale)
											BlzSetSpecialEffectScale(build_menu[n].model,scale)
										end
										
										
										--по дефолту 270.
										build_menu[n].building_facing = 270.
										
                                        BlzSetSpecialEffectYaw(build_menu[n].model, math.rad(build_menu[n].building_facing))
                                        BlzSetSpecialEffectColorByPlayer( build_menu[n].model,GetOwningPlayer(LastSelestedUnit[n]))
                                        
										if type(build_size_pathing[Type_Building]) == 'number' then
											build_menu[n].width=build_size_pathing[Type_Building]
											build_menu[n].height=build_size_pathing[Type_Building]
										else
											build_menu[n].width=build_size_pathing[Type_Building].width
											build_menu[n].height=build_size_pathing[Type_Building].height
										end
                                        build_menu[n].can_build=false
                                            
                                        local block = 32.
                                        local half_width,half_height = (build_menu[n].width/2),(build_menu[n].height/2)
                                        local cx,cy = build_menu[n].coord_x,build_menu[n].coord_y
                                        --границы
										local minx,maxx,miny,maxy = cx-half_width,cx+half_width,cy-half_height,cy+half_height

                                        local x,y = minx,miny+(block/2)
                                        local num = 0
                                        
                                        for y=miny+(block/2),maxy,block do
                                            for x=minx+(block/2),maxx,block do
                                                num = num+1
												build_menu[n].image[num]=CreateSquareImageForPlayer(GetTriggerPlayer(),"war3mapImported\\block 32x32.TGA",block*2,x,y,2)
												--координаты image
												build_menu[n].image_x[num]=x
												build_menu[n].image_y[num]=y
												--оффсеты от центра
												build_menu[n].image_offset_x[num]=x-cx
												build_menu[n].image_offset_y[num]=y-cy
                                            end
                                        end
										build_menu[n].count_images = num
										
										--при повороте может меняться число images, статичное число изображении достаточно подвинуть
										--а динамичное число нужно пересоздавать
										if type_building_for_rotate[Type_Building] then
											build_menu[n].building_can_be_rotated = true
											build_menu[n].building_update_rotate = true
											build_menu[n].offsets_rotate.vx1=-half_width
											build_menu[n].offsets_rotate.vx2=-half_width
											build_menu[n].offsets_rotate.vx3=half_width
											build_menu[n].offsets_rotate.vx4=half_width
											build_menu[n].offsets_rotate.vy1=-half_height
											build_menu[n].offsets_rotate.vy2=half_height
											build_menu[n].offsets_rotate.vy3=half_height
											build_menu[n].offsets_rotate.vy4=-half_height
										else
											build_menu[n].building_can_be_rotated = false
										end
										
                                        UpdatePathingPlayer(cx,cy,half_width,half_height,block,GetTriggerPlayer())
                                        
                                    end
                                end
                            end
                        end
                    end
                end

            end)


        
            
        --триггер фиксирует поворот колесиком
            local trigger_button_wheel=CreateTrigger()
            BlzTriggerRegisterFrameEvent(trigger_button_wheel, build_menu[n].Mask, FRAMEEVENT_MOUSE_WHEEL)
            BlzTriggerRegisterFrameEvent(trigger_button_wheel, build_menu[n].button[1], FRAMEEVENT_MOUSE_WHEEL)
            BlzTriggerRegisterFrameEvent(trigger_button_wheel, build_menu[n].button[2], FRAMEEVENT_MOUSE_WHEEL)
            BlzTriggerRegisterFrameEvent(trigger_button_wheel, build_menu[n].button[3], FRAMEEVENT_MOUSE_WHEEL)
            BlzTriggerRegisterFrameEvent(trigger_button_wheel, build_menu[n].button[4], FRAMEEVENT_MOUSE_WHEEL)
            BlzTriggerRegisterFrameEvent(trigger_button_wheel, build_menu[n].button[5], FRAMEEVENT_MOUSE_WHEEL)
            BlzTriggerRegisterFrameEvent(trigger_button_wheel, build_menu[n].button[6], FRAMEEVENT_MOUSE_WHEEL)
            BlzTriggerRegisterFrameEvent(trigger_button_wheel, build_menu[n].button[7], FRAMEEVENT_MOUSE_WHEEL)
            BlzTriggerRegisterFrameEvent(trigger_button_wheel, build_menu[n].button[8], FRAMEEVENT_MOUSE_WHEEL)
            BlzTriggerRegisterFrameEvent(trigger_button_wheel, build_menu[n].button[9], FRAMEEVENT_MOUSE_WHEEL)
            BlzTriggerRegisterFrameEvent(trigger_button_wheel, build_menu[n].button[10], FRAMEEVENT_MOUSE_WHEEL)
            BlzTriggerRegisterFrameEvent(trigger_button_wheel, build_menu[n].button[11], FRAMEEVENT_MOUSE_WHEEL)
            BlzTriggerRegisterFrameEvent(trigger_button_wheel, build_menu[n].button[12], FRAMEEVENT_MOUSE_WHEEL)
            BlzTriggerRegisterFrameEvent(trigger_button_wheel, button_cancel, FRAMEEVENT_MOUSE_WHEEL)
            TriggerAddAction(trigger_button_wheel,function()
                local n = GetPlayerId(GetTriggerPlayer())
                if build_menu[n].player_chooses_place then
                
					local type_building = build_menu[n].id
					
					--проверяем указано ли такое здание в базе данных как здание, способное на повороты
                    if type_building_for_rotate[type_building] then
                    
                        if BlzGetTriggerFrameValue()>0 then
                            build_menu[n].building_facing=build_menu[n].building_facing+30.
						elseif BlzGetTriggerFrameValue()<0 then
                            build_menu[n].building_facing=build_menu[n].building_facing-30.
                        end
						build_menu[n].building_update_rotate = true
                        
                        local cx,cy=build_menu[n].coord_x,build_menu[n].coord_y
                        local Type = build_menu[n].id
                        local block = 32.
                        
                        local half_width,half_height=build_menu[n].width/2,build_menu[n].height/2
                        BlzSetSpecialEffectYaw(build_menu[n].model, math.rad(math.fmod(build_menu[n].building_facing,360)))
                        UpdatePathingPlayer(cx,cy,half_width,half_height,block,GetTriggerPlayer())
                    end
                end
            end)
            
            
end

		InitFramesBuildMenu() --инициируем фреймы
		
        local triggerLoad = CreateTrigger()
        timer = CreateTimer()
        TriggerRegisterGameEvent(triggerLoad, EVENT_GAME_LOADED)
        TriggerAddAction(triggerLoad, function()
            TimerStart(timer, 0, false, function()
				InitFrames_v2()
				InitFramesBuildMenu(true)
            end)
        end)
        --фиксирует изменение выбора игрока
            --инициируем глобалки (помогают отслеживать изменение выбора игрока)
            NewSelestedUnit = {} 
            LastSelestedUnit = {}
			
            --таймер чекает интерфейс и группу выделенных игроком юнитов
            TimerStart(TimerForSelectedPlayer, 1/32, true, function()
                SelectedUnit()
            end)

    
            function SelectedUnit()
                local n = GetPlayerId(GetLocalPlayer())
                local index = GetSelectedUnitIndex()
                local u = GetMainSelectedUnit(index)
                
                NewSelestedUnit[n] = u

                --если юнит живой и существует
                if not ( GetUnitTypeId (u) == 0 or IsUnitType (u, UNIT_TYPE_DEAD)) then

                        
                    --если юнит новый, обновляем инфу
                    if LastSelestedUnit[n] ~= NewSelestedUnit[n] then 
                        
                        
                        if IsUnitType(u, UNIT_TYPE_HERO) then
                            if index then
                                print("|cffff00ffвыбран "..GetUnitName(u)..' '..GetHeroProperName(u)..', index group:|r '..tostring(index))
                            else
                                print("|cffff00ffвыделен "..GetUnitName(u)..' '..GetHeroProperName(u)..'|r')
                            end
                        else
                            if index then
                                print("|cffff00ffвыбран "..GetUnitName(u)..', index group:|r '..tostring(index))
                            else
                                print("|cffff00ffвыделен "..GetUnitName(u)..' '..GetHeroProperName(u)..'|r')
                            end
                        end

                        LastSelestedUnit[n] = NewSelestedUnit[n]  
                        
                        if GetUnitTypeId (u)==FourCC('hpea') or GetUnitTypeId (u)==FourCC('nhew') or GetUnitTypeId (u)==FourCC('nbee') then
                                
                            --закрываем меню
                            CloseBuildMenu(n)
                            --если выбран рабочий хуманов, показываем меню
                            BlzFrameSetVisible(build_menu[n].interface, true)
                            --сменить иконку на хуманскую
                            BlzFrameSetTexture(icon_button_build_menu, path_icon_human_build, 0, true)

                            
                        elseif GetUnitTypeId (u)==FourCC('opeo') or GetUnitTypeId (u)==FourCC('nmpe') then
                            
                            --закрываем меню
                            CloseBuildMenu(n)
                            --если выбран пеон орков, показываем меню
                            BlzFrameSetVisible(build_menu[n].interface, true)
                            --сменить иконку на орочью
                            BlzFrameSetTexture(icon_button_build_menu, path_icon_orc_build, 0, true)
						elseif GetUnitTypeId (u)==FourCC('uaco') then
                            --закрываем меню
                            CloseBuildMenu(n)
                            --если выбран послушник нежити, показываем меню
                            BlzFrameSetVisible(build_menu[n].interface, true)
                            --сменить иконку на иконку нежити
                            BlzFrameSetTexture(icon_button_build_menu, path_icon_undead_build, 0, true)
                        else
                            --если выбран не рабочий-строитель, а какой-то обычный юнит или герой
                        
                            --закрываем меню
                            CloseBuildMenu(n)
                            --иначе, если выбран новый юнит, которыйф не является рабочим
                            --если выбран не рабочий, меню скрываем
                            BlzFrameSetVisible(build_menu[n].interface, false)
                            --скрываем кнопку меню
                            BlzFrameSetVisible(button_build_menu, false)
                        end 
                    end

                else
                    --если юнит мертв или не существует (возможна выделена декорация или итем)
                    
                    --закрываем меню
                    CloseBuildMenu(n)
                    --иначе, если выбран новый юнит, которыйф не является рабочим
                    --если выбран не рабочий, меню скрываем
                    BlzFrameSetVisible(build_menu[n].interface, false)
                    --скрываем кнопку меню
                    BlzFrameSetVisible(button_build_menu, false)
                end
            end
        
        --триггер фиксирует изменения на поле боя
            --если здание удалилось/сменило владельца/заново построено
            --фиксирует исчезновение, появление юнита, и заносит изменение в подсказку фрейма
            --здания, которые не достроены, не учитываются
            local trigger_update = CreateTrigger()
            TriggerRegisterAnyUnitEventBJ( trigger_update, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH )
            TriggerRegisterAnyUnitEventBJ( trigger_update, EVENT_PLAYER_UNIT_DEATH )
            TriggerRegisterAnyUnitEventBJ( trigger_update, EVENT_PLAYER_UNIT_CHANGE_OWNER )
            TriggerRegisterAnyUnitEventBJ( trigger_update, EVENT_PLAYER_UNIT_UPGRADE_FINISH )
            TriggerRegisterAnyUnitEventBJ( trigger_update, EVENT_PLAYER_UNIT_RESEARCH_FINISH )
            TriggerAddAction( trigger_update, function()
               
                local n = GetPlayerId(GetTriggerPlayer())
            
                --print('фиксируем изменения +')

                if build_menu[n].display_menu_builder then
                    TimerStart(CreateTimer(),0.03,false,function()
                
                        --тип раба-строителя
                        local Type_builder = GetUnitTypeId(LastSelestedUnit[n])
                        if Type_builder==FourCC('hpea') or Type_builder==FourCC('opeo') or Type_builder==FourCC('nmpe') or Type_builder==FourCC('nhew') or Type_builder==FourCC('nbee') or Type_builder==FourCC('uaco') then
                    
                            local num = 1
                            for a=1, #list_builder[Type_builder] do
                                --тип постройки
                                local Type_building = FourCC(list_builder[Type_builder][a])

                                --записываем тип здания в ячейку
                                build_menu[n].Building_Id[num]=Type_building
                                
                                --эти три переменные текста просто защита, мало ли в таблице мб не указаны тексты
                                local text_hotkey = ''
                                local text_title = ''
                                local text_descript = ''
                                --если в базе данных присутствует заглавие, то показываем. Иначе, пустая строка
                                if build_text_tip[Type_building] then
                                    text_title = tostring(build_text_tip[Type_building])
                                end
                                --если в базе данных присутствует горячая клавиша, то показываем. Иначе, пустая строка
                                if build_text_hotkey[Type_building] then
                                    BlzFrameSetText(build_menu[n].Tooltip_title[num],text_title..' (|cffffcc00'..tostring(build_text_hotkey[Type_building])..'|r)')
                                else
                                    BlzFrameSetText(build_menu[n].Tooltip_title[num],text_title)
                                end
                                --если в базе данных присутствует описание, то показываем. Иначе, пустая строка
                                if build_text_ubertip[Type_building] then
                                    text_descript = tostring(build_text_ubertip[Type_building])
                                end
                                BlzFrameSetText(build_menu[n].Tooltip_Text[num],text_descript)
                                
                                update_Tooltip_for_menu_builder(num, Player(n))
                                num = num + 1
                            end
                        end
                        DestroyTimer(GetExpiredTimer())
                    end)
                end
            end)
    
  end
end

--почему-то только в InitGlobals норм таймер работает
do 
	local InitGlobalsOrigin = InitGlobals
	function InitGlobals()
		InitGlobalsOrigin()

        --группа здании, которые строятся. отсеивает достроенные здания от построенных
        local group_construct = CreateGroup()

        --триггер фиксирует начало строительства здания (отсеивает построенные здания от недостроенных)
        local start_construction = CreateTrigger()
        TriggerRegisterAnyUnitEventBJ( start_construction, EVENT_PLAYER_UNIT_CONSTRUCT_START )
        TriggerRegisterAnyUnitEventBJ( start_construction, EVENT_PLAYER_UNIT_UPGRADE_START )
        TriggerAddAction( start_construction, function()
			if GetSpellAbilityId()==EVENT_PLAYER_UNIT_CONSTRUCT_START then

			end
            GroupAddUnit(group_construct, GetTriggerUnit())
        end)
        --триггер фиксирует завершение строительства здания (отсеивает построенные здания от недостроенных)
        local end_construction = CreateTrigger()
        TriggerRegisterAnyUnitEventBJ( end_construction, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH )
        TriggerRegisterAnyUnitEventBJ( end_construction, EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL )
        TriggerRegisterAnyUnitEventBJ( end_construction, EVENT_PLAYER_UNIT_UPGRADE_CANCEL )
        TriggerRegisterAnyUnitEventBJ( end_construction, EVENT_PLAYER_UNIT_UPGRADE_FINISH )
        TriggerRegisterAnyUnitEventBJ( end_construction, EVENT_PLAYER_UNIT_DEATH )
        TriggerAddAction( end_construction, function()
            GroupRemoveUnit(group_construct, GetTriggerUnit())
        end)

        function BlzCountLivingPlayerUnitsOfTypeId(unitId, whichPlayer)
            local g = CreateGroup()
            GroupEnumUnitsOfPlayer(g, whichPlayer, Condition(function()
            return GetUnitTypeId(GetFilterUnit())==unitId and (not IsUnitType( GetFilterUnit(), UNIT_TYPE_DEAD )) and (not IsUnitInGroup(GetFilterUnit(),group_construct))
            end))
            local Count = BlzGroupGetSize(g)
            DestroyGroup(g)

            return Count
        end
        
        

        
        TimerStart(CreateTimer(),0.00,false,function()
            print('init trigger_mouse_move')
            tr_mouse_move = CreateTrigger()
            TriggerRegisterPlayerEvent(tr_mouse_move, Player(0), EVENT_PLAYER_MOUSE_MOVE )
            TriggerAddAction(tr_mouse_move, function()
                
                
                local n = GetPlayerId(GetTriggerPlayer())
                --print(GetPlayerName(GetTriggerPlayer()))

                local block = 32

                local half_width,half_height = (build_menu[n].width/2),(build_menu[n].height/2)
                local x = Real_offset_64(BlzGetTriggerPlayerMouseX()) 
                local y = Real_offset_64(BlzGetTriggerPlayerMouseY()) 
                --local Z = Real_offset_64(GetLocationZ(loc))
                
                if x<0 then
                    x=x+64.
                end
                if y<0 then
                    y=y+64.
                end
                --print(x,y)
                --if (not IsTerrainPathable(x,y,PATHING_TYPE_PEONHARVESTPATHING)) then
                    --print('peon')
                --else
                    --print('not peon')
                --end
                
                if build_menu[n].coord_x ~= x or build_menu[n].coord_y ~= y then
                    build_menu[n].coord_x = x
                    build_menu[n].coord_y = y
                    
                     if build_menu[n].player_chooses_place then
                        --print(BlzGetTriggerPlayerMouseX(),BlzGetTriggerPlayerMouseY())
                    
                        if build_menu[n].mask_cursor_mouse_in_frame then
                            BlzEnableCursor(false)
                        else
                            BlzEnableCursor(true)
                        end
                    
                        BlzSetSpecialEffectPosition(build_menu[n].model, x, y,0)
                        UpdatePathingPlayer(x,y,half_width,half_height,block,GetTriggerPlayer())
                    end
                end

            end)

            tr_mouse_click = CreateTrigger()
            TriggerRegisterPlayerEvent(tr_mouse_click, Player(0), EVENT_PLAYER_MOUSE_DOWN )
            TriggerAddAction(tr_mouse_click, function()
                local n = GetPlayerId(GetTriggerPlayer())    
                  
                if MOUSE_BUTTON_TYPE_LEFT ==BlzGetTriggerPlayerMouseButton() then
                  
                    if build_menu[n].player_chooses_place then --если игрок выбирает место строительства
                        
						if build_menu[n].can_build then
                        
                        
                            local Type_Building = build_menu[n].id
                                
                            local gold,lumber,food,mana =0,0,0,0
                            if Type_Building>0 then

								if build_gold_cost[Type_Building]then
									if build_gold_cost[Type_Building]> 0 then
										gold=build_gold_cost[Type_Building]
									end
								end
								if build_lumb_cost[Type_Building]then
									if build_lumb_cost[Type_Building]> 0 then
										lumber=build_lumb_cost[Type_Building]
									end
								end 
								if build_food_cost[Type_Building]then
									if build_food_cost[Type_Building]> 0 then
										food=build_food_cost[Type_Building]
									end
								end 
								if build_mana_cost[Type_Building]then
									if build_mana_cost[Type_Building]> 0 then
										mana=build_mana_cost[Type_Building]
									end
								end 
								local flag = true
								if (gold>GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_GOLD) and lumber>GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_LUMBER)) or gold>GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_GOLD)  then
									DisplayTimedTextToPlayer(GetTriggerPlayer(), 0.3, 0.21, 0.3, "|Cffffcc00Недостаточно золото|r")
									flag = false
								elseif lumber>GetPlayerState(GetTriggerPlayer(), PLAYER_STATE_RESOURCE_LUMBER) then
									DisplayTimedTextToPlayer(GetTriggerPlayer(), 0.3, 0.21, 0.3, "|Cffffcc00Недостаточно древесины|r")
									flag = false
								end
                            
								if flag then
                                    --закрываем меню
									CloseBuildMenu(n)
                                    if (Type_Building == FourCC('ugol')) then
                                        local g, goldMine = CreateGroup(),nil
                                        local loc = Location(build_menu[n].coord_x,build_menu[n].coord_y)
                                        GroupEnumUnitsInRangeOfLoc(g, loc, 2*bj_CELLWIDTH, filterIssueHauntOrderAtLocBJ)
                                        goldMine = FirstOfGroup(g)
                                        DestroyGroup(g)
                                        RemoveLocation(loc)

                                        if (goldMine ~= nil) then
                                            IssueTargetOrderById(LastSelestedUnit[n], FourCC('ugol'), goldMine)
                                        end
                                    else
										if build_menu[n].building_can_be_rotated then
											IssueBuildOrderById(LastSelestedUnit[n],id_dummy_for_rotate,build_menu[n].coord_x,build_menu[n].coord_y)
										else
											IssueBuildOrderById(LastSelestedUnit[n],Type_Building,build_menu[n].coord_x,build_menu[n].coord_y)
										end
                                    end
								end
							end
							
							
                        else
                            DisplayTimedTextToPlayer(GetTriggerPlayer(), 0.3, 0.21, 0.3, "|Cffffcc00Вы не можете здесь строить|r")
                        end
                     
                    end
                end
            end)
            DestroyTimer(GetExpiredTimer())

        end)
    end
end
`
ОЖИДАНИЕ РЕКЛАМЫ...
29
И снова спойлерное адище. Может собственный githab завести вам? xd
27
И снова спойлерное адище. Может собственный githab завести вам? xd
это пробник, пробую написать свой список нативок.
30
Может собственный githab завести вам?
Ну так заведи, и заодно сможешь систему gist прикрутить, чтоб можно было удобно кодом делиться и не править его прям в статье.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.