| 12-05-2007, 04:41 AM | #1 |
Multibars version 1.20 Created by Ammorth Please give credit if you use this in your map. Multibars is an easy way to create dynamic and sexy looking progress bars for multiboards. Included in this version are 11 different bartypes:
Also included in the pack is the photoshop document with all the borders and fills I used to make the bartypes in the map. I am willing to make other bartypes on request and include them in different version/packs. Just include a picture or description on what you want it to look like. As of version 1.20 there is both a standard Jass version and a vJass version. For those who do not have vJass, the Jass version is available. Download Pack (version 1.20) Download Jass Map Only (Jass version 1.20) Download vJass Map Only (vJass version 1.20) vJass vJass Read-Me:Multibars Readme (vJass) Created by Ammorth Compiled January 10th, 2008 Requires vJass PLEASE GIVE CREDIT IF YOU USE MULTIBARS OR ANY OF MY BARTYPES IN YOUR MAP! ================================== About ================================== Multibars is an easy way to create dynamic and sexy looking progress bars for multiboards. You can also create dynamic health, mana and experience bars with 1 line of code. Included in this version are 11 different bartypes: Name - Type (Description) Build - MULTIBAR_TYPE_BUILD (based on the in-game construction bar) Health - MULTIBAR_TYPE_HEALTH (A red health bar) Mana - MULTIBAR_TYPE_MANA (A blue mana bar) Experience - MULTIBAR_TYPE_EXPERIENCE (A purple experience bar) Chunk - MULTIBAR_TYPE_CHUNK (A green bar that displays in chunks, rather than smoothly) Radio - MULTIBAR_TYPE_RADIO (A radioactive [yellow and black] bar) Mac - MULTIBAR_TYPE_MAC (resembles a Mac OS X loading bar) Orange - MULTIBAR_TYPE_ORANGE (An orange bar that displays in chuncks, but chunks light up vs. appearing) Hearts - MULTIBAR_TYPE_HEARTS (Hearts which display health based off of Zelda Ocarina of Time) Hearts Up - MULTIBAR_TYPE_HEARTS_UP (Hearts with a white outline which display health, based off of Zelda Ocarina of Time) Magic - MULTIBAR_TYPE_MAGIC (Green energy bar based off of Zelda Ocarina of Time) ================================== Installation ================================== 1) Copy the Multibars Library to your map (copy the trigger and paste it) 2) For each type of bar you want to use, import the entire folder to your map 3a) If you want to use the dynamic health, mana and experience bars, copy the MutliBarsHelper library aswell 3b) Change the MULTIBAR_PERIOD constant if you want the bars updating smoother or mre efficiently. ================================== Usage ================================== To create a Multibar, call: static method create takes multiboard whichboard, integer colstart, integer row, integer size, real maxval, real currentval, integer bartype returns MultiBar - whichboard - the multiboard which the bar will be added to - colstart - which column do you want the bar to start on - row - which row do you want the bar on - size - how many columns do you want to use for your bar (max of 16, min of 2) - maxval - the maximum value of the bar - currentval - the starting value the bar will display - bartype - the bartype of the bar (Defualts are shown in the table above) An example of calling this function would be: local Multibar mb = Multibar.create(SomeMultiboard, 3, 0, 12, 50., 10., BAR_TYPE_BUILD) - This would create a Build Multibar on SomeMultiboard, at column 4, row 1, (remember, multiboards in jass start at 0,0) a size of 12, max value is 50, and the current value is 10. To update the value of the bar, call: method UpdateValue takes real newvalue, boolean update returns nothing - newvalue - the new current value - update - if you want the bar to visually update to the new value An exmaple of calling this function would be: call mb.UpdateValue(45., true) - This would update our Multibar stored in mb to a value of 45. It would also update the visual bar on the multiboard. To update the maximum value of the bar, call: method UpdateMaxValue takes real newvalue, boolean update returns nothing - newvalue - the new maximum value - update - if you want the bar to visually update to the new value An exmaple of calling this function would be: call mb.UpdateValue(45., true) - This would update our Multibar stored in mb to a value of 45. It would also update the visual bar on the multiboard. - Note: if the maximum value becomes less than the current value, the current value will automatically equal the new max value. To create dynamic Health, Mana or Experience bars, make sure you have the MultibarsHelper library installed then call: static method create takes unit whichunit, multiboard whichboard, integer col, integer row, integer size, integer bartype, integer whichtype returns MultiBarHelper - whichunit - the unit you want to create the bar for - whichboard - the multiboard which the bar will be added to - col - which column do you want the bar to start on - row - which row do you want the bar on - size - how many columns do you want to use for your bar (max of 16, min of 2) - bartype - the bartype of the bar (Defualts are shown in the table above) - whichtype - the type of the helper bar. - MULTIBAR_HELPER_HEALTH = health bar - MULTIBAR_HELPER_MANA = mana bar - MULTIBAR_HELPER_EXPERIENCE = experience bar This function will create a helper bar that will automatically update itself, depending on the units status. An exmaple of calling this functions is: local MultibarHelper h = MultibarHelper.create(someunit, someboard, 0, 0, 14, MULTIBAR_TYPE_HEALTH, MULTIBAR_HELPER_HEALTH) - This function would create a health bar at col 0 row 0 on someboard, displaying the health of someunit. - The types used do not have to be the default types. For example, you can use MULTIBAR_TYPE_CHUNK for a health bar. If you want to create a label for your health, mana, or experience bar, call: method AddLabel takes integer col, integer row, real width, integer red, integer green, integer blue, integer alpha, string icon returns nothing - col - which column you want the label to be on - row - which row you want the label to be on - width - the width you want the label cell to be - red/green/blue/alpha - the color your want the label to be - icon - the icon you want beside the label (use "" for no icon) Labels can only be created for MultiBarHelpers bars (health, mana, experience). Attempting to create a label for a regular MultiBar bar will produce an error. An exmaple of calling this function would be: call somebarhelper.AddLabel(0, 2, 0.07, 0, 0, 255, 255, "") - This will create a label for somebar at column 0, row 2, with a width of 7%, blue text and no icon. - Labels are automatically cleared from memory when the multibarhelper is destroyed. - You can only have 1 label per multibarhelper. When you are done with a MultiBar, dont forget to call: method destroy takes nothing returns nothing An example of calling this function would be: call mb.destroy() - This will remove the Multibar or MultibarHelper from memory, but will not remove the visuals from the multiboard. To do this, either clear the multiboard or replace it with something else. - Always remember to destroy multibars and multibarhelpers when you are done with them. ================================== Customization ================================== Multibars allows for custom bartypes that are created by others. The formats that are supported are .tga and .blp (same as WC3). To create a new bartype, it is important to understand what makes up a bar. Each bar consists of 3 different types: A left piece ---- A middle piece ---- A right piece Using all 3 pieces, the MultiBar script can place them side-by-side and simulate a progress bar. Now, to make the bars smoother, there are sub levels to each piece. These are called the divisions. In this demo map, 5 out of the 6 bartypes have a division of 8. This means that there are 8 images of varying "fill" to simulate a smooth fill. Counting up, from 1 to n (where n is complete fill and 1 is only 1/n fill) are how the divisions are arranged. Since an image is only 16x16, it is not smart to have more than 16 divisions (because they will not be noticed). The trick is to use the "cover fill" layer to cover up parts of the fill, then save. So if you have a bartype with a division of 16, you would cover up 1/16 of the fill at a time (1 pixel at 16x16) and then save. With a division of 4 you would cover up 1/4 of the fill at a time (4 pixels at 16x16) and then save. A visual representation would be: 1 2 3 4 5 6 7 8 [| ] [|| ] [||| ] [|||| ] [||||| ] [|||||| ] [||||||| ] [||||||||] Of course, on top of the divisions, there is an empty image, or 0. 0 [ ] This image is not counted in the divisions since it is required no matter how many divisions there are. DONT FORGET TO MAKE A 0 DIVISION! Each piece of each bartype requires the same number of divisions. Using both the divisions and the pieces, the MultiBar script can draw the progress bars on the multiboard. Creating the images may take some time. I have included the .ps (photoshop) document I used to create the bars in the demo. It contains all the fills and borders, arranged in groups. Hopefully this will help ease some pains. When saving the images, make sure to follow this name-scheme. [Bartype][piece][divisionN].[filetype] The bartype, is the name or type that you will use to distinguish your bartype from others The piece is the piece the image is(either "L" for left, "M" for middle or "R" for right) The divisionN is the division number (look at the visual representation above for more info) The filetype is either .tga or .blp (Most graphics programs save as .tga so I would recommend to use that. The ammount of file-size you save by compressing to .blp is small, since each image is only 1kb to begin with). Exmaple: Bartype is called "Crazy" The piece is the left ("L") This is the 4th Division("4") and it will be a .tga "CrazyL4.tga" Once you have made all your images, just stick them all in a folder and upload the entire folder to your map. There, you can leave them in the default directory or change the directory of the images. MAKE SURE, IF YOU CHANGE THE DIRECTORY, TO CHANGE ALL THE IMAGES OF THE SAME BARTYPE TO THE NEW DIRECTORY! To create a bartype for your custom bar, use the function: public function CreateBartype takes string name, string filetype, string directory, integer divisions returns integer - name - the name of the bartype - filetype - the filetype of the images - directory - where the images can be found - divisions - the number of divisions the bar uses Because this is a public function, it will have MultiBars_ as a prefix to the function. An exmaple of calling this function would be: set MyBar_NewBar = MultiBars_CreateBartype("NewBar", ".tga", "MyBars\\", 8) - MyBar_NewBar is a global integer you use to store the bartype in. - Thie function created a bartype called NewBar found in MyBars\ with a filetype of .tga and 8 divisions. Summary: Each image is 16x16 .tga or .blp There are 3 piece types: left ("L"), middle ("M") and right ("R"). Each piece has n divisions, which progress from 1 being 1/n fill to n being 100% fill. Each piece also has an empty image, called the 0 division. Images are saved as [Bartype][piece][divisionN].[filetype] Use CreateBartype() to create your custom bartypes ================================== Public Functions and Variables ================================== MultiBars ========= constant integer MULTIBAR_TYPE_HEALTH = 1 constant integer MULTIBAR_TYPE_MANA = 2 constant integer MULTIBAR_TYPE_EXPERIENCE = 3 constant integer MULTIBAR_TYPE_BUILD = 4 constant integer MULTIBAR_TYPE_CHUNK = 5 constant integer MULTIBAR_TYPE_RADIO = 6 constant integer MULTIBAR_TYPE_MAC = 7 constant integer MULTIBAR_TYPE_ORANGE = 8 constant integer MULTIBAR_TYPE_HEARTS = 9 constant integer MULTIBAR_TYPE_HEARTS_UP = 10 constant integer MULTIBAR_TYPE_MAGIC = 11 static method create takes multiboard whichboard, integer colstart, integer row, integer size, real maxval, real currentval, integer bartype returns MultiBar method onDestroy takes nothing returns nothing method UpdateValue takes real newvalue, boolean update returns nothing method UpdateMaxValue takes real newvalue, boolean update returns nothing public function CreateBartype takes string name, string filetype, string directory, integer divisions returns integer MultiBars Helper ================ constant real MULTIBAR_PERIOD = 0.035 constant integer MULTIBAR_HELPER_HEALTH = 1 constant integer MULTIBAR_HELPER_MANA = 2 constant integer MULTIBAR_HELPER_EXPERIENCE = 3 static method create takes unit whichunit, multiboard whichboard, integer col, integer row, integer size, integer bartype, integer whichtype returns MultiBarHelper method AddLabel takes integer col, integer row, real width, integer red, integer green, integer blue, integer alpha, string icon returns nothing method onDestroy takes nothing returns nothing ================================== Change-Log ================================== Version 1.20 - Created a non-vJass Version (not this version) - Changed the MultibarHelper group to use an array rather than a list (improves performance) - Should have fixed the problem with both winning and losing - Fixed a minor leak when creating a label - Added 3 new bar types (Hearts, HeartsUp and Magic) - Changed all instances of MultiBar(s) to Multibar(s) (made the "B" lowercase). It was not consistent within the systems. - Made other minor changes that I dont remember anymore Version 1.11 - Split MultiBars into two libraries (core and helper) - Decreased difficulty of survival game Version 1.10 - Added dynamic health, mana and experience bars - Changed the name of the library from "MultiBarsEngine" to "MultiBars" - Bartypes are now stored as integers and must be created - Added labels for dynamic health, mana and experience bars - Default bartypes now have constant pointers - Added CreateBartype() - Added "Mac" and "Orange" bartypes - Added a list of public functions and variables to the readme Version 1.00 - First Public Release - Includes the "Health", "Mana", "Experience", "Build", "Chunk" and "Radio" bartypes. End of Readme vJass Multibars:library Multibars initializer InitMultibars globals // ==================== // PUBLIC CONSTANTS // ==================== // These constants should not be modified constant integer MULTIBAR_TYPE_HEALTH = 1 constant integer MULTIBAR_TYPE_MANA = 2 constant integer MULTIBAR_TYPE_EXPERIENCE = 3 constant integer MULTIBAR_TYPE_BUILD = 4 constant integer MULTIBAR_TYPE_CHUNK = 5 constant integer MULTIBAR_TYPE_RADIO = 6 constant integer MULTIBAR_TYPE_MAC = 7 constant integer MULTIBAR_TYPE_ORANGE = 8 constant integer MULTIBAR_TYPE_HEARTS = 9 constant integer MULTIBAR_TYPE_HEARTS_UP = 10 constant integer MULTIBAR_TYPE_MAGIC = 11 // ==================== // END PUBLIC CONSTANTS // ==================== //Private Variables private integer Gcurrent = 0 private string array Gbartype private string array Gfiletype private string array Gdir private integer array Gdivs endglobals struct Multibar integer row integer colstart integer numcols integer numdivs real max real current string bartype string filetype string dir multiboard whichboard integer array curfill[16] static method create takes multiboard whichboard, integer colstart, integer row, integer size, real maxval, real currentval, integer bartype returns Multibar local Multibar b = Multibar.allocate() local integer i = 0 set b.whichboard = whichboard if row > 32 then debug call BJDebugMsg("Multibars Error: Multiboards only have 32 rows!") elseif row < 0 then debug call BJDebugMsg("Multibars Error: Multiboards do not have negative rows!") endif set b.row = row set b. colstart = colstart if colstart > 16 then debug call BJDebugMsg("Multibars Error: Multiboards only have 16 columns") elseif colstart < 0 then debug call BJDebugMsg("Multibars Error: Multiboards do not have negative columns!") endif if size < 2 then debug call BJDebugMsg("Multibars Error: Bar size must be greater than 1!") elseif size > 16 then debug call BJDebugMsg("Multibars Error: Bar size must be less than 17!") endif set b.numcols = size set b.max = maxval if maxval < 0 then debug call BJDebugMsg("Multibars Error: Multibars does not support negative values!") set b.max = 1 endif set b.current = currentval if currentval < 0 then debug call BJDebugMsg("Multibars Error: Multibars does not support negative values!") set b.current = 0 elseif currentval > b.max then debug call BJDebugMsg("Multibars Error: Value cannot exceed max value!") set b.current = b.max endif if bartype > Gcurrent then debug call BJDebugMsg("Multibars Error: Invalid bartype!") endif set b.numdivs = Gdivs[bartype] set b.bartype = Gbartype[bartype] set b.filetype = Gfiletype[bartype] set b.dir = Gdir[bartype] loop exitwhen i > 15 set b.curfill[i] = -1 set i = i + 1 endloop call b.SetMultiboardBar() call b.UpdateBoard() return b endmethod method onDestroy takes nothing returns nothing set .whichboard = null endmethod private method UpdateBoard takes nothing returns nothing local real step = .max/.numcols local real step2 = step/.numdivs local real val = .current local multiboarditem mbi local integer col = .colstart local integer num loop exitwhen val <= 0. if val >= step then if .curfill[col] != .numdivs then // check if it requires an update set mbi = MultiboardGetItem(.whichboard, .row, col) if col == .colstart then call MultiboardSetItemIcon(mbi, .dir+.bartype+"L"+I2S(.numdivs)+.filetype) // Left elseif col == .colstart+.numcols-1 then call MultiboardSetItemIcon(mbi, .dir+.bartype+"R"+I2S(.numdivs)+.filetype) // Right else call MultiboardSetItemIcon(mbi, .dir+.bartype+"M"+I2S(.numdivs)+.filetype) // Middle endif call MultiboardReleaseItem(mbi) set .curfill[col] = .numdivs endif set val = val - step else set num = R2I((val/step2)+0.5) if .curfill[col] != num then // check if it requires an update set mbi = MultiboardGetItem(.whichboard, .row, col) if col == .colstart then call MultiboardSetItemIcon(mbi, .dir+.bartype+"L"+I2S(num)+.filetype) // Left elseif col == .colstart+.numcols-1 then call MultiboardSetItemIcon(mbi, .dir+.bartype+"R"+I2S(num)+.filetype) // Right else call MultiboardSetItemIcon(mbi, .dir+.bartype+"M"+I2S(num)+.filetype) // Middle endif call MultiboardReleaseItem(mbi) set .curfill[col] = num endif set val = 0. endif set col = col + 1 endloop loop exitwhen col >= .colstart + .numcols if .curfill[col] != 0 then // check if it requires an update set mbi = MultiboardGetItem(.whichboard, .row, col) if col == .colstart then call MultiboardSetItemIcon(mbi, .dir+.bartype+"L0"+.filetype) // Left elseif col == .colstart+.numcols-1 then call MultiboardSetItemIcon(mbi, .dir+.bartype+"R0"+.filetype) // Right else call MultiboardSetItemIcon(mbi, .dir+.bartype+"M0"+.filetype) // Middle endif call MultiboardReleaseItem(mbi) set .curfill[col] = 0 endif set col = col + 1 endloop set mbi = null endmethod method UpdateValue takes real newvalue, boolean update returns nothing if newvalue > .max then set .current = .max elseif newvalue < 0. then set .current = 0. else set .current = newvalue endif if update then call .UpdateBoard() endif endmethod method UpdateMaxValue takes real newvalue, boolean update returns nothing if newvalue < 1 then set .max = 1 else set .max = newvalue endif if .current > .max then set .current = .max endif if update then call .UpdateBoard() endif endmethod private method SetMultiboardBar takes nothing returns nothing local integer col = .colstart local integer end = col + .numcols local multiboarditem mbi loop exitwhen col >= end set mbi = MultiboardGetItem(.whichboard, .row, col) call MultiboardSetItemWidth(mbi, 0.01) call MultiboardSetItemStyle(mbi, false, true) call MultiboardReleaseItem(mbi) set col = col + 1 endloop set mbi = null endmethod endstruct public function CreateBartype takes string name, string filetype, string directory, integer divisions returns integer set Gcurrent = Gcurrent + 1 set Gbartype[Gcurrent] = name set Gfiletype[Gcurrent] = filetype set Gdir[Gcurrent] = directory set Gdivs[Gcurrent] = divisions return Gcurrent endfunction private function CreateNativeBartype takes integer bartype, string name, string filetype, string directory, integer divisions returns nothing if bartype > Gcurrent then set Gcurrent = bartype endif set Gbartype[bartype] = name set Gfiletype[bartype] = filetype set Gdir[bartype] = directory set Gdivs[bartype] = divisions endfunction private function InitMultibars takes nothing returns nothing // Set-up Native Bartypes call CreateNativeBartype(MULTIBAR_TYPE_HEALTH, "Health", ".tga", "war3mapImported\\", 8) call CreateNativeBartype(MULTIBAR_TYPE_MANA, "Mana", ".tga", "war3mapImported\\", 8) call CreateNativeBartype(MULTIBAR_TYPE_EXPERIENCE, "Experience", ".tga", "war3mapImported\\", 8) call CreateNativeBartype(MULTIBAR_TYPE_BUILD, "Build", ".tga", "war3mapImported\\", 8) call CreateNativeBartype(MULTIBAR_TYPE_CHUNK, "Chunk", ".tga", "war3mapImported\\", 2) call CreateNativeBartype(MULTIBAR_TYPE_RADIO, "Radio", ".tga", "war3mapImported\\", 8) call CreateNativeBartype(MULTIBAR_TYPE_MAC, "Mac", ".tga", "war3mapImported\\", 8) call CreateNativeBartype(MULTIBAR_TYPE_ORANGE, "Orange", ".tga", "war3mapImported\\", 2) call CreateNativeBartype(MULTIBAR_TYPE_HEARTS, "ZeldaHearts", ".tga", "war3mapImported\\", 4) call CreateNativeBartype(MULTIBAR_TYPE_HEARTS_UP, "ZeldaHeartsUp", ".tga", "war3mapImported\\", 4) call CreateNativeBartype(MULTIBAR_TYPE_MAGIC, "ZeldaMagic", ".tga", "war3mapImported\\", 8) endfunction endlibrary vJass MultibarHelper:library MultibarsHelper initializer InitMultibarsHelper requires Multibars globals // ==================== // PUBLIC CONSTANTS // ==================== // This constant can be modified // The speed at which the unit bars and labels refresh // Defualt = 0.035, should be somewhere between 0.10 and 0.02 // Lower == smoother but may cause some lag. // Higher == choppier but will reduce lag. constant real MULTIBAR_PERIOD = 0.035 // ==================== // END PUBLIC CONSTANTS // ==================== //Private Variables constant integer MULTIBAR_HELPER_HEALTH = 1 constant integer MULTIBAR_HELPER_MANA = 2 constant integer MULTIBAR_HELPER_EXPERIENCE = 3 private integer HelperTotal = 0 private MultibarHelper array HelperArray private integer array GXPForLevel private integer DummyHeroUnit = 'Hpal' endglobals private function GetMaxXP takes integer level returns integer local unit u set level = level + 1 if level == 1 then return 0 endif if GXPForLevel[level] == 0 then set u = CreateUnit(Player(12), DummyHeroUnit, 0., 0., 0.) call SetHeroLevel(u, level, false) set GXPForLevel[level] = GetHeroXP(u) call RemoveUnit(u) set u = null endif return GXPForLevel[level] endfunction struct MultibarHelper Multibar bar unit whichunit integer mtype integer row integer col boolean label integer slot static method create takes unit whichunit, multiboard whichboard, integer col, integer row, integer size, integer bartype, integer whichtype returns MultibarHelper local MultibarHelper u = MultibarHelper.allocate() set u.bar = Multibar.create(whichboard, col, row, size, 1, 1, bartype) set u.whichunit = whichunit set u.mtype = whichtype set u.label = false set HelperTotal = HelperTotal + 1 set HelperArray[HelperTotal] = u set u.slot = HelperTotal call u.UpdateParent(true) return u endmethod method AddLabel takes integer col, integer row, real width, integer red, integer green, integer blue, integer alpha, string icon returns nothing local multiboarditem mbi = MultiboardGetItem(.bar.whichboard, row, col) local string text set .row = row set .col = col set .label = true if icon != "" then call MultiboardSetItemStyle(mbi, true, true) call MultiboardSetItemIcon(mbi, icon) else call MultiboardSetItemStyle(mbi, true, false) endif call MultiboardSetItemWidth(mbi, width) call MultiboardSetItemValueColor(mbi, red, green, blue, alpha) call MultiboardReleaseItem(mbi) set mbi = null call .UpdateParent(true) endmethod method onDestroy takes nothing returns nothing set .whichunit = null call .bar.destroy() set HelperArray[.slot] = HelperArray[HelperTotal] set HelperTotal = HelperTotal - 1 endmethod method UpdateParent takes boolean always returns nothing local real value local real maxvalue local integer level local string text local multiboarditem mbi if .mtype == MULTIBAR_HELPER_HEALTH then set value = GetUnitState(.whichunit, UNIT_STATE_LIFE) set maxvalue = GetUnitState(.whichunit, UNIT_STATE_MAX_LIFE) elseif .mtype == MULTIBAR_HELPER_MANA then set value = GetUnitState(.whichunit, UNIT_STATE_MANA) set maxvalue = GetUnitState(.whichunit, UNIT_STATE_MAX_MANA) elseif .mtype == MULTIBAR_HELPER_EXPERIENCE then set level = GetHeroLevel(.whichunit) if GetMaxXP(level-1) == GetMaxXP(level) then // Max level set value = GetHeroXP(.whichunit) set maxvalue = value else set value = GetHeroXP(.whichunit) - GetMaxXP(level-1) set maxvalue = GetMaxXP(level)-GetMaxXP(level-1) endif endif if .bar.current != value or .bar.max != maxvalue or always then call .bar.UpdateMaxValue(maxvalue, false) call .bar.UpdateValue(value, true) if .label then set mbi = MultiboardGetItem(.bar.whichboard, .row, .col) if .mtype == MULTIBAR_HELPER_EXPERIENCE then set text = (I2S(GetHeroXP(.whichunit))+"/"+I2S(GetMaxXP(level))) else set text = (I2S(R2I(value+0.5))+"/"+I2S(R2I(maxvalue+0.5))) // 0.5 to round, like the health is shown in-game endif call MultiboardSetItemValue(mbi, text) call MultiboardReleaseItem(mbi) endif endif endmethod endstruct private function UnitBarController takes nothing returns nothing local integer i = 1 loop exitwhen i > HelperTotal call HelperArray[i].UpdateParent(false) set i = i + 1 endloop endfunction private function InitMultibarsHelper takes nothing returns nothing local unit u = CreateUnit(Player(12), DummyHeroUnit, 0., 0., 0.) // Preload First couple of XP Levels call SetHeroLevel(u, 2, false) set GXPForLevel[2] = GetHeroXP(u) call SetHeroLevel(u, 3, false) set GXPForLevel[3] = GetHeroXP(u) call SetHeroLevel(u, 4, false) set GXPForLevel[4] = GetHeroXP(u) call RemoveUnit(u) set u = null // Start update timer call TimerStart(CreateTimer(), MULTIBAR_PERIOD, true, function UnitBarController) endfunction endlibrary Jass Jass Read-Me:Multibars (Jass) Readme Created by Ammorth Compiled January 10th, 2008 This version does NOT Requires vJass If you want to use the vJass version, you can download it here: [url]www.wc3campaigns.net/showthread.php?t=98138[/url] PLEASE GIVE CREDIT IF YOU USE MULTIBARS OR ANY OF MY BARTYPES IN YOUR MAP! ================================== About ================================== Multibars is an easy way to create dynamic and sexy looking progress bars for multiboards. You can also create dynamic health, mana and experience bars with 1 line of code. Included in this version are 11 different bartypes: Name - Type (Description) Build - udg_MULTIBAR_TYPE_BUILD (based on the in-game construction bar) Health - udg_MULTIBAR_TYPE_HEALTH (A red health bar) Mana - udg_MULTIBAR_TYPE_MANA (A blue mana bar) Experience - udg_MULTIBAR_TYPE_EXPERIENCE (A purple experience bar) Chunk - udg_MULTIBAR_TYPE_CHUNK (A green bar that displays in chunks, rather than smoothly) Radio - udg_MULTIBAR_TYPE_RADIO (A radioactive [yellow and black] bar) Mac - udg_MULTIBAR_TYPE_MAC (resembles a Mac OS X loading bar) Orange - udg_MULTIBAR_TYPE_ORANGE (An orange bar that displays in chuncks, but chunks light up vs. appearing) Hearts - udg_MULTIBAR_TYPE_HEARTS (Hearts which display health based off of Zelda Ocarina of Time) Hearts Up - udg_MULTIBAR_TYPE_HEARTS_UP (Hearts with a white outline which display health, based off of Zelda Ocarina of Time) Magic - udg_MULTIBAR_TYPE_MAGIC (Green energy bar based off of Zelda Ocarina of Time) ================================== Installation ================================== 1) Copy the Multibars Library to your map script (copy the entire text, except for the bottem section mentioned, and paste it) 2) Copy the MultiBars Variables trigger to your map. Make sure you have "Automatically create unknown variables while pasting trigger data" before pasting, as this will create all required variables. Delete it after since it is of no use but to create the variables. 3) For each type of bar you want to use, import the entire folder to your map 4) If you want to use the dynamic health, mana and experience bars, copy the MutliBarsHelper library to the custom script section aswell Note: You must paste the MultibarsHelper library BELOW the Multibars library for it to compile correctly. A) Paste the MultiBars Helper Variables trigger to your map. Make sure you have "Automatically create unknown variables while pasting trigger data" before pasting, as this will create all required variables. Delete it after since it is of no use but to create the variables. B) Change the udg_MULTIBAR_PERIOD constant, found in the MultibarsHelper Init function, if you want the bars updating smoother or more efficiently. ================================== Usage ================================== Before doing anything, you must call: function InitMultibars takes nothing returns nothing to setup the system. If you are using MultibarHelpers then you must also call: function InitMultibarsHelper takes nothing returns nothing to setup the helper system. To create a MultiBar, call: function CreateMultibar takes multiboard whichboard, integer colstart, integer row, integer size, real maxval, real currentval, integer bartype returns integer - whichboard - the multiboard which the bar will be added to - colstart - which column do you want the bar to start on - row - which row do you want the bar on - size - how many columns do you want to use for your bar (max of 16, min of 2) - maxval - the maximum value of the bar - currentval - the starting value the bar will display - bartype - the bartype of the bar (Defualts are shown in the table above) The integer returned is the unique Multibar ID which is given to each multibar. You must keep track of these in variables if you wish to modify the bar later on. An example of calling this function would be: local integer mb = CreateMultibar(SomeMultiboard, 3, 0, 12, 50., 10., BAR_TYPE_BUILD) - This would create a Build Multibar on SomeMultiboard, at column 4, row 1, (remember, multiboards in jass start at 0,0) a size of 12, max value is 50, and the current value is 10. To update the value of the bar, call: Ufunction UpdateMultibarValue takes integer this, real newvalue, boolean update returns nothing - this - the unique ID of the multibar you want to update - newvalue - the new current value - update - if you want the bar to visually update to the new value An exmaple of calling this function would be: call UpdateMultibarValue(MyBar, 45., true) - This would update our Multibar with the ID stored in MyBar to a value of 45. It would also update the visual bar on the multiboard. function UpdateMultibarMaxValue takes integer this, real newvalue, boolean update returns nothing - this - the unique ID of the multibar you want to update - newvalue - the new maximum value - update - if you want the bar to visually update to the new value An exmaple of calling this function would be: call UpdateMultibarMaxValue(MyBar, 45., true) - This would update our Multibar with the ID stored in MyBar to a value of 45. It would also update the visual bar on the multiboard. - Note: if the maximum value becomes less than the current value, the current value will automatically equal the new max value. To create dynamic Health, Mana or Experience bars, make sure you have the MultiBarsHelper library installed then call: function CreateMultibarHelper takes unit whichunit, multiboard whichboard, integer col, integer row, integer size, integer bartype, integer whichtype returns integer - whichunit - the unit you want to create the bar for - whichboard - the multiboard which the bar will be added to - col - which column do you want the bar to start on - row - which row do you want the bar on - size - how many columns do you want to use for your bar (max of 16, min of 2) - bartype - the bartype of the bar (Defualts are shown in the table above) - whichtype - the type of the helper bar. - MULTIBAR_HELPER_HEALTH = health bar - MULTIBAR_HELPER_MANA = mana bar - MULTIBAR_HELPER_EXPERIENCE = experience bar The integer returned is the unique MultibarHelper ID which is given to each multibar. You must keep track of these in variables if you wish to modify the bar later on. THIS ID SHOULD BE NOT CONFUSED WITH THE MULTIBAR ID. Calling this function with a Multibar ID or vice-versa may cause serious problems. This function will create a helper bar that will automatically update itself, depending on the units status. An exmaple of calling this functions is: local integer h = CreateMultibarHelper(someunit, someboard, 0, 0, 14, MULTIBAR_TYPE_HEALTH, MULTIBAR_HELPER_HEALTH) - This function would create a health bar at col 0 row 0 on someboard, displaying the health of someunit. - The types used do not have to be the default types. For example, you can use MULTIBAR_TYPE_CHUNK for a health bar. If you want to create a label for your health, mana, or experience bar, call: function AddMultibarHelperLabel takes integer this, integer col, integer row, real width, integer red, integer green, integer blue, integer alpha, string icon returns nothing - this - the unique ID of the MultibarHelper you want to update - col - which column you want the label to be on - row - which row you want the label to be on - width - the width you want the label cell to be - red/green/blue/alpha - the color your want the label to be - icon - the icon you want beside the label (use "" for no icon) Labels can only be created for MultiBarHelpers bars (health, mana, experience). Attempting to create a label for a regular MultiBar bar will cause serious problems. Do not try it! An exmaple of calling this function would be: call AddMultibarHelperLabel(Helper, 0, 2, 0.07, 0, 0, 255, 255, "") - This will create a label for somebar at column 1, row 3, with a width of 7%, blue text and no icon. - Labels are automatically cleared from memory when the multibarhelper is destroyed. - You can only have 1 label per multibarhelper. When you are done with a MultiBar, dont forget to call: function DestroyMultibar takes integer this returns nothing - this - The unique ID of the multibar you want to destroy An example of calling this function would be: call DestroyMultibar(MyBar) - This will remove the Multibar from memory, but will not remove the visuals from the multiboard. To do this, either clear the multiboard or replace it with something else. - Always remember to destroy multibars when you are done with them. To Destroy MultibarHelpers, call: function DestroyMultibarHelper takes integer this returns nothing - this - the unique ID of the multibarhelper you want to destroy An example of calling this function would be: call DestroyMultibarHelper(MyHelper) - This will remove the MultibarHelper from memory, but will not remove the visuals from the multiboard. To do this, either clear the multiboard or replace it with something else. - Always remember to destroy multibarhelpers when you are done with them. NOTE: DO NOT CONFUSED MULTIBARS AND MULTIBARHELPERS! MIXING IDS UP WHILE CALLING THE WRONG FUNCTION WILL CREATE SERIOUS ERRORS. IE: DONT USE DestroyMultibarHelper TO DESTROY A MULTIBAR. IT WILL NOT WORK. DO NOT TRY IT! ================================== Customization ================================== MultiBars allows for custom bartypes that are created by others. The formats that are supported are .tga and .blp (same as WC3). To create a new bartype, it is important to understand what makes up a bar. Each bar consists of 3 different types: A left piece ---- A middle piece ---- A right piece Using all 3 pieces, the MultiBar script can place them side-by-side and simulate a progress bar. Now, to make the bars smoother, there are sub levels to each piece. These are called the divisions. In this demo map, 5 out of the 6 bartypes have a division of 8. This means that there are 8 images of varying "fill" to simulate a smooth fill. Counting up, from 1 to n (where n is complete fill and 1 is only 1/n fill) are how the divisions are arranged. Since an image is only 16x16, it is not smart to have more than 16 divisions (because they will not be noticed). The trick is to use the "cover fill" layer to cover up parts of the fill, then save. So if you have a bartype with a division of 16, you would cover up 1/16 of the fill at a time (1 pixel at 16x16) and then save. With a division of 4 you would cover up 1/4 of the fill at a time (4 pixels at 16x16) and then save. A visual representation would be: 1 2 3 4 5 6 7 8 [| ] [|| ] [||| ] [|||| ] [||||| ] [|||||| ] [||||||| ] [||||||||] Of course, on top of the divisions, there is an empty image, or 0. 0 [ ] This image is not counted in the divisions since it is required no matter how many divisions there are. DONT FORGET TO MAKE A 0 DIVISION! Each piece of each bartype requires the same number of divisions. Using both the divisions and the pieces, the MultiBar script can draw the progress bars on the multiboard. Creating the images may take some time. I have included the .ps (photoshop) document I used to create the bars in the demo. It contains all the fills and borders, arranged in groups. Hopefully this will help ease some pains. When saving the images, make sure to follow this name-scheme. [Bartype][piece][divisionN].[filetype] The bartype, is the name or type that you will use to distinguish your bartype from others The piece is the piece the image is(either "L" for left, "M" for middle or "R" for right) The divisionN is the division number (look at the visual representation above for more info) The filetype is either .tga or .blp (Most graphics programs save as .tga so I would recommend to use that. The ammount of file-size you save by compressing to .blp is small, since each image is only 1kb to begin with). Exmaple: Bartype is called "Crazy" The piece is the left ("L") This is the 4th Division("4") and it will be a .tga "CrazyL4.tga" Once you have made all your images, just stick them all in a folder and upload the entire folder to your map. There, you can leave them in the default directory or change the directory of the images. MAKE SURE, IF YOU CHANGE THE DIRECTORY, TO CHANGE ALL THE IMAGES OF THE SAME BARTYPE TO THE NEW DIRECTORY! To create a bartype for your custom bar, use the function: function CreateMultibarBartype takes string name, string filetype, string directory, integer divisions returns integer - name - the name of the bartype - filetype - the filetype of the images - directory - where the images can be found - divisions - the number of divisions the bar uses An exmaple of calling this function would be: set MyBar_NewBar = CreateMultibarBartype("NewBar", ".tga", "MyBars\\", 8) - MyBar_NewBar is a global integer you use to store the bartype in. - Thie function created a bartype called NewBar found in MyBars\ with a filetype of .tga and 8 divisions. Summary: Each image is 16x16 .tga or .blp There are 3 piece types: left ("L"), middle ("M") and right ("R"). Each piece has n divisions, which progress from 1 being 1/n fill to n being 100% fill. Each piece also has an empty image, called the 0 division. Images are saved as [Bartype][piece][divisionN].[filetype] Use CreateBartype() to create your custom bartypes ================================== Public Functions and Variables ================================== MultiBars ========= udg_MULTIBAR_TYPE_HEALTH = 1 udg_MULTIBAR_TYPE_MANA = 2 udg_MULTIBAR_TYPE_EXPERIENCE = 3 udg_MULTIBAR_TYPE_BUILD = 4 udg_MULTIBAR_TYPE_CHUNK = 5 udg_MULTIBAR_TYPE_RADIO = 6 udg_MULTIBAR_TYPE_MAC = 7 udg_MULTIBAR_TYPE_ORANGE = 8 udg_MULTIBAR_TYPE_HEARTS = 9 udg_MULTIBAR_TYPE_HEARTS_UP = 10 udg_MULTIBAR_TYPE_MAGIC = 11 function CreateMultibar takes multiboard whichboard, integer colstart, integer row, integer size, real maxval, real currentval, integer bartype returns integer function DestroyMultibar takes integer this returns nothing function UpdateMultibarValue takes integer this, real newvalue, boolean update returns nothing function UpdateMultibarMaxValue takes integer this, real newvalue, boolean update returns nothing function CreateMultibarBartype takes string name, string filetype, string directory, integer divisions returns integer function InitMultibars takes nothing returns nothing MultiBars Helper ================ udg_MULTIBAR_HELPER_HEALTH = 1 udg_MULTIBAR_HELPER_MANA = 2 udg_MULTIBAR_HELPER_EXPERIENCE = 3 udg_multibarhelper_MULTIBAR_PERIOD = 0.035 function CreateMultibarHelper takes unit whichunit, multiboard whichboard, integer col, integer row, integer size, integer bartype, integer whichtype returns integer function AddMultibarHelperLabel takes integer this, integer col, integer row, real width, integer red, integer green, integer blue, integer alpha, string icon returns nothing function DestroyMultibarHelper takes integer this returns nothing function InitMultibarsHelper takes nothing returns nothing ================================== Change-Log ================================== Version 1.20 - Created a non-vJass Version (this version) - Changed the MultibarHelper group to use an array rather than a list (improves performance) - Modfied some of the variable names to comply with GUI variable name lengths - Should have fixed the problem with both winning and losing - Fixed a minor leak when creating a label - Added 3 new bar types (Hearts, HeartsUp and Magic) Version 1.11 - Split MultiBars into two libraries (core and helper) - Decreased difficulty of survival game Version 1.10 - Added dynamic health, mana and experience bars - Changed the name of the library from "MultiBarsEngine" to "MultiBars" - Bartypes are now stored as integers and must be created - Added labels for dynamic health, mana and experience bars - Default bartypes now have constant pointers - Added CreateBartype() - Added "Mac" and "Orange" bartypes - Added a list of public functions and variables to the readme Version 1.00 - First Public Release - Includes the "Health", "Mana", "Experience", "Build", "Chunk" and "Radio" bartypes. End of Readme Jass Multibars:// Start of Multibar Library (GUI) // Paste this into the custom script section of your map function private_AllocateMultibarSlot takes nothing returns integer local integer this if udg_multibar_sdata_size > 0 then set udg_multibar_sdata_size = udg_multibar_sdata_size - 1 set this = udg_multibar_sdata_free[udg_multibar_sdata_size] else set udg_multibar_sdata_used = udg_multibar_sdata_used + 1 set this = udg_multibar_sdata_used endif if this > 511 then call BJDebugMsg("Exceeded number of Multibars Allowed at once! Make sure you are destroying un-used multibars!") return -1 else set udg_multibar_sdata_isUsed[this] = true return this endif endfunction function private_SetMultiboardBar takes integer this returns nothing local integer col = udg_multibar_s_colstart[this] local integer end = col + udg_multibar_s_numcols[this] local multiboarditem mbi loop exitwhen col >= end set mbi = MultiboardGetItem(udg_multibar_s_whichboard[this], udg_multibar_s_row[this], col) call MultiboardSetItemWidth(mbi, 0.01) call MultiboardSetItemStyle(mbi, false, true) call MultiboardReleaseItem(mbi) set col = col + 1 endloop set mbi = null endfunction function private_UpdateMultibar takes integer this returns nothing local real step = udg_multibar_s_max[this]/udg_multibar_s_numcols[this] local real step2 = step/udg_multibar_s_numdivs[this] local real val = udg_multibar_s_current[this] local multiboarditem mbi local integer col = udg_multibar_s_colstart[this] local integer num loop exitwhen val <= 0. if val >= step then if udg_multibar_s_curfill[this+col*511] != udg_multibar_s_numdivs[this] then // check if it requires an update set mbi = MultiboardGetItem(udg_multibar_s_whichboard[this], udg_multibar_s_row[this], col) if col == udg_multibar_s_colstart[this] then call MultiboardSetItemIcon(mbi, udg_multibar_s_dir[this]+udg_multibar_s_bartype[this]+"L"+I2S(udg_multibar_s_numdivs[this])+udg_multibar_s_filetype[this]) // Left elseif col == udg_multibar_s_colstart[this]+udg_multibar_s_numcols[this]-1 then call MultiboardSetItemIcon(mbi, udg_multibar_s_dir[this]+udg_multibar_s_bartype[this]+"R"+I2S(udg_multibar_s_numdivs[this])+udg_multibar_s_filetype[this]) // Right else call MultiboardSetItemIcon(mbi, udg_multibar_s_dir[this]+udg_multibar_s_bartype[this]+"M"+I2S(udg_multibar_s_numdivs[this])+udg_multibar_s_filetype[this]) // Middle endif call MultiboardReleaseItem(mbi) set udg_multibar_s_curfill[this+col*511] = udg_multibar_s_numdivs[this] endif set val = val - step else set num = R2I((val/step2)+0.5) if udg_multibar_s_curfill[this+col*511] != num then // check if it requires an update set mbi = MultiboardGetItem(udg_multibar_s_whichboard[this], udg_multibar_s_row[this], col) if col == udg_multibar_s_colstart[this] then call MultiboardSetItemIcon(mbi, udg_multibar_s_dir[this]+udg_multibar_s_bartype[this]+"L"+I2S(num)+udg_multibar_s_filetype[this]) // Left elseif col == udg_multibar_s_colstart[this]+udg_multibar_s_numcols[this]-1 then call MultiboardSetItemIcon(mbi, udg_multibar_s_dir[this]+udg_multibar_s_bartype[this]+"R"+I2S(num)+udg_multibar_s_filetype[this]) // Right else call MultiboardSetItemIcon(mbi, udg_multibar_s_dir[this]+udg_multibar_s_bartype[this]+"M"+I2S(num)+udg_multibar_s_filetype[this]) // Middle endif call MultiboardReleaseItem(mbi) set udg_multibar_s_curfill[this+col*511] = num endif set val = 0. endif set col = col + 1 endloop loop exitwhen col >= udg_multibar_s_colstart[this] + udg_multibar_s_numcols[this] if udg_multibar_s_curfill[this+col*511] != 0 then // check if it requires an update set mbi = MultiboardGetItem(udg_multibar_s_whichboard[this], udg_multibar_s_row[this], col) if col == udg_multibar_s_colstart[this] then call MultiboardSetItemIcon(mbi, udg_multibar_s_dir[this]+udg_multibar_s_bartype[this]+"L0"+udg_multibar_s_filetype[this]) // Left elseif col == udg_multibar_s_colstart[this]+udg_multibar_s_numcols[this]-1 then call MultiboardSetItemIcon(mbi, udg_multibar_s_dir[this]+udg_multibar_s_bartype[this]+"R0"+udg_multibar_s_filetype[this]) // Right else call MultiboardSetItemIcon(mbi, udg_multibar_s_dir[this]+udg_multibar_s_bartype[this]+"M0"+udg_multibar_s_filetype[this]) // Middle endif call MultiboardReleaseItem(mbi) set udg_multibar_s_curfill[this+col*511] = 0 endif set col = col + 1 endloop set mbi = null endfunction function CreateMultibar takes multiboard whichboard, integer colstart, integer row, integer size, real maxval, real currentval, integer bartype returns integer local integer this = private_AllocateMultibarSlot() local integer i = 0 if this == -1 then return -1 endif call BJDebugMsg(I2S(this)) set udg_multibar_s_whichboard[this] = whichboard set udg_multibar_s_row[this] = row set udg_multibar_s_colstart[this] = colstart set udg_multibar_s_numcols[this] = size set udg_multibar_s_max[this] = maxval set udg_multibar_s_current[this] = currentval set udg_multibar_s_numdivs[this] = udg_multibar_Gdivs[bartype] set udg_multibar_s_bartype[this] = udg_multibar_Gbartype[bartype] set udg_multibar_s_filetype[this] = udg_multibar_Gfiletype[bartype] set udg_multibar_s_dir[this] = udg_multibar_Gdir[bartype] loop exitwhen i > 15 set udg_multibar_s_curfill[this+i*511] = -1 set i = i + 1 endloop call private_SetMultiboardBar(this) call private_UpdateMultibar(this) return this endfunction function DestroyMultibar takes integer this returns nothing if udg_multibar_sdata_isUsed[this] then set udg_multibar_sdata_free[udg_multibar_sdata_size] = this set udg_multibar_sdata_size = udg_multibar_sdata_size + 1 set udg_multibar_sdata_isUsed[this] = false // set values (onDestroy) set udg_multibar_s_whichboard[this] = null else call BJDebugMsg("Attempting to destroy a null multibar!") endif endfunction function UpdateMultibarValue takes integer this, real newvalue, boolean update returns nothing if newvalue > udg_multibar_s_max[this] then set udg_multibar_s_current[this] = udg_multibar_s_max[this] elseif newvalue < 0. then set udg_multibar_s_current[this] = 0. else set udg_multibar_s_current[this] = newvalue endif if update then call private_UpdateMultibar(this) endif endfunction function UpdateMultibarMaxValue takes integer this, real newvalue, boolean update returns nothing if newvalue < 1 then set udg_multibar_s_max[this] = 1 else set udg_multibar_s_max[this] = newvalue endif if udg_multibar_s_current[this] > udg_multibar_s_max[this] then set udg_multibar_s_current[this] = udg_multibar_s_max[this] endif if update then call private_UpdateMultibar(this) endif endfunction function CreateMultibarBartype takes string name, string filetype, string directory, integer divisions returns integer set udg_multibar_Gcurrent = udg_multibar_Gcurrent + 1 set udg_multibar_Gbartype[udg_multibar_Gcurrent] = name set udg_multibar_Gfiletype[udg_multibar_Gcurrent] = filetype set udg_multibar_Gdir[udg_multibar_Gcurrent] = directory set udg_multibar_Gdivs[udg_multibar_Gcurrent] = divisions return udg_multibar_Gcurrent endfunction function private_CreateNativeMultibarBartype takes integer bartype, string name, string filetype, string directory, integer divisions returns nothing if bartype > udg_multibar_Gcurrent then set udg_multibar_Gcurrent = bartype endif set udg_multibar_Gbartype[bartype] = name set udg_multibar_Gfiletype[bartype] = filetype set udg_multibar_Gdir[bartype] = directory set udg_multibar_Gdivs[bartype] = divisions endfunction function InitMultibars takes nothing returns nothing // Set-up Native Bartypes set udg_MULTIBAR_TYPE_HEALTH = 1 set udg_MULTIBAR_TYPE_MANA = 2 set udg_MULTIBAR_TYPE_EXPERIENCE = 3 set udg_MULTIBAR_TYPE_BUILD = 4 set udg_MULTIBAR_TYPE_CHUNK = 5 set udg_MULTIBAR_TYPE_RADIO = 6 set udg_MULTIBAR_TYPE_MAC = 7 set udg_MULTIBAR_TYPE_ORANGE = 8 set udg_MULTIBAR_TYPE_HEARTS = 9 set udg_MULTIBAR_TYPE_HEARTS_UP = 10 set udg_MULTIBAR_TYPE_MAGIC = 11 call private_CreateNativeMultibarBartype(udg_MULTIBAR_TYPE_HEALTH, "Health", ".tga", "war3mapImported\\", 8) call private_CreateNativeMultibarBartype(udg_MULTIBAR_TYPE_MANA, "Mana", ".tga", "war3mapImported\\", 8) call private_CreateNativeMultibarBartype(udg_MULTIBAR_TYPE_EXPERIENCE, "Experience", ".tga", "war3mapImported\\", 8) call private_CreateNativeMultibarBartype(udg_MULTIBAR_TYPE_BUILD, "Build", ".tga", "war3mapImported\\", 8) call private_CreateNativeMultibarBartype(udg_MULTIBAR_TYPE_CHUNK, "Chunk", ".tga", "war3mapImported\\", 2) call private_CreateNativeMultibarBartype(udg_MULTIBAR_TYPE_RADIO, "Radio", ".tga", "war3mapImported\\", 8) call private_CreateNativeMultibarBartype(udg_MULTIBAR_TYPE_MAC, "Mac", ".tga", "war3mapImported\\", 8) call private_CreateNativeMultibarBartype(udg_MULTIBAR_TYPE_ORANGE, "Orange", ".tga", "war3mapImported\\", 2) call private_CreateNativeMultibarBartype(udg_MULTIBAR_TYPE_HEARTS, "ZeldaHearts", ".tga", "war3mapImported\\", 4) call private_CreateNativeMultibarBartype(udg_MULTIBAR_TYPE_HEARTS_UP, "ZeldaHeartsUp", ".tga", "war3mapImported\\", 4) call private_CreateNativeMultibarBartype(udg_MULTIBAR_TYPE_MAGIC, "ZeldaMagic", ".tga", "war3mapImported\\", 8) endfunction //End of Multibar Library // DO NOT COPY THIS BELOW! IT IS ONLY REQUIRED WHEN THE SCRIPT EXISTS AS A TRIGGER function InitTrig_MultiBars takes nothing returns nothing endfunction Jass MultibarHelper:// Start of MultibarHelper Library (GUI) // Paste this into the custom script section of your map, AFTER the Multibar Library // THIS REQUIRES THE MULTBAR LIBRARY function private_MultibarHelperGetMaxXP takes integer level returns integer local unit u set level = level + 1 if level == 1 then return 0 endif if udg_multibarhelper_GXPForLevel[level] == 0 then set u = CreateUnit(Player(12), udg_multibarhelper_DummyHeroUnit, 0., 0., 0.) call SetHeroLevel(u, level, false) set udg_multibarhelper_GXPForLevel[level] = GetHeroXP(u) call RemoveUnit(u) set u = null endif return udg_multibarhelper_GXPForLevel[level] endfunction function private_AllocateMultibarHelperSlot takes nothing returns integer local integer this if udg_multibarhelper_sdata_size > 0 then set udg_multibarhelper_sdata_size = udg_multibarhelper_sdata_size - 1 set this = udg_multibarhelper_sdata_free[udg_multibarhelper_sdata_size] else set udg_multibarhelper_sdata_used = udg_multibarhelper_sdata_used + 1 set this = udg_multibarhelper_sdata_used endif if this > 8191 then call BJDebugMsg("Exceeded number of Multibar Helpers Allowed at once! Make sure you are destroying un-used multibar helpers!") return -1 else set udg_multibarhelper_sdata_isUsed[this] = true return this endif endfunction function private_MultibarHelperUpdateParent takes integer this, boolean always returns nothing local real value local real maxvalue local integer level local string text local multiboarditem mbi if udg_multibarhelper_s_mtype[this] == udg_MULTIBAR_HELPER_HEALTH then set value = GetUnitState(udg_multibarhelper_s_whichunit[this], UNIT_STATE_LIFE) set maxvalue = GetUnitState(udg_multibarhelper_s_whichunit[this], UNIT_STATE_MAX_LIFE) elseif udg_multibarhelper_s_mtype[this] == udg_MULTIBAR_HELPER_MANA then set value = GetUnitState(udg_multibarhelper_s_whichunit[this], UNIT_STATE_MANA) set maxvalue = GetUnitState(udg_multibarhelper_s_whichunit[this], UNIT_STATE_MAX_MANA) elseif udg_multibarhelper_s_mtype[this] == udg_MULTIBAR_HELPER_EXPERIENCE then set level = GetHeroLevel(udg_multibarhelper_s_whichunit[this]) if private_MultibarHelperGetMaxXP(level-1) == private_MultibarHelperGetMaxXP(level) then // Max level set value = GetHeroXP(udg_multibarhelper_s_whichunit[this]) set maxvalue = value else set value = GetHeroXP(udg_multibarhelper_s_whichunit[this]) - private_MultibarHelperGetMaxXP(level-1) set maxvalue = private_MultibarHelperGetMaxXP(level)-private_MultibarHelperGetMaxXP(level-1) endif endif if udg_multibar_s_current[udg_multibarhelper_s_bar[this]] != value or udg_multibar_s_max[udg_multibarhelper_s_bar[this]] != maxvalue or always then call UpdateMultibarMaxValue(udg_multibarhelper_s_bar[this], maxvalue, false) call UpdateMultibarValue(udg_multibarhelper_s_bar[this], value, true) if udg_multibarhelper_s_label[this] then set mbi = MultiboardGetItem(udg_multibar_s_whichboard[udg_multibarhelper_s_bar[this]], udg_multibarhelper_s_row[this], udg_multibarhelper_s_col[this]) if udg_multibarhelper_s_mtype[this] == udg_MULTIBAR_HELPER_EXPERIENCE then set text = (I2S(GetHeroXP(udg_multibarhelper_s_whichunit[this]))+"/"+I2S(private_MultibarHelperGetMaxXP(level))) else set text = (I2S(R2I(value+0.5))+"/"+I2S(R2I(maxvalue+0.5))) // 0.5 to round, like the health is shown in-game endif call MultiboardSetItemValue(mbi, text) call MultiboardReleaseItem(mbi) endif endif set mbi = null endfunction function CreateMultibarHelper takes unit whichunit, multiboard whichboard, integer col, integer row, integer size, integer bartype, integer whichtype returns integer local integer this = private_AllocateMultibarHelperSlot() if this == -1 then return -1 endif set udg_multibarhelper_s_bar[this] = CreateMultibar(whichboard, col, row, size, 1, 1, bartype) set udg_multibarhelper_s_whichunit[this] = whichunit set udg_multibarhelper_s_mtype[this] = whichtype set udg_multibarhelper_s_label[this] = false set udg_multibarhelper_HelperTotal = udg_multibarhelper_HelperTotal + 1 set udg_multibarhelper_HelperArray[udg_multibarhelper_HelperTotal] = this set udg_multibarhelper_s_slot[this] = udg_multibarhelper_HelperTotal call private_MultibarHelperUpdateParent(this, true) return this endfunction function AddMultibarHelperLabel takes integer this, integer col, integer row, real width, integer red, integer green, integer blue, integer alpha, string icon returns nothing local multiboarditem mbi = MultiboardGetItem(udg_multibar_s_whichboard[udg_multibarhelper_s_bar[this]], row, col) local string text set udg_multibarhelper_s_row[this] = row set udg_multibarhelper_s_col[this] = col set udg_multibarhelper_s_label[this] = true if icon != "" then call MultiboardSetItemStyle(mbi, true, true) call MultiboardSetItemIcon(mbi, icon) else call MultiboardSetItemStyle(mbi, true, false) endif call MultiboardSetItemWidth(mbi, width) call MultiboardSetItemValueColor(mbi, red, green, blue, alpha) call MultiboardReleaseItem(mbi) set mbi = null call private_MultibarHelperUpdateParent(this, true) endfunction function DestroyMultibarHelper takes integer this returns nothing set udg_multibarhelper_s_whichunit[this] = null call DestroyMultibar(udg_multibarhelper_s_bar[this]) set udg_multibarhelper_HelperArray[udg_multibarhelper_s_slot[this]] = udg_multibarhelper_HelperArray[udg_multibarhelper_HelperTotal] set udg_multibarhelper_HelperTotal = udg_multibarhelper_HelperTotal - 1 endfunction function private_MultibarHelperController takes nothing returns nothing local integer i = 1 loop exitwhen i > udg_multibarhelper_HelperTotal call private_MultibarHelperUpdateParent(udg_multibarhelper_HelperArray[i], true) set i = i + 1 endloop endfunction function InitMultibarsHelper takes nothing returns nothing local unit u set udg_MULTIBAR_HELPER_HEALTH = 1 set udg_MULTIBAR_HELPER_MANA = 2 set udg_MULTIBAR_HELPER_EXPERIENCE = 3 set udg_multibarhelper_MULTIBAR_PERIOD = 0.035 // You can change this value to improve performance or improve update rate. (Default : 0.035 ) set udg_multibarhelper_DummyHeroUnit = 'Hpal' set u = CreateUnit(Player(12), udg_multibarhelper_DummyHeroUnit, 0., 0., 0.) // Preload First couple of XP Levels call SetHeroLevel(u, 2, false) set udg_multibarhelper_GXPForLevel[2] = GetHeroXP(u) call SetHeroLevel(u, 3, false) set udg_multibarhelper_GXPForLevel[3] = GetHeroXP(u) call SetHeroLevel(u, 4, false) set udg_multibarhelper_GXPForLevel[4] = GetHeroXP(u) call RemoveUnit(u) set u = null // Start update timer call TimerStart(CreateTimer(), udg_multibarhelper_MULTIBAR_PERIOD, true, function private_MultibarHelperController) endfunction //End of Multibar Helper Library // DO NOT COPY THIS BELOW! IT IS ONLY REQUIRED WHEN THE SCRIPT EXISTS AS A TRIGGER function InitTrig_MultiBars_Helper takes nothing returns nothing endfunction |
| 12-05-2007, 07:50 AM | #2 |
Looks damned sweet. Does it automatically update Health, Mana and Experience bars or do I have to manually do so? I'm hoping it's automatic.. |
| 12-05-2007, 09:34 AM | #3 |
im gonna use this for ET2 |
| 12-05-2007, 02:18 PM | #4 |
Currently, all you have to do is call method UpdateValue takes real newvalue, boolean update returns nothing to update it, but I can include linking bars to events (unit health, mana, exp, etc) so then the lazy people don't even need to call it. |
| 12-05-2007, 04:32 PM | #5 |
Cool! I challenge you to make verticle ones as well. |
| 12-05-2007, 10:16 PM | #6 |
Vertical bars are going to be tricky since there is a small gap between the icons, height-wise. It is possible, but it would look funny with the gaps. |
| 12-06-2007, 01:28 AM | #7 |
Lovely!! This resource would be almost perfect if you could add to the system a way to set a label for each bar, so you can give more customization to this system. If you do that I'll approve it at once. |
| 12-06-2007, 02:17 AM | #8 |
Explain what you mean by labels? The new version is going to have unit bars (bars the update automatically for unit health, mana and exp), and bars are now truly classified as bartypes. You create a bartype with function CreateBarType takes string name, string filetype, string directory, integer divisions returns integer and then use that integer as your type when you create new bars. |
| 12-06-2007, 08:17 AM | #9 |
I'm guessing he means put some text either on the bar or besides the bar. |
| 12-06-2007, 08:27 AM | #10 |
I'm gonna wait on the new version ^^ I pray you could code linked experience bars, I don't know how to get the max exp needed for the next level and I think there's no GetExpRequiredToLevel(unit) function :P |
| 12-06-2007, 11:29 AM | #11 | |
Quote:
|
| 12-06-2007, 03:50 PM | #12 | ||
Quote:
Quote:
By the way, this is a cute system. |
| 12-06-2007, 10:49 PM | #13 | |
Quote:
Actually, the new (yet to be released) version does detect the XP required for the next upgrade without changing any constants (except for a max level). The idea revolves around a unit who has their level set will have the minimum XP to get to that level, which is the required XP for that particular level. JASS:globals private integer array GXPForLevel private integer DummyHeroUnit = 'Hpal' endglobals private function GetMaxXP takes integer level returns integer local unit u set level = level + 1 if level <= 1 then return 0 endif if GXPForLevel[level] == 0 then set u = CreateUnit(Player(12), DummyHeroUnit, 0., 0., 0.) call SetHeroLevel(u, level, false) set GXPForLevel[level] = GetHeroXP(u) call RemoveUnit(u) set u = null endif return GXPForLevel[level] endfunction This function takes the current level of the unit and returns the XP required for the next level-up (level 1, returns level 2 requirement). A level less than 2 requires 0 XP. I think I will include labels, only because the health, mana, and XP bars are already automatic. It would be a waste of calculations for a person to then find the values outside the system and update the board. Look for the new version some-time tonight or tomorrow evening. If you have any ideas for bartypes, tell me now, and I may include them in the next release. |
| 12-06-2007, 11:33 PM | #14 |
very unique and will greatly benefit the warcraft modding community. +rep. |
| 12-07-2007, 06:35 AM | #15 | |
Quote:
|
