Name | Type | is_array | initial_value |
Count | integer | No | |
HeroSelectorCategory | integer | Yes | |
HeroSelectorEvent | real | No | |
HeroSelectorRandomOnly | unitcode | Yes | |
HeroSelectorUnitCode | unitcode | Yes |
-- in 1.31 and upto 1.32.9 PTR (when I wrote this). Frames are not correctly saved and loaded, breaking the game.
-- This runs all functions added to it with a 0s delay after the game was loaded.
FrameLoader = {
OnLoadTimer = function ()
for _,v in ipairs(FrameLoader) do v() end
end
,OnLoadAction = function()
TimerStart(FrameLoader.Timer, 0, false, FrameLoader.OnLoadTimer)
end
}
function FrameLoaderAdd(func)
if not FrameLoader.Timer then
FrameLoader.Trigger = CreateTrigger()
FrameLoader.Timer = CreateTimer()
TriggerRegisterGameEvent(FrameLoader.Trigger, EVENT_GAME_LOADED)
TriggerAddAction(FrameLoader.Trigger, FrameLoader.OnLoadAction)
end
table.insert(FrameLoader, func)
end
-- Credits Luashine
-- FourCC breaks after Save & Load and only worked for 4 digit rawcodes
function FourCC(str)
local n = 0
local len = #str
for i = len, 1, -1 do
n = n + (str:byte(i,i) << 8*(len-i)) -- shift by 0,8,16,24
end
return n
end
do
local real = InitBlizzard
function InitBlizzard()
real()
-- enable the next line as soon blizzard fixed the bug in current version
--if GetLocalizedString("REFORGED") ~= "REFORGED" then return end
local tim = CreateTimer()
local trig = CreateTrigger()
TriggerRegisterGameEvent(trig, EVENT_GAME_SAVE)
TriggerAddAction(trig, function()
local backup = string.pack
local backup2 = string.unpack
string.pack = nil
string.unpack = nil
TimerStart(tim, 0, false, function()
string.pack = backup
string.unpack = backup2
end)
end)
local trig2 = CreateTrigger()
TriggerRegisterGameEvent(trig2, EVENT_GAME_LOADED)
TriggerAddAction(trig2, function()
-- prevent restoring the backups when the game is loaded
PauseTimer(tim)
end)
end
end
--[[ TasFrameAction by Tasyen
TasFrameAction is an Lua system to not have to care about Trigger and FrameEvents for FrameAction. All FrameEvents are binded to one trigger that trigger than calls the action for
handles frame Events in one trigger, care only about the actionFunction itself.
calls give Actions inside xpcall.
Supports only one Action per Event+Frame
Example
TasSliderAction(sliderFrame, function(frame, player, value)
print(BlzFrameGetName(frame), GetPlayerId(player), value)
end)
TasButtonAction(frame, function(frame, player))
wrapper for TasFrameAction meant for BUTTON just ControlClick
Removes focus & StopCamera
takes FRAMEEVENT_CONTROL_CLICK from TasFrameAction for this frame
TasSliderAction(frame, function(frame, player, value))
action happens when a Value is set
TasSliderAction.AvoidPoll (true) skip actions with the same value in a row by 1 player
takes FRAMEEVENT_MOUSE_WHEEL and FRAMEEVENT_SLIDER_VALUE_CHANGED from TasFrameAction for this frame
TasEditBoxAction(frame[, actionEnter, actionEdit])
skip an action to not have one for that event
function(frame, player, text)
TasDialogAction(frame, function(frame, player, accept))
TasCheckBoxAction(frame, function(frame, player, checked))
TasFrameMouseMoveAction(frame, actionEnter(frame, player), actionLeave(frame, player), actionWheel(frame, player, upwards))
TasFrameMouseUpAction(frame, action(frame, player, rightClick)
Happens when the mouse click is released over frame
rightClick does not work probably during Paused Games
TasMenuAction(frame, function(frame, player, value))
for POPUPMENU
functions above use an entry in TasFrameAction
TasFrameAction(frame, action, frameEvent)
action = function(frame, player, value, text)
]]
TasFrameAction = setmetatable({
EVENTNAME= {
"CONTROL_CLICK", "MOUSE_ENTER", "MOUSE_LEAVE", "MOUSE_UP"
, "MOUSE_DOWN", "MOUSE_WHEEL", "CHECKBOX_CHECKED", "CHECKBOX_UNCHECKED"
, "EDITBOX_TEXT_CHANGED", "POPUPMENU_ITEM_CHANGED", "MOUSE_DOUBLECLICK", "SPRITE_ANIM_UPDATE"
, "SLIDER_VALUE_CHANGED", "DIALOG_CANCEL", "DIALOG_ACCEPT", "EDITBOX_ENTER"
}
,ERROR = function(x)
print("TasFrameAction - ERROR")
print("FrameName", BlzFrameGetName(BlzGetTriggerFrame()), TasFrameAction.EVENTNAME[GetHandleId(BlzGetTriggerFrameEvent())]
, "PlayerId:", GetPlayerId(GetTriggerPlayer())
-- , BlzGetTriggerFrameValue(), BlzGetTriggerFrameText()
)
print(x)
return x
end
}
,{
__call = function(table, frame, action, frameEvent)
-- first call?
if not TasFrameAction.Trigger then
-- FrameEventData
for i = 1, 16 do
TasFrameAction[ConvertFrameEventType(i)] = {}
end
-- yes, Create the Trigger and the click handler.
TasFrameAction.Trigger = CreateTrigger()
TriggerAddAction(TasFrameAction.Trigger, function()
local frame = BlzGetTriggerFrame()
local event = BlzGetTriggerFrameEvent()
-- call the action set for that frame&Event
if TasFrameAction[event][frame] then
xpcall(TasFrameAction[event][frame], TasFrameAction.ERROR, frame, GetTriggerPlayer(), BlzGetTriggerFrameValue(), BlzGetTriggerFrameText())
--TasFrameAction[event][frame](frame, GetTriggerPlayer(), BlzGetTriggerFrameValue(), BlzGetTriggerFrameText())
end
frame = nil
event = nil
end)
end
-- create the click event only when it does not exist yet.
if not TasFrameAction[frameEvent][frame] then
BlzTriggerRegisterFrameEvent(TasFrameAction.Trigger, frame, frameEvent)
end
-- Using [frameEvent][frame] brings a fixed amout of Tables.
TasFrameAction[frameEvent][frame] = action
end
})
TasSliderAction = setmetatable({
AvoidPoll = true
,WHEEL = function(frame, player, value, text)
if GetLocalPlayer() == player then
if value > 0 then
BlzFrameSetValue(frame, BlzFrameGetValue(frame) + 1)
else
BlzFrameSetValue(frame, BlzFrameGetValue(frame) - 1)
end
end
end
,VALUE = function(frame, player, value, text)
-- avoid Polling
if not TasSliderAction.AvoidPoll or TasSliderAction.AvoidPollData[player][frame] ~= value then
TasSliderAction.AvoidPollData[player][frame] = value
TasSliderAction[frame](frame, player, value)
end
end
}
,{__call = function(table, frame, action)
-- first call?
if not TasSliderAction.AvoidPollData then
TasSliderAction.AvoidPollData = {}
for i=0, bj_MAX_PLAYER_SLOTS - 1 do TasSliderAction.AvoidPollData[Player(i)] = __jarray(0.0) end
end
TasFrameAction(frame, TasSliderAction.WHEEL, FRAMEEVENT_MOUSE_WHEEL)
TasFrameAction(frame, TasSliderAction.VALUE, FRAMEEVENT_SLIDER_VALUE_CHANGED)
TasSliderAction[frame] = action
end
})
TasSliderAction.Set = TasSliderAction
TasButtonAction = setmetatable({
ACTION = function(frame, player, value, text)
-- remove Focus for the local clicking player
if player == GetLocalPlayer() then
BlzFrameSetEnable(frame, false)
BlzFrameSetEnable(frame, true)
StopCamera()
end
-- call the action set for that frame
TasButtonAction[frame](frame, player)
end
},{
__call = function(table, frame, action)
TasFrameAction(frame, TasButtonAction.ACTION, FRAMEEVENT_CONTROL_CLICK)
TasButtonAction[frame] = action
end
})
TasButtonAction.Set = TasButtonAction
TasEditBoxAction = setmetatable({
A = {}
,B = {}
,ENTER = function(frame, player, value, text)
TasEditBoxAction.A[frame](frame, player, text)
end
,EDIT = function(frame, player, value, text)
TasEditBoxAction.B[frame](frame, player, text)
end
},{
__call = function(table, frame, actionEnter, actionEdit)
if actionEnter then
TasFrameAction(frame, TasEditBoxAction.ENTER, FRAMEEVENT_EDITBOX_ENTER)
TasEditBoxAction.A[frame] = actionEnter
end
if actionEdit then
TasFrameAction(frame, TasEditBoxAction.EDIT, FRAMEEVENT_EDITBOX_TEXT_CHANGED)
TasEditBoxAction.B[frame] = actionEdit
end
end
})
TasEditBoxAction.Set = TasEditBoxAction
TasDialogAction = setmetatable({
ACTION = function(frame, player)
TasDialogAction[frame](frame, player, BlzGetTriggerFrameEvent() == FRAMEEVENT_DIALOG_ACCEPT)
end
},{
__call = function(table, frame, action)
TasFrameAction(frame, TasDialogAction.ACTION, FRAMEEVENT_DIALOG_ACCEPT)
TasFrameAction(frame, TasDialogAction.ACTION, FRAMEEVENT_DIALOG_CANCEL)
TasDialogAction[frame] = action
end
})
TasDialogAction.Set = TasDialogAction
TasCheckBoxAction = setmetatable({
ACTION = function(frame, player)
TasCheckBoxAction[frame](frame, player, BlzGetTriggerFrameEvent() == FRAMEEVENT_CHECKBOX_CHECKED)
end
},{
__call = function(table, frame, action)
TasFrameAction(frame, TasCheckBoxAction.ACTION, FRAMEEVENT_CHECKBOX_CHECKED)
TasFrameAction(frame, TasCheckBoxAction.ACTION, FRAMEEVENT_CHECKBOX_UNCHECKED)
TasCheckBoxAction[frame] = action
end
})
TasCheckBoxAction.Set = TasCheckBoxAction
TasFrameMouseMoveAction = setmetatable({
A = {}
,B = {}
,C = {}
,ENTER = function(frame, player)
TasFrameMouseMoveAction.A[frame](frame, player)
end
,LEAVE = function(frame, player)
TasFrameMouseMoveAction.B[frame](frame, player)
end
,WHEEL = function(frame, player, value)
TasFrameMouseMoveAction.C[frame](frame, player, value > 0)
end
},{
__call = function(table, frame, actionEnter, actionLeave, actionWheel)
if actionEnter then
TasFrameAction(frame, TasFrameMouseMoveAction.ENTER, FRAMEEVENT_MOUSE_ENTER)
TasFrameMouseMoveAction.A[frame] = actionEnter
end
if actionLeave then
TasFrameAction(frame, TasFrameMouseMoveAction.LEAVE, FRAMEEVENT_MOUSE_LEAVE)
TasFrameMouseMoveAction.B[frame] = actionLeave
end
if actionWheel then
TasFrameAction(frame, TasFrameMouseMoveAction.WHEEL, FRAMEEVENT_MOUSE_WHEEL)
TasFrameMouseMoveAction.C[frame] = actionWheel
end
end
})
TasFrameMouseMoveAction.Set = TasFrameMouseMoveAction
TasFrameMouseUpAction = setmetatable({
TriggerCount = 0
,ACTION = function(frame, player)
-- during Pause EVENT_PLAYER_MOUSE_UP does not work, -> when The counter didn't increase since last Time do not allow this count as right click
local clickWorked = GetTriggerExecCount(TasFrameMouseUpAction.MouseTrigger) > TasFrameMouseUpAction.TriggerCount
TasFrameMouseUpAction[frame](frame, player, TasFrameMouseUpAction.RightClick[player] and clickWorked)
TasFrameMouseUpAction.TriggerCount = GetTriggerExecCount(TasFrameMouseUpAction.MouseTrigger)
end
},{
__call = function(table, frame, action)
if not TasFrameMouseUpAction.MouseTrigger then
TasFrameMouseUpAction.RightClick = __jarray(false)
TasFrameMouseUpAction.MouseTrigger = CreateTrigger()
for i = 0, bj_MAX_PLAYERS - 1 do
TriggerRegisterPlayerEvent(TasFrameMouseUpAction.MouseTrigger, Player(i), EVENT_PLAYER_MOUSE_UP)
end
TriggerAddAction(TasFrameMouseUpAction.MouseTrigger, function()
TasFrameMouseUpAction.RightClick[GetTriggerPlayer()] = GetHandleId(BlzGetTriggerPlayerMouseButton()) == GetHandleId(MOUSE_BUTTON_TYPE_RIGHT)
end)
end
TasFrameAction(frame, TasFrameMouseUpAction.ACTION, FRAMEEVENT_MOUSE_UP)
TasFrameMouseUpAction[frame] = action
end
})
TasFrameMouseUpAction.Set = TasFrameMouseUpAction
TasMenuAction = setmetatable({
ACTION = function(frame, player, value)
TasMenuAction[frame](frame, player, value)
end
},{
__call = function(table, frame, action)
TasFrameAction(frame, TasMenuAction.ACTION, FRAMEEVENT_POPUPMENU_ITEM_CHANGED)
TasMenuAction[frame] = action
end
})
TasMenuAction.Set = TasMenuAction
function CreateSimpleTooltip(frame, text, bottom)
-- this FRAME is important when the Box is outside of 4:3 it can be limited to 4:3.
local toolTipParent = BlzCreateFrameByType("FRAME", "", frame, "", 0)
local toolTipBox = BlzCreateFrame("EscMenuControlBackdropTemplate", toolTipParent, 0, 0)
local toolTip = BlzCreateFrame("TasTooltipText", toolTipBox, 0, 0)
if not bottom then
BlzFrameSetPoint(toolTip, FRAMEPOINT_BOTTOM, frame, FRAMEPOINT_TOP, 0, 0.008)
else
BlzFrameSetPoint(toolTip, FRAMEPOINT_TOP, frame, FRAMEPOINT_BOTTOM, 0, -0.008)
end
BlzFrameSetPoint(toolTipBox, FRAMEPOINT_TOPLEFT, toolTip, FRAMEPOINT_TOPLEFT, -0.008, 0.008)
BlzFrameSetPoint(toolTipBox, FRAMEPOINT_BOTTOMRIGHT, toolTip, FRAMEPOINT_BOTTOMRIGHT, 0.008, -0.008)
BlzFrameSetText(toolTip, text)
BlzFrameSetTooltip(frame, toolTipParent)
return toolTip
end
--[[
HeroSelector V1.9 by Tasyen
A UI System to pick a Hero/UnitCode also supports ban and requirments
]]
HeroSelector = {}
HeroSelector.TocPath = "war3mapImported\\HeroSelector.toc" --ex/import also "HeroSelector.fdf"
--Box
HeroSelector.BoxFrameName = "HeroSelectorRaceBox" --this is the background box being created
HeroSelector.BackgroundTexture = "" -- if this is not "" it displays it over the box background
HeroSelector.BackgroundTiles = 1 -- 0=streched 1=tileMode
HeroSelector.BoxPosX = 0.5
HeroSelector.BoxPosY = 0.4
HeroSelector.BoxPosPoint = FRAMEPOINT_CENTER
HeroSelector.AutoShow = true --(true) shows the box and the Selection at 0.0 for all players
HeroSelector.AutoCreate = true --(true) create itself when gameStarted. (false) you need to HeroSelector.initHeroes() HeroSelector.initFrames()
--Unique Picks
HeroSelector.UnitCount = 999 --each hero is in total allowed to be picked this amount of times (includes random, repicking allows a hero again).
HeroSelector.UnitCountPerTeam = 1 --Each Team is allowed to pick this amount of each unitType
HeroSelector.ToManyTooltip = "OUTOFSTOCKTOOLTIP"
-- HeroSelector.PickAbleHeroes is a Way to define pickable Units without touching HeroSelector.initHeroes
-- pickable options expects one string like "Hamg,Hmkg,Hpal,Hblm". It can contain 0 to have empty slots "Hamg,0,Hpal,0,Hblm"
-- all melee heroes "Hamg,Hmkg,Hpal,Hblm,Obla,Ofar,Otch,Oshd,Udea,Ulic,Udre,Ucrl,Edem,Ekee,Emoo,Ewar,Nngs,Nbrn,Npbm,Nplh,Nbst,Nfir,Ntin,Nalc"
HeroSelector.PickAbleHeroes = ""
HeroSelector.EnableGUICode = true -- enables the gui parser and throwing the picked event. if you don't use either you should set this to false.
--Ban
HeroSelector.DelayBanUntilPick = false --(true) baning will not be applied instantly, instead it is applied when HeroSelector.enablePick is called the next time.
--Category
HeroSelector.CategoryData = {
--Icon path, tooltip Text (tries to localize), HeroCdes "Hmkg,Hpal"
{"ReplaceableTextures\\CommandButtons\\BTNSteelMelee", "MELEE"}, --1, automatic detected when adding an unit
{"ReplaceableTextures\\CommandButtons\\BTNHumanMissileUpOne", "Ranged"}, --2, automatic detected when adding an unit
{"ReplaceableTextures\\CommandButtons\\BTNGauntletsOfOgrePower", "STRENGTH"}, --4
{"ReplaceableTextures\\CommandButtons\\BTNSlippersOfAgility", "AGILITY"}, --8
{"ReplaceableTextures\\CommandButtons\\BTNMantleOfIntelligence", "INTELLECT"}, --16
}
HeroSelector.CategoryAffectRandom = true --(false) random will not care about selected category
HeroSelector.CategorySize = 0.02 --the size of the Category Button
HeroSelector.CategorySpaceX = 0.0008 --space between 2 category Buttons, it is meant to need only one line of Categoryy Buttons.
HeroSelector.CategoryFilteredAlpha = 45 -- Alpha value of Heroes being filtered by unselected categories
HeroSelector.CategoryAutoDetect = true -- try to set category of added options automatic
HeroSelector.CategoryAutoDetectHero = true -- (heavy performance wise) create and remove added Heroes to setup the Category for the primary Attribute Str(4) Agi(8) Int(16)
HeroSelector.CategorySingleSelect = __jarray(true) -- (true) clicking category will unselect others, you need this false when you want to have multiselect
HeroSelector.PlayerSelectModeExclusive = __jarray(false) -- (true) hero needs to fit all categories selected (false) needs to fit 1 category
--Indicator
HeroSelector.IndicatorPathPick = "UI\\Feedback\\Autocast\\UI-ModalButtonOn.mdl" --this model is used by the indicator during picking
HeroSelector.IndicatorPathBan = "war3mapImported\\HeroSelectorBan.mdl" --this model is used by the indicator during baning
--Grid
HeroSelector.SpaceBetweenX = 0.008 --space between 2 buttons in one row
HeroSelector.SpaceBetweenY = 0.008 --space between 2 rows
HeroSelector.ButtonColCount = 4 --amount of buttons in one row
HeroSelector.ButtonRowCount = 4 --amount of rows
HeroSelector.ChainedButtons = true --(true) connect to the previous button/ or row, (false) have a offset to the box topLeft in this moving a button has no effect on other buttons.
--Button
HeroSelector.ButtonSize = 0.036 --size of each button
HeroSelector.ButtonBlendAll = false --(true) when a hero icon uses transparenzy
HeroSelector.EmptyButtonPath = "UI\\Widgets\\EscMenu\\Human\\blank-background.blp"
HeroSelector.HideEmptyButtons = true
--Ban Button
HeroSelector.BanButtonTextPrefix = "|cffcf2084" --Prefix Text for the Ban Button
HeroSelector.BanButtonText = "CHAT_ACTION_BAN"
HeroSelector.BanButtonTooltipText = "CHAT_ACTION_BAN" --over the ban button
HeroSelector.BanButtonSizeX = 0.085
HeroSelector.BanButtonSizeY = 0.03
HeroSelector.BanTooltip = "DISALLOWED" -- over the hero button
HeroSelector.BanIgnoreRequirment = true -- (true) Ban is not restricted by Requirments
--BanDone Button
HeroSelector.BanDoneButtonTextPrefix = "|cffcf2084" --Prefix Text for the Ban Button
HeroSelector.BanDoneButtonText = "QUESTACCEPT" --tries to get a Localized String
HeroSelector.BanDoneButtonTooltipText = "I am done with Banning" --tries to get a Localized String
HeroSelector.BanDoneButtonSizeX = 0.085
HeroSelector.BanDoneButtonSizeY = 0.03
HeroSelector.BanDoneButtonIsShown = true --show this button in the Ban Phase
--BanMany Button
HeroSelector.BanManyButtonTextPrefix = "|cffcf2084" --Prefix Text for the Ban Button
HeroSelector.BanManyButtonTooltipText = "String_BanManyButtonTooltip" --Prefix Text for the Ban Button
HeroSelector.BanManyButtonText = "Massen Bann" --tries to get a Localized String
HeroSelector.BanManyButtonSizeX = 0.085
HeroSelector.BanManyButtonSizeY = 0.03
HeroSelector.BanManyBannRemain = __jarray(0) -- how many bans this button does? write a number in __jarray(x) BanMany bans random heroes of current category
HeroSelector.BanManyButtonIsShown = false --show this button in the Ban Phase
--Accept Button
HeroSelector.AcceptButtonTextPrefix = ""
HeroSelector.AcceptButtonText = "ACCEPT"
HeroSelector.AcceptButtonTooltipText = "ACCEPT"
HeroSelector.AcceptButtonSizeX = 0.085
HeroSelector.AcceptButtonSizeY = 0.03
HeroSelector.AcceptButtonIsShown = true --show this button in the Pick Phase
--Random Button
HeroSelector.RandomButtonTextPrefix = ""
HeroSelector.RandomButtonText = "RANDOM" --tries Localizing
HeroSelector.RandomButtonTooltipText = "String_RandomButtonTooltip" --tries Localizing
HeroSelector.RandomButtonTooltipText2 = { [false] ="String_RandomButtonTooltipSelect" ,[true] = "String_RandomButtonTooltipPick"} --tries Localizing
HeroSelector.RandomButtonSizeX = 0.085
HeroSelector.RandomButtonSizeY = 0.03
HeroSelector.RandomButtonIsShown = true --show this button in the Pick Phase
HeroSelector.RandomButtonPick = false --(true) pressing the random button will pick the option. (false) pressing the random button will select a button, random only heroes can not be selected, but that does not matter. This weak random and randomonly should not be combined.
--Repick Button
HeroSelector.RepickButtonTextPrefix = ""
HeroSelector.RepickButtonText = "REPICK" --tries Localizing
HeroSelector.RepickButtonTooltipText = "String_RepickButtonTooltip" --tries Localizing
HeroSelector.RepickButtonTextLimit = "Repick (#)" --tries Localizing # is the variable for the remaining
HeroSelector.RepickButtonSizeX = 0.085
HeroSelector.RepickButtonSizeY = 0.03
HeroSelector.RepickButtonIsShown = true --show this button in the Pick Phase
HeroSelector.RepickMax = 0 -- when bigger than 0 only that amount of Repicks is allowed
--ShowButton
HeroSelector.ShowButtonTextPrefix = ""
HeroSelector.ShowButtonText = "PICK-HERO" --tries Localizing
HeroSelector.ShowButtonSizeX = 0.085
HeroSelector.ShowButtonSizeY = 0.03
HeroSelector.ShowButtonIsShown = false --show this button
HeroSelector.ShowButtonX = 0.42
HeroSelector.ShowButtonY = 0.58
HeroSelector.ShowButtonPoint = FRAMEPOINT_TOPLEFT
HeroSelector.ShowButtonParent = function() return BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0) end
--Search
HeroSelector.SearchBoxToolTipText = "Search in Name & Spells.|nNot used by Random."
HeroSelector.SearchBoxSizeX = 0.12
HeroSelector.SearchBoxSizeY = 0.035
HeroSelector.SearchBoxSizeIsShown = false
--MUltiSelect Button
HeroSelector.MultiSelectButtonTextures = {"ui\\widgets\\battlenet\\bnet-mainmenu-friends-disabled", "ui\\widgets\\battlenet\\bnet-mainmenu-friends-up"}
HeroSelector.MultiSelectButtonTooltipText = {"Multi Concentrate", "Multi Expand"}
HeroSelector.MultiSelectButtonIsShown = false
--MUltiSelect Button
HeroSelector.CategoryClearButtonTexture = "replaceabletextures\\commandbuttons\\btncancel"
HeroSelector.CategoryClearButtonTooltipText = "Clear Category"
HeroSelector.CategoryClearButtonIsShown = false
--Tooltip
HeroSelector.TooltipPrefix = "|cffffcc00"
HeroSelector.TooltipOffsetX = 0
HeroSelector.TooltipOffsetY = 0
HeroSelector.TooltipPoint = FRAMEPOINT_BOTTOM --pos the Tooltip with which Point
HeroSelector.TooltipRelativePoint = FRAMEPOINT_TOP --pos the Tooltip to which Point of the Relative
HeroSelector.TooltipRelativIsBox = false --(true) use the box as anchor, (false) use the button as anchor
HeroSelector.TooltipRequires = "QUESTCOMPONENTS"
HeroSelector.TooltipRequires2 = {
[RACE_HUMAN] = "HUMAN"
,[RACE_ORC] = "ORC"
,[RACE_UNDEAD] = "UNDEAD"
,[RACE_NIGHTELF] = "NIGHT_ELF"
,[PLAYER_STATE_RESOURCE_HERO_TOKENS] = "HERO TOCKEN"
}
--Border
HeroSelector.BorderSize = {}
HeroSelector.BorderSize[RACE_HUMAN] = 0.029 --border size seen by Race Human, this is needed cause the borders are different in size.
HeroSelector.BorderSize[RACE_ORC] = 0.029
HeroSelector.BorderSize[RACE_UNDEAD] = 0.035
HeroSelector.BorderSize[RACE_NIGHTELF] = 0.035
HeroSelector.BorderSize[RACE_DEMON] = 0.024
--This runs before the box is created with that the system has the needed data right when it is needed.
--you can add units somewhere else but it is done after the box was created you have to use the update function to update the textures of shown buttons
function HeroSelector.initHeroes()
--create categories setuped in config
local categories = HeroSelector.CategoryData
HeroSelector.Category = {}
for index, value in ipairs(categories) do
HeroSelector.addCategory(value[1], value[2])
end
--read GUI, when the variable exist
if HeroSelector.EnableGUICode and udg_HeroSelectorUnitCode then
local index = 1
--add from index 1 all random only heroes
while udg_HeroSelectorRandomOnly[index] ~= 0 do
HeroSelector.addUnit(udg_HeroSelectorRandomOnly[index], true)
index = index + 1
end
--copy the setuped field
for index = 1, HeroSelector.ButtonColCount*HeroSelector.ButtonRowCount,1 do
HeroSelector.addUnit(udg_HeroSelectorUnitCode[index])
if udg_HeroSelectorCategory and udg_HeroSelectorCategory[index] ~= 0 then
HeroSelector.addUnitCategory(udg_HeroSelectorUnitCode[index], udg_HeroSelectorCategory[index])
end
end
--kill the tables
udg_HeroSelectorUnitCode = nil
udg_HeroSelectorRandomOnly = nil
udg_HeroSelectorCategory = nil
end
--adding further units when using the GUI Array does not make much sense, except you would add rows.
if HeroSelector.PickAbleHeroes and (type(HeroSelector.PickAbleHeroes) =="string" and string.len( HeroSelector.PickAbleHeroes ) >= 4 ) then HeroSelector.addUnit(HeroSelector.PickAbleHeroes) end
local iCat = 1
for index, value in ipairs(categories) do
if value[3] then
HeroSelector.addUnitCategory(value[3], iCat)
end
iCat=iCat*2
end
--skip further demo code
if true then return end
HeroSelector.addUnit("Hgam", true, 0) --antonidas is an only random Hero that can only be randomed by team 0 (for users 1).
HeroSelector.addUnit("Eevi", true, 1) --evil Illidan is an only random Hero that can only be randomed by team 1 (for users 2).
--Adds requirments
--when you have a ban phase it might be better to add the requirments after the ban phase is over, otherwise one can only ban own options.
--paladin requires having 5 footman, Archmage a Hero Tocken other human heroes can only picked by human-Race, as nightelf only for Nightelf
HeroSelector.setUnitReq('Hpal', {FourCC('hfoo'), 5})
HeroSelector.setUnitReq('Hamg', PLAYER_STATE_RESOURCE_HERO_TOKENS)
HeroSelector.setUnitReq('Hblm', RACE_HUMAN)
HeroSelector.setUnitReq('Hmkg', RACE_HUMAN)
--HeroSelector.setUnitReq('Ofar', RACE_ORC)
--HeroSelector.setUnitReq('Oshd', RACE_ORC)
--HeroSelector.setUnitReq('Otch', RACE_ORC)
--HeroSelector.setUnitReq('Obla', RACE_ORC)
HeroSelector.setUnitReq('Emoo', RACE_NIGHTELF)
HeroSelector.setUnitReq('Edem', RACE_NIGHTELF)
HeroSelector.setUnitReq('Ekee', RACE_NIGHTELF)
HeroSelector.setUnitReq('Ewar', RACE_NIGHTELF)
--HeroSelector.setUnitReq('Udea', RACE_UNDEAD)
--HeroSelector.setUnitReq('Ulic', RACE_UNDEAD)
--HeroSelector.setUnitReq('Udre', RACE_UNDEAD)
--HeroSelector.setUnitReq('Ucrl', RACE_UNDEAD)
--[[
local categoryMelee = 1 --autodetected
local categoryRanged = 2 --autodetected
local categoryStr = 4
local categoryAgi = 8
local categoryInt = 16
HeroSelector.addUnitCategory('Hpal', categoryStr)
HeroSelector.addUnitCategory('Hamg', categoryInt)
HeroSelector.addUnitCategory('Hblm', categoryInt)
HeroSelector.addUnitCategory('Hmkg', categoryStr)
HeroSelector.addUnitCategory('Ofar', categoryInt)
HeroSelector.addUnitCategory('Oshd', categoryAgi)
HeroSelector.addUnitCategory('Otch', categoryAgi)
HeroSelector.addUnitCategory('Obla', categoryAgi)
HeroSelector.addUnitCategory('Emoo', categoryAgi)
HeroSelector.addUnitCategory('Edem', categoryAgi)
HeroSelector.addUnitCategory('Ekee', categoryInt)
HeroSelector.addUnitCategory('Ewar', categoryAgi)
HeroSelector.addUnitCategory('Udea', categoryStr)
HeroSelector.addUnitCategory('Ulic', categoryInt)
HeroSelector.addUnitCategory('Udre', categoryStr)
HeroSelector.addUnitCategory('Ucrl', categoryStr)
HeroSelector.setUnitCategory('Hgam', categoryInt + categoryRanged)
HeroSelector.setUnitCategory("Eevi", categoryAgi + categoryMelee)
--]]
--[[
HeroSelector.addUnit('Hpal') --add paladin as selectable Hero
HeroSelector.addUnit('Hamg')
HeroSelector.addUnit('Hblm')
HeroSelector.addUnit('Hmkg')
HeroSelector.addUnit("Obla", true) --this unit can only be randomed
HeroSelector.addUnit("Ofar")
HeroSelector.addUnit("Otch", 1) --this unit can only be randomed
HeroSelector.addUnit() --this is an empty box. It still takes a slot.
HeroSelector.addUnit()
HeroSelector.addUnit("Oshd")
HeroSelector.addUnit("Edem")
HeroSelector.addUnit() --this is an empty box. It still takes a slot.
HeroSelector.addUnit()
HeroSelector.addUnit("Ekee")
HeroSelector.addUnit("Emoo")
HeroSelector.addUnit("Ewar",true)
HeroSelector.addUnit("Udea")
HeroSelector.addUnit("Ulic")
HeroSelector.addUnit("Udre")
HeroSelector.addUnit("Ucrl",1)
--]]
end
function HeroSelector.autoDetectCategory(unitCode)
if HeroSelector.CategoryAutoDetect then
if IsUnitIdType(unitCode, UNIT_TYPE_MELEE_ATTACKER) then
HeroSelector.UnitData[unitCode].Category = 1
elseif IsUnitIdType(unitCode, UNIT_TYPE_RANGED_ATTACKER) then
HeroSelector.UnitData[unitCode].Category = 2
end
if HeroSelector.CategoryAutoDetectHero and IsUnitIdType(unitCode, UNIT_TYPE_HERO) then
local unit = CreateUnit(Player(bj_PLAYER_NEUTRAL_EXTRA), unitCode, 0, 0, 270)
local primaryAttribute = BlzGetUnitIntegerField(unit, UNIT_IF_PRIMARY_ATTRIBUTE)
RemoveUnit(unit)
if ConvertHeroAttribute(primaryAttribute) == HERO_ATTRIBUTE_STR then
HeroSelector.UnitData[unitCode].Category = HeroSelector.UnitData[unitCode].Category + 4
elseif ConvertHeroAttribute(primaryAttribute) == HERO_ATTRIBUTE_AGI then
HeroSelector.UnitData[unitCode].Category = HeroSelector.UnitData[unitCode].Category + 8
elseif ConvertHeroAttribute(primaryAttribute) == HERO_ATTRIBUTE_INT then
HeroSelector.UnitData[unitCode].Category = HeroSelector.UnitData[unitCode].Category + 16
end
end
end
end
--what happens to the unit beeing picked, player is the one having pressed the button
function HeroSelector.unitCreated(player, unitCode, isRandom)
bj_lastCreatedUnit = CreateUnit(player, unitCode, GetPlayerStartLocationX(player), GetPlayerStartLocationY(player), 0)
local unit = bj_lastCreatedUnit
HeroSelector.PickedUnit[player] = unit
if isRandom then
--randomed
else
--picked
end
if player == Player(1) then
end
PanCameraToTimedForPlayer(player, GetUnitX(unit), GetUnitY(unit),0)
SelectUnitForPlayerSingle(unit, player)
HeroSelector.enablePick(false, player) --only one pick for this player
if HeroSelector.EnableGUICode then
globals.udg_HeroSelectorEvent = 0
globals.udg_HeroSelectorEvent = 1.0
end
--print(GetPlayerName(player),"picks",GetUnitName(unit))
end
--happens when the banButton is pressed, player is the one having pressed the button
function HeroSelector.unitBaned(player, unitCode)
HeroSelector.enableBan(false, player) --only one ban
--print(GetPlayerName(player),"bans",GetObjectName(unitCode))
end
function HeroSelector.buttonSelected(player, unitCode)
--player who pressed the button
--unitCode the unitCode selected
--this is not picked.
--print(GetPlayerName(player),"selects",GetObjectName(unitCode))
end
function HeroSelector.repick(unit, player)
if not unit then return end
UnitRemoveBuffsBJ(bj_REMOVEBUFFS_ALL, unit) --this is done to undo metamorph
local unitCode = GetUnitTypeId(unit)
if unitCode == 0 then return end
HeroSelector.counterChangeUnitCode(unitCode, -1, player)
if not player then
player = GetOwningPlayer(unit)
end
HeroSelector.PickedUnit[player] = nil
HeroSelector.show(true, player)
HeroSelector.enablePick(true, player)
RemoveUnit(unit)
end
function HeroSelector.actionBanDoneButton(frame, player)
-- HeroSelector.enablePick(true) -> on click finish the Ban Phase and start pick Phase
HeroSelector.enablePick(true)
end
function HeroSelector.actionShowButton(frame, player)
if GetLocalPlayer() == player then BlzFrameSetVisible(HeroSelector.Box, not BlzFrameIsVisible(HeroSelector.Box)) end
end
--[[
This functions are found directly below the config and belong to the config.
They also can be hooked but you might lose the default. Could do it like it is done in TeamViewer create a Backup of the current then overwrite it and call the backup in the replacement.
function HeroSelector.unitCreated(player, unitCode, isRandom)
this function is called when an unit is picked, add here you actions that have to be done for the picked unit
function HeroSelector.buttonSelected(player, unitCode)
this function is called when an player selects an button, this is not the picking.
function HeroSelector.unitBaned(player, unitCode)
this function is called when a player bans an unitCode.
function HeroSelector.actionBanDoneButton(frame, player)
this function happens when the banDone Button is clicked
function HeroSelector.repick(unit[, player])
if player is skiped unit owner sees the selection
this will remove the unit from the game.
Adds thie unitcode of the unit to the randompool
function HeroSelector.autoDetectCategory(unitCode)
this called on every unit added. It is a good place for simple automatic categorizes, on default it categorizes melee as 1 and ranged as 2.
function HeroSelector.initHeroes()
this function will be called before anything is created, when not using GUI to setup data you could add the selectable heroes here.
------
How use the Selection grid?
Each hero can only be once in the grid. When using HeroSelector.addUnit it will add a new slot. There are HeroSelector.ButtonColCount*HeroSelector.ButtonRowCount slots.
3 rows with 4 cols would result into:
01 02 03 04
05 06 07 08
09 10 11 12
When you want to leave fields in the grid empty use HeroSelector.addUnit(0) or HeroSelector.addUnit().
There is a GUI setup which works with indexes, not set indexes will be empty fields.
------
function HeroSelector.setUnitReq(unitCode, who)
adds an requirement: can be a player, a force, a teamNumber, a race, a table {techcode, level}, playerState (need to have 1 of it, mostly useful for PLAYER_STATE_RESOURCE_HERO_TOKENS), skip who or nil will remove an requirment.
unitCode can be a number or a string 'Hpal' or 'Hpal,Ofar,Ulic'
Only when the local player fullfills than he can click the button.
calling this will not update the selected buttonIndex of players nor does this update the clickability.
To update the clickability when setting requirments after the Box was created use HeroSelector.update() and deselect indexes
won't work when the unitCode wasn't added yet.
function HeroSelector.addUnit([unitCode, onlyRandom, requirement])
unitCode can be a number or a string 'Hpal' or 'Hpal,Ofar,Ulic,0,Obla'
can be called without arguments to hava a empty slot calling it with 0 has the same effect
requirement works like who in HeroSelector.setUnitReq.
function HeroSelector.setUnitCategory(unitCode, category)
unitCode can be a number or a string 'Hpal' or 'Hpal,Ofar,Ulic'
sets the category of an added Option.
Category should be a power 2 number. 1 2 4 8 16 32 ....
function HeroSelector.addUnitCategory(unitCode, category)
unitCode can be a number or a string 'Hpal' or 'Hpal,Ofar,Ulic'
Keeps previous setings untouched
function HeroSelector.addCategory(icon, text)
icon is the enabled image, text is the tooltip text.
function HeroSelector.clearUnitData()
removes all current UnitData this includes limit-counters, requirements, categories.
function HeroSelector.show(flag, [who])
Shows/Hides HeroSelector to who
flag = true show it, false = hide it
who can be a player, a force, a teamNumber, a race or nothing = anyone
teamNumbers are the warcraft 3 given teamNumbers starting with 0 for team 1.
the force is expected to be kept alive
function HeroSelector.setFrameText(frame, text[, who])
uses BlzFrameSetText onto frame when the local player is included in who by the rules of function HeroSelector.includesPlayer
function HeroSelector.setTitleText(text[, who])
wrapper HeroSelector.setFrameText
function HeroSelector.setBanButtonText(text[, who])
wrapper HeroSelector.setFrameText
function HeroSelector.setAcceptButtonText(text[, who])
wrapper HeroSelector.setFrameText
function HeroSelector.enablePick(flag[, who])
enable/disable the accept/random button also makes them visible for that players and hides the ban Button.
function HeroSelector.enableBan(flag[, who])
enable/disable the ban button also makes accept/random invisible for that players and shows the ban Button.
function HeroSelector.forceRandom([who])
wrapper for doRandom for player
function HeroSelector.forcePick([who])
forces to pick what currently is selected, if that fails doRandom
function HeroSelector.buttonRequirementDone(unitCode, player)
function HeroSelector.deselectButtons([buttonIndex])
deselect selected buttons for all players with 0 or nil
when an index is given only this specific buttonIndex
function HeroSelector.update()
reDo possible selection, textures and enability for all heroButtons.
function HeroSelector.getDisabledIcon(icon)
ReplaceableTextures\CommandButtons\BTNHeroPaladin.tga -> ReplaceableTextures\CommandButtonsDisabled\DISBTNHeroPaladin.tga
function HeroSelector.showFrame(frame, flag[, who])
Set the visibility of frame to flag when who includes the local player by the rules of function HeroSelector.includesPlayer
function HeroSelector.includesPlayer(who, player)
does player include who?
return true, if yes.
return false otherwise
who can be a number(GetPlayerTeam), a race(GetPlayerRace), a player, a force(BlzForceHasPlayer) or
nil => true
function HeroSelector.counterChangeUnitCode(unitCode, add, player)
increases/decreases the counter for picks of unitCode for the player's team.
This can allow/disallow picking this unit for that team.
function HeroSelector.rollOption(player, includeRandomOnly, excludedIndex, category)
get an random Unitcode from the added options
returns an unitcode or nil when none could be found
function HeroSelector.categoryUsed([unitCode])
returns a string listing the categories and the amount of heroes for each.
Or a table containg the category numbers used by the Hero
function HeroSelector.listHeroes(returnOneLineUnitCodes)
returns a string of pickable UnitCodes and names
(true) return "UnitCode,UnitCode,UnitCode"
--]]
--=====
--code start
--=====
HeroSelector.PickedUnit = {} --Picked Unit HeroSelector.PickedUnit[player]
HeroSelector.UnitData = {} --all avaiable selections
HeroSelector.UnitDataPool = {} -- all possible random values
HeroSelector.BanDelayed = {}
HeroSelector.StringCache = {}
HeroSelector.RepicksDone = __jarray(0)
function HeroSelector.categoryUsed(unitCode)
if not unitCode then
--returns for each category the amount of heroes Used
local count = {[0] = 0}
local category
for unitCode, value in pairs(HeroSelector.UnitDataPool) do
count[0] = count[0] + 1
category = 1
for i = 1, #HeroSelector.CategoryData do
if BlzBitAnd(category, HeroSelector.UnitData[unitCode].Category) > 0 then
if not count[i] then count[i] = 1 else
count[i] = count[i] + 1
end
end
category = category*2
end
end
local text = "category=HeroCount"
for i = 1, #HeroSelector.CategoryData do
if count[i] then
text = text .."\n"..HeroSelector.CategoryData[i][2].."="..count[i]
end
end
text = text .."\nTotal="..count[0]
return text
else
local catsUsed = {}
local catValue = 1
for i, cat in ipairs(HeroSelector.CategoryData) do
if BlzBitAnd(catValue, HeroSelector.UnitData[unitCode].Category) > 0 then
table.insert(catsUsed, catValue)
end
catValue= catValue*2
end
return catsUsed
end
end
function HeroSelector.listHeroes(returnOneLineUnitCodes)
--write heroselector unitCode and names in a list
if not returnOneLineUnitCodes then
-- unitCode Name
-- unitCode Name
local text = "UnitCode".. "\t" .. "Name"
for unitCode in pairs(HeroSelector.UnitDataPool) do
text = text .."\n".. string.pack(">I4", unitCode) .."\t".. GetObjectName(unitCode)
end
return text
else
-- unitCode,unitCode,unitCode,unitCode,unitCode,unitCode
local text = ""
for unitCode in pairs(HeroSelector.UnitDataPool) do
text = text .. string.pack(">I4", unitCode) ..","
end
return string.sub(text, 1, -2)
end
end
function HeroSelector.CategoryButtonUpdate()
local playerData = HeroSelector.Category[GetLocalPlayer()] or 0
local category
for i, button in ipairs(HeroSelector.CategoryButton) do
category = HeroSelector.CategoryButton[button]
if BlzBitAnd(playerData, category.Value) == 0 then
BlzFrameSetTexture(category.Icon, category.TextureDisabled, 0, true)
BlzFrameSetTexture(category.IconPushed, category.TextureDisabled, 0, true)
else
BlzFrameSetTexture(category.Icon, category.Texture, 0, true)
BlzFrameSetTexture(category.IconPushed, category.Texture, 0, true)
end
end
end
function HeroSelector.CategoryClickAction(button, player)
local category = HeroSelector.CategoryButton[button]
local playerData = HeroSelector.Category[player]
if not playerData then
playerData = 0
end
--has this category already?
if BlzBitAnd(playerData, category.Value) ~= 0 then
--yes, unable
playerData = playerData - category.Value
else
--no, enable
playerData = playerData + category.Value
HeroSelector.CategoryButton[player] = category
end
if HeroSelector.CategorySingleSelect[player] then playerData = BlzBitAnd(playerData, category.Value) end
HeroSelector.Category[player] = playerData
if GetLocalPlayer() == player then
HeroSelector.updateHeroButtonAlpha()
HeroSelector.CategoryButtonUpdate()
end
end
function HeroSelector.getDisabledIcon(icon)
--ReplaceableTextures\CommandButtons\BTNHeroPaladin.tga -> ReplaceableTextures\CommandButtonsDisabled\DISBTNHeroPaladin.tga
if not HeroSelector.StringCache[icon] and string.sub(icon,35,35) ~= "\\" then return icon end --this string has not enough chars return it
if not HeroSelector.StringCache[icon] then
local old = icon
-- make it lower to reduce the amount of cases and for warcraft 3 FilePath case does not matter
icon = string.lower(icon)
if string.find(icon, "commandbuttons\\btn") then HeroSelector.StringCache[old] = string.gsub(icon, "commandbuttons\\btn", "commandbuttonsdisabled\\disbtn" )
-- default wacraft 3 style
elseif string.find(icon, "passivebuttons\\pasbtn") then HeroSelector.StringCache[old] = string.gsub(icon, "passivebuttons\\pasbtn", "commandbuttonsdisabled\\dispasbtn" )
--recommented by hiveworkshop
elseif string.find(icon, "passivebuttons\\pas") then HeroSelector.StringCache[old] = string.gsub(icon, "passivebuttons\\pas", "commandbuttonsdisabled\\dispas" )
elseif string.find(icon, "commandbuttons\\atc") then HeroSelector.StringCache[old] = string.gsub(icon, "commandbuttons\\atc", "commandbuttonsdisabled\\disbtn" ) end
icon = old
end
return HeroSelector.StringCache[icon]
end
-- use the lib when provided
if GetDisabledIcon then HeroSelector.getDisabledIcon = GetDisabledIcon end
function HeroSelector.updateHeroButtonAlphaIncludes(unitCode, category, requiredCat, text)
if category > 0 and BlzBitAnd(HeroSelector.UnitData[unitCode].Category, category) < requiredCat then return false end
if not text or text == "" then return true end
if string.find(string.lower(GetObjectName(unitCode)), text, 1, true) then return true end
if string.find(string.lower(BlzGetAbilityTooltip(unitCode, 0)), text, 1, true) then return true end
if string.find(string.lower(BlzGetAbilityExtendedTooltip(unitCode, 0)), text, 1, true) then return true end
if HeroInfo and HeroInfo.HeroData[unitCode] then
for _, spell in ipairs(HeroInfo.HeroData[unitCode]) do
if string.find(string.lower(BlzGetAbilityTooltip(spell, 0)), text, 1, true) then return true end
if string.find(string.lower(BlzGetAbilityExtendedTooltip(spell, 0)), text, 1, true) then return true end
end
end
return false
end
function HeroSelector.updateHeroButtonAlpha()
local playerData = HeroSelector.Category[GetLocalPlayer()] or 0
local requiredCat = 1
if HeroSelector.PlayerSelectModeExclusive[GetLocalPlayer()] then
requiredCat = playerData
end
--update all buttons
--buttons not fitting current category & category mode become partly transparent
for buttonIndex, value in ipairs(HeroSelector.HeroButtons) do
local button = HeroSelector.HeroButtons[buttonIndex].Frame
local unitCode = HeroSelector.UnitData[buttonIndex]
if unitCode and unitCode > 0 then
if HeroSelector.updateHeroButtonAlphaIncludes(unitCode, playerData, requiredCat, HeroSelector.LastSearchText) then
--if playerData == 0 or BlzBitAnd(HeroSelector.UnitData[unitCode].Category, playerData) >= requiredCat then
BlzFrameSetAlpha(button, 255)
else
BlzFrameSetAlpha(button, HeroSelector.CategoryFilteredAlpha)
end
end
end
end
function HeroSelector.updateTooltip(unitCode)
local tooltipFrame = HeroSelector.HeroButtons[HeroSelector.UnitData[unitCode].Index].Tooltip
local unitData = HeroSelector.UnitData[unitCode]
if unitData.Count > HeroSelector.UnitCount then
BlzFrameSetText(tooltipFrame, HeroSelector.TooltipPrefix..GetObjectName(unitCode).."\n|r("..GetLocalizedString(HeroSelector.BanTooltip)..")")
else
if unitData.Count == HeroSelector.UnitCount or unitData.InTeam[GetPlayerTeam(GetLocalPlayer())] >= HeroSelector.UnitCountPerTeam then
BlzFrameSetText(tooltipFrame, HeroSelector.TooltipPrefix..GetObjectName(unitCode).."\n|r("..GetLocalizedString(HeroSelector.ToManyTooltip)..")")
elseif not HeroSelector.buttonRequirementDone(unitCode, GetLocalPlayer()) then
BlzFrameSetText(tooltipFrame, HeroSelector.TooltipPrefix..GetObjectName(unitCode).."\n|r("..GetLocalizedString(HeroSelector.TooltipRequires)..")\n"..HeroSelector.GetUnitReqString(unitCode))
else
BlzFrameSetText(tooltipFrame, HeroSelector.TooltipPrefix..GetObjectName(unitCode))
end
end
end
function HeroSelector.CreateTextTooltip(button, tooltipText)
local tooltipBox = BlzCreateFrame("HeroSelectorTextBox", HeroSelector.Box, 0, 0)
local tooltip = BlzCreateFrame("HeroSelectorText", tooltipBox, 0, 0)
BlzFrameSetPoint(tooltipBox, FRAMEPOINT_BOTTOMLEFT, tooltip, FRAMEPOINT_BOTTOMLEFT, -0.007, -0.007)
BlzFrameSetPoint(tooltipBox, FRAMEPOINT_TOPRIGHT, tooltip, FRAMEPOINT_TOPRIGHT, 0.007, 0.007)
BlzFrameSetText(tooltip, GetLocalizedString(tooltipText))
BlzFrameSetPoint(tooltip, FRAMEPOINT_BOTTOM, button, FRAMEPOINT_TOP, 0, 0)
BlzFrameSetTooltip(button, tooltipBox)
return tooltip, tooltipBox
end
function HeroSelector.CreateIconButton(size, tooltipText, texture)
local box = HeroSelector.Box
local button = BlzCreateFrame("HeroSelectorCategoryButton", box, 0, 0)
local icon = BlzGetFrameByName("HeroSelectorCategoryButtonIcon", 0)
local iconPushed = BlzGetFrameByName("HeroSelectorCategoryButtonIconPushed", 0)
local text = HeroSelector.CreateTextTooltip(button, tooltipText)
BlzFrameSetSize(button, size, size)
BlzFrameSetTexture(icon, texture, 0, true)
BlzFrameSetTexture(iconPushed, texture, 0, true)
return button, text
end
function HeroSelector.addCategoryButton(categoryObject)
local box = HeroSelector.Box
local button, tooltip = HeroSelector.CreateIconButton(HeroSelector.CategorySize, categoryObject.TextValue, categoryObject.TextureDisabled)
local icon = BlzGetFrameByName("HeroSelectorCategoryButtonIcon", 0)
local iconPushed = BlzGetFrameByName("HeroSelectorCategoryButtonIconPushed", 0)
categoryObject.Text = tooltip --when this is reached overwritte textframe with the tooltip
HeroSelector.CategoryButton[button] = categoryObject
TasButtonAction.Set(button, HeroSelector.CategoryClickAction)
categoryObject.IconPushed = iconPushed
categoryObject.Button = button
categoryObject.Icon = icon
if #HeroSelector.CategoryButton <= 0 then
local titleSize = 0.015
local borderSize = HeroSelector.BorderSize[GetPlayerRace(GetLocalPlayer())]
local y = -0.9*borderSize - titleSize - 0.0025
local x = borderSize*0.65
BlzFrameSetPoint(button, FRAMEPOINT_TOPLEFT, box, FRAMEPOINT_TOPLEFT, x, y)
else
local lastButton = HeroSelector.CategoryButton[#HeroSelector.CategoryButton]
BlzFrameSetPoint(button, FRAMEPOINT_LEFT, lastButton, FRAMEPOINT_RIGHT, 0, 0)
end
table.insert(HeroSelector.CategoryButton, button)
end
function HeroSelector.addCategory(icon, text)
if HeroSelector.CategoryHighest then
HeroSelector.CategoryHighest = HeroSelector.CategoryHighest*2
else
HeroSelector.CategoryHighest = 1
end
local newObject = {}
table.insert(HeroSelector.Category, newObject)
newObject.Value = HeroSelector.CategoryHighest
newObject.Texture = icon
newObject.TextureDisabled = HeroSelector.getDisabledIcon(icon)
newObject.Text = text
newObject.TextValue = text
if HeroSelector.Box then
HeroSelector.addCategoryButton(newObject)
end
end
function HeroSelector.unitCodeStringBatch(callBack, unitCode, ...)
-- "Hamg,Hmkg,Hpal,Hblm"?
-- also support "Hamg,0,Hpal,0,Hblm"
if string.len( unitCode ) > 4 and string.find( unitCode, ",",1, true) then
local startIndex = 1
local skillCode
while startIndex + 3 <= string.len(unitCode) do
skillCode = string.sub(unitCode, startIndex, startIndex + 3)
if string.sub(skillCode, 1, 2) == "0," then
callBack(0, ...)
startIndex = startIndex + 2
else
startIndex = startIndex + 5
skillCode = FourCC(skillCode)
callBack(skillCode, ...)
end
end
return "return"
--'Hpal' -> number?
elseif string.len(unitCode) == 4 then
return FourCC(unitCode)
end
return "return"
end
function HeroSelector.addUnit(unitCode, onlyRandom, requirement)
--no unitCode => empty field
if not unitCode or unitCode == 0 then
table.insert(HeroSelector.UnitData, 0)
else
if type(unitCode) == "string" then
unitCode = HeroSelector.unitCodeStringBatch(HeroSelector.addUnit, unitCode, onlyRandom, requirement)
if unitCode == "return" then return end
end
--Such an object Exist?
if GetObjectName(unitCode) == "" then print(('>I4'):pack(unitCode), "is not an valid Object") return end
--only unique
if HeroSelector.UnitData[unitCode] then return end
HeroSelector.UnitDataPool[unitCode] = true -- add to random
HeroSelector.UnitData[unitCode] = {Index = 0, Count = 0, InTeam = __jarray(0), Category = 0, Requirment = HeroSelector.convertReq(requirement), RequirmentData = requirement}
HeroSelector.autoDetectCategory(unitCode)
if not onlyRandom then
table.insert(HeroSelector.UnitData, unitCode)
HeroSelector.UnitData[unitCode].Index = #HeroSelector.UnitData --remember the index for the unitCode
end
end
end
function HeroSelector.clearUnitData()
HeroSelector.UnitDataPool = {}
HeroSelector.UnitData = {}
HeroSelector.BanDelayed = {}
HeroSelector.update()
end
function HeroSelector.setFrameText(frame, text, who)
if HeroSelector.includesPlayer(who, GetLocalPlayer()) then
BlzFrameSetText(frame, text)
end
end
function HeroSelector.setTitleText(text, who)
HeroSelector.setFrameText(HeroSelector.Title, text, who)
end
function HeroSelector.setAcceptButtonText(text, who)
HeroSelector.setFrameText(HeroSelector.AcceptButton, text, who)
end
function HeroSelector.setBanButtonText(text, who)
HeroSelector.setFrameText(HeroSelector.BanButton, text, who)
end
function HeroSelector.isPlayerRace(unitCode, player)
return HeroSelector.UnitData[unitCode].RequirmentData == GetPlayerRace(player)
end
function HeroSelector.IsPlayerForce(unitCode, player)
return BlzForceHasPlayer(HeroSelector.UnitData[unitCode].RequirmentData, player)
end
function HeroSelector.IsPlayerTeamNr(unitCode, player)
return HeroSelector.UnitData[unitCode].RequirmentData == GetPlayerTeam(player)
end
function HeroSelector.isPlayer(unitCode, player)
return HeroSelector.UnitData[unitCode].RequirmentData == player
end
function HeroSelector.HasPlayerTechLevel(unitCode, player)
return GetPlayerTechCount(player, HeroSelector.UnitData[unitCode].RequirmentData[1], true) >= HeroSelector.UnitData[unitCode].RequirmentData[2]
end
function HeroSelector.HasPlayerState(unitCode, player)
return GetPlayerState(player, HeroSelector.UnitData[unitCode].RequirmentData) >= 1
end
function HeroSelector.convertReq(who)
if not who then
return nil
elseif type(who) == "number" then
return HeroSelector.IsPlayerTeamNr
elseif type(who) == "table" then
return HeroSelector.HasPlayerTechLevel
elseif tostring(who):sub(1, 5) == "race:" then
return HeroSelector.isPlayerRace
elseif tostring(who):sub(1, 7) == "player:" then
return HeroSelector.isPlayer
elseif tostring(who):sub(1, 6) == "force:" then
return HeroSelector.IsPlayerForce
elseif tostring(who):sub(1, 12) == "playerstate:" then
return HeroSelector.HasPlayerState
end
return nil
end
function HeroSelector.GetUnitReqString(unitCode)
--invalid hero
if not HeroSelector.UnitData[unitCode] then return "" end
local reqData = HeroSelector.UnitData[unitCode].RequirmentData
-- have fixed tooltipstring
if HeroSelector.TooltipRequires2[reqData] then return GetLocalizedString(HeroSelector.TooltipRequires2[reqData]) end
local reqFunc = HeroSelector.UnitData[unitCode].Requirment
if reqFunc == HeroSelector.IsPlayerTeamNr then
return GetLocalizedString("TEAM") .." ".. reqData
elseif reqFunc == HeroSelector.isPlayer then
return GetPlayerName(reqData)
elseif reqFunc == HeroSelector.HasPlayerTechLevel then
if reqData[2] > 1 then
return GetObjectName(reqData[1]) .." (" .. reqData[2] ..")"
else
return GetObjectName(reqData[1])
end
elseif reqFunc == HeroSelector.IsPlayerForce then
return "Force"
end
return ""
end
function HeroSelector.setUnitReq(unitCode, who)
if type(unitCode) == "string" then
unitCode = HeroSelector.unitCodeStringBatch(HeroSelector.setUnitReq, unitCode, who)
if unitCode == "return" then return end
end
--Such an object Exist?
if not HeroSelector.UnitData[unitCode] then return end
HeroSelector.UnitData[unitCode].RequirmentData = who
HeroSelector.UnitData[unitCode].Requirment = HeroSelector.convertReq(who)
end
function HeroSelector.setUnitCategory(unitCode, category)
if type(unitCode) == "string" then
unitCode = HeroSelector.unitCodeStringBatch(HeroSelector.setUnitCategory, unitCode, category)
if unitCode == "return" then return end
end
--Such an object Exist?
if not HeroSelector.UnitData[unitCode] then return end
HeroSelector.UnitData[unitCode].Category = category
end
function HeroSelector.addUnitCategory(unitCode, category)
if type(unitCode) == "string" then
unitCode = HeroSelector.unitCodeStringBatch(HeroSelector.addUnitCategory, unitCode, category)
if unitCode == "return" then return end
end
--Such an object Exist?
if not HeroSelector.UnitData[unitCode] then return end
HeroSelector.UnitData[unitCode].Category = BlzBitOr(category, HeroSelector.UnitData[unitCode].Category)
end
function HeroSelector.deselectButtons(buttonIndex)
if buttonIndex and buttonIndex > 0 then
if HeroSelector.HeroButtons[GetLocalPlayer()] == buttonIndex then
BlzFrameSetVisible(HeroSelector.SelectedIndikator, false)
end
for index= 0, GetBJMaxPlayers() - 1,1 do
if HeroSelector.HeroButtons[Player(index)] == buttonIndex then
HeroSelector.HeroButtons[Player(index)] = 0
end
end
else
for index= 0, GetBJMaxPlayers() - 1,1 do
HeroSelector.HeroButtons[Player(index)] = 0
end
BlzFrameSetVisible(HeroSelector.SelectedIndikator, false)
end
end
function HeroSelector.buttonRequirementDone(unitCode, player)
--true when no requirement is set or the requirment call is successful
return not HeroSelector.UnitData[unitCode].Requirment or HeroSelector.UnitData[unitCode].Requirment(unitCode, player)
end
function HeroSelector.disableButtonIndex(buttonIndex, teamNr)
if buttonIndex > 0 then
if HeroSelector.includesPlayer(teamNr, GetLocalPlayer()) then
BlzFrameSetEnable(HeroSelector.HeroButtons[buttonIndex].Frame, false)
end
if HeroSelector.HeroButtons[GetLocalPlayer()] == buttonIndex then
BlzFrameSetVisible(HeroSelector.SelectedIndikator, false)
end
--deselect this Button from all players or the team
for index= 0, GetBJMaxPlayers() - 1,1 do
local player = Player(index)
if (not teamNr or teamNr == GetPlayerTeam(player)) and HeroSelector.HeroButtons[player] == buttonIndex then
HeroSelector.HeroButtons[player] = 0
end
end
end
end
function HeroSelector.enableButtonIndex(unitCode, buttonIndex, teamNr)
if buttonIndex > 0 and (not teamNr or teamNr == GetPlayerTeam(GetLocalPlayer())) then
BlzFrameSetEnable(HeroSelector.HeroButtons[buttonIndex].Frame, true and (HeroSelector.BanIgnoreRequirment and BlzFrameIsVisible(HeroSelector.BanButton)) or HeroSelector.buttonRequirementDone(unitCode, GetLocalPlayer()))
end
end
function HeroSelector.counterChangeUnitCode(unitCode, add, player)
if not HeroSelector.UnitData[unitCode] then HeroSelector.UnitData[unitCode] = {Count = 0, InTeam = __jarray(0)} end
local buttonIndex = HeroSelector.UnitData[unitCode].Index
if not buttonIndex then buttonIndex = 0 end
local teamNr = GetPlayerTeam(player)
HeroSelector.UnitData[unitCode].InTeam[teamNr] = HeroSelector.UnitData[unitCode].InTeam[teamNr] + add
HeroSelector.UnitData[unitCode].Count = HeroSelector.UnitData[unitCode].Count + add
if GetHandleId(HeroSelector.Box) > 0 then
if HeroSelector.UnitData[unitCode].Count >= HeroSelector.UnitCount then
--disable for all
HeroSelector.disableButtonIndex(buttonIndex)
else
--enable for all
HeroSelector.enableButtonIndex(unitCode, buttonIndex)
if HeroSelector.UnitData[unitCode].InTeam[teamNr] >= HeroSelector.UnitCountPerTeam then
--disable for this team
HeroSelector.disableButtonIndex(buttonIndex, teamNr)
end
end
HeroSelector.updateTooltip(unitCode)
end
end
HeroSelector.rollOptionData = {Count = 0}
function HeroSelector.rollOption(player, includeRandomOnly, excludedIndex, category)
if not excludedIndex then excludedIndex = 0 end
if not category then category = 0 end
local requiredCat = 1
if HeroSelector.PlayerSelectModeExclusive[player] then
requiredCat = category
end
local teamNr = GetPlayerTeam(player)
HeroSelector.rollOptionData.Count = 0
for unitCode, value in pairs(HeroSelector.UnitDataPool) do
local allowed = value
--total limited reached?
if HeroSelector.UnitData[unitCode].Count >= HeroSelector.UnitCount then
allowed = false
--print(GetObjectName(unitCode))
--print("rejected total limit")
end
--team limited reached?
if allowed and HeroSelector.UnitData[unitCode].InTeam[teamNr] >= HeroSelector.UnitCountPerTeam then
--print(GetObjectName(unitCode))
--print("rejected team limit")
allowed = false
end
--allow randomOnly?
if allowed and not includeRandomOnly and HeroSelector.UnitData[unitCode].Index == 0 then
--print(GetObjectName(unitCode))
--print("rejected random only")
allowed = false
end
--this index is excluded? This can make sure you get another button.
if allowed and HeroSelector.UnitData[unitCode].Index > 0 and HeroSelector.UnitData[unitCode].Index == excludedIndex then
--print(GetObjectName(unitCode))
--print("rejected exclude")
allowed = false
end
--fullfills the requirement?
if allowed and not HeroSelector.buttonRequirementDone(unitCode, player) then
--print(GetObjectName(unitCode))
--print("rejected requirement")
allowed = false
end
--when having an given an category only allow options having that category atleast partly
if allowed and category > 0 and BlzBitAnd(category, HeroSelector.UnitData[unitCode].Category) < requiredCat then
--print(GetObjectName(unitCode))
--print(" rejected category", category, HeroSelector.UnitData[unitCode].Category)
allowed = false
end
if allowed then
HeroSelector.rollOptionData.Count = HeroSelector.rollOptionData.Count + 1
HeroSelector.rollOptionData[HeroSelector.rollOptionData.Count] = unitCode
end
end
--nothing is allwoed?
if HeroSelector.rollOptionData.Count == 0 then return nil end
return HeroSelector.rollOptionData[GetRandomInt(1, HeroSelector.rollOptionData.Count)]
end
function HeroSelector.doRandom(player)
local category = 0
if HeroSelector.CategoryAffectRandom then category = HeroSelector.Category[player] end
local unitCode = HeroSelector.rollOption(player, true, 0, category)
if not unitCode then return end
HeroSelector.counterChangeUnitCode(unitCode, 1, player)
HeroSelector.unitCreated(player, unitCode, true)
end
function HeroSelector.doPick(player)
--pick what currently is selected, returns true on success returns false when something went wrong,
if not HeroSelector.HeroButtons[player] then return false end
local buttonIndex = HeroSelector.HeroButtons[player]
if buttonIndex <= 0 then return false end --reject nothing selected
local unitCode = HeroSelector.UnitData[buttonIndex]
if not HeroSelector.buttonRequirementDone(unitCode, player) then return false end --requirment fullfilled
HeroSelector.counterChangeUnitCode(unitCode, 1, player)
HeroSelector.unitCreated(player, unitCode)
return true
end
function HeroSelector.forceRandom(who)
--this is a wrapper for doRandom allowing different dataTypes
if not who then
for index= 0, GetBJMaxPlayers() - 1,1 do
local player = Player(index)
if GetPlayerSlotState(player) == PLAYER_SLOT_STATE_PLAYING then
HeroSelector.doRandom(Player(index))
end
end
elseif type(who) == "number" then
for index= 0, GetBJMaxPlayers() - 1,1 do
local player = Player(index)
if GetPlayerSlotState(player) == PLAYER_SLOT_STATE_PLAYING then
if GetPlayerTeam(player) == who then
HeroSelector.doRandom(player)
end
end
end
elseif tostring(who):sub(1, 5) == "race:" then
for index= 0, GetBJMaxPlayers() - 1,1 do
local player = Player(index)
if GetPlayerSlotState(player) == PLAYER_SLOT_STATE_PLAYING then
if GetPlayerRace(player) == who then
HeroSelector.doRandom(player)
end
end
end
elseif tostring(who):sub(1, 7) == "player:" then
HeroSelector.doRandom(who)
elseif tostring(who):sub(1, 6) == "force:"then
ForForce(who, function() HeroSelector.doRandom(GetEnumPlayer()) end)
end
end
function HeroSelector.forcePick(who)
if not who then
for index= 0, GetBJMaxPlayers() - 1,1 do
local player = Player(index)
if GetPlayerSlotState(player) == PLAYER_SLOT_STATE_PLAYING then
if not HeroSelector.doPick(player) then --do picking, when that fails doRandom
HeroSelector.doRandom(player)
end
end
end
elseif type(who) == "number" then
for index= 0, GetBJMaxPlayers() - 1,1 do
local player = Player(index)
if GetPlayerSlotState(player) == PLAYER_SLOT_STATE_PLAYING then
if GetPlayerTeam(player) == who then
if not HeroSelector.doPick(player) then
HeroSelector.doRandom(player)
end
end
end
end
elseif tostring(who):sub(1, 5) == "race:" then
for index= 0, GetBJMaxPlayers() - 1,1 do
local player = Player(index)
if GetPlayerSlotState(player) == PLAYER_SLOT_STATE_PLAYING then
if GetPlayerRace(player) == who then
if not HeroSelector.doPick(player) then
HeroSelector.doRandom(player)
end
end
end
end
elseif tostring(who):sub(1, 7) == "player:" then
if not HeroSelector.doPick(who) then
HeroSelector.doRandom(who)
end
elseif tostring(who):sub(1, 6) == "force:" then
ForForce(who, function()
local player = GetEnumPlayer()
if not HeroSelector.doPick(player) then
HeroSelector.doRandom(player)
end
end)
end
end
function HeroSelector.includesPlayer(who, player)
if not who then --there is no who -> everyone
return true
elseif type(who) == "number" and GetPlayerTeam(player) == who then
return true
elseif tostring(who):sub(1, 5) == "race:" and GetPlayerRace(player) == who then
return true
elseif tostring(who):sub(1, 7) == "player:" and player == who then
return true
elseif tostring(who):sub(1, 6) == "force:" and BlzForceHasPlayer(who, player) then
return true
end
return false
end
function HeroSelector.enablePick(flag, who)
for index = #HeroSelector.BanDelayed, 1, -1 do
local ban = table.remove(HeroSelector.BanDelayed)
HeroSelector.counterChangeUnitCode(ban[1], HeroSelector.UnitCount + 1, ban[2])
end
if HeroSelector.includesPlayer(who, GetLocalPlayer()) then
HeroSelector.LastAction = "enablePick"
HeroSelector.LastActionArg = flag
BlzFrameSetVisible(HeroSelector.AcceptButton, true and HeroSelector.AcceptButtonIsShown)
BlzFrameSetVisible(HeroSelector.RandomButton, true and HeroSelector.RandomButtonIsShown)
BlzFrameSetVisible(HeroSelector.RepickButton, true and HeroSelector.RepickButtonIsShown)
BlzFrameSetVisible(HeroSelector.BanButton, false)
BlzFrameSetVisible(HeroSelector.BanDoneButton, false)
BlzFrameSetVisible(HeroSelector.BanManyButton, false)
BlzFrameSetEnable(HeroSelector.AcceptButton, flag)
BlzFrameSetEnable(HeroSelector.RandomButton, flag)
BlzFrameSetModel(HeroSelector.SelectedIndikator, HeroSelector.IndicatorPathPick, 0)
if HeroSelector.BanIgnoreRequirment then HeroSelector.update() end
end
end
function HeroSelector.enableBan(flag, who)
if HeroSelector.includesPlayer(who, GetLocalPlayer()) then
HeroSelector.LastAction = "enableBan"
HeroSelector.LastActionArg = flag
BlzFrameSetVisible(HeroSelector.AcceptButton, false)
BlzFrameSetVisible(HeroSelector.RandomButton, false)
BlzFrameSetVisible(HeroSelector.RepickButton, false)
BlzFrameSetVisible(HeroSelector.BanButton, true)
BlzFrameSetVisible(HeroSelector.BanDoneButton, true and HeroSelector.BanDoneButtonIsShown)
BlzFrameSetVisible(HeroSelector.BanManyButton, true and HeroSelector.BanManyButtonIsShown)
BlzFrameSetEnable(HeroSelector.BanButton, flag)
BlzFrameSetEnable(HeroSelector.BanDoneButton, flag)
BlzFrameSetEnable(HeroSelector.BanManyButton, flag)
BlzFrameSetVisible(banRepeatButton, false)
BlzFrameSetModel(HeroSelector.SelectedIndikator, HeroSelector.IndicatorPathBan, 0)
if HeroSelector.BanIgnoreRequirment then HeroSelector.update() end
end
end
function HeroSelector.actionPressHeroButton(button, player)
local buttonIndex = HeroSelector.HeroButtons[button]
local unitCode = HeroSelector.UnitData[buttonIndex]
HeroSelector.HeroButtons[player] = buttonIndex
if GetLocalPlayer() == player then
BlzFrameSetVisible(HeroSelector.SelectedIndikator, true)
BlzFrameSetPoint(HeroSelector.SelectedIndikator, FRAMEPOINT_TOPLEFT, button, FRAMEPOINT_TOPLEFT, -0.001, 0.001)
BlzFrameSetPoint(HeroSelector.SelectedIndikator, FRAMEPOINT_BOTTOMRIGHT, button, FRAMEPOINT_BOTTOMRIGHT, -0.0012, -0.0016)
end
HeroSelector.buttonSelected(player, unitCode)
end
function HeroSelector.actionRandomButton(frame, player)
if HeroSelector.RandomButtonPick then
HeroSelector.doRandom(player)
else
local unitCode = HeroSelector.rollOption(player, false, HeroSelector.HeroButtons[player], HeroSelector.Category[player])
if unitCode and GetLocalPlayer() == player then
local buttonIndex = HeroSelector.UnitData[unitCode].Index
BlzFrameClick(HeroSelector.HeroButtons[buttonIndex].Frame)
end
end
end
function HeroSelector.actionAcceptButton(frame, player)
HeroSelector.doPick(player)
end
function HeroSelector.actionRepickButton(frame, player)
if HeroSelector.PickedUnit[player] then
HeroSelector.repick(HeroSelector.PickedUnit[player], player)
HeroSelector.RepicksDone[player] = HeroSelector.RepicksDone[player] + 1
if HeroSelector.RepickMax > 0 then
BlzFrameSetText(frame, HeroSelector.RepickButtonTextPrefix .. string.gsub(GetLocalizedString(HeroSelector.RepickButtonTextLimit), "#", HeroSelector.RepickMax - HeroSelector.RepicksDone[player]))
if HeroSelector.RepicksDone[player] >= HeroSelector.RepickMax and GetLocalPlayer() == player then
BlzFrameSetEnable(frame, false)
end
end
end
end
function HeroSelector.actionBanButton(frame, player)
if not HeroSelector.HeroButtons[player] then return end
local buttonIndex = HeroSelector.HeroButtons[player]
if buttonIndex <= 0 then return end --reject nothing selected
local unitCode = HeroSelector.UnitData[buttonIndex]
if not HeroSelector.DelayBanUntilPick then
HeroSelector.counterChangeUnitCode(unitCode, HeroSelector.UnitCount + 1, player)
else
table.insert(HeroSelector.BanDelayed, {unitCode, player})
end
HeroSelector.unitBaned(player, unitCode)
end
function HeroSelector.actionBanManyButton(frame, player)
-- bann current category until all banned or no bann allowed anymore.
if HeroSelector.BanManyBannRemain[player] <= 0 then return end
HeroSelector.BanManyBannRemain[player] = HeroSelector.BanManyBannRemain[player] - 1
local category = HeroSelector.Category[player]
local unitCode = HeroSelector.rollOption(player, true, 0, category)
if not unitCode then return end
if not HeroSelector.DelayBanUntilPick then
HeroSelector.counterChangeUnitCode(unitCode, HeroSelector.UnitCount + 1, player)
else
table.insert(HeroSelector.BanDelayed, {unitCode, player})
end
HeroSelector.unitBaned(player, unitCode)
if HeroSelector.BanManyBannRemain[player] > 0 then HeroSelector.actionBanManyButton(frame, player) end
end
function HeroSelector.actionMultiSelectButton(frame, player)
-- bann current category until all banned or no bann allowed anymore.
HeroSelector.PlayerSelectModeExclusive[player] = not HeroSelector.PlayerSelectModeExclusive[player]
if GetLocalPlayer() == player then
BlzFrameSetVisible(frame, false)
BlzFrameSetVisible(HeroSelector.MultiSelectButton[HeroSelector.PlayerSelectModeExclusive[player]], true)
HeroSelector.updateHeroButtonAlpha()
end
end
function HeroSelector.actionCategoryClearButton(frame, player)
-- bann current category until all banned or no bann allowed anymore.
HeroSelector.Category[player] = 0
if GetLocalPlayer() == player then
HeroSelector.updateHeroButtonAlpha()
HeroSelector.CategoryButtonUpdate()
end
end
function HeroSelector.update()
for buttonIndex, value in ipairs(HeroSelector.HeroButtons) do
--have data for this button?
if HeroSelector.UnitData[buttonIndex] and HeroSelector.UnitData[buttonIndex] > 0 then
if HeroSelector.HideEmptyButtons then BlzFrameSetVisible(value.Frame, true) end
local unitCode = HeroSelector.UnitData[buttonIndex]
if HeroSelector.UnitData[unitCode].Count >= HeroSelector.UnitCount then
--disable for all
HeroSelector.disableButtonIndex(buttonIndex)
else
--enable for all
HeroSelector.enableButtonIndex(unitCode, buttonIndex)
for teamNr, inTeamCount in pairs(HeroSelector.UnitData[unitCode].InTeam) do
if HeroSelector.UnitData[unitCode].InTeam[teamNr] >= HeroSelector.UnitCountPerTeam then
--disable for this team
HeroSelector.disableButtonIndex(buttonIndex, teamNr)
end
end
end
BlzFrameSetTexture(value.Icon, BlzGetAbilityIcon(unitCode), 0, HeroSelector.ButtonBlendAll)
BlzFrameSetTexture(value.IconPushed, BlzGetAbilityIcon(unitCode), 0, HeroSelector.ButtonBlendAll)
BlzFrameSetTexture(value.IconDisabled, HeroSelector.getDisabledIcon(BlzGetAbilityIcon(unitCode)), 0, HeroSelector.ButtonBlendAll)
--BlzFrameSetText(value.Tooltip, HeroSelector.TooltipPrefix..GetObjectName(unitCode))
HeroSelector.updateTooltip(unitCode)
else
--no, make it unclickable and empty
if HeroSelector.HideEmptyButtons then BlzFrameSetVisible(value.Frame, false) end
BlzFrameSetEnable(value.Frame, false)
BlzFrameSetTexture(value.Icon, HeroSelector.EmptyButtonPath, 0, true)
BlzFrameSetTexture(value.IconPushed, HeroSelector.EmptyButtonPath, 0, true)
BlzFrameSetTexture(value.IconDisabled, HeroSelector.EmptyButtonPath, 0, true)
end
end
end
function HeroSelector.showFrame(frame, flag, who)
if HeroSelector.includesPlayer(who, GetLocalPlayer()) then
BlzFrameSetVisible(frame, flag)
end
end
function HeroSelector.show(flag, who)
HeroSelector.showFrame(HeroSelector.Box, flag, who)
end
do
local function InitFrames()
BlzLoadTOCFile(HeroSelector.TocPath)
HeroSelector.HeroButtons = {} --the clickable Buttons
HeroSelector.CategoryButton = {}
local titleSize = 0.015
local buttonSize = HeroSelector.ButtonSize
local borderSize = HeroSelector.BorderSize[GetPlayerRace(GetLocalPlayer())]
local colCount = HeroSelector.ButtonColCount
local rowCount = HeroSelector.ButtonRowCount
local box = BlzCreateFrame(HeroSelector.BoxFrameName, BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
HeroSelector.Box = box
local background = BlzCreateFrameByType("BACKDROP", "HeroSelectorBackground", box, "", 0)
--local boxTitle = BlzCreateFrame(HeroSelector.BoxFrameName, box, 0, 0)
local boxBottom = BlzCreateFrame("HeroSelectorRaceTopBox", box, 0, 0)
local titel = BlzCreateFrame("HeroSelectorTitle", box, 0, 0)
if HeroSelector.BackgroundTexture and HeroSelector.BackgroundTexture ~= "" then
BlzFrameSetPoint(background, FRAMEPOINT_BOTTOMLEFT, box, FRAMEPOINT_BOTTOMLEFT, borderSize, borderSize)
BlzFrameSetPoint(background, FRAMEPOINT_TOPRIGHT, box, FRAMEPOINT_TOPRIGHT, -borderSize, -borderSize)
BlzFrameSetTexture(background, HeroSelector.BackgroundTexture, HeroSelector.BackgroundTiles, true)
end
HeroSelector.Title = titel
local indicatorParent = BlzCreateFrameByType("BUTTON", "MyHeroIndikatorParent", box, "", 0)
HeroSelector.SelectedIndikator = BlzCreateFrameByType("SPRITE", "MyHeroIndikator", indicatorParent, "", 0)
BlzFrameSetLevel(indicatorParent, 9)
BlzFrameSetModel(HeroSelector.SelectedIndikator, HeroSelector.IndicatorPathPick, 0)
BlzFrameSetScale(HeroSelector.SelectedIndikator, buttonSize/0.036) --scale the model to the button size.
--BlzFrameSetPoint(boxTitle, FRAMEPOINT_TOPLEFT, box, FRAMEPOINT_TOPLEFT, 0, -(titleSize - 0.003 + 0.9*borderSize))
--BlzFrameSetPoint(boxTitle, FRAMEPOINT_BOTTOMRIGHT, box, FRAMEPOINT_TOPRIGHT, 0, - 0.9*borderSize - titleSize - 0.003 -HeroSelector.CategorySize)
--BlzFrameSetSize(boxTitle, 0.01, 0.1)
-- human UI size differs much, needs other numbers
if GetPlayerRace(GetLocalPlayer()) == RACE_HUMAN then
BlzFrameSetPoint(boxBottom, FRAMEPOINT_TOPLEFT, box, FRAMEPOINT_TOPLEFT, borderSize*0.055, - 0.9*borderSize - titleSize - 0.003 -HeroSelector.CategorySize)
BlzFrameSetPoint(boxBottom, FRAMEPOINT_TOPRIGHT, box, FRAMEPOINT_TOPRIGHT, -borderSize*0.055, - 0.9*borderSize - titleSize - 0.003 -HeroSelector.CategorySize)
else
BlzFrameSetPoint(boxBottom, FRAMEPOINT_TOPLEFT, box, FRAMEPOINT_TOPLEFT, borderSize*0.25, - 0.9*borderSize - titleSize - 0.003 -HeroSelector.CategorySize)
BlzFrameSetPoint(boxBottom, FRAMEPOINT_TOPRIGHT, box, FRAMEPOINT_TOPRIGHT, -borderSize*0.25, - 0.9*borderSize - titleSize - 0.003 -HeroSelector.CategorySize)
end
BlzFrameSetSize(boxBottom, 0.01, 0.1)
BlzFrameSetVisible(HeroSelector.SelectedIndikator, false)
BlzFrameSetAbsPoint(box, HeroSelector.BoxPosPoint, HeroSelector.BoxPosX, HeroSelector.BoxPosY)
BlzFrameSetSize(box, borderSize*2 + buttonSize*colCount + HeroSelector.SpaceBetweenX*(colCount-1), borderSize*2 + buttonSize*rowCount + HeroSelector.SpaceBetweenY*(rowCount - 1) + titleSize + HeroSelector.CategorySize + 0.0145)
BlzFrameSetTextAlignment(titel, TEXT_JUSTIFY_MIDDLE, TEXT_JUSTIFY_CENTER)
BlzFrameSetPoint(titel, FRAMEPOINT_TOP, box, FRAMEPOINT_TOP, 0, -borderSize*0.6)
BlzFrameSetSize(titel, BlzFrameGetWidth(box) - borderSize*2, 0.03)
BlzFrameSetText(titel, "Hero Selection")
local rowRemaining = colCount
if colCount*rowCount < #HeroSelector.UnitData then
print("FieldCount:",colCount*rowCount, "HeroCount",#HeroSelector.UnitData)
end
local y = -borderSize - titleSize - 0.0125 - HeroSelector.CategorySize
local x = borderSize
for buttonIndex = 1, colCount*rowCount, 1 do
local button = BlzCreateFrame("HeroSelectorButton", box, 0, buttonIndex)
local icon = BlzGetFrameByName("HeroSelectorButtonIcon", buttonIndex)
local iconPushed = BlzGetFrameByName("HeroSelectorButtonIconPushed", buttonIndex)
local iconDisabled = BlzGetFrameByName("HeroSelectorButtonIconDisabled", buttonIndex)
local tooltipBox = BlzCreateFrame("HeroSelectorTextBox", box, 0, buttonIndex)
local tooltip = BlzCreateFrame("HeroSelectorText", tooltipBox, 0, buttonIndex)
BlzFrameSetTooltip(button, tooltipBox)
if not HeroSelector.TooltipRelativIsBox then
BlzFrameSetPoint(tooltip, HeroSelector.TooltipPoint, button, HeroSelector.TooltipRelativePoint, HeroSelector.TooltipOffsetX ,HeroSelector.TooltipOffsetY)
else
BlzFrameSetPoint(tooltip, HeroSelector.TooltipPoint, box, HeroSelector.TooltipRelativePoint, HeroSelector.TooltipOffsetX ,HeroSelector.TooltipOffsetY)
end
BlzFrameSetPoint(tooltipBox, FRAMEPOINT_BOTTOMLEFT, tooltip, FRAMEPOINT_BOTTOMLEFT, -0.007, -0.007)
BlzFrameSetPoint(tooltipBox, FRAMEPOINT_TOPRIGHT, tooltip, FRAMEPOINT_TOPRIGHT, 0.007, 0.007)
TasButtonAction.Set(button, HeroSelector.actionPressHeroButton)
BlzFrameSetSize(button, buttonSize, buttonSize)
local heroButton = {}
HeroSelector.HeroButtons[buttonIndex] = heroButton
heroButton.Frame = button
heroButton.Icon = icon
heroButton.IconPushed = iconPushed
heroButton.IconDisabled = iconDisabled
heroButton.Tooltip = tooltip
HeroSelector.HeroButtons[button] = buttonIndex
if HeroSelector.ChainedButtons then --buttons are connected to the previous one or the previous row
if buttonIndex == 1 then
BlzFrameSetPoint(button, FRAMEPOINT_TOPLEFT, box, FRAMEPOINT_TOPLEFT, borderSize, y)
elseif rowRemaining <= 0 then
BlzFrameSetPoint(button, FRAMEPOINT_TOPLEFT, HeroSelector.HeroButtons[buttonIndex - colCount].Frame, FRAMEPOINT_BOTTOMLEFT, 0, -HeroSelector.SpaceBetweenY)
rowRemaining = colCount
else
BlzFrameSetPoint(button, FRAMEPOINT_LEFT, HeroSelector.HeroButtons[buttonIndex - 1].Frame, FRAMEPOINT_RIGHT, HeroSelector.SpaceBetweenX, 0)
end
else --buttons have an offset to the TopLeft of the box
if rowRemaining <= 0 then
x = borderSize
rowRemaining = colCount
y = y - HeroSelector.SpaceBetweenY - buttonSize
elseif buttonIndex ~= 1 then
x = x + buttonSize + HeroSelector.SpaceBetweenX
end
BlzFrameSetPoint(button, FRAMEPOINT_TOPLEFT, box, FRAMEPOINT_TOPLEFT, x, y)
end
rowRemaining = rowRemaining - 1
end
--create category buttons added before the box was created
for buttonIndex, value in ipairs(HeroSelector.Category) do
HeroSelector.addCategoryButton(value)
end
--create multiSelectButtons
HeroSelector.MultiSelectButton = {}
for i=1,#HeroSelector.MultiSelectButtonTooltipText do
local button, tooltipFrame = HeroSelector.CreateIconButton(0.02, GetLocalizedString(HeroSelector.MultiSelectButtonTooltipText[i]), HeroSelector.MultiSelectButtonTextures[i])
HeroSelector.MultiSelectButton[i] = button
HeroSelector.MultiSelectButton[i == 1] = button
HeroSelector.MultiSelectButton[button] = i
TasButtonAction(button, HeroSelector.actionMultiSelectButton)
BlzFrameSetVisible(button, HeroSelector.MultiSelectButtonIsShown and HeroSelector.PlayerSelectModeExclusive[GetLocalPlayer()] == (i == 1))
BlzFrameSetPoint(button, FRAMEPOINT_BOTTOMLEFT, HeroSelector.Category[1].Button, FRAMEPOINT_TOPLEFT, 0, 0.003)
end
if true then
local button, tooltipFrame = HeroSelector.CreateIconButton(0.02, GetLocalizedString(HeroSelector.CategoryClearButtonTooltipText), HeroSelector.CategoryClearButtonTexture)
TasButtonAction(button, HeroSelector.actionCategoryClearButton)
BlzFrameSetPoint(button, FRAMEPOINT_LEFT, HeroSelector.MultiSelectButton[1], FRAMEPOINT_RIGHT, 0.003, 0)
BlzFrameSetVisible(button, HeroSelector.CategoryClearButtonIsShown)
end
local acceptButton = BlzCreateFrame("HeroSelectorTextButton", box, 0, 0)
local randomButton = BlzCreateFrame("HeroSelectorTextButton", box, 0, 1)
local banButton = BlzCreateFrame("HeroSelectorTextButton", box, 0, 2)
local repickButton = BlzCreateFrame("HeroSelectorTextButton", box, 0, 3)
local banDoneButton = BlzCreateFrame("HeroSelectorTextButton", box, 0, 4)
local showButton = BlzCreateFrame("HeroSelectorTextButton", HeroSelector.ShowButtonParent(), 0, 5)
local banRepeatButton = BlzCreateFrame("HeroSelectorTextButton", box, 0, 6)
TasButtonAction.Set(acceptButton, HeroSelector.actionAcceptButton)
TasButtonAction.Set(randomButton, HeroSelector.actionRandomButton)
TasButtonAction.Set(banButton, HeroSelector.actionBanButton)
TasButtonAction.Set(repickButton, HeroSelector.actionRepickButton)
TasButtonAction.Set(banDoneButton, HeroSelector.actionBanDoneButton)
TasButtonAction.Set(showButton, HeroSelector.actionShowButton)
TasButtonAction.Set(banRepeatButton, HeroSelector.actionBanManyButton)
BlzFrameSetSize(acceptButton, HeroSelector.AcceptButtonSizeX, HeroSelector.AcceptButtonSizeY)
BlzFrameSetSize(randomButton, HeroSelector.RandomButtonSizeX, HeroSelector.RandomButtonSizeY)
BlzFrameSetSize(banButton, HeroSelector.BanButtonSizeX, HeroSelector.BanButtonSizeY)
BlzFrameSetSize(repickButton, HeroSelector.RepickButtonSizeX, HeroSelector.RepickButtonSizeY)
BlzFrameSetSize(banDoneButton, HeroSelector.BanDoneButtonSizeX, HeroSelector.BanDoneButtonSizeY)
BlzFrameSetSize(showButton, HeroSelector.ShowButtonSizeX, HeroSelector.ShowButtonSizeY)
BlzFrameSetSize(banRepeatButton, HeroSelector.BanManyButtonSizeX, HeroSelector.BanManyButtonSizeY)
--OK, READY, ACCEPT
BlzFrameSetText(acceptButton, HeroSelector.AcceptButtonTextPrefix .. GetLocalizedString(HeroSelector.AcceptButtonText))
BlzFrameSetText(randomButton, HeroSelector.RandomButtonTextPrefix .. GetLocalizedString(HeroSelector.RandomButtonText))
BlzFrameSetText(banButton, HeroSelector.BanButtonTextPrefix .. GetLocalizedString(HeroSelector.BanButtonText))
BlzFrameSetText(banRepeatButton, HeroSelector.BanManyButtonTextPrefix .. GetLocalizedString(HeroSelector.BanManyButtonText))
if HeroSelector.RepickMax > 0 then
BlzFrameSetText(repickButton, HeroSelector.RepickButtonTextPrefix .. string.gsub(GetLocalizedString(HeroSelector.RepickButtonTextLimit), "#", HeroSelector.RepickMax))
else
BlzFrameSetText(repickButton, HeroSelector.RepickButtonTextPrefix .. GetLocalizedString(HeroSelector.RepickButtonText))
end
BlzFrameSetText(banDoneButton, HeroSelector.BanDoneButtonTextPrefix .. GetLocalizedString(HeroSelector.BanDoneButtonText))
BlzFrameSetText(showButton, HeroSelector.ShowButtonTextPrefix .. GetLocalizedString(HeroSelector.ShowButtonText))
BlzFrameSetPoint(acceptButton, FRAMEPOINT_BOTTOMRIGHT, box, FRAMEPOINT_BOTTOM, 0, 0)
BlzFrameSetPoint(randomButton, FRAMEPOINT_LEFT, acceptButton, FRAMEPOINT_RIGHT, 0, 0)
BlzFrameSetPoint(repickButton, FRAMEPOINT_TOP, acceptButton, FRAMEPOINT_BOTTOMRIGHT, 0, 0)
BlzFrameSetPoint(banButton, FRAMEPOINT_BOTTOMRIGHT, box, FRAMEPOINT_BOTTOM, 0, 0)
BlzFrameSetPoint(banDoneButton, FRAMEPOINT_LEFT, banButton, FRAMEPOINT_RIGHT, 0, 0)
BlzFrameSetPoint(banRepeatButton, FRAMEPOINT_LEFT, banDoneButton, FRAMEPOINT_RIGHT, 0, 0)
BlzFrameSetAbsPoint(showButton, HeroSelector.ShowButtonPoint, HeroSelector.ShowButtonX, HeroSelector.ShowButtonY)
HeroSelector.AcceptButton = acceptButton
HeroSelector.RandomButton = randomButton
HeroSelector.BanButton = banButton
HeroSelector.BanDoneButton = banDoneButton
HeroSelector.RepickButton = repickButton
HeroSelector.ShowButton = showButton
HeroSelector.BanManyButton = banRepeatButton
BlzFrameSetVisible(banButton, false)
BlzFrameSetVisible(banDoneButton, false)
BlzFrameSetVisible(banRepeatButton, false)
BlzFrameSetVisible(acceptButton, HeroSelector.AcceptButtonIsShown)
BlzFrameSetVisible(randomButton, HeroSelector.RandomButtonIsShown)
BlzFrameSetVisible(repickButton, HeroSelector.RepickButtonIsShown)
BlzFrameSetVisible(showButton, HeroSelector.ShowButtonIsShown)
HeroSelector.CreateTextTooltip(banRepeatButton, GetLocalizedString(HeroSelector.BanManyButtonTooltipText), true)
HeroSelector.CreateTextTooltip(banDoneButton, GetLocalizedString(HeroSelector.BanDoneButtonTooltipText), true)
HeroSelector.CreateTextTooltip(banButton, GetLocalizedString(HeroSelector.BanButtonTooltipText), true)
HeroSelector.CreateTextTooltip(repickButton, GetLocalizedString(HeroSelector.RepickButtonTooltipText), true)
HeroSelector.CreateTextTooltip(randomButton, GetLocalizedString(HeroSelector.RandomButtonTooltipText) .. GetLocalizedString(HeroSelector.RandomButtonTooltipText2[HeroSelector.RandomButtonPick]), true)
HeroSelector.CreateTextTooltip(acceptButton, GetLocalizedString(HeroSelector.AcceptButtonTooltipText), true)
local searchBox = BlzCreateFrame("HeroSelectorSearch", box, 0, 0)
HeroSelector.SearchBox = searchBox
BlzFrameClearAllPoints(searchBox)
BlzFrameSetPoint(searchBox, FRAMEPOINT_TOPRIGHT, box, FRAMEPOINT_TOPRIGHT, -borderSize*0.65, -0.9*borderSize)
BlzFrameSetSize(searchBox, HeroSelector.SearchBoxSizeX, HeroSelector.SearchBoxSizeY)
HeroSelector.CreateTextTooltip(searchBox, HeroSelector.SearchBoxToolTipText)
BlzFrameSetVisible(searchBox, HeroSelector.SearchBoxSizeIsShown)
TasEditBoxAction(searchBox, function(frame, player, text)
if GetLocalPlayer() == player then HeroSelector.LastSearchText = string.lower(text) end
if GetLocalPlayer() == player then
HeroSelector.updateHeroButtonAlpha()
end
end)
if not HeroSelector.AutoShow then
BlzFrameSetVisible(box, false)
end
HeroSelector.update()
if TeamViewer then TeamViewer.Init() end
if HeroInfo then HeroInfo.Init() end
-- LastAction is used to Restore the current Pick/Bann Phase after Save&Load
if HeroSelector.LastAction then
HeroSelector[HeroSelector.LastAction](HeroSelector.LastActionArg, GetLocalPlayer())
end
end
HeroSelector.initFrames = InitFrames
if HeroSelector.AutoCreate then
if not OnGameStart then
local backUp = MarkGameStarted
function MarkGameStarted()
backUp()
if HeroSelector.initHeroes then HeroSelector.initHeroes() end
--xpcall(InitFrames, print)
InitFrames()
if FrameLoaderAdd then FrameLoaderAdd(InitFrames) end
end
else
OnGameStart(function()
if HeroSelector.initHeroes then HeroSelector.initHeroes() end
InitFrames()
if FrameLoaderAdd then FrameLoaderAdd(InitFrames) end
end)
end
end
end
--TeamViewer 1.4
--Plugin for HeroSelector by Tasyen
--It shows the selection of Teams in groups
--Default setup could be suited for 2 team games
-- function TeamViewer.Reset()
TeamViewer = {}
TeamViewer.ShowNonAllies = true --show non allies
TeamViewer.UpdateNonAllies = false --update the image of non allies when the select or pick
TeamViewer.Scale = 1.0
--position when TeamViewer.ShowNonAllies = false or when a TeamPos is not set
TeamViewer.TeamPosX = 0.02
TeamViewer.TeamPosY = 0.5
TeamViewer.TeamPosGapY = 0.015
TeamViewer.TeamPosLeft2Right = true --(true) button is left and text is right, (false) button is right and text ist left
--how big are the Faces
TeamViewer.ButtonSize = 0.03
TeamViewer.ButtonAlphaSelected = 150
TeamViewer.ButtonDefaultIcon = "UI\\Widgets\\EscMenu\\Human\\quest-unknown.blp"
TeamViewer.CategoryButtonSize = 0.015 --size of the CategoryButtons below an players name
TeamViewer.CategoryButtonGap = 0.002 -- space between 2 CategoryButtons
TeamViewer.AllowSwapAlly = true
TeamViewer.AllowSwapEnemy = true
TeamViewer.SwapTexture = "ReplaceableTextures\\CommandButtons\\BTNPatrol.blp"
TeamViewer.SwapSize = 0.017
--used when ShowNonAllies = true
--warcraft 3 Teams start with 0
TeamViewer.TeamPos = {}
TeamViewer.TeamPos[0] = {}
--abs positions on the screen
TeamViewer.TeamPos[0].X = 0.02
TeamViewer.TeamPos[0].Y = 0.5
TeamViewer.TeamPos[0].GapY = 0.015
TeamViewer.TeamPos[0].Left2Right = true
TeamViewer.TeamPos[1] = {}
TeamViewer.TeamPos[1].X = 0.75
TeamViewer.TeamPos[1].Y = 0.5
TeamViewer.TeamPos[1].Left2Right = false
TeamViewer.Frames = {} --this is used to destroy all frames created by TeamViewer.
TeamViewer.HasPicked = {}
TeamViewer.Swap = __jarray(0)
TeamViewer.BackupSelected = HeroSelector.buttonSelected
TeamViewer.BackupCreated = HeroSelector.unitCreated
TeamViewer.BackupRepick = HeroSelector.repick
TeamViewer.BackupDestroy = HeroSelector.destroy
function TeamViewer.AllowPlayer(player)
return GetPlayerSlotState(player) == PLAYER_SLOT_STATE_PLAYING
-- and GetPlayerController(player) == MAP_CONTROL_USER
end
function oppositeFramePoint(framepoint)
if framepoint == FRAMEPOINT_BOTTOM then return FRAMEPOINT_TOP
elseif framepoint == FRAMEPOINT_TOP then return FRAMEPOINT_BOTTOM
elseif framepoint == FRAMEPOINT_TOPLEFT then return FRAMEPOINT_BOTTOMRIGHT
elseif framepoint == FRAMEPOINT_TOPRIGHT then return FRAMEPOINT_BOTTOMLEFT
elseif framepoint == FRAMEPOINT_LEFT then return FRAMEPOINT_RIGHT
elseif framepoint == FRAMEPOINT_RIGHT then return FRAMEPOINT_LEFT
elseif framepoint == FRAMEPOINT_CENTER then return FRAMEPOINT_CENTER
elseif framepoint == FRAMEPOINT_BOTTOMLEFT then return FRAMEPOINT_TOPRIGHT
elseif framepoint == FRAMEPOINT_BOTTOMRIGHT then return FRAMEPOINT_TOPLEFT
else return framepoint
end
end
function HeroSelector.destroy()
for key, value in pairs(TeamViewer.Frames)
do
BlzDestroyFrame(value)
end
TeamViewer.BackupDestroy()
TeamViewer = nil
end
function TeamViewer.PosFirstFrame(movingFrame, relativFrame, left2Right)
if left2Right then
--BlzFrameSetPoint(movingFrame, FRAMEPOINT_TOPLEFT, relativFrame, FRAMEPOINT_BOTTOMRIGHT, 0, 0)
BlzFrameSetPoint(movingFrame, FRAMEPOINT_TOPLEFT, relativFrame, FRAMEPOINT_BOTTOMLEFT, 0, 0)
else
BlzFrameSetPoint(movingFrame, FRAMEPOINT_TOPRIGHT, relativFrame, FRAMEPOINT_BOTTOMRIGHT, 0, 0)
end
end
function TeamViewer.PosFrame(movingFrame, relativFrame, left2Right)
if left2Right then
BlzFrameSetPoint(movingFrame, FRAMEPOINT_TOPLEFT, relativFrame, FRAMEPOINT_TOPRIGHT, TeamViewer.CategoryButtonGap, 0)
else
BlzFrameSetPoint(movingFrame, FRAMEPOINT_TOPRIGHT, relativFrame, FRAMEPOINT_TOPLEFT, -TeamViewer.CategoryButtonGap, 0)
end
end
function TeamViewer.Init()
local function buttonActionFunc(frame)
TeamViewer.ButtonClicked(GetTriggerPlayer(), TeamViewer[frame])
end
for index= 0, GetBJMaxPlayers() - 1,1 do
local player = Player(index)
if TeamViewer.AllowPlayer(player) then
local teamNr = GetPlayerTeam(player)
if not TeamViewer[teamNr] then TeamViewer[teamNr] = {} end
table.insert(TeamViewer[teamNr], player)
local createContext = 1000 + index
--local playerFrame = BlzCreateFrameByType("FRAME", "TeamViewerPlayerFrame", HeroSelector.Box, "", createContext)
local playerFrame = BlzCreateFrame("HeroSelectorTextBox", HeroSelector.Box, 0, createContext)
local colorFrame = BlzCreateFrameByType("BACKDROP", "", playerFrame, "", createContext)
local button = BlzCreateFrame("HeroSelectorButton", playerFrame, 0, createContext)
local textFrame = BlzCreateFrame("HeroSelectorText", playerFrame, 0, createContext) -- do not the buttons child, else it is affected by Alpha change
local icon = BlzGetFrameByName("HeroSelectorButtonIcon", createContext)
local iconPushed = BlzGetFrameByName("HeroSelectorButtonIconPushed", createContext)
local iconDisabled = BlzGetFrameByName("HeroSelectorButtonIconDisabled", createContext)
local tooltipBox = BlzCreateFrame("HeroSelectorTextBox", button, 0, createContext)
local tooltip = BlzCreateFrame("HeroSelectorText", tooltipBox, 0, createContext)
local swapFrame = BlzCreateFrameByType("BACKDROP", "", playerFrame, "", createContext)
local left2Right = nil
TasButtonAction.Set(button , buttonActionFunc)
BlzFrameSetSize(playerFrame, 0.11 + TeamViewer.ButtonSize, TeamViewer.ButtonSize + TeamViewer.CategoryButtonSize + 0.001)
BlzFrameSetPoint(colorFrame, FRAMEPOINT_TOPLEFT, playerFrame, FRAMEPOINT_TOPLEFT, 0.005, -0.0035)
BlzFrameSetPoint(colorFrame, FRAMEPOINT_TOPRIGHT, playerFrame, FRAMEPOINT_TOPRIGHT, -0.005, -0.0035)
BlzFrameSetSize(colorFrame, 0, 0.003)
BlzFrameSetSize(swapFrame, TeamViewer.SwapSize, TeamViewer.SwapSize)
BlzFrameSetTexture(swapFrame, TeamViewer.SwapTexture, 0, false)
BlzFrameSetPoint(swapFrame, FRAMEPOINT_TOPRIGHT, playerFrame, FRAMEPOINT_TOPRIGHT, 0, 0)
BlzFrameSetVisible(swapFrame, false)
local colorIndex = GetHandleId(GetPlayerColor(player))
if colorIndex < 10 then
BlzFrameSetTexture(colorFrame, "ReplaceableTextures\\TeamColor\\TeamColor0"..colorIndex, 0, false)
else
BlzFrameSetTexture(colorFrame, "ReplaceableTextures\\TeamColor\\TeamColor"..colorIndex, 0, false)
end
if TeamViewer.ShowNonAllies and TeamViewer.TeamPos[teamNr] then
left2Right = TeamViewer.TeamPos[teamNr].Left2Right
else
left2Right = TeamViewer.TeamPosLeft2Right
end
BlzFrameSetSize(button, TeamViewer.ButtonSize, TeamViewer.ButtonSize)
BlzFrameSetSize(textFrame, 0.105 - TeamViewer.ButtonSize, 0.013)
if #TeamViewer[teamNr] == 1 then
if TeamViewer.ShowNonAllies and TeamViewer.TeamPos[teamNr] then
BlzFrameSetAbsPoint(button, FRAMEPOINT_BOTTOMLEFT, TeamViewer.TeamPos[teamNr].X, TeamViewer.TeamPos[teamNr].Y)
else
BlzFrameSetAbsPoint(button, FRAMEPOINT_BOTTOMLEFT, TeamViewer.TeamPosX, TeamViewer.TeamPosY)
end
else
local prevTeamPlayer = TeamViewer[teamNr][#TeamViewer[teamNr] - 1]
if TeamViewer.TeamPos[teamNr].GapY then
BlzFrameSetPoint(button, FRAMEPOINT_TOPLEFT, TeamViewer[prevTeamPlayer].Button, FRAMEPOINT_BOTTOMLEFT, 0, -TeamViewer.TeamPos[teamNr].GapY)
else
BlzFrameSetPoint(button, FRAMEPOINT_TOPLEFT, TeamViewer[prevTeamPlayer].Button, FRAMEPOINT_BOTTOMLEFT, 0, -TeamViewer.TeamPosGapY)
end
end
TeamViewer.PosFrame(textFrame, button, left2Right)
if left2Right then
BlzFrameSetPoint(tooltip, FRAMEPOINT_BOTTOMLEFT, button, FRAMEPOINT_TOPLEFT, 0, 0.007)
BlzFrameSetPoint(playerFrame, FRAMEPOINT_TOPLEFT, button, FRAMEPOINT_TOPLEFT, -0.007, 0.007)
else
BlzFrameSetPoint(tooltip, FRAMEPOINT_BOTTOMRIGHT, button, FRAMEPOINT_TOPRIGHT, 0, 0.007)
BlzFrameSetPoint(playerFrame, FRAMEPOINT_TOPRIGHT, button, FRAMEPOINT_TOPRIGHT, 0.007, 0.007)
BlzFrameSetTextAlignment(textFrame, TEXT_JUSTIFY_TOP, TEXT_JUSTIFY_RIGHT)
end
BlzFrameSetPoint(tooltipBox, FRAMEPOINT_BOTTOMLEFT, tooltip, FRAMEPOINT_BOTTOMLEFT, -0.007, -0.007)
BlzFrameSetPoint(tooltipBox, FRAMEPOINT_TOPRIGHT, tooltip, FRAMEPOINT_TOPRIGHT, 0.007, 0.007)
BlzFrameSetText(textFrame, GetPlayerName(player))
BlzFrameSetTooltip(button, tooltipBox)
BlzFrameSetTexture(icon, TeamViewer.ButtonDefaultIcon, 0, true)
BlzFrameSetTexture(iconPushed, TeamViewer.ButtonDefaultIcon, 0, true)
table.insert(TeamViewer.Frames, button)
table.insert(TeamViewer.Frames, textFrame)
table.insert(TeamViewer.Frames, icon)
table.insert(TeamViewer.Frames, iconDisabled)
table.insert(TeamViewer.Frames, iconPushed)
table.insert(TeamViewer.Frames, tooltip)
table.insert(TeamViewer.Frames, playerFrame)
TeamViewer[player] = {}
TeamViewer[player].PlayerFrame = playerFrame
TeamViewer[player].Text = textFrame
TeamViewer[player].Button = button
TeamViewer[button] = player
TeamViewer[player].Icon = icon
TeamViewer[player].IconPushed = iconPushed
TeamViewer[player].IconDisabled = iconDisabled
TeamViewer[player].Tooltip = tooltip
TeamViewer[player].SwapFrame = swapFrame
TeamViewer[player].Category = {}
local prevCategoryButton = nil
--print("Pre HeroSelector.Category")
for key, value in ipairs(HeroSelector.Category)
do
--print("Index",key)
local categoryButton = {}
categoryButton.Button, categoryButton.Tooltip = HeroSelector.CreateIconButton(0.015, value.TextValue, value.Texture)
categoryButton.Icon = BlzGetFrameByName("HeroSelectorCategoryButtonIcon", 0)
categoryButton.IconPushed = BlzGetFrameByName("HeroSelectorCategoryButtonIcon", 0)
BlzFrameSetVisible(categoryButton.Button, false)
table.insert(TeamViewer[player].Category, categoryButton)
table.insert(TeamViewer.Frames, categoryButton.Button)
table.insert(TeamViewer.Frames, categoryButton.Icon)
table.insert(TeamViewer.Frames, categoryButton.Tooltip)
end
BlzFrameSetScale(playerFrame, TeamViewer.Scale)
--When showning only allies, hide non allies
if not TeamViewer.ShowNonAllies and not IsPlayerAlly(player, GetLocalPlayer()) then
BlzFrameSetVisible(playerFrame, false)
end
end
end
end
function TeamViewer.UpdateButton(player, unitCode, alpha, updateCategory)
if not TeamViewer[player] then return end
if TeamViewer.UpdateNonAllies or IsPlayerAlly(GetLocalPlayer(), player) then
if unitCode then
BlzFrameSetText(TeamViewer[player].Tooltip, GetObjectName(unitCode))
BlzFrameSetTexture(TeamViewer[player].Icon, BlzGetAbilityIcon(unitCode), 0, true)
BlzFrameSetTexture(TeamViewer[player].IconPushed, BlzGetAbilityIcon(unitCode), 0, true)
BlzFrameSetAlpha(TeamViewer[player].Button, alpha)
else
BlzFrameSetText(TeamViewer[player].Tooltip, "")
BlzFrameSetTexture(TeamViewer[player].Icon, TeamViewer.ButtonDefaultIcon, 0, true)
BlzFrameSetTexture(TeamViewer[player].IconPushed, TeamViewer.ButtonDefaultIcon, 0, true)
BlzFrameSetAlpha(TeamViewer[player].Button, 255)
end
if updateCategory then
local teamNr = GetPlayerTeam(player)
local category = 1
local prevCategoryButton = nil
local left2Right = nil
if TeamViewer.ShowNonAllies and TeamViewer.TeamPos[teamNr] then
left2Right = TeamViewer.TeamPos[teamNr].Left2Right
else
left2Right = TeamViewer.TeamPosLeft2Right
end
for key, value in ipairs(HeroSelector.Category) do
local categoryButton = TeamViewer[player].Category[key]
BlzFrameClearAllPoints(categoryButton.Button)
if BlzBitAnd(category, HeroSelector.UnitData[unitCode].Category) > 0 then
BlzFrameSetVisible(categoryButton.Button, true)
if TeamViewer.ShowNonAllies and TeamViewer.TeamPos[teamNr] then
if not prevCategoryButton then
--TeamViewer.PosFirstFrame(categoryButton.Button, TeamViewer[player].Button, left2Right)
TeamViewer.PosFirstFrame(categoryButton.Button, TeamViewer[player].Text, left2Right)
--TeamViewer[player].Text
else
TeamViewer.PosFrame(categoryButton.Button, prevCategoryButton, left2Right)
end
else
if not prevCategoryButton then
TeamViewer.PosFirstFrame(categoryButton.Button, TeamViewer[player].Button, left2Right)
else
TeamViewer.PosFrame(categoryButton.Button, prevCategoryButton, left2Right)
end
end
prevCategoryButton = categoryButton.Button
else
BlzFrameSetVisible(categoryButton.Button, false)
end
category = category + category
end
end
end
end
function TeamViewer.ButtonClicked(clickingPlayer, targetPlayer)
--print(GetPlayerName(clickingPlayer),"Clicked",GetPlayerName(targetPlayer))
if GetUnitTypeId(HeroSelector.PickedUnit[clickingPlayer]) == 0 then return end
if GetUnitTypeId(HeroSelector.PickedUnit[targetPlayer]) == 0 then return end
-- self click allows all others to swap with you
if clickingPlayer == targetPlayer then
if TeamViewer.Swap[clickingPlayer] == 0 then
TeamViewer.Swap[clickingPlayer] = 2147483647
DisplayTextToPlayer(GetLocalPlayer(), 0, 0, GetPlayerName(clickingPlayer).."wants to Swap")
else
TeamViewer.Swap[clickingPlayer] = 0
end
elseif (TeamViewer.AllowSwapAlly and IsPlayerAlly(clickingPlayer, targetPlayer) ) or (TeamViewer.AllowSwapEnemy and IsPlayerEnemy(clickingPlayer, targetPlayer)) then
local clickNumber = 2^GetPlayerId(clickingPlayer)
local targetNumber = 2^GetPlayerId(targetPlayer)
TeamViewer.Swap[clickingPlayer] = BlzBitXor(TeamViewer.Swap[clickingPlayer], targetNumber)
if BlzBitAnd(TeamViewer.Swap[clickingPlayer], targetNumber) then DisplayTextToPlayer(targetPlayer, 0, 0, GetPlayerName(clickingPlayer).."wants to Swap") end
--print(TeamViewer.Swap[clickingPlayer], TeamViewer.Swap[targetPlayer])
if BlzBitAnd(TeamViewer.Swap[clickingPlayer], targetNumber) > 0 and BlzBitAnd(TeamViewer.Swap[targetPlayer], clickNumber) > 0 then
DisplayTextToPlayer(GetLocalPlayer(), 0, 0, GetPlayerName(clickingPlayer) .. " <-> " .. GetPlayerName(targetPlayer))
SetUnitOwner(HeroSelector.PickedUnit[clickingPlayer], targetPlayer, true)
SetUnitOwner(HeroSelector.PickedUnit[targetPlayer], clickingPlayer, true)
local unit = HeroSelector.PickedUnit[clickingPlayer]
HeroSelector.PickedUnit[clickingPlayer] = HeroSelector.PickedUnit[targetPlayer]
HeroSelector.PickedUnit[targetPlayer] = unit
TeamViewer.UpdateButton(clickingPlayer, GetUnitTypeId(HeroSelector.PickedUnit[clickingPlayer]), 255, true)
TeamViewer.UpdateButton(targetPlayer, GetUnitTypeId(HeroSelector.PickedUnit[targetPlayer]), 255, true)
-- after swap reset to 0
TeamViewer.Swap[clickingPlayer] = 0
TeamViewer.Swap[targetPlayer] = 0
BlzFrameSetVisible(TeamViewer[targetPlayer].SwapFrame, false)
BlzFrameSetVisible(TeamViewer[clickingPlayer].SwapFrame, false)
end
end
BlzFrameSetVisible(TeamViewer[clickingPlayer].SwapFrame, GetLocalPlayer() ~= clickingPlayer and BlzBitAnd(TeamViewer.Swap[clickingPlayer], 2^GetPlayerId(GetLocalPlayer())) > 0)
end
function HeroSelector.buttonSelected(player, unitCode)
TeamViewer.BackupSelected(player, unitCode)
if not TeamViewer.HasPicked[player] then
TeamViewer.UpdateButton(player, unitCode, TeamViewer.ButtonAlphaSelected, true)
end
end
function HeroSelector.unitCreated(player, unitCode, isRandom)
TeamViewer.BackupCreated(player, unitCode, isRandom)
TeamViewer.UpdateButton(player, unitCode, 255, true)
TeamViewer.HasPicked[player] = true
end
function HeroSelector.repick(unit, player)
TeamViewer.BackupRepick(unit, player)
if not player then player = GetOwningPlayer(unit) end
if TeamViewer.UpdateNonAllies or IsPlayerAlly(GetLocalPlayer(), player) then
TeamViewer.UpdateButton(player, nil)
end
TeamViewer.HasPicked[player] = false
end
function TeamViewer.Reset()
local player
local categoryButtonIndex
for _, player in ipairs(TeamViewer) do
TeamViewer.UpdateButton(player, nil)
TeamViewer.HasPicked[player] = false
--print("Pre HeroSelector.Category")
if TeamViewer[player] then
for key, value in ipairs(HeroSelector.Category) do
local categoryButton = TeamViewer[player].Category[key]
BlzFrameClearAllPoints(categoryButton.Button)
BlzFrameSetVisible(categoryButton.Button, false)
end
end
end
end
--TeamViewerReset = TeamViewer.Reset
--TeamViewer (one) 1.4
--Plugin for HeroSelector by Tasyen
--It shows the selection of Players in cols, when a col is full right of it a new is started
-- TeamViewer.Reset()
TeamViewer = {}
TeamViewer.Scale = 1.0
TeamViewer.TeamPosX = 0.02
TeamViewer.TeamPosY = 0.5
TeamViewer.TeamPosGapY = 0.015
TeamViewer.TeamPosGapX = 0.015
TeamViewer.TeamRowCount = 7
--how big are the Faces
TeamViewer.ButtonSize = 0.03
TeamViewer.ButtonAlphaSelected = 150
TeamViewer.ButtonDefaultIcon = "UI\\Widgets\\EscMenu\\Human\\quest-unknown.blp"
TeamViewer.CategoryButtonSize = 0.015 --size of the CategoryButtons below an players name
TeamViewer.CategoryButtonGap = 0.002 -- space between 2 CategoryButtons
TeamViewer.AllowSwapAlly = true
TeamViewer.AllowSwapEnemy = true
TeamViewer.SwapTexture = "ReplaceableTextures\\CommandButtons\\BTNPatrol.blp"
TeamViewer.SwapSize = 0.017
TeamViewer.HasPicked = {}
TeamViewer.Swap = __jarray(0)
TeamViewer.BackupSelected = HeroSelector.buttonSelected
TeamViewer.BackupCreated = HeroSelector.unitCreated
TeamViewer.BackupRepick = HeroSelector.repick
function TeamViewer.AllowPlayer(player)
return GetPlayerSlotState(player) == PLAYER_SLOT_STATE_PLAYING
-- and GetPlayerController(player) == MAP_CONTROL_USER
end
function TeamViewer.PosFrame(movingFrame, relativFrame)
BlzFrameSetPoint(movingFrame, FRAMEPOINT_TOPLEFT, relativFrame, FRAMEPOINT_TOPRIGHT, TeamViewer.CategoryButtonGap, 0)
end
function TeamViewer.Init()
while table.remove(TeamViewer) do end
local function buttonActionFunc(frame)
TeamViewer.ButtonClicked(GetTriggerPlayer(), TeamViewer[frame])
end
local colRemain = TeamViewer.TeamRowCount
for index= 0, GetBJMaxPlayers() - 1,1 do
local player = Player(index)
if TeamViewer.AllowPlayer(player) then
table.insert(TeamViewer, player)
local createContext = 1000 + index
--local playerFrame = BlzCreateFrameByType("FRAME", "TeamViewerPlayerFrame", HeroSelector.Box, "", createContext)
local playerFrame = BlzCreateFrame("HeroSelectorTextBox", HeroSelector.Box, 0, createContext)
local colorFrame = BlzCreateFrameByType("BACKDROP", "", playerFrame, "", createContext)
local button = BlzCreateFrame("HeroSelectorButton", playerFrame, 0, createContext)
local textFrame = BlzCreateFrame("HeroSelectorText", playerFrame, 0, createContext) -- do not the buttons child, else it is affected by Alpha change
local icon = BlzGetFrameByName("HeroSelectorButtonIcon", createContext)
local iconDisabled = BlzGetFrameByName("HeroSelectorButtonIconDisabled", createContext)
local iconPushed = BlzGetFrameByName("HeroSelectorButtonIconPushed", createContext)
local tooltipBox = BlzCreateFrame("HeroSelectorTextBox", button, 0, createContext)
local tooltip = BlzCreateFrame("HeroSelectorText", tooltipBox, 0, createContext)
local swapFrame = BlzCreateFrameByType("BACKDROP", "", playerFrame, "", createContext)
TasButtonAction.Set(button , buttonActionFunc)
BlzFrameSetSize(playerFrame, 0.11 + TeamViewer.ButtonSize, TeamViewer.ButtonSize + TeamViewer.CategoryButtonSize + 0.001)
BlzFrameSetPoint(colorFrame, FRAMEPOINT_TOPLEFT, playerFrame, FRAMEPOINT_TOPLEFT, 0.005, -0.0035)
BlzFrameSetPoint(colorFrame, FRAMEPOINT_TOPRIGHT, playerFrame, FRAMEPOINT_TOPRIGHT, -0.005, -0.0035)
BlzFrameSetSize(colorFrame, 0, 0.003)
BlzFrameSetSize(swapFrame, TeamViewer.SwapSize, TeamViewer.SwapSize)
BlzFrameSetTexture(swapFrame, TeamViewer.SwapTexture, 0, false)
BlzFrameSetPoint(swapFrame, FRAMEPOINT_TOPRIGHT, playerFrame, FRAMEPOINT_TOPRIGHT, 0, 0)
BlzFrameSetVisible(swapFrame, false)
local colorIndex = GetHandleId(GetPlayerColor(player))
if colorIndex < 10 then
BlzFrameSetTexture(colorFrame, "ReplaceableTextures\\TeamColor\\TeamColor0"..colorIndex, 0, false)
else
BlzFrameSetTexture(colorFrame, "ReplaceableTextures\\TeamColor\\TeamColor"..colorIndex, 0, false)
end
BlzFrameSetSize(button, TeamViewer.ButtonSize, TeamViewer.ButtonSize)
BlzFrameSetSize(textFrame, 0.105 - TeamViewer.ButtonSize, 0.013)
if #TeamViewer == 1 then
BlzFrameSetAbsPoint(button, FRAMEPOINT_BOTTOMLEFT, TeamViewer.TeamPosX, TeamViewer.TeamPosY)
else
if colRemain <= 0 then
local prevTeamPlayer = TeamViewer[#TeamViewer - TeamViewer.TeamRowCount]
colRemain = TeamViewer.TeamRowCount
BlzFrameSetPoint(button, FRAMEPOINT_TOPLEFT, TeamViewer[prevTeamPlayer].Button, FRAMEPOINT_TOPRIGHT, TeamViewer.TeamPosGapX + 0.11, 0)
else
local prevTeamPlayer = TeamViewer[#TeamViewer - 1]
BlzFrameSetPoint(button, FRAMEPOINT_TOPLEFT, TeamViewer[prevTeamPlayer].Button, FRAMEPOINT_BOTTOMLEFT, 0, -TeamViewer.TeamPosGapY)
end
end
colRemain = colRemain - 1
TeamViewer.PosFrame(textFrame, button)
BlzFrameSetPoint(tooltip, FRAMEPOINT_BOTTOMLEFT, button, FRAMEPOINT_TOPLEFT, 0, 0.007)
BlzFrameSetPoint(playerFrame, FRAMEPOINT_TOPLEFT, button, FRAMEPOINT_TOPLEFT, -0.007, 0.007)
BlzFrameSetPoint(tooltipBox, FRAMEPOINT_BOTTOMLEFT, tooltip, FRAMEPOINT_BOTTOMLEFT, -0.007, -0.007)
BlzFrameSetPoint(tooltipBox, FRAMEPOINT_TOPRIGHT, tooltip, FRAMEPOINT_TOPRIGHT, 0.007, 0.007)
BlzFrameSetText(textFrame, GetPlayerName(player))
BlzFrameSetTooltip(button, tooltipBox)
BlzFrameSetTexture(icon, TeamViewer.ButtonDefaultIcon, 0, true)
BlzFrameSetTexture(iconPushed, TeamViewer.ButtonDefaultIcon, 0, true)
TeamViewer[player] = {}
TeamViewer[player].PlayerFrame = playerFrame
TeamViewer[player].Text = textFrame
TeamViewer[player].Button = button
TeamViewer[button] = player
TeamViewer[player].Icon = icon
TeamViewer[player].IconDisabled = iconDisabled
TeamViewer[player].IconPushed = iconPushed
TeamViewer[player].Tooltip = tooltip
TeamViewer[player].SwapFrame = swapFrame
TeamViewer[player].Category = {}
local prevCategoryButton = nil
--print("Pre HeroSelector.Category")
for key, value in ipairs(HeroSelector.Category) do
--print("Index",key)
local categoryButton = {}
categoryButton.Button, categoryButton.Tooltip = HeroSelector.CreateIconButton(0.015, value.TextValue, value.Texture)
categoryButton.Icon = BlzGetFrameByName("HeroSelectorCategoryButtonIcon", 0)
categoryButton.IconPushed = BlzGetFrameByName("HeroSelectorCategoryButtonIcon", 0)
BlzFrameSetVisible(categoryButton.Button, false)
table.insert(TeamViewer[player].Category, categoryButton)
end
BlzFrameSetScale(playerFrame, TeamViewer.Scale)
end
end
end
function TeamViewer.UpdateButton(player, unitCode, alpha, updateCategory)
if not TeamViewer[player] then return end
if unitCode then
BlzFrameSetText(TeamViewer[player].Tooltip, GetObjectName(unitCode))
BlzFrameSetTexture(TeamViewer[player].Icon, BlzGetAbilityIcon(unitCode), 0, true)
BlzFrameSetTexture(TeamViewer[player].IconPushed, BlzGetAbilityIcon(unitCode), 0, true)
BlzFrameSetAlpha(TeamViewer[player].Button, alpha)
else
BlzFrameSetText(TeamViewer[player].Tooltip, "")
BlzFrameSetTexture(TeamViewer[player].Icon, TeamViewer.ButtonDefaultIcon, 0, true)
BlzFrameSetTexture(TeamViewer[player].IconPushed, TeamViewer.ButtonDefaultIcon, 0, true)
BlzFrameSetAlpha(TeamViewer[player].Button, 255)
end
if updateCategory then
local category = 1
local prevCategoryButton = nil
for key, value in ipairs(HeroSelector.Category) do
local categoryButton = TeamViewer[player].Category[key]
BlzFrameClearAllPoints(categoryButton.Button)
if BlzBitAnd(category, HeroSelector.UnitData[unitCode].Category) > 0 then
BlzFrameSetVisible(categoryButton.Button, true)
if not prevCategoryButton then
BlzFrameSetPoint(categoryButton.Button, FRAMEPOINT_TOPLEFT, TeamViewer[player].Text, FRAMEPOINT_BOTTOMLEFT, 0, 0)
else
TeamViewer.PosFrame(categoryButton.Button, prevCategoryButton)
end
prevCategoryButton = categoryButton.Button
else
BlzFrameSetVisible(categoryButton.Button, false)
end
category = category + category
end
end
end
function TeamViewer.ButtonClicked(clickingPlayer, targetPlayer)
--print(GetPlayerName(clickingPlayer),"Clicked",GetPlayerName(targetPlayer))
if GetUnitTypeId(HeroSelector.PickedUnit[clickingPlayer]) == 0 then return end
if GetUnitTypeId(HeroSelector.PickedUnit[targetPlayer]) == 0 then return end
-- self click allows all others to swap with you
if clickingPlayer == targetPlayer then
if TeamViewer.Swap[clickingPlayer] == 0 then
TeamViewer.Swap[clickingPlayer] = 2147483647
DisplayTextToPlayer(GetLocalPlayer(), 0, 0, GetPlayerName(clickingPlayer).." wants to Swap")
else
TeamViewer.Swap[clickingPlayer] = 0
end
elseif (TeamViewer.AllowSwapAlly and IsPlayerAlly(clickingPlayer, targetPlayer) ) or (TeamViewer.AllowSwapEnemy and IsPlayerEnemy(clickingPlayer, targetPlayer)) then
local clickNumber = 2^GetPlayerId(clickingPlayer)
local targetNumber = 2^GetPlayerId(targetPlayer)
TeamViewer.Swap[clickingPlayer] = BlzBitXor(TeamViewer.Swap[clickingPlayer], targetNumber)
if BlzBitAnd(TeamViewer.Swap[clickingPlayer], targetNumber) then DisplayTextToPlayer(targetPlayer, 0, 0, GetPlayerName(clickingPlayer).." wants to Swap") end
--print(TeamViewer.Swap[clickingPlayer], TeamViewer.Swap[targetPlayer])
if BlzBitAnd(TeamViewer.Swap[clickingPlayer], targetNumber) > 0 and BlzBitAnd(TeamViewer.Swap[targetPlayer], clickNumber) > 0 then
DisplayTextToPlayer(GetLocalPlayer(), 0, 0, GetPlayerName(clickingPlayer) .. " <-> " .. GetPlayerName(targetPlayer))
SetUnitOwner(HeroSelector.PickedUnit[clickingPlayer], targetPlayer, true)
SetUnitOwner(HeroSelector.PickedUnit[targetPlayer], clickingPlayer, true)
local unit = HeroSelector.PickedUnit[clickingPlayer]
HeroSelector.PickedUnit[clickingPlayer] = HeroSelector.PickedUnit[targetPlayer]
HeroSelector.PickedUnit[targetPlayer] = unit
TeamViewer.UpdateButton(clickingPlayer, GetUnitTypeId(HeroSelector.PickedUnit[clickingPlayer]), 255, true)
TeamViewer.UpdateButton(targetPlayer, GetUnitTypeId(HeroSelector.PickedUnit[targetPlayer]), 255, true)
-- after swap reset to 0
TeamViewer.Swap[clickingPlayer] = 0
TeamViewer.Swap[targetPlayer] = 0
BlzFrameSetVisible(TeamViewer[targetPlayer].SwapFrame, false)
BlzFrameSetVisible(TeamViewer[clickingPlayer].SwapFrame, false)
end
end
BlzFrameSetVisible(TeamViewer[clickingPlayer].SwapFrame, GetLocalPlayer() ~= clickingPlayer and BlzBitAnd(TeamViewer.Swap[clickingPlayer], 2^GetPlayerId(GetLocalPlayer())) > 0)
end
function HeroSelector.buttonSelected(player, unitCode)
TeamViewer.BackupSelected(player, unitCode)
if not TeamViewer.HasPicked[player] then
TeamViewer.UpdateButton(player, unitCode, TeamViewer.ButtonAlphaSelected, true)
end
end
function HeroSelector.unitCreated(player, unitCode, isRandom)
TeamViewer.BackupCreated(player, unitCode, isRandom)
TeamViewer.UpdateButton(player, unitCode, 255, false)
TeamViewer.HasPicked[player] = true
end
function HeroSelector.repick(unit, player)
TeamViewer.BackupRepick(unit, player)
if not player then player = GetOwningPlayer(unit) end
TeamViewer.UpdateButton(player, nil)
TeamViewer.HasPicked[player] = false
end
function TeamViewer.Reset()
local player
local categoryButtonIndex
for _, player in ipairs(TeamViewer) do
TeamViewer.UpdateButton(player, nil)
TeamViewer.HasPicked[player] = false
if TeamViewer[player] then
--print("Pre HeroSelector.Category")
for key, value in ipairs(HeroSelector.Category) do
local categoryButton = TeamViewer[player].Category[key]
BlzFrameClearAllPoints(categoryButton.Button)
BlzFrameSetVisible(categoryButton.Button, false)
end
end
end
end
TeamViewerReset = TeamViewer.Reset
--HeroInfo 1.2e
--Plugin for HeroInfo by Tasyen
--This Creates a TextArea which displays the name, the Extended tooltip of selected units and can show some of their skills.
HeroInfo = {}
-- TextArea
HeroInfo.DescHeroNamePrefix = "|cffffcc00" --added before the Units Name
HeroInfo.DescHeroNameSufix = "|r" --added after the units Name
HeroInfo.TextAreaSizeX = 0.2
HeroInfo.TextAreaSizeY = 0.2
HeroInfo.TextAreaOffsetX = 0
HeroInfo.TextAreaOffsetY = 0
HeroInfo.TextAreaPoint = FRAMEPOINT_TOPLEFT --pos the Tooltip with which Point
HeroInfo.TextAreaRelativePoint = FRAMEPOINT_TOPRIGHT --pos the Tooltip to which Point of the Relative
HeroInfo.TextAreaRelativeGame = false --(false) relativ to box, (true) relativ to GameUI
HeroInfo.BackupSelected = HeroSelector.buttonSelected
-- Skill Priview
HeroInfo.MaxButtonCount = 7 -- max amount of preview skills
HeroInfo.ButtonPerRow = 7
HeroInfo.DetectUnitSkills = true -- (true) creates a dummy (for neutral Passive) when selecting an option to find any skill this unitCode has on default and displays them in the preview
HeroInfo.ButtonSizeX = 0.03
HeroInfo.ButtonSizeY = 0.03
HeroInfo.ToolTipSize = 0.2 -- how big is one line in the tooltip
HeroInfo.ToolTipFixedPos = true -- (true) All tooltip's starts over the first Button
-- feed HeroInfo with skills units will preview.
HeroInfo.HeroData = {
-- unitCode = "skillA,Skillb,SkillC..."
-- get skill list from object editor: hold shift then open the hero/unit skill field now copy paste the content
Hpal = "AHhb,AHds,AHre,AHad"
,Hamg = "AHbz,AHab,AHwe,AHmt"
,Hmkg = "AHtc,AHtb,AHbh,AHav"
,Hblm = "AHfs,AHbn,AHdr,AHpx"
,Obla = "AOwk,AOcr,AOmi,AOww"
,Ofar = "AOfs,AOsf,AOcl,AOeq"
,Otch = "AOsh,AOae,AOre,AOws"
,Oshd = "AOhw,AOhx,AOsw,AOvd"
,Udea = "AUdc,AUdp,AUau,AUan"
,Ulic = "AUfn,AUfu,AUdr,AUdd"
,Udre = "AUav,AUsl,AUcs,AUin"
,Ucrl = "AUim,AUts,AUcb,AUls"
,Ekee = "AEer,AEfn,AEah,AEtq"
,Emoo = "AHfa,AEst,AEar,AEsf"
,Edem = "AEmb,AEim,AEev,AEme"
,Ewar = "AEbl,AEfk,AEsh,AEsv"
,Nbrn = "ANsi,ANba,ANdr,ANch"
,Nbst = "ANsg,ANsq,ANsw,ANst"
,Nngs = "ANfl,ANfa,ANms,ANto"
,Npbm = "ANbf,ANdh,ANdb,ANef"
,Nalc = "ANhs,ANab,ANcr,ANtm"
,Ntin = "ANsy,ANcs,ANeg,ANrg"
,Nfir = "ANia,ANso,ANlm,ANvc"
,Nplh = "ANrf,ANht,ANca,ANdo"
}
HeroInfo.Buttons = {}
HeroInfo.ButtonCurrentIndex = 0
-- taken from Prometheus3375
-- converts an objectId into it's string equl x -> "hfoo"
function GetFourCC(num)
return string.pack(">I4", num)
end
function HeroInfo.Init()
HeroInfo.TextArea = BlzCreateFrame("HeroSelectorTextArea", HeroSelector.Box, 0, 0)
BlzFrameSetSize(HeroInfo.TextArea , HeroInfo.TextAreaSizeX, HeroInfo.TextAreaSizeY)
if not HeroInfo.TextAreaRelativeGame then
BlzFrameSetPoint(HeroInfo.TextArea, HeroInfo.TextAreaPoint, HeroSelector.Box, HeroInfo.TextAreaRelativePoint, HeroInfo.TextAreaOffsetX, HeroInfo.TextAreaOffsetY)
else
BlzFrameSetPoint(HeroInfo.TextArea, HeroInfo.TextAreaPoint, BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), HeroInfo.TextAreaRelativePoint, HeroInfo.TextAreaOffsetX, HeroInfo.TextAreaOffsetY)
end
local this, col
local col = 0
for index = 1, HeroInfo.MaxButtonCount do
HeroInfo.Buttons[index] = {}
this = HeroInfo.Buttons[index]
this.Button = BlzCreateFrame("HeroSelectorButton", HeroInfo.TextArea, 0, 0)
this.Icon = BlzGetFrameByName("HeroSelectorButtonIcon", 0)
this.IconPushed = BlzGetFrameByName("HeroSelectorButtonIconPushed", 0)
this.IconOff = BlzGetFrameByName("HeroSelectorButtonIconDisabled", 0)
this.TooltipBox = BlzCreateFrame("HeroSelectorTextBox", this.Button, 0, 0)
this.Tooltip = BlzCreateFrame("HeroSelectorText", this.TooltipBox, 0, 0)
BlzFrameSetSize(this.Button, HeroInfo.ButtonSizeX, HeroInfo.ButtonSizeY)
if HeroInfo.ToolTipFixedPos then
BlzFrameSetPoint(this.Tooltip, FRAMEPOINT_BOTTOMLEFT, HeroInfo.Buttons[1].Button, FRAMEPOINT_TOPLEFT, 0, 0.007)
else
BlzFrameSetPoint(this.Tooltip, FRAMEPOINT_BOTTOMLEFT, this.Button, FRAMEPOINT_TOPLEFT, 0, 0.007)
end
BlzFrameSetPoint(this.TooltipBox, FRAMEPOINT_BOTTOMLEFT, this.Tooltip, FRAMEPOINT_BOTTOMLEFT, -0.007, -0.007)
BlzFrameSetPoint(this.TooltipBox, FRAMEPOINT_TOPRIGHT, this.Tooltip, FRAMEPOINT_TOPRIGHT, 0.007, 0.007)
BlzFrameSetTooltip(this.Button, this.TooltipBox)
BlzFrameSetSize(this.Tooltip, HeroInfo.ToolTipSize, 0)
if index > 1 then
col = col + 1
if col >= HeroInfo.ButtonPerRow then
col = 0
BlzFrameSetPoint(this.Button, FRAMEPOINT_TOPLEFT, HeroInfo.Buttons[index - HeroInfo.ButtonPerRow].Button, FRAMEPOINT_BOTTOMLEFT, 0.00, -0.004)
else
BlzFrameSetPoint(this.Button, FRAMEPOINT_TOPLEFT, HeroInfo.Buttons[index - 1].Button, FRAMEPOINT_TOPRIGHT, 0.004, 0)
end
else
BlzFrameSetPoint(this.Button, FRAMEPOINT_TOPLEFT, HeroInfo.TextArea, FRAMEPOINT_BOTTOMLEFT, 0.002, 0)
end
BlzFrameSetEnable(this.Button, false)
BlzFrameSetVisible(this.Button, false)
end
end
function HeroInfo.UpdateSkillPreivew(icon, name, text)
HeroInfo.ButtonCurrentIndex = HeroInfo.ButtonCurrentIndex + 1
local object = HeroInfo.Buttons[HeroInfo.ButtonCurrentIndex]
if not object then return end
BlzFrameSetVisible(object.Button, true)
BlzFrameSetTexture(object.Icon, icon, 0, false)
BlzFrameSetTexture(object.IconPushed, icon, 0, false)
BlzFrameSetTexture(object.IconOff, HeroSelector.getDisabledIcon(icon), 0, false)
BlzFrameSetTexture(object.IconOff, icon, 0, false)
-- x Size and no y Size makes it multiline text when the text does not fit into 1 line
if text and name then
BlzFrameSetSize(object.Tooltip, HeroInfo.ToolTipSize, 0)
BlzFrameSetText(object.Tooltip, name.."\n"..text)
else
-- only the name, set frameSize to 0/0 to match the displayed text
BlzFrameSetSize(object.Tooltip, 0, 0)
BlzFrameSetText(object.Tooltip, name)
end
end
function HeroSelector.ValidTooltip(text)
if text == "Tool tip missing!" or text == "" or text == " " then
return false
end
return true
end
function HeroSelector.abiFilter(abi)
-- no skills markes as item skills
if BlzGetAbilityBooleanField(abi, ABILITY_BF_ITEM_ABILITY) then
return false
end
if not HeroSelector.ValidTooltip(BlzGetAbilityStringLevelField(abi, ABILITY_SLF_TOOLTIP_NORMAL, 0)) then
return false
end
return true
end
function HeroSelector.buttonSelected(player, unitCode)
HeroInfo.BackupSelected(player, unitCode)
local dummyUnit
if HeroInfo.DetectUnitSkills then
dummyUnit = CreateUnit(Player(GetPlayerNeutralPassive()), unitCode, 0, 0, 0)
end
-- Reset the global button Index
HeroInfo.ButtonCurrentIndex = 0
if GetLocalPlayer() == player then
BlzFrameSetText(HeroInfo.TextArea, HeroInfo.DescHeroNamePrefix .. GetObjectName(unitCode).. HeroInfo.DescHeroNameSufix)
BlzFrameAddText(HeroInfo.TextArea, BlzGetAbilityExtendedTooltip(unitCode,0))
if not HeroInfo.HeroData[unitCode] and HeroInfo.HeroData[GetFourCC(unitCode)] then
-- user did a none number setup
unitCode = GetFourCC(unitCode)
end
if HeroInfo.HeroData[unitCode] then
local startIndex = 1
while startIndex + 3 <= string.len(HeroInfo.HeroData[unitCode]) do
local skillCode = string.sub(HeroInfo.HeroData[unitCode], startIndex, startIndex + 3)
startIndex = startIndex + 5
skillCode = FourCC(skillCode)
-- for hero skills show the learn text, "Tool tip missing!" is the default string
if HeroSelector.ValidTooltip(BlzGetAbilityResearchExtendedTooltip(skillCode, 0)) then
HeroInfo.UpdateSkillPreivew(BlzGetAbilityIcon(skillCode), GetObjectName(skillCode), BlzGetAbilityResearchExtendedTooltip(skillCode, 0) )
elseif HeroSelector.ValidTooltip(BlzGetAbilityExtendedTooltip(skillCode, 0)) then
-- skills without a research text show the first Level
HeroInfo.UpdateSkillPreivew(BlzGetAbilityIcon(skillCode), GetObjectName(skillCode), BlzGetAbilityExtendedTooltip(skillCode, 0) )
else
HeroInfo.UpdateSkillPreivew(BlzGetAbilityIcon(skillCode), GetObjectName(skillCode))
end
end
end
if HeroInfo.DetectUnitSkills then
local abi, abiIndex
abiIndex = 0
while (true) do
abi = BlzGetUnitAbilityByIndex(dummyUnit, abiIndex)
if abi then
if HeroSelector.abiFilter(abi) then
if HeroSelector.ValidTooltip(BlzGetAbilityStringLevelField(abi, ABILITY_SLF_TOOLTIP_LEARN_EXTENDED, 0)) then
HeroInfo.UpdateSkillPreivew(BlzGetAbilityStringLevelField(abi, ABILITY_SLF_ICON_NORMAL, 0), BlzGetAbilityStringLevelField(abi, ABILITY_SLF_TOOLTIP_NORMAL, 0), BlzGetAbilityStringLevelField(abi, ABILITY_SLF_TOOLTIP_LEARN_EXTENDED, 0))
else
HeroInfo.UpdateSkillPreivew(BlzGetAbilityStringLevelField(abi, ABILITY_SLF_ICON_NORMAL, 0), BlzGetAbilityStringLevelField(abi, ABILITY_SLF_TOOLTIP_NORMAL, 0), BlzGetAbilityStringLevelField(abi, ABILITY_SLF_TOOLTIP_NORMAL_EXTENDED, 0))
end
end
abiIndex = abiIndex + 1
else
break
end
end
end
for index = HeroInfo.ButtonCurrentIndex + 1, HeroInfo.MaxButtonCount do
BlzFrameSetVisible(HeroInfo.Buttons[index].Button, false)
end
end
if HeroInfo.DetectUnitSkills then
RemoveUnit(dummyUnit)
dummyUnit = nil
end
end