нативки 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.
указывают в них идишники здании или ид-технологии
еще можно указать ряд исследовании, которые нужно изучить, чтобы построить - 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
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
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
Ред. nazarpunk