Name | Type | is_array | initial_value |
Ability | ability | No | |
AbilityCode | abilcode | No | |
AddNextCar_Clock | timer | No | |
AddNextCar_Group | group | No | |
Admin | string | Yes | |
AdminCounter | integer | No | |
AdminGroup | force | No | |
AllowCamLock | boolean | No | |
AllowChangeColor | boolean | No | |
AllowFlagClick | boolean | No | |
Angle_Save | real | No | |
Author | string | No | |
AutoRevive | boolean | No | |
Boolean | boolean | No | |
Boost_Count | integer | Yes | |
Boost_Effect | effect | Yes | |
Boost_Rect | rect | No | |
CamLock | boolean | Yes | |
CarChange_Ability | abilcode | Yes | |
CarChange_Index | integer | Yes | |
CarChange_Max | integer | No | |
CarType | unitcode | Yes | |
Cata_Amount | integer | No | |
Cata_Point | location | Yes | |
Cata_Unit | unit | Yes | |
Checkpoint_Rect | rect | No | |
Circle | unit | Yes | |
ClickCounter | integer | Yes | |
ClickDistance | real | Yes | |
ClickDistanceAverage | integer | Yes | |
CloseClick_ShowRadius | boolean | No | |
CloseClickRange_Mirror | real | No | |
CloseClickRange_Normal | real | No | |
Coin | unit | Yes | |
Coins_Alive | real | No | |
Color | string | Yes | |
CP_HiddenItems | item | Yes | |
CP_HiddenItemsIndex | integer | No | |
CP_Item | item | No | |
CP_Point | location | No | |
CP_PointIsWalkable | boolean | No | |
CP_Rect | rect | No | |
CV | integer | No | |
Data_Path | string | No | |
Death_Bool | boolean | Yes | |
DeathCounter | integer | Yes | |
DeathCounterLevel | integer | Yes | |
DeathCounterTotal | integer | Yes | |
DeathHero | unit | Yes | |
Destructable_Counter | integer | No | |
DistanceTravelled | integer | Yes | |
ENEMY | player | No | |
External_Position | location | No | |
Finish | unit | Yes | |
Finish_Group | group | No | |
Finish_Level_Event | real | No | |
FinishRegion | rect | No | |
FinishTrigger | trigger | No | |
Flag | unit | Yes | |
FlagIsVisible | boolean | Yes | |
FloatingText_Enabled | boolean | Yes | |
FloatingText_PlayerName | texttag | Yes | |
Hashtable | hashtable | No | |
Hero | unit | Yes | |
HeroColor_Index | integer | Yes | |
Heroes_Alive | real | No | |
IcePriest_Amount | integer | No | |
IcePriest_Point | location | Yes | |
IcePriest_Unit | unit | Yes | |
IncreaseSpeed_Boost | real | No | |
IncreaseSpeed_Wave | real | No | |
InitialPlayerName | string | Yes | |
Int | integer | No | |
Int_2 | integer | No | |
Int_3 | integer | No | |
Int_4 | integer | No | |
Item | item | No | |
KeyAmount | integer | No | |
KeyItem | item | Yes | |
KeyPoint | location | Yes | |
LastSlideableTerrainType | terraintype | Yes | |
Level | rect | Yes | |
Level_Amount | integer | No | |
Level_Destructable | destructable | Yes | |
Level_Int | integer | No | |
Level_Lightning | lightning | Yes | |
Level_nr | integer | No | |
Level_Unit | unit | Yes | |
LevelBounds | rect | No | |
LevelFinishedCounter | integer | Yes | |
LevelWeatherEffect | weathereffect | No | |
Lightning_Counter | integer | No | |
LightningUnit1 | unit | No | |
LightningUnit2 | unit | No | |
LoadedPlayerName | string | Yes | |
MapName | string | No | |
MAX_PLAYER_POSSIBLE | integer | No | |
MyResourceBarCount | integer | No | |
MyResourceBarIcons | imagefile | Yes | |
MyResourceBarTooltipText | string | Yes | |
MyResourceBarTooltipTitle | string | Yes | |
MyResourceValue | string | Yes | |
Orb | unit | Yes | |
Orb_Amount | integer | No | |
Orb_Angle | real | Yes | |
Orb_Centre | location | Yes | |
Orb_Distance | real | Yes | |
Orb_Intern_Angle | real | No | |
Orb_Pt | location | Yes | |
Orb_Speed | real | Yes | |
Player | player | No | |
Player_Amount | real | No | |
PlayerIndex | integer | No | |
PlayerScore_Current | integer | Yes | |
PlayerScore_Loaded | integer | Yes | |
PT | location | No | |
PT_2 | location | No | |
PT_3 | location | No | |
PT_Level_6_Circle | location | Yes | |
RangeIndicator_AmountOfUnits | integer | No | |
RangeIndicator_AngleOffset | real | No | |
RangeIndicator_Enabled | boolean | Yes | |
RangeIndicator_Unit | unit | Yes | |
Rank | integer | Yes | |
RankPath | string | No | |
Real | real | No | |
Real2 | real | No | |
Region | rect | No | |
RemoveBuff_Clock | timer | No | |
SaveCounter | integer | Yes | |
Select_Bool | boolean | Yes | |
Share_Bool | boolean | Yes | |
Share_Text | string | No | |
Slide_Order | ordercode | No | |
SlidingSpeed | real | Yes | |
SlidingSpeed_Default | real | No | |
Snow_Count | integer | Yes | |
Spawn | location | No | |
Spawn_Int | location | Yes | |
Speed_Max | real | Yes | |
Speed_Min | real | Yes | |
SpeedIce_ExtraSpeed | real | No | |
Spider_Bool | boolean | Yes | |
Spider_Effect | effect | Yes | |
Splash_Amount | integer | No | |
Splash_Pt | location | Yes | |
Splash_Unit | unit | Yes | |
Start_Level_Event | real | No | |
StartNewLevel | real | No | |
String | string | No | |
String2 | string | No | |
Terrain_Type | terraintype | Yes | |
TerrainMatch | boolean | No | |
TerrainType | terraintype | No | |
TomeOfRetraining_Amount | integer | No | |
Transparency_Percent | real | No | |
Transparency_Range | real | No | |
Unit | unit | No | |
Unit_Int | integer | No | |
UnitGroup | group | No | |
UnitStatIcon | imagefile | Yes | |
Used_Speed | real | Yes | |
UseRankingBoard | boolean | No | |
UseTemplatePath | boolean | No | |
Version | string | No | |
X_More | real | Yes | |
X_Save | real | Yes | |
Y_More | real | Yes | |
Y_Save | real | Yes | |
Zoom_Time | real | No | |
Zoom_Value | real | No |
struct LevelHandler extends array
// public static Level CurrentLevel = 0
private static string array p_rankIcon
private static string array p_rankTitle
private static string array p_rankColor
private static string p_levelName
private static integer p_levelRank
private static timer p_clock
private static constant integer P_RANK_AMOUNT = 6
public static method getRankAmount takes nothing returns integer
return P_RANK_AMOUNT
endmethod
public static method getValidRank takes integer rank returns integer
if ( rank <= 0 or rank >= P_RANK_AMOUNT ) then
set rank = 0
endif
return rank
endmethod
public static method getRankColor takes integer rank returns string
return p_rankColor[getValidRank(rank)]
endmethod
public static method getRankIcon takes integer rank returns string
return p_rankIcon[getValidRank(rank)]
endmethod
public static method getRankTitle takes integer rank returns string
return p_rankTitle[getValidRank(rank)]
endmethod
public static method getPlayerRankIcon takes player p returns string
return getRankIcon(udg_Rank[GetConvertedPlayerId(p)])
endmethod
/*
private static method startNextLevel takes nothing returns nothing
if ( p_levelRank == 0 ) then
set CurrentLevel = Peon.create()
elseif ( p_levelRank == 1 ) then
set CurrentLevel = Grunt.create()
elseif ( p_levelRank == 2 ) then
set CurrentLevel = Headhunter.create()
elseif ( p_levelRank == 3 ) then
set CurrentLevel = Raider.create()
elseif ( p_levelRank == 4 ) then
set CurrentLevel = Tauren.create()
elseif ( p_levelRank == 5 ) then
set CurrentLevel = Blademaster.create()
endif
set p_levelName = getRankTitle(p_levelRank)
call CurrentLevel.start()
endmethod
private static method endCurrentLevel takes nothing returns nothing
if ( CurrentLevel != 0 ) then
set udg_Unit = null
call CurrentLevel.end()
endif
endmethod
public static method StartNewLevelByRank takes integer rank returns nothing
set p_levelRank = getValidRank(rank)
call endCurrentLevel()
call TimerStart(p_clock, 2, false, function thistype.startNextLevel)
endmethod
private static method getRankByTitle takes string name returns integer
local string title
local integer rank = 0
set name = StringCase(name, false)
loop
exitwhen ( rank >= P_RANK_AMOUNT )
set title = StringCase(getRankTitle(rank), false)
exitwhen ( name == title )
set rank = rank + 1
endloop
return getValidRank(rank)
endmethod
public static method StartNewLevelByName takes string name returns nothing
call StartNewLevelByRank(getRankByTitle(name))
endmethod
public static method StartNextLevel takes nothing returns nothing
call StartNewLevelByRank(p_levelRank + 1)
endmethod
private static method onMessageByName takes nothing returns nothing
local string chat = GetEventPlayerChatString()
local string name = SubString(chat, 1, StringLength(chat))
call StartNewLevelByName(name)
endmethod
private static method onMessageByRank takes nothing returns nothing
local string chat = GetEventPlayerChatString()
local integer rank = S2I(SubString(chat, 6, StringLength(chat)))
call StartNewLevelByRank(rank)
endmethod
private static method init takes nothing returns nothing
local integer i = 0
local trigger t_name = CreateTrigger()
local trigger t_rank = CreateTrigger()
local player p
loop
exitwhen i >= udg_MAX_PLAYER_POSSIBLE
set p = Player(i)
call TriggerRegisterPlayerChatEvent(t_name, p, "-peon", true )
call TriggerRegisterPlayerChatEvent(t_name, p, "-grunt", true )
call TriggerRegisterPlayerChatEvent(t_name, p, "-headhunter", true )
call TriggerRegisterPlayerChatEvent(t_name, p, "-raider", true )
call TriggerRegisterPlayerChatEvent(t_name, p, "-tauren", true )
call TriggerRegisterPlayerChatEvent(t_name, p, "-blademaster", true )
call TriggerRegisterPlayerChatEvent(t_rank, p, "-rank 0", true )
call TriggerRegisterPlayerChatEvent(t_rank, p, "-rank 1", true )
call TriggerRegisterPlayerChatEvent(t_rank, p, "-rank 2", true )
call TriggerRegisterPlayerChatEvent(t_rank, p, "-rank 3", true )
call TriggerRegisterPlayerChatEvent(t_rank, p, "-rank 4", true )
call TriggerRegisterPlayerChatEvent(t_rank, p, "-rank 5", true )
set i = i + 1
endloop
call TriggerAddAction(t_name, function thistype.onMessageByName)
call TriggerAddAction(t_rank, function thistype.onMessageByRank)
endmethod
*/
private static method onInit takes nothing returns nothing
set p_rankIcon[0] = "ReplaceableTextures\\CommandButtons\\BTNPeon.tga"
set p_rankIcon[1] = "ReplaceableTextures\\CommandButtons\\BTNGrunt.tga"
set p_rankIcon[2] = "ReplaceableTextures\\CommandButtons\\BTNHeadhunter.tga"
set p_rankIcon[3] = "ReplaceableTextures\\CommandButtons\\BTNRaider.tga"
set p_rankIcon[4] = "ReplaceableTextures\\CommandButtons\\BTNTauren.tga"
set p_rankIcon[5] = "ReplaceableTextures\\CommandButtons\\BTNHeroBlademaster.tga"
set p_rankTitle[0] = "Peon"
set p_rankTitle[1] = "Grunt"
set p_rankTitle[2] = "Headhunter"
set p_rankTitle[3] = "Raider"
set p_rankTitle[4] = "Tauren"
set p_rankTitle[5] = "Blademaster"
// https://www.reddit.com/r/discordapp/comments/849bxc/what_are_the_hex_values_of_all_the_default_role/
// https://imgur.com/t/discord/f7xq1du
set p_rankColor[0] = "|cff95a5a6" // light grey
set p_rankColor[1] = "|cff2ecc71" // light green
set p_rankColor[2] = "|cff3498db" // light blue
set p_rankColor[3] = "|cff9b59b6" // light purple
set p_rankColor[4] = "|cffcc7900" // light orange
set p_rankColor[5] = "|cfff93a2f" // light red
set p_levelName = ""
set p_levelRank = 0
set p_clock = CreateTimer()
//call TimerStart(p_clock, 0, false, function thistype.init)
endmethod
endstruct
struct Board extends array
static Multiboard Board
static integer array playerRow
static method update takes player p returns nothing
local integer row = playerRow[GetPlayerId(p)]
local integer rank = udg_Rank[GetPlayerId(p) + 1]
set Board[row][0].text = GetPlayerName(p)
set Board[row][0].icon = LevelHandler.getRankIcon(rank)
set Board[row][1].text = LevelHandler.getRankColor(rank) + LevelHandler.getRankTitle(rank) + "|r"
endmethod
static method NewBoard takes nothing returns nothing
local integer i = 0
local integer currentRow
local integer currentPlayerAmount = User.AmountPlaying
local player p
if ( not udg_UseRankingBoard ) then
return
endif
if Board != 0 then
call Board.destroy()
endif
set Board = Multiboard.create(currentPlayerAmount + 2, 2)
set Board.title = "Ranking Board"
call Board.setStyle(true, false)
call Board.column[0].setStyle(true, true)
call Board.row[0].setStyle(true, false)
call Board.row[1].setStyle(true, false)
set Board.column[0].width = 0.15
set Board.column[1].width = 0.10
set Board[0][0].text = udg_Color[0] + "Player"
set Board[0][1].text = udg_Color[0] + "Rank"
set currentRow = 1
set i = 0
loop
exitwhen i >= currentPlayerAmount
set currentRow = currentRow + 1
set p = User.fromPlaying(i).toPlayer()
set playerRow[GetPlayerId(p)] = currentRow
call update(p)
set i = i + 1
endloop
set Board.display = true
set Board.minimize = false
call DestroyTimer(GetExpiredTimer())
endmethod
private static method onInit takes nothing returns nothing
set Board = 0
call TimerStart(CreateTimer(),1.8 ,false,function thistype.NewBoard)
endmethod
endstruct
library PlayerData uses FileIO
struct PlayerData extends array
private static constant string SYNC_PREFIX_SCORE = "score"
private static constant string SYNC_PREFIX_CARINDEX = "carindex"
private static constant string SYNC_PREFIX_HASH = "hash"
private static constant integer MAX_VALUE = 100000
private static constant integer INTERNAL_BOUNDS = 28000000
private static constant integer SAVE_CODE_VERSION = 1
static method setLocalPlayerData takes player p returns nothing
local File file
local string s
local integer playerId = GetConvertedPlayerId(p)
local integer score = udg_PlayerScore_Current[playerId]
local integer carChangeIndex = udg_CarChange_Index[playerId]
local integer hash = ModuloInteger(StringHash(udg_InitialPlayerName[playerId]), INTERNAL_BOUNDS)
local Savecode savecode = Savecode.create()
call savecode.Encode(score, MAX_VALUE)
call savecode.Encode(carChangeIndex, MAX_VALUE)
call savecode.Encode(hash, INTERNAL_BOUNDS + 1)
set s = savecode.Save(p, SAVE_CODE_VERSION)
if ( GetLocalPlayer() == p ) then
set file = File.open(udg_Data_Path)
call file.write(s)
call file.close()
endif
call savecode.destroy()
endmethod
private static method syncLocalPlayerData takes player p returns nothing
local File file
local integer score
local integer carChangeIndex
local Savecode savecode = Savecode.create()
local string s
local integer playerId = GetConvertedPlayerId(p)
local integer hash
local integer hashCorrect = ModuloInteger(StringHash(udg_InitialPlayerName[playerId]), INTERNAL_BOUNDS)
if ( GetLocalPlayer() == p ) then
set file = File.open(udg_Data_Path)
set s = file.readAndClose()
call savecode.Load(p, s, SAVE_CODE_VERSION)
set hash = savecode.Decode(INTERNAL_BOUNDS + 1)
set carChangeIndex = savecode.Decode(MAX_VALUE)
set score = savecode.Decode(MAX_VALUE)
if ( hash == hashCorrect ) then
call BlzSendSyncData(SYNC_PREFIX_CARINDEX, I2S(carChangeIndex))
call BlzSendSyncData(SYNC_PREFIX_SCORE, I2S(score))
endif
endif
call savecode.destroy()
endmethod
private static method syncData takes nothing returns nothing
local player p = GetTriggerPlayer()
local integer playerId = GetConvertedPlayerId(p)
local string prefix = BlzGetTriggerSyncPrefix()
local string data = BlzGetTriggerSyncData()
if ( prefix == SYNC_PREFIX_SCORE ) then
set udg_PlayerScore_Loaded[playerId] = S2I(data)
set udg_PlayerScore_Current[playerId] = udg_PlayerScore_Loaded[playerId]
elseif ( prefix == SYNC_PREFIX_CARINDEX ) then
set udg_CarChange_Index[playerId] = S2I(data)
endif
endmethod
private static method init takes nothing returns nothing
local integer playerId = 0
local player p
local trigger t = CreateTrigger()
loop
set p = Player(playerId)
call BlzTriggerRegisterPlayerSyncEvent(t, p, SYNC_PREFIX_CARINDEX, false)
call BlzTriggerRegisterPlayerSyncEvent(t, p, SYNC_PREFIX_SCORE, false)
call syncLocalPlayerData(p)
set playerId = playerId + 1
exitwhen ( playerId >= bj_MAX_PLAYER_SLOTS )
endloop
call TriggerAddAction(t, function thistype.syncData)
endmethod
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(), 0.1, false, function thistype.init)
endmethod
endstruct
endlibrary
library RankData uses FileIO
struct RankData extends array
private static constant string SYNC_PREFIX_RANK = "rank"
private static constant string SYNC_PREFIX_HASH = "hash"
private static constant integer MAX_VALUE = 100000
private static constant integer INTERNAL_BOUNDS = 28000000
private static constant integer SAVE_CODE_VERSION = 1
private static string path
private static method syncLocalRankData takes player p returns nothing
local File file
local integer rank
local Savecode savecode = Savecode.create()
local string s
local integer playerId = GetConvertedPlayerId(p)
local integer hash
local integer hashCorrect = ModuloInteger(StringHash(udg_InitialPlayerName[playerId]), INTERNAL_BOUNDS)
if ( GetLocalPlayer() == p ) then
set file = File.open(path)
set s = file.readAndClose()
call savecode.Load(p, s, SAVE_CODE_VERSION)
set hash = savecode.Decode(INTERNAL_BOUNDS + 1)
set rank = savecode.Decode(MAX_VALUE)
if ( hash == hashCorrect ) then
call BlzSendSyncData(SYNC_PREFIX_RANK, I2S(rank))
endif
endif
call savecode.destroy()
endmethod
private static method syncData takes nothing returns nothing
local player p = GetTriggerPlayer()
local integer playerId = GetConvertedPlayerId(p)
local string prefix = BlzGetTriggerSyncPrefix()
local string data = BlzGetTriggerSyncData()
if ( prefix == SYNC_PREFIX_RANK ) then
set udg_Rank[playerId] = S2I(data)
endif
endmethod
private static method init takes nothing returns nothing
local integer playerId = 0
local player p
local player localPlayer = GetLocalPlayer()
local trigger t = CreateTrigger()
loop
set p = Player(playerId)
if ( p == localPlayer ) then
set path = "Ice Escape Ranks\\" + GetPlayerName(p) + " Data.pld"
endif
call BlzTriggerRegisterPlayerSyncEvent(t, p, SYNC_PREFIX_RANK, false)
call syncLocalRankData(p)
set playerId = playerId + 1
exitwhen ( playerId >= bj_MAX_PLAYER_SLOTS )
endloop
call TriggerAddAction(t, function thistype.syncData)
endmethod
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(), 0.1, false, function thistype.init)
endmethod
endstruct
endlibrary
library CustomStatFrame
globals
private integer Count = 0
framehandle CustomStatFrameBoxS
framehandle CustomStatFrameBoxF
public framehandle array Frame
public framehandle array Icon
public framehandle array Text
public framehandle array Hover
public framehandle array ToolTipBox
public framehandle array ToolTipTitle
public framehandle array ToolTipText
public unit array SelectedUnit
endglobals
private function Add takes string icon, string text, string tooltipTitle returns nothing
local framehandle fh
local framehandle tooltipBox
local framehandle fhHover
set Count = Count + 1
set fh = BlzCreateSimpleFrame("CustomStat", CustomStatFrameBoxS, Count)
set tooltipBox = BlzCreateFrame("BoxedText", CustomStatFrameBoxF,0, Count)
set fhHover = BlzCreateFrameByType("FRAME", "CustomStatHover", CustomStatFrameBoxF, "", Count)
call BlzFrameSetPoint(fhHover, FRAMEPOINT_BOTTOMLEFT, fh, FRAMEPOINT_BOTTOMLEFT, 0, 0)
call BlzFrameSetPoint(fhHover, FRAMEPOINT_TOPRIGHT, BlzGetFrameByName("CustomStatText", Count), FRAMEPOINT_TOPRIGHT, 0, 0)
call BlzFrameSetTooltip(fhHover, tooltipBox) //when faceHover is hovered with the mouse frame tooltip becomes visible.
call BlzFrameSetAbsPoint(tooltipBox, FRAMEPOINT_BOTTOM, 0.4, 0.15)
call BlzFrameSetSize(tooltipBox, 0.17, 0.03)
call BlzFrameSetText(BlzGetFrameByName("CustomStatText", Count), text)
call BlzFrameSetText(BlzGetFrameByName("BoxedTextTitle", Count), tooltipTitle)
//call BlzFrameSetText(BlzGetFrameByName("BoxedTextValue", Count), text)
call BlzFrameSetTexture(BlzGetFrameByName("CustomStatIcon", Count), icon, 0, true)
//[[ 4x3
if Count == 1 then
call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.31, 0.08)
elseif Count == 5 then
call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.375, 0.08)
elseif Count == 9 then
call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.435, 0.08)
else
call BlzFrameSetPoint(fh, FRAMEPOINT_TOPLEFT, BlzGetFrameByName("CustomStat", Count - 1), FRAMEPOINT_BOTTOMLEFT, 0, 0)
endif
//]]
//[[ 4x4
if Count == 1 then
call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.31, 0.08)
elseif Count == 5 then
call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.36, 0.08)
elseif Count == 9 then
call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.41, 0.08)
elseif Count == 13 then
call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.46, 0.08)
else
call BlzFrameSetPoint(fh, FRAMEPOINT_TOPLEFT, BlzGetFrameByName("CustomStat", Count - 1), FRAMEPOINT_BOTTOMLEFT, 0, 0)
endif
//]]
//3x3
if Count == 1 then
call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.31, 0.08)
elseif Count == 4 then
call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.375, 0.08)
elseif Count == 7 then
call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, 0.435, 0.08)
else
call BlzFrameSetPoint(fh, FRAMEPOINT_TOPLEFT, BlzGetFrameByName("CustomStat", Count - 1), FRAMEPOINT_BOTTOMLEFT, 0, -0.005)
endif
//save into table
set Frame[Count] = fh
set Icon[Count] = BlzGetFrameByName("CustomStatIcon", Count)
set Text[Count] = BlzGetFrameByName("CustomStatText", Count)
set Hover[Count] = fhHover
set ToolTipBox[Count] = tooltipBox
set ToolTipTitle[Count] = BlzGetFrameByName("BoxedTextTitle", Count)
//set ToolTipText[Count] = BlzGetFrameByName("BoxedTextValue", Count)
set fh = null
set fhHover = null
set tooltipBox = null
endfunction
public function Update takes nothing returns nothing
local integer id = GetPlayerId(GetOwningPlayer(SelectedUnit[GetPlayerId(GetLocalPlayer())])) + 1
local string deathsLevel = I2S(udg_DeathCounterLevel[id])
local string deathsTotal = I2S(udg_DeathCounterTotal[id])
local string levelsFinished = I2S(udg_LevelFinishedCounter[id])
local string saveCounter = I2S(udg_SaveCounter[id])
local string clickCounter = I2S(udg_ClickCounter[id])
local string clickDistanceAverage = I2S(udg_ClickDistanceAverage[id])
call BlzFrameSetText(Text[1], deathsLevel)
call BlzFrameSetText(Text[2], deathsTotal)
call BlzFrameSetText(Text[3], levelsFinished)
call BlzFrameSetText(Text[4], saveCounter)
call BlzFrameSetText(Text[5], clickCounter)
call BlzFrameSetText(Text[6], clickDistanceAverage)
call BlzFrameSetVisible(CustomStatFrameBoxF, BlzFrameIsVisible(CustomStatFrameBoxS))
endfunction
private function MouveOutOfScreen takes string name, integer index returns nothing
local framehandle fh = BlzGetFrameByName(name, index)
call BlzFrameClearAllPoints(fh)
call BlzFrameSetAbsPoint(fh, FRAMEPOINT_CENTER, 3, 3)
call BlzFrameSetScale(fh, 0.001)
set fh = null
endfunction
private function SelectUnitAction takes nothing returns nothing
set SelectedUnit[GetPlayerId(GetTriggerPlayer())] = GetTriggerUnit()
endfunction
function CustomStatFrameInit takes nothing returns nothing
local trigger trig = CreateTrigger()
local integer index = 0
//move the default unit infos out of the screen and scale it down
call MouveOutOfScreen("SimpleInfoPanelIconDamage",0)
call MouveOutOfScreen("SimpleInfoPanelIconDamage",1)
call MouveOutOfScreen("SimpleInfoPanelIconArmor",2)
call MouveOutOfScreen("SimpleInfoPanelIconRank",3)
call MouveOutOfScreen("SimpleInfoPanelIconFood",4)
call MouveOutOfScreen("SimpleInfoPanelIconGold",5)
call MouveOutOfScreen("SimpleInfoPanelIconHero",6)
call MouveOutOfScreen("SimpleInfoPanelIconAlly",7)
//Create a Selection Trigger thats a pretty naive approach.
call TriggerAddAction(trig, function SelectUnitAction)
loop
call TriggerRegisterPlayerSelectionEventBJ(trig, Player(index), true)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
//create a Parent for the Stats so you can easyly hide/show them-
//Stats use SimpleUnitStatsPanel as parent that way they are only shown when an unit is selected which does not build.
set CustomStatFrameBoxS = BlzCreateFrameByType("SIMPLEFRAME", "CustomStatFrameBoxSBoss", BlzGetFrameByName("SimpleUnitStatsPanel",0), "", 0)
set CustomStatFrameBoxF = BlzCreateFrameByType("FRAME", "CustomStatFrameBoxFBoss", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
call BlzLoadTOCFile("war3mapimported\\CustomStat.toc")
call BlzLoadTOCFile("war3mapimported\\BoxedText.toc")
call Add(udg_UnitStatIcon[Count + 1],"0", "Deaths Level")
call Add(udg_UnitStatIcon[Count + 1],"0", "Deaths Total")
call Add(udg_UnitStatIcon[Count + 1],"0", "Levels Done")
call Add(udg_UnitStatIcon[Count + 1],"0", "Saves")
call Add(udg_UnitStatIcon[Count + 1],"0", "Clicks on ice")
call Add(udg_UnitStatIcon[Count + 1],"0", "Average click distance")
call TimerStart(CreateTimer(), 0.1, true, function Update)
endfunction
endlibrary
//MyResourceBar 1.2c
//By Tasyen
function MyResourceBarPlayerSize takes nothing returns integer
return 100 //each player has 100 slots allwing upto 9 additional bars (on default). MyResourceBarAutoCreateCount * MyResourceBarDataSize should not reach that number
endfunction
function MyResourceBarDataSize takes nothing returns integer
return 10 //each Bar takes that amount of slots
endfunction
function MyResourceBarAutoCreateCount takes nothing returns integer
return 1 //Create this amount of addtional Bars automatically.
endfunction
//Allow and Pos the checkbox hidding the additional Bars.
function MyResourceBarCreateCheckBox takes nothing returns boolean
return true //(true) create a checkbox to tooggle visiblity of the additional ResourceBarFrames
endfunction
function MyResourceBarCheckBoxLabelText takes nothing returns string
return "Hide Stats"
endfunction
function MyResourceBarCheckBoxX takes nothing returns real
return 0.1
endfunction
function MyResourceBarCheckBoxY takes nothing returns real
return 0.57
endfunction
//Where is the tooltip of this Bars placed.
function MyResourceBarTooltipX takes nothing returns real
return 0.8
endfunction
function MyResourceBarTooltipY takes nothing returns real
return 0.16
endfunction
function MyResourceBarTooltipPoint takes nothing returns framepointtype
return FRAMEPOINT_BOTTOMRIGHT
endfunction
function MyResourceBarAnchor takes nothing returns framepointtype
//Poses the first Bar where in the world Frame?
//I suggest to use a y-offset when using any Bottom Point.
//return FRAMEPOINT_TOPLEFT
//return FRAMEPOINT_TOP
return FRAMEPOINT_TOPRIGHT
//return FRAMEPOINT_BOTTOMLEFT
//return FRAMEPOINT_BOTTOM
//return FRAMEPOINT_BOTTOMRIGHT
//return FRAMEPOINT_LEFT
//return FRAMEPOINT_RIGHT
//return FRAMEPOINT_CENTER
endfunction
function MyResourceBarAnchor1OffsetX takes nothing returns real
return 0.0 //Offset the first bar by that amount from its FramePoint
endfunction
function MyResourceBarAnchor1OffsetY takes nothing returns real
return 0.0
endfunction
function MyResourceBarCreateTooltip takes framehandle targetFrameLeft, framehandle targetFrameRight, string title, string text, integer index returns nothing
local framehandle box = BlzGetFrameByName("MyResourceBarBoss",0)
local framehandle fhHover = BlzCreateFrameByType("FRAME", "MyResourceHover", box, "", index)
local framehandle tooltipBox = BlzCreateFrame("MyResourceBarBoxedText", box,0, index)
call BlzFrameSetPoint(fhHover, FRAMEPOINT_BOTTOMLEFT, targetFrameLeft, FRAMEPOINT_BOTTOMLEFT, 0, 0)
call BlzFrameSetPoint(fhHover, FRAMEPOINT_TOPRIGHT, targetFrameRight, FRAMEPOINT_TOPRIGHT, 0, 0)
call BlzFrameSetTooltip(fhHover, tooltipBox)
call BlzFrameSetAbsPoint(tooltipBox, MyResourceBarTooltipPoint(), MyResourceBarTooltipX(), MyResourceBarTooltipY())
call BlzFrameSetSize(tooltipBox, 0.285, 0.06)
call BlzFrameSetText(BlzGetFrameByName("MyResourceBarBoxedTextTitle", index), title)
call BlzFrameSetText(BlzGetFrameByName("MyResourceBarBoxedTextValue", index), text)
set box = null
set fhHover = null
set tooltipBox = null
endfunction
function MyResourceBarSetup takes integer barIndex returns nothing //create an additonal ResourceBar between the orginal one.
local integer playerIndex = GetConvertedPlayerId(GetLocalPlayer()) * MyResourceBarPlayerSize()
local integer dataIndex = barIndex*MyResourceBarDataSize()
local integer loopIndex = 1
call MyResourceBarCreateTooltip(BlzGetFrameByName("MyResourceBar1Icon", barIndex), BlzGetFrameByName("MyResourceBar1Text", barIndex), udg_MyResourceBarTooltipTitle[dataIndex + 1], udg_MyResourceBarTooltipText[dataIndex +1], dataIndex + 1)
call MyResourceBarCreateTooltip(BlzGetFrameByName("MyResourceBar2Icon", barIndex), BlzGetFrameByName("MyResourceBar2Text", barIndex), udg_MyResourceBarTooltipTitle[dataIndex + 2], udg_MyResourceBarTooltipText[dataIndex +2], dataIndex + 2)
call MyResourceBarCreateTooltip(BlzGetFrameByName("MyResourceBar3Icon", barIndex), BlzGetFrameByName("MyResourceBar3Text", barIndex), udg_MyResourceBarTooltipTitle[dataIndex + 3], udg_MyResourceBarTooltipText[dataIndex +3], dataIndex + 3)
call MyResourceBarCreateTooltip(BlzGetFrameByName("MyResourceBar4Icon", barIndex), BlzGetFrameByName("MyResourceBar4Text", barIndex), udg_MyResourceBarTooltipTitle[dataIndex + 4], udg_MyResourceBarTooltipText[dataIndex +4], dataIndex + 4)
loop
if udg_MyResourceBarIcons[playerIndex + dataIndex + loopIndex] == null or udg_MyResourceBarIcons[playerIndex + dataIndex + loopIndex] == "" then
call BlzFrameSetTexture(BlzGetFrameByName("MyResourceBar"+I2S(loopIndex)+"Icon", barIndex), udg_MyResourceBarIcons[dataIndex + loopIndex], 0 ,true)
else
call BlzFrameSetTexture(BlzGetFrameByName("MyResourceBar"+I2S(loopIndex)+"Icon", barIndex), udg_MyResourceBarIcons[playerIndex + dataIndex + loopIndex], 0 ,true)
endif
if udg_MyResourceBarTooltipTitle[playerIndex + dataIndex + loopIndex] != null then //player specific Tooltip?
call BlzFrameSetText(BlzGetFrameByName("MyResourceBarBoxedTextTitle", dataIndex + loopIndex), udg_MyResourceBarTooltipTitle[playerIndex + dataIndex + loopIndex])
endif
if udg_MyResourceBarTooltipText[playerIndex + dataIndex + loopIndex] != null then //player specific TooltipText?
call BlzFrameSetText(BlzGetFrameByName("MyResourceBarBoxedTextValue", dataIndex + loopIndex), udg_MyResourceBarTooltipText[playerIndex + dataIndex + loopIndex])
endif
set loopIndex = loopIndex + 1
exitwhen loopIndex == 5
endloop
endfunction
function CreateMyResourceBar takes nothing returns nothing
local framehandle bar = BlzCreateSimpleFrame("MyResourceBarFrame", BlzGetFrameByName("MyResourceBarBoss2",0), udg_MyResourceBarCount + 1)
set udg_MyResourceBarCount = udg_MyResourceBarCount + 1
if udg_MyResourceBarCount == 1 then //if this is the first create one Pos it below the default one
call BlzFrameSetPoint(bar, MyResourceBarAnchor(), BlzGetOriginFrame(ORIGIN_FRAME_WORLD_FRAME,0), MyResourceBarAnchor(), MyResourceBarAnchor1OffsetX(), MyResourceBarAnchor1OffsetY())
else
if MyResourceBarAnchor() == FRAMEPOINT_TOPRIGHT or MyResourceBarAnchor() == FRAMEPOINT_TOPLEFT or MyResourceBarAnchor() == FRAMEPOINT_TOP then
call BlzFrameSetPoint(bar, FRAMEPOINT_TOP, BlzGetFrameByName("MyResourceBarFrame", udg_MyResourceBarCount - 1), FRAMEPOINT_BOTTOM, 0, 0)
elseif MyResourceBarAnchor() == FRAMEPOINT_BOTTOMLEFT or MyResourceBarAnchor() == FRAMEPOINT_BOTTOM or MyResourceBarAnchor() == FRAMEPOINT_BOTTOMRIGHT then
call BlzFrameSetPoint(bar, FRAMEPOINT_BOTTOMLEFT, BlzGetFrameByName("MyResourceBarFrame", udg_MyResourceBarCount - 1), FRAMEPOINT_TOPLEFT, 0, 0)
else
call BlzFrameSetPoint(bar, FRAMEPOINT_TOP, BlzGetFrameByName("MyResourceBarFrame", udg_MyResourceBarCount - 1), FRAMEPOINT_BOTTOM, 0, 0)
endif
endif
call MyResourceBarSetup(udg_MyResourceBarCount)
set bar = null
endfunction
function MyResourceBarUpdateBarsReplay takes nothing returns nothing
local integer playerIndex = (R2I(BlzFrameGetValue(BlzGetFrameByName("ReplayVisionMenu",0))) + 1) * MyResourceBarPlayerSize()
local integer i
local integer barIndex = 1
local integer dataIndex
//Takes over all udg_MyResourceValue data into the MyResourceBarFrames also updates the title
//The outher Loop are the Bars, the inner Loop handles the tooltipTitle update
loop
set dataIndex = barIndex*MyResourceBarDataSize()
call BlzFrameSetText(BlzGetFrameByName("MyResourceBar1Text", barIndex), udg_MyResourceValue[playerIndex + dataIndex + 1])
call BlzFrameSetText(BlzGetFrameByName("MyResourceBar2Text", barIndex), udg_MyResourceValue[playerIndex + dataIndex + 2])
call BlzFrameSetText(BlzGetFrameByName("MyResourceBar3Text", barIndex), udg_MyResourceValue[playerIndex + dataIndex + 3])
call BlzFrameSetText(BlzGetFrameByName("MyResourceBar4Text", barIndex), udg_MyResourceValue[playerIndex + dataIndex + 4])
set i = 1
loop
if udg_MyResourceBarTooltipTitle[playerIndex + dataIndex + i] == null then
call BlzFrameSetText(BlzGetFrameByName("MyResourceBarBoxedTextTitle", dataIndex + i), udg_MyResourceBarTooltipTitle[dataIndex + i]+": "+udg_MyResourceValue[playerIndex +dataIndex + i])
else
call BlzFrameSetText(BlzGetFrameByName("MyResourceBarBoxedTextTitle", dataIndex + i), udg_MyResourceBarTooltipTitle[playerIndex + dataIndex + i]+": "+udg_MyResourceValue[playerIndex +dataIndex + i])
endif
if udg_MyResourceBarTooltipText[playerIndex + dataIndex + i] == null then
call BlzFrameSetText(BlzGetFrameByName("MyResourceBarBoxedTextValue", dataIndex + i), udg_MyResourceBarTooltipText[dataIndex + i])
else
call BlzFrameSetText(BlzGetFrameByName("MyResourceBarBoxedTextValue", dataIndex + i), udg_MyResourceBarTooltipText[playerIndex + dataIndex + i])
endif
if udg_MyResourceBarIcons[playerIndex + dataIndex + i] == null or udg_MyResourceBarIcons[playerIndex + dataIndex + i] == "" then
call BlzFrameSetTexture(BlzGetFrameByName("MyResourceBar"+I2S(i)+"Icon", barIndex), udg_MyResourceBarIcons[dataIndex + i], 0 ,true)
else
call BlzFrameSetTexture(BlzGetFrameByName("MyResourceBar"+I2S(i)+"Icon", barIndex), udg_MyResourceBarIcons[playerIndex + dataIndex + i], 0 ,true)
endif
set i = i + 1
exitwhen i == 5
endloop
set barIndex = barIndex + 1
exitwhen barIndex > udg_MyResourceBarCount
endloop
endfunction
function MyResourceBarUpdateBars takes nothing returns nothing
local integer playerIndex = GetConvertedPlayerId(GetLocalPlayer()) * MyResourceBarPlayerSize()
local integer i
local integer barIndex = 1
local integer dataIndex
//Takes over all udg_MyResourceValue data into the MyResourceBarFrames also updates the title
//The outher Loop are the Bars, the inner Loop handles the tooltipTitle update
loop
set dataIndex = barIndex*MyResourceBarDataSize()
call BlzFrameSetText(BlzGetFrameByName("MyResourceBar1Text", barIndex), udg_MyResourceValue[playerIndex + dataIndex + 1])
call BlzFrameSetText(BlzGetFrameByName("MyResourceBar2Text", barIndex), udg_MyResourceValue[playerIndex + dataIndex + 2])
call BlzFrameSetText(BlzGetFrameByName("MyResourceBar3Text", barIndex), udg_MyResourceValue[playerIndex + dataIndex + 3])
call BlzFrameSetText(BlzGetFrameByName("MyResourceBar4Text", barIndex), udg_MyResourceValue[playerIndex + dataIndex + 4])
set i = 1
loop
if udg_MyResourceBarTooltipTitle[playerIndex + dataIndex + i] == null then
call BlzFrameSetText(BlzGetFrameByName("MyResourceBarBoxedTextTitle", dataIndex + i), udg_MyResourceBarTooltipTitle[dataIndex + i]+": "+udg_MyResourceValue[playerIndex +dataIndex + i])
else
call BlzFrameSetText(BlzGetFrameByName("MyResourceBarBoxedTextTitle", dataIndex + i), udg_MyResourceBarTooltipTitle[playerIndex + dataIndex + i]+": "+udg_MyResourceValue[playerIndex +dataIndex + i])
endif
set i = i + 1
exitwhen i == 5
endloop
set barIndex = barIndex + 1
exitwhen barIndex > udg_MyResourceBarCount
endloop
endfunction
function MyResourceBarsFitFrames takes nothing returns nothing
local framehandle leadbor = BlzGetFrameByName("Leaderboard",0)
local framehandle multi = BlzGetFrameByName("Multiboard",0)
local framehandle time = BlzGetFrameByName("TimerDialog",0)
local framehandle prev = BlzGetFrameByName("MyResourceBarFrame", udg_MyResourceBarCount)
local framehandle resourcebar = BlzGetFrameByName("ResourceBarFrame", 0)
local real yPlus = -0.005
if MyResourceBarAnchor() == FRAMEPOINT_TOPRIGHT then
if not BlzFrameIsVisible(BlzGetFrameByName("MyResourceBarFrame", udg_MyResourceBarCount)) then
set prev = resourcebar
set yPlus = -0.0165
endif
if time != null then //bugs if the 1. timer window is destroyed
call BlzFrameSetPoint(time, FRAMEPOINT_TOPRIGHT, prev, FRAMEPOINT_BOTTOMRIGHT, 0, -0.005 + yPlus)
set yPlus = 0
set prev = time
endif
if multi != null then //bugs if the current shown multiboard is not the last created one
call BlzFrameSetPoint(multi, FRAMEPOINT_TOPRIGHT, prev, FRAMEPOINT_BOTTOMRIGHT, 0, -0.005 + yPlus)
set yPlus = 0
set prev = multi
endif
if leadbor != null then//bugs if the current shown leaderboard is not the last created one
call BlzFrameSetPoint(leadbor, FRAMEPOINT_TOPRIGHT, prev, FRAMEPOINT_BOTTOMRIGHT, 0, -0.005 + yPlus)
set yPlus = 0
set prev = leadbor
endif
endif
set leadbor = null
set multi = null
set time = null
set prev = null
set resourcebar = null
endfunction
function MyResourceBarsCheckBox takes nothing returns nothing
//In some test BlzGetFrameByName could disconnect the game hence done for all players
local framehandle fh = BlzGetFrameByName("MyResourceBarBoss",0)
local framehandle fh2 = BlzGetFrameByName("MyResourceBarBoss2",0)
if GetTriggerPlayer() == GetLocalPlayer() then //only do something for the player having pressed the checkbox
call BlzFrameSetVisible(fh, BlzGetTriggerFrameEvent() == FRAMEEVENT_CHECKBOX_UNCHECKED)
call BlzFrameSetVisible(fh2, BlzGetTriggerFrameEvent() == FRAMEEVENT_CHECKBOX_UNCHECKED)
endif
set fh = null
set fh2 = null
call MyResourceBarsFitFrames()
endfunction
function MyResourceBarCreateCheckBoxAction takes nothing returns nothing
local trigger trig = CreateTrigger()
local framehandle fh = BlzCreateFrameByType("GLUECHECKBOX", "MyResourceBarCheckBox", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0),"QuestCheckBox",0)
local framehandle fhText = BlzCreateFrameByType("TEXT", "MyResourceBarCheckBoxLabel", fh, "", 0)
call BlzFrameSetAbsPoint(fh, FRAMEPOINT_TOPLEFT, MyResourceBarCheckBoxX(), MyResourceBarCheckBoxY())
call BlzFrameSetPoint(fhText, FRAMEPOINT_TOP, fh, FRAMEPOINT_BOTTOM, 0.0, 0.0)
call BlzFrameSetEnable(fhText, false)
call BlzFrameSetText(fhText, MyResourceBarCheckBoxLabelText())
call BlzTriggerRegisterFrameEvent(trig, fh, FRAMEEVENT_CHECKBOX_CHECKED)
call BlzTriggerRegisterFrameEvent(trig, fh, FRAMEEVENT_CHECKBOX_UNCHECKED)
call TriggerAddAction(trig, function MyResourceBarsCheckBox)
set fh = null
set fhText = null
set trig = null
endfunction
function MyResourceBarsCreate takes nothing returns nothing
//Create Hide ResourceBar checkbox
local integer i = MyResourceBarAutoCreateCount()
if MyResourceBarCreateCheckBox() and not BlzFrameIsVisible(BlzGetFrameByName("SimpleReplayPanel",0)) then
call MyResourceBarCreateCheckBoxAction()
endif
//Create Parents of the ResourceBarFrames, one needs a SIMPLEFRAME and a FRAME. They allow to easyly hide/show the ResourceBarFrames
call BlzCreateFrameByType("FRAME", "MyResourceBarBoss", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0),"",0) //Parent of Frames (tooltips stuff)
call BlzCreateFrameByType("SIMPLEFRAME", "MyResourceBarBoss2", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0),"",0) //Parent of SimpleFrames (bar and its content)
//Create ResourceBarFrames
loop
exitwhen i <= 0
call CreateMyResourceBar()
set i = i - 1
endloop
//CleanUP
call DestroyTimer(GetExpiredTimer())
if not BlzFrameIsVisible(BlzGetFrameByName("SimpleReplayPanel",0)) then
call TriggerAddAction( gg_trg_MyResourceBar, function MyResourceBarUpdateBars)
else
call TriggerAddAction( gg_trg_MyResourceBar, function MyResourceBarUpdateBarsReplay)
endif
endfunction
//===========================================================================
function InitTrig_MyResourceBar takes nothing returns nothing
set gg_trg_MyResourceBar = CreateTrigger( )
call TriggerRegisterTimerEventPeriodic( gg_trg_MyResourceBar , 0.2)
call TimerStart(CreateTimer(),0.0, false, function MyResourceBarsCreate)
call BlzLoadTOCFile("war3mapImported\\MyResourceBar.toc")
endfunction
library PreventSave initializer onInit
/***************************************************************
*
* v1.0.1 by TriggerHappy
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* This library allows you to enable or disable game saving. It works by showing
* a dialog instantly before a game is saved, causing the save to interrupt. There
* are no known side effects.
* _________________________________________________________________________
* 1. Installation
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Copy the script to your map and save it (requires JassHelper *or* JNGP)
* _________________________________________________________________________
* 2. API
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* function SaveGameEnable takes boolean flag returns nothing
* function IsSaveEnabled takes nothing returns boolean
* function PreventSave takes player p, boolean flag returns nothing
*
***************************************************************/
globals
boolean GameAllowSave = false
endglobals
//====================================
// Do not edit below this line
//====================================
globals
private dialog Dialog = DialogCreate()
private timer Timer = CreateTimer()
private player LocalPlayer
endglobals
function SaveGameEnable takes boolean flag returns nothing
set GameAllowSave = flag
endfunction
function IsSaveEnabled takes nothing returns boolean
return GameAllowSave
endfunction
function PreventSave takes player p, boolean flag returns nothing
if (p == LocalPlayer) then
call SaveGameEnable(not flag)
endif
endfunction
private function Exit takes nothing returns nothing
call DialogDisplay(LocalPlayer, Dialog, false)
endfunction
private function StopSave takes nothing returns boolean
if not IsSaveEnabled() then
call DialogDisplay(LocalPlayer, Dialog, true)
endif
call TimerStart(Timer, 0.00, false, function Exit)
return false
endfunction
private function onInit takes nothing returns nothing
local trigger t = CreateTrigger()
set LocalPlayer = GetLocalPlayer()
call TriggerRegisterGameEvent(t, EVENT_GAME_SAVE)
call TriggerAddCondition(t, Filter(function StopSave))
endfunction
endlibrary
library ResourcePreloader /* v1.4c
*/uses /*
*/optional BJObjectId /* http://www.hiveworkshop.com/threads/bjobjectid.287128/
*/optional Table /* http://www.hiveworkshop.com/threads/snippet-new-table.188084/
*/optional UnitRecycler /* http://www.hiveworkshop.com/threads/snippet-unit-recycler.286701/
*///! novjass
|================|
| Written by AGD |
|================|
[CREDITS]
/* IcemanBo - for suggesting further improvements
Silvenon - for the sound preloading method */
|-----|
| API |
|-----|
function PreloadUnit takes integer rawcode returns nothing/*
- Assigns a certain type of unit to be preloaded
*/function PreloadItem takes integer rawcode returns nothing/*
- Assigns a certain type of item to be preloaded
*/function PreloadAbility takes integer rawcode returns nothing/*
- Assigns a certain type of ability to be preloaded
*/function PreloadEffect takes string modelPath returns nothing/*
- Assigns a certain type of effect to be preloaded
*/function PreloadSound takes string soundPath returns nothing/*
- Assigns a certain type of sound to be preloaded
The following functions requires the BJObjectId library:
*/function PreloadUnitEx takes integer start, integer end returns nothing/*
- Assigns a range of units to be preloaded
*/function PreloadItemEx takes integer start, integer end returns nothing/*
- Assigns a range of items to be preloaded
*/function PreloadAbilityEx takes integer start, integer end returns nothing/*
- Assigns a range of abilities to be preloaded
*///! endnovjass
/*========================================================================================================*/
/* Do not try to change below this line if you're not so sure on what you're doing. */
/*========================================================================================================*/
private keyword S
/*============================================== TextMacros ==============================================*/
//! textmacro PRELOAD_TYPE takes NAME, ARG, TYPE, INDEX, I
function Preload$NAME$ takes $ARG$ what returns nothing
static if LIBRARY_Table then
if S.tb[$I$].boolean[$INDEX$] then
return
endif
set S.tb[$I$].boolean[$INDEX$] = true
call Do$NAME$Preload(what)
else
if LoadBoolean(S.tb, $I$, $INDEX$) then
return
endif
call SaveBoolean(S.tb, $I$, $INDEX$, true)
call Do$NAME$Preload(what)
endif
endfunction
//! endtextmacro
//! textmacro RANGED_PRELOAD_TYPE takes NAME
function Preload$NAME$Ex takes integer start, integer end returns nothing
local boolean mode = start < end
loop
call Preload$NAME$(start)
exitwhen start == end
if mode then
set start = BJObjectId(start).plus_1()
exitwhen start > end
else
set start = BJObjectId(start).minus_1()
exitwhen start < end
endif
endloop
endfunction
//! endtextmacro
/*========================================================================================================*/
private function DoUnitPreload takes integer id returns nothing
static if LIBRARY_UnitRecycler then
call RecycleUnitEx(CreateUnit(Player(15), id, 0, 0, 270))
else
call RemoveUnit(CreateUnit(Player(15), id, 0, 0, 0))
endif
endfunction
private function DoItemPreload takes integer id returns nothing
call RemoveItem(UnitAddItemById(S.dummy, id))
endfunction
private function DoAbilityPreload takes integer id returns boolean
return UnitAddAbility(S.dummy, id) and UnitRemoveAbility(S.dummy, id)
endfunction
private function DoEffectPreload takes string path returns nothing
call DestroyEffect(AddSpecialEffectTarget(path, S.dummy, "origin"))
endfunction
private function DoSoundPreload takes string path returns nothing
local sound s = CreateSound(path, false, false, false, 10, 10, "")
call SetSoundVolume(s, 0)
call StartSound(s)
call KillSoundWhenDone(s)
set s = null
endfunction
//! runtextmacro PRELOAD_TYPE("Unit", "integer", "unit", "what", "0")
//! runtextmacro PRELOAD_TYPE("Item", "integer", "item", "what", "1")
//! runtextmacro PRELOAD_TYPE("Ability", "integer", "ability", "what", "2")
//! runtextmacro PRELOAD_TYPE("Effect", "string", "effect", "StringHash(what)", "3")
//! runtextmacro PRELOAD_TYPE("Sound", "string", "sound", "StringHash(what)", "4")
static if LIBRARY_BJObjectId then
//! runtextmacro RANGED_PRELOAD_TYPE("Unit")
//! runtextmacro RANGED_PRELOAD_TYPE("Item")
//! runtextmacro RANGED_PRELOAD_TYPE("Ability")
endif
/*========================================================================================================*/
private module Init
private static method onInit takes nothing returns nothing
local rect world = GetWorldBounds()
static if LIBRARY_Table then
set tb = TableArray[5]
endif
set dummy = CreateUnit(Player(15), 'hpea', 0, 0, 0)
call UnitAddAbility(dummy, 'AInv')
call UnitAddAbility(dummy, 'Avul')
call UnitRemoveAbility(dummy, 'Amov')
call SetUnitY(dummy, GetRectMaxY(world) + 1000)
call RemoveRect(world)
set world = null
endmethod
endmodule
private struct S extends array
static if LIBRARY_Table then
static TableArray tb
else
static hashtable tb = InitHashtable()
endif
static unit dummy
implement Init
endstruct
endlibrary
library Savecode requires BigNum
private constant function uppercolor takes nothing returns string
return "|cffff0000"
endfunction
private constant function lowercolor takes nothing returns string
return "|cff00ff00"
endfunction
private constant function numcolor takes nothing returns string
return "|cff0000ff"
endfunction
private function player_charset takes nothing returns string
return "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
endfunction
private function player_charsetlen takes nothing returns integer
return StringLength(player_charset())
endfunction
private function charset takes nothing returns string
return "!#$%&'()*+,-.0123456789:;=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}`"
endfunction
private function charsetlen takes nothing returns integer
return StringLength(charset())
endfunction
private function BASE takes nothing returns integer
return charsetlen()
endfunction
private constant function HASHN takes nothing returns integer
return 5000 //1./HASHN() is the probability of a random code being valid
endfunction
private constant function MAXINT takes nothing returns integer
return 2147483647
endfunction
private function player_chartoi takes string c returns integer
local integer i = 0
local string cs = player_charset()
local integer len = player_charsetlen()
loop
exitwhen i>=len or c == SubString(cs,i,i+1)
set i = i + 1
endloop
return i
endfunction
private function chartoi takes string c returns integer
local integer i = 0
local string cs = charset()
local integer len = charsetlen()
loop
exitwhen i>=len or c == SubString(cs,i,i+1)
set i = i + 1
endloop
return i
endfunction
private function itochar takes integer i returns string
return SubString(charset(),i,i+1)
endfunction
//You probably want to use a different char set for this
//Also, use a hash that doesn't suck so much
private function scommhash takes string s returns integer
local integer array count
local integer i = 0
local integer len = StringLength(s)
local integer x
set s = StringCase(s,true)
loop
exitwhen i >= len
set x = player_chartoi(SubString(s,i,i+1))
set count[x] = count[x] + 1
set i = i + 1
endloop
set i = 0
set len = player_charsetlen()
set x = 0
loop
exitwhen i>= len
set x = count[i]*count[i]*i+count[i]*x+x+199
// call BJDebugMsg(I2S(x)+" "+I2S(count[i]))
// call TriggerSleepAction(0.)
set i = i + 1
endloop
if x < 0 then
set x = -x
endif
return x
endfunction
private function modb takes integer x returns integer
if x >= BASE() then
return x - BASE()
elseif x < 0 then
return x + BASE()
else
return x
endif
endfunction
struct Savecode
real digits //logarithmic approximation
BigNum bignum
static method create takes nothing returns Savecode
local Savecode sc = Savecode.allocate()
set sc.digits = 0.
set sc.bignum = BigNum.create(BASE())
return sc
endmethod
method onDestroy takes nothing returns nothing
call .bignum.destroy()
endmethod
method Encode takes integer val, integer max returns nothing
set .digits = .digits + log(max+1,BASE())
call .bignum.MulSmall(max+1)
call .bignum.AddSmall(val)
endmethod
method Decode takes integer max returns integer
return .bignum.DivSmall(max+1)
endmethod
method IsEmpty takes nothing returns boolean
return .bignum.IsZero()
endmethod
method Length takes nothing returns real
return .digits
endmethod
method Clean takes nothing returns nothing
call .bignum.Clean()
endmethod
//These functions get too intimate with BigNum_l
method Pad takes nothing returns nothing
local BigNum_l cur = .bignum.list
local BigNum_l prev
local integer maxlen = R2I(1.0 + .Length())
loop
exitwhen cur == 0
set prev = cur
set cur = cur.next
set maxlen = maxlen - 1
endloop
loop
exitwhen maxlen <= 0
set prev.next = BigNum_l.create()
set prev = prev.next
set maxlen = maxlen - 1
endloop
endmethod
method ToString takes nothing returns string
local BigNum_l cur = .bignum.list
local string s = ""
loop
exitwhen cur == 0
set s = itochar(cur.leaf) + s
set cur = cur.next
endloop
return s
endmethod
method FromString takes string s returns nothing
local integer i = StringLength(s)-1
local BigNum_l cur = BigNum_l.create()
set .bignum.list = cur
loop
set cur.leaf = chartoi(SubString(s,i,i+1))
exitwhen i <= 0
set cur.next = BigNum_l.create()
set cur = cur.next
set i = i - 1
endloop
endmethod
method Hash takes nothing returns integer
local integer hash = 0
local integer x
local BigNum_l cur = .bignum.list
loop
exitwhen cur == 0
set x = cur.leaf
set hash = ModuloInteger(hash+79*hash/(x+1) + 293*x/(1+hash - (hash/BASE())*BASE()) + 479,HASHN())
set cur = cur.next
endloop
return hash
endmethod
//this is not cryptographic which is fine for this application
//sign = 1 is forward
//sign = -1 is backward
method Obfuscate takes integer key, integer sign returns nothing
local integer seed = GetRandomInt(0,MAXINT())
local integer advance
local integer x
local BigNum_l cur = .bignum.list
if sign == -1 then
call SetRandomSeed(.bignum.LastDigit())
set cur.leaf = modb(cur.leaf + sign*GetRandomInt(0,BASE()-1))
set x = cur.leaf
endif
call SetRandomSeed(key)
loop
exitwhen cur == 0
if sign == -1 then
set advance = cur.leaf
endif
set cur.leaf = modb(cur.leaf + sign*GetRandomInt(0,BASE()-1))
if sign == 1 then
set advance = cur.leaf
endif
set advance = advance + GetRandomInt(0,BASE()-1)
call SetRandomSeed(advance)
set x = cur.leaf
set cur = cur.next
endloop
if sign == 1 then
call SetRandomSeed(x)
set .bignum.list.leaf = modb(.bignum.list.leaf + sign*GetRandomInt(0,BASE()-1))
endif
call SetRandomSeed(seed)
endmethod
method Dump takes nothing returns nothing
local BigNum_l cur = .bignum.list
local string s = ""
set s = "max: "+R2S(.digits)
loop
exitwhen cur == 0
set s = I2S(cur.leaf)+" "+s
set cur = cur.next
endloop
call BJDebugMsg(s)
endmethod
method Save takes player p, integer loadtype returns string
local integer key = scommhash(GetPlayerName(p))+loadtype*73
local string s
local integer hash
call .Clean()
set hash = .Hash()
call .Encode(hash,HASHN())
call .Clean()
/////////////////////// Save code information. Comment out next two lines in implementation
//call BJDebugMsg("Expected length: " +I2S(R2I(1.0+.Length())))
//call BJDebugMsg("Room left in last char: "+R2S(1.-ModuloReal((.Length()),1)))
///////////////////////
call .Pad()
call .Obfuscate(key,1)
return .ToString()
endmethod
method Load takes player p, string s, integer loadtype returns boolean
local integer ikey = scommhash(GetPlayerName(p))+loadtype*73
local integer inputhash
call .FromString(s)
call .Obfuscate(ikey,-1)
set inputhash = .Decode(HASHN())
call .Clean()
return inputhash == .Hash()
endmethod
endstruct
private function isupper takes string c returns boolean
return c == StringCase(c,true)
endfunction
private function ischar takes string c returns boolean
return S2I(c) == 0 and c!= "0"
endfunction
private function chartype takes string c returns integer
if(ischar(c)) then
if isupper(c) then
return 0
else
return 1
endif
else
return 2
endif
endfunction
private function testchar takes string c returns nothing
if(ischar(c)) then
if isupper(c) then
call BJDebugMsg(c+" isupper")
else
call BJDebugMsg(c+" islower")
endif
else
call BJDebugMsg(c+ " isnumber")
endif
endfunction
public function colorize takes string s returns string
local string out = ""
local integer i = 0
local integer len = StringLength(s)
local integer ctype
local string c
loop
exitwhen i >= len
set c = SubString(s,i,i+1)
set ctype = chartype(c)
if ctype == 0 then
set out = out + uppercolor()+c+"|r"
elseif ctype == 1 then
set out = out + lowercolor()+c+"|r"
else
set out = out + numcolor()+c+"|r"
endif
set i = i + 1
endloop
return out
endfunction
private function prop_Savecode takes nothing returns boolean
local string s
local Savecode loadcode
//--- Data you want to save ---
local integer medal1 = 10
local integer medal2 = 3
local integer medalmax = 13
local integer XP = 1337
local integer XPmax = 1000000
local Savecode savecode = Savecode.create()
call SetPlayerName(Player(0),"yomp")
call SetPlayerName(Player(1),"fruitcup")
call savecode.Encode(medal1,medalmax)
call savecode.Encode(medal2,medalmax)
call savecode.Encode(XP,XPmax)
//--- Savecode_save generates the savecode for a specific player ---
set s = savecode.Save(Player(0),1)
call savecode.destroy()
// call BJDebugMsg("Savecode: " + Savecode_colorize(s))
//--- User writes down code, inputs again ---
set loadcode = Savecode.create()
if loadcode.Load(Player(0),s,1) then
// call BJDebugMsg("load ok")
else
call BJDebugMsg("load failed")
return false
endif
//Must decode in reverse order of encodes
// load object : max value that data can take
if XP != loadcode.Decode(XPmax) then
return false
elseif medal2 != loadcode.Decode(medalmax) then
return false
elseif medal1 != loadcode.Decode(medalmax) then
return false
endif
call loadcode.destroy()
return true
endfunction
endlibrary
library FileIO
/***************************************************************
*
* v1.1.0, by TriggerHappy
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*
* Provides functionality to read and write files.
* _________________________________________________________________________
* 1. Requirements
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* - Patch 1.29 or higher.
* - JassHelper (vJASS)
* _________________________________________________________________________
* 2. Installation
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Copy the script to your map and save it.
* _________________________________________________________________________
* 3. API
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* struct File extends array
*
* static constant integer AbilityCount
* static constant integer PreloadLimit
*
* readonly static boolean ReadEnabled
* readonly static integer Counter
* readonly static integer array List
*
* static method open takes string filename returns File
* static method create takes string filename returns File
*
* ---------
*
* method write takes string value returns File
* method read takes nothing returns string
* method clear takes nothing returns File
*
* method readEx takes boolean close returns string
* method readAndClose takes nothing returns string
* method readBuffer takes nothing returns string
* method writeBuffer takes string contents returns nothing
* method appendBuffer takes string contents returns nothing
*
* method close takes nothing returns nothing
*
* public function Write takes string filename, string contents returns nothing
* public function Read takes string filename returns string
*
***************************************************************/
globals
// Enable this if you want to allow the system to read files generated in patch 1.30 or below.
// NOTE: For this to work properly you must edit the 'Amls' ability and change the levels to 2
// as well as typing something in "Level 2 - Text - Tooltip - Normal" text field.
//
// Enabling this will also cause the system to treat files written with .write("") as empty files.
//
// This setting is really only intended for those who were already using the system in their map
// prior to patch 1.31 and want to keep old files created with this system to still work.
private constant boolean BACKWARDS_COMPATABILITY = false
endglobals
private keyword FileInit
struct File extends array
static constant integer AbilityCount = 10
static constant integer PreloadLimit = 200
readonly static integer Counter = 0
readonly static integer array List
readonly static integer array AbilityList
readonly static boolean ReadEnabled
readonly string filename
private string buffer
static method open takes string filename returns thistype
local thistype this = .List[0]
if (this == 0) then
set this = Counter + 1
set Counter = this
else
set .List[0] = .List[this]
endif
set this.filename = filename
set this.buffer = null
debug if (this >= JASS_MAX_ARRAY_SIZE) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 120, "FileIO(" + filename + ") WARNING: Maximum instance limit " + I2S(JASS_MAX_ARRAY_SIZE) + " reached.")
debug endif
return this
endmethod
// This is used to detect invalid characters which aren't supported in preload files.
static if (DEBUG_MODE) then
private static method validateInput takes string contents returns string
local integer i = 0
local integer l = StringLength(contents)
local string ch = ""
loop
exitwhen i >= l
set ch = SubString(contents, i, i + 1)
if (ch == "\\") then
return ch
elseif (ch == "\"") then
return ch
endif
set i = i + 1
endloop
return null
endmethod
endif
method write takes string contents returns thistype
local integer i = 0
local integer c = 0
local integer len = StringLength(contents)
local integer lev = 0
local string prefix = "-" // this is used to signify an empty string vs a null one
local string chunk
debug if (.validateInput(contents) != null) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 120, "FileIO(" + filename + ") ERROR: Invalid character |cffffcc00" + .validateInput(contents) + "|r")
debug return this
debug endif
set this.buffer = null
// Check if the string is empty. If null, the contents will be cleared.
if (contents == "") then
set len = len + 1
endif
// Begin to generate the file
call PreloadGenClear()
call PreloadGenStart()
loop
exitwhen i >= len
debug if (c >= .AbilityCount) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 120, "FileIO(" + filename + ") ERROR: String exceeds max length (" + I2S(.AbilityCount * .PreloadLimit) + ").|r")
debug endif
set lev = 0
static if (BACKWARDS_COMPATABILITY) then
if (c == 0) then
set lev = 1
set prefix = ""
else
set prefix = "-"
endif
endif
set chunk = SubString(contents, i, i + .PreloadLimit)
call Preload("\" )\ncall BlzSetAbilityTooltip(" + I2S(.AbilityList[c]) + ", \"" + prefix + chunk + "\", " + I2S(lev) + ")\n//")
set i = i + .PreloadLimit
set c = c + 1
endloop
call Preload("\" )\nendfunction\nfunction a takes nothing returns nothing\n //")
call PreloadGenEnd(this.filename)
return this
endmethod
method clear takes nothing returns thistype
return this.write(null)
endmethod
private method readPreload takes nothing returns string
local integer i = 0
local integer lev = 0
local string array original
local string chunk = ""
local string output = ""
loop
exitwhen i == .AbilityCount
set original[i] = BlzGetAbilityTooltip(.AbilityList[i], 0)
set i = i + 1
endloop
// Execute the preload file
call Preloader(this.filename)
// Read the output
set i = 0
loop
exitwhen i == .AbilityCount
set lev = 0
// Read from ability index 1 instead of 0 if
// backwards compatability is enabled
static if (BACKWARDS_COMPATABILITY) then
if (i == 0) then
set lev = 1
endif
endif
// Make sure the tooltip has changed
set chunk = BlzGetAbilityTooltip(.AbilityList[i], lev)
if (chunk == original[i]) then
if (i == 0 and output == "") then
return null // empty file
endif
return output
endif
// Check if the file is an empty string or null
static if not (BACKWARDS_COMPATABILITY) then
if (i == 0) then
if (SubString(chunk, 0, 1) != "-") then
return null // empty file
endif
set chunk = SubString(chunk, 1, StringLength(chunk))
endif
endif
// Remove the prefix
if (i > 0) then
set chunk = SubString(chunk, 1, StringLength(chunk))
endif
// Restore the tooltip and append the chunk
call BlzSetAbilityTooltip(.AbilityList[i], original[i], lev)
set output = output + chunk
set i = i + 1
endloop
return output
endmethod
method close takes nothing returns nothing
if (this.buffer != null) then
call .write(.readPreload() + this.buffer)
set this.buffer = null
endif
set .List[this] = .List[0]
set .List[0] = this
endmethod
method readEx takes boolean close returns string
local string output = .readPreload()
local string buf = this.buffer
if (close) then
call this.close()
endif
if (output == null) then
return buf
endif
if (buf != null) then
set output = output + buf
endif
return output
endmethod
method read takes nothing returns string
return .readEx(false)
endmethod
method readAndClose takes nothing returns string
return .readEx(true)
endmethod
method appendBuffer takes string contents returns thistype
set .buffer = .buffer + contents
return this
endmethod
method readBuffer takes nothing returns string
return .buffer
endmethod
method writeBuffer takes string contents returns nothing
set .buffer = contents
endmethod
static method create takes string filename returns thistype
return .open(filename).write("")
endmethod
implement FileInit
endstruct
private module FileInit
private static method onInit takes nothing returns nothing
local string originalTooltip
// We can't use a single ability with multiple levels because
// tooltips return the first level's value if the value hasn't
// been set. This way we don't need to edit any object editor data.
set File.AbilityList[0] = 'Amls'
set File.AbilityList[1] = 'Aroc'
set File.AbilityList[2] = 'Amic'
set File.AbilityList[3] = 'Amil'
set File.AbilityList[4] = 'Aclf'
set File.AbilityList[5] = 'Acmg'
set File.AbilityList[6] = 'Adef'
set File.AbilityList[7] = 'Adis'
set File.AbilityList[8] = 'Afbt'
set File.AbilityList[9] = 'Afbk'
// Backwards compatability check
static if (BACKWARDS_COMPATABILITY) then
static if (DEBUG_MODE) then
set originalTooltip = BlzGetAbilityTooltip(File.AbilityList[0], 1)
call BlzSetAbilityTooltip(File.AbilityList[0], SCOPE_PREFIX, 1)
if (BlzGetAbilityTooltip(File.AbilityList[0], 1) == originalTooltip) then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 120, "FileIO WARNING: Backwards compatability enabled but \"" + GetObjectName(File.AbilityList[0]) + "\" isn't setup properly.|r")
endif
endif
endif
// Read check
set File.ReadEnabled = File.open("FileTester.pld").write(SCOPE_PREFIX).readAndClose() == SCOPE_PREFIX
endmethod
endmodule
public function Write takes string filename, string contents returns nothing
call File.open(filename).write(contents).close()
endfunction
public function Read takes string filename returns string
return File.open(filename).readEx(true)
endfunction
endlibrary
library BigNum
//prefer algebraic approach because of real subtraction issues
function log takes real y, real base returns real
local real x
local real factor = 1.0
local real logy = 0.0
local real sign = 1.0
if(y < 0.) then
return 0.0
endif
if(y < 1.) then
set y = 1.0/y
set sign = -1.0
endif
//Chop out powers of the base
loop
exitwhen y < 1.0001 //decrease this ( bounded below by 1) to improve precision
if(y > base) then
set y = y / base
set logy = logy + factor
else
set base = SquareRoot(base) //If you use just one base a lot, precompute its squareroots
set factor = factor / 2.
endif
endloop
return sign*logy
endfunction
struct BigNum_l
integer leaf
BigNum_l next
debug static integer nalloc = 0
static method create takes nothing returns BigNum_l
local BigNum_l bl = BigNum_l.allocate()
set bl.next = 0
set bl.leaf = 0
debug set BigNum_l.nalloc = BigNum_l.nalloc + 1
return bl
endmethod
method onDestroy takes nothing returns nothing
debug set BigNum_l.nalloc = BigNum_l.nalloc - 1
endmethod
//true: want destroy
method Clean takes nothing returns boolean
if .next == 0 and .leaf == 0 then
return true
elseif .next != 0 and .next.Clean() then
call .next.destroy()
set .next = 0
return .leaf == 0
else
return false
endif
endmethod
method DivSmall takes integer base, integer denom returns integer
local integer quotient
local integer remainder = 0
local integer num
if .next != 0 then
set remainder = .next.DivSmall(base,denom)
endif
set num = .leaf + remainder*base
set quotient = num/denom
set remainder = num - quotient*denom
set .leaf = quotient
return remainder
endmethod
endstruct
struct BigNum
BigNum_l list
integer base
static method create takes integer base returns BigNum
local BigNum b = BigNum.allocate()
set b.list = 0
set b.base = base
return b
endmethod
method onDestroy takes nothing returns nothing
local BigNum_l cur = .list
local BigNum_l next
loop
exitwhen cur == 0
set next = cur.next
call cur.destroy()
set cur = next
endloop
endmethod
method IsZero takes nothing returns boolean
local BigNum_l cur = .list
loop
exitwhen cur == 0
if cur.leaf != 0 then
return false
endif
set cur = cur.next
endloop
return true
endmethod
method Dump takes nothing returns nothing
local BigNum_l cur = .list
local string s = ""
loop
exitwhen cur == 0
set s = I2S(cur.leaf)+" "+s
set cur = cur.next
endloop
call BJDebugMsg(s)
endmethod
method Clean takes nothing returns nothing
local BigNum_l cur = .list
call cur.Clean()
endmethod
//fails if bignum is null
//BASE() + carry must be less than MAXINT()
method AddSmall takes integer carry returns nothing
local BigNum_l next
local BigNum_l cur = .list
local integer sum
if cur == 0 then
set cur = BigNum_l.create()
set .list = cur
endif
loop
exitwhen carry == 0
set sum = cur.leaf + carry
set carry = sum / .base
set sum = sum - carry*.base
set cur.leaf = sum
if cur.next == 0 then
set cur.next = BigNum_l.create()
endif
set cur = cur.next
endloop
endmethod
//x*BASE() must be less than MAXINT()
method MulSmall takes integer x returns nothing
local BigNum_l cur = .list
local integer product
local integer remainder
local integer carry = 0
loop
exitwhen cur == 0 and carry == 0
set product = x * cur.leaf + carry
set carry = product/.base
set remainder = product - carry*.base
set cur.leaf = remainder
if cur.next == 0 and carry != 0 then
set cur.next = BigNum_l.create()
endif
set cur = cur.next
endloop
endmethod
//Returns remainder
method DivSmall takes integer denom returns integer
return .list.DivSmall(.base,denom)
endmethod
method LastDigit takes nothing returns integer
local BigNum_l cur = .list
local BigNum_l next
loop
set next = cur.next
exitwhen next == 0
set cur = next
endloop
return cur.leaf
endmethod
endstruct
private function prop_Allocator1 takes nothing returns boolean
local BigNum b1
local BigNum b2
set b1 = BigNum.create(37)
call b1.destroy()
set b2 = BigNum.create(37)
call b2.destroy()
return b1 == b2
endfunction
private function prop_Allocator2 takes nothing returns boolean
local BigNum b1
local boolean b = false
set b1 = BigNum.create(37)
call b1.AddSmall(17)
call b1.MulSmall(19)
debug if BigNum_l.nalloc < 1 then
debug return false
debug endif
call b1.destroy()
debug set b = BigNum_l.nalloc == 0
return b
endfunction
private function prop_Arith takes nothing returns boolean
local BigNum b1
set b1 = BigNum.create(37)
call b1.AddSmall(73)
call b1.MulSmall(39)
call b1.AddSmall(17)
//n = 2864
if b1.DivSmall(100) != 64 then
return false
elseif b1.DivSmall(7) != 0 then
return false
elseif b1.IsZero() then
return false
elseif b1.DivSmall(3) != 1 then
return false
elseif b1.DivSmall(3) != 1 then
return false
elseif not b1.IsZero() then
return false
endif
return true
endfunction
endlibrary
//TESH.scrollpos=177
//TESH.alwaysfold=0
library Multiboard /* v2.0.0.1
*************************************************************************************
*
* Multiboard Struct API that actually works and is actually easy to use.
*
*************************************************************************************
*
* */uses/*
*
* */ Table /* hiveworkshop.com/forums/jass-functions-413/snippet-new-table-188084/
*
************************************************************************************
*
* struct Multiboard
*
* string title
* boolean display
* boolean minimize
* boolean suppress
*
* real width= (set only)
* string icon= (set only)
* string text= (set only)
*
* readonly MultiboardRow row
* readonly MultiboardColumn column
*
* this[row][column] -> MultiboardItem
*
* static method create takes integer rowCount, integer columnCount returns Multiboard
* method destroy takes nothing returns nothing
*
* method clear takes nothing returns nothing
*
* method setTitleColor takes integer red, integer green, integer blue, integer alpha returns nothing
* method setColor takes integer red, integer green, integer blue, integer alpha returns nothing
* method setStyle takes boolean showValues, boolean showIcons returns nothing
*
************************************************************************************
*
* struct MultiboardRow extends array
* struct MultiboardColumn extends array
*
* integer count
* - row.count
*
* string text
* string icon=
* real width=
* - row[0].width
*
* method setColor takes integer red, integer green, integer blue, integer alpha returns nothing
* method setStyle takes boolean showValue, boolean showIcon returns nothing
* - row[0].setStyle
*
************************************************************************************
*
* struct MultiboardItem extends array
*
* string text= (set only)
* string icon= (set only)
* real width= (set only)
*
* method setColor takes integer red, integer green, integer blue, integer alpha returns nothing
* method setStyle takes boolean showValue, boolean showIcon returns nothing
*
************************************************************************************/
globals
private Table table
private Table table2
private integer array r
private integer ic = 0
private multiboard array boardp
private integer array rc
private integer array cc
private boolean array suppressed
endglobals
private module Init
private static method onInit takes nothing returns nothing
set table = Table.create()
set table2 = Table.create()
endmethod
endmodule
struct MultiboardItem extends array
method operator text= takes string value returns nothing
call MultiboardSetItemValue(table.multiboarditem[this], value)
endmethod
method setColor takes integer red, integer green, integer blue, integer alpha returns nothing
call MultiboardSetItemValueColor(table.multiboarditem[this], red, green, blue, alpha)
endmethod
method setStyle takes boolean showValue, boolean showIcon returns nothing
call MultiboardSetItemStyle(table.multiboarditem[this], showValue, showIcon)
endmethod
method operator icon= takes string str returns nothing
call MultiboardSetItemIcon(table.multiboarditem[this], str)
endmethod
method operator width= takes real percent returns nothing
call MultiboardSetItemWidth(table.multiboarditem[this], percent)
endmethod
implement Init
endstruct
//! textmacro MULTIBOARD_LOOPER takes ROW, TABLE, CODE
local multiboarditem mb
loop
exitwhen 0 == $ROW$
set mb = $TABLE$.multiboarditem[this]
call $CODE$
set this = this + 1
set $ROW$ = $ROW$ - 1
endloop
set mb = null
//! endtextmacro
private keyword Multiboard2D
private keyword getItems
private keyword clearItems
struct Multiboard extends array
method getItems takes nothing returns nothing
local integer row = rc[this]
local integer column
local multiboarditem mb
loop
set column = cc[this]
loop
set mb = MultiboardGetItem(boardp[this], row, column)
set table.multiboarditem[(this*500+row)*500+column] = mb
set table2.multiboarditem[(this*500+column)*500+row] = mb
exitwhen 0 == column
set column = column - 1
endloop
exitwhen 0 == row
set row = row - 1
endloop
set mb = null
endmethod
method clearItems takes nothing returns nothing
local integer row = rc[this]
local integer column
loop
set column = cc[this]
loop
call MultiboardReleaseItem(table.multiboarditem[(this*500+row)*500+column])
call table.handle.remove((this*500+row)*500+column)
call table2.handle.remove((this*500+column)*500+row)
exitwhen 0 == column
set column = column - 1
endloop
exitwhen 0 == row
set row = row - 1
endloop
endmethod
static method create takes integer rowCount, integer columnCount returns thistype
local thistype this = r[0]
if (0 == this) then
set this = ic + 1
set ic = this
else
set suppressed[this] = false
set r[0] = r[this]
endif
set boardp[this] = CreateMultiboard()
call MultiboardSetColumnCount(boardp[this], columnCount)
call MultiboardSetRowCount(boardp[this], rowCount)
set rc[this] = rowCount
set cc[this] = columnCount
call getItems()
return this
endmethod
method destroy takes nothing returns nothing
set r[this] = r[0]
set r[0] = this
call clearItems()
call DestroyMultiboard(boardp[this])
set boardp[this] = null
endmethod
method clear takes nothing returns nothing
call MultiboardClear(boardp[this])
endmethod
method operator display takes nothing returns boolean
return IsMultiboardDisplayed(boardp[this])
endmethod
method operator display= takes boolean b returns nothing
call MultiboardDisplay(boardp[this], b)
endmethod
method operator minimize takes nothing returns boolean
return IsMultiboardMinimized(boardp[this])
endmethod
method operator minimize= takes boolean b returns nothing
call MultiboardMinimize(boardp[this], b)
endmethod
method operator title takes nothing returns string
return MultiboardGetTitleText(boardp[this])
endmethod
method operator title= takes string txt returns nothing
call MultiboardSetTitleText(boardp[this], txt)
endmethod
method setTitleColor takes integer red, integer green, integer blue, integer alpha returns nothing
call MultiboardSetTitleTextColor(boardp[this], red, green, blue, alpha)
endmethod
method operator suppress takes nothing returns boolean
return suppressed[this]
endmethod
method operator suppress= takes boolean b returns nothing
set suppressed[this] = b
call MultiboardSuppressDisplay(b)
endmethod
method operator width= takes real percent returns nothing
call MultiboardSetItemsWidth(boardp[this], percent)
endmethod
method operator row takes nothing returns MultiboardRow
return this
endmethod
method operator column takes nothing returns MultiboardColumn
return this
endmethod
method operator [] takes integer row returns Multiboard2D
return this*500+row
endmethod
method setColor takes integer red, integer green, integer blue, integer alpha returns nothing
call MultiboardSetItemsValueColor(boardp[this], red, green, blue, alpha)
endmethod
method setStyle takes boolean showValues, boolean showIcons returns nothing
call MultiboardSetItemsStyle(boardp[this], showValues, showIcons)
endmethod
method operator icon= takes string txt returns nothing
call MultiboardSetItemsIcon(boardp[this], txt)
endmethod
method operator text= takes string txt returns nothing
call MultiboardSetItemsValue(boardp[this], txt)
endmethod
endstruct
private struct MultiboardSet extends array
method text takes string v, integer c, Table t returns nothing
//! runtextmacro MULTIBOARD_LOOPER("c", "t", "MultiboardSetItemValue(mb, v)")
endmethod
method color takes integer red, integer green, integer blue, integer alpha, integer c, Table t returns nothing
//! runtextmacro MULTIBOARD_LOOPER("c", "t", "MultiboardSetItemValueColor(mb, red, green, blue, alpha)")
endmethod
method style takes boolean v, boolean i, integer c, Table t returns nothing
//! runtextmacro MULTIBOARD_LOOPER("c", "t", "MultiboardSetItemStyle(mb, v, i)")
endmethod
method icon takes string s, integer c, Table t returns nothing
//! runtextmacro MULTIBOARD_LOOPER("c", "t", "MultiboardSetItemIcon(mb, s)")
endmethod
method width takes real p, integer c, Table t returns nothing
//! runtextmacro MULTIBOARD_LOOPER("c", "t", "MultiboardSetItemWidth(mb, p)")
endmethod
endstruct
struct MultiboardColumn extends array
method operator count takes nothing returns integer
return MultiboardGetColumnCount(boardp[this])
endmethod
method operator count= takes integer columns returns nothing
call Multiboard(this).clearItems()
call MultiboardSetColumnCount(boardp[this], columns)
set cc[this] = columns
call Multiboard(this).getItems()
endmethod
method operator text= takes string value returns nothing
call MultiboardSet(this).text(value, rc[this/250000], table2)
endmethod
method setColor takes integer red, integer green, integer blue, integer alpha returns nothing
call MultiboardSet(this).color(red, green, blue, alpha, rc[this/250000], table2)
endmethod
method setStyle takes boolean showValue, boolean showIcon returns nothing
call MultiboardSet(this).style(showValue, showIcon, rc[this/250000], table2)
endmethod
method operator icon= takes string str returns nothing
call MultiboardSet(this).icon(str, rc[this/250000], table2)
endmethod
method operator width= takes real percent returns nothing
call MultiboardSet(this).width(percent, rc[this/250000], table2)
endmethod
method operator [] takes integer column returns thistype
return (this*500+column)*500
endmethod
endstruct
struct MultiboardRow extends array
method operator count takes nothing returns integer
return MultiboardGetRowCount(boardp[this])
endmethod
method operator count= takes integer rows returns nothing
call Multiboard(this).clearItems()
call MultiboardSetRowCount(boardp[this], rows)
set rc[this] = rows
call Multiboard(this).getItems()
endmethod
method operator text= takes string value returns nothing
call MultiboardSet(this).text(value, cc[this/250000], table)
endmethod
method setColor takes integer red, integer green, integer blue, integer alpha returns nothing
call MultiboardSet(this).color(red, green, blue, alpha, cc[this/250000], table)
endmethod
method setStyle takes boolean showValue, boolean showIcon returns nothing
call MultiboardSet(this).style(showValue, showIcon, cc[this/250000], table)
endmethod
method operator icon= takes string str returns nothing
call MultiboardSet(this).icon(str, cc[this/250000], table)
endmethod
method operator width= takes real percent returns nothing
call MultiboardSet(this).width(percent,cc[this/250000], table)
endmethod
method operator [] takes integer row returns thistype
return (this*500+row)*500
endmethod
endstruct
private struct Multiboard2D extends array
method operator [] takes integer column returns MultiboardItem
return this*500+column
endmethod
endstruct
endlibrary
library PlayerUtils
/**************************************************************
*
* v1.2.9 by TriggerHappy
*
* This library provides a struct which caches data about players
* as well as provides functionality for manipulating player colors.
*
* Constants
* ------------------
*
* force FORCE_PLAYING - Player group of everyone who is playing.
*
* Struct API
* -------------------
* struct User
*
* static method fromIndex takes integer i returns User
* static method fromLocal takes nothing returns User
* static method fromPlaying takes integer id returns User
*
* static method operator [] takes integer id returns User
* static method operator count takes nothing returns integer
*
* method operator name takes nothing returns string
* method operator name= takes string name returns nothing
* method operator color takes nothing returns playercolor
* method operator color= takes playercolor c returns nothing
* method operator defaultColor takes nothing returns playercolor
* method operator hex takes nothing returns string
* method operator nameColored takes nothing returns string
*
* method toPlayer takes nothing returns player
* method colorUnits takes playercolor c returns nothing
*
* readonly string originalName
* readonly boolean isPlaying
* readonly static player Local
* readonly static integer LocalId
* readonly static integer AmountPlaying
* readonly static playercolor array Color
* readonly static player array PlayingPlayer
*
**************************************************************/
globals
// automatically change unit colors when changing player color
private constant boolean AUTO_COLOR_UNITS = true
// use an array for name / color lookups (instead of function calls)
private constant boolean ARRAY_LOOKUP = false
// this only applies if ARRAY_LOOKUP is true
private constant boolean HOOK_SAFETY = false // disable for speed, but only use the struct to change name/color safely
constant force FORCE_PLAYING = CreateForce()
private string array Name
private string array Hex
private string array OriginalHex
private playercolor array CurrentColor
endglobals
private keyword PlayerUtilsInit
struct User extends array
static constant integer NULL = bj_MAX_PLAYER_SLOTS
readonly player handle
readonly integer id
readonly thistype next
readonly thistype prev
readonly string originalName
readonly boolean isPlaying
readonly static thistype first
readonly static thistype last
readonly static player Local
readonly static integer LocalId
readonly static integer AmountPlaying = 0
readonly static playercolor array Color
static if not (LIBRARY_GroupUtils) then
readonly static group ENUM_GROUP = CreateGroup()
endif
static thistype array PlayingPlayer
static integer array PlayingPlayerIndex
// similar to Player(#)
static method fromIndex takes integer i returns thistype
return thistype(i)
endmethod
// similar to GetLocalPlayer
static method fromLocal takes nothing returns thistype
return thistype(thistype.LocalId)
endmethod
// access active players array
static method fromPlaying takes integer index returns thistype
return PlayingPlayer[index]
endmethod
static method operator [] takes player p returns thistype
return thistype(GetPlayerId(p))
endmethod
method toPlayer takes nothing returns player
return this.handle
endmethod
method operator name takes nothing returns string
static if (ARRAY_LOOKUP) then
return Name[this]
else
return GetPlayerName(this.handle)
endif
endmethod
method operator name= takes string newName returns nothing
call SetPlayerName(this.handle, newName)
static if (ARRAY_LOOKUP) then
static if not (HOOK_SAFETY) then
set Name[this] = newName
endif
endif
endmethod
method operator color takes nothing returns playercolor
static if (ARRAY_LOOKUP) then
return CurrentColor[this]
else
return GetPlayerColor(this.handle)
endif
endmethod
method operator hex takes nothing returns string
return OriginalHex[GetHandleId(this.color)]
endmethod
method operator color= takes playercolor c returns nothing
call SetPlayerColor(this.handle, c)
static if (ARRAY_LOOKUP) then
set CurrentColor[this] = c
static if not (HOOK_SAFETY) then
static if (AUTO_COLOR_UNITS) then
call this.colorUnits(color)
endif
endif
endif
endmethod
method operator defaultColor takes nothing returns playercolor
return Color[this]
endmethod
method operator nameColored takes nothing returns string
return hex + this.name + "|r"
endmethod
method colorUnits takes playercolor c returns nothing
local unit u
call GroupEnumUnitsOfPlayer(ENUM_GROUP, this.handle, null)
loop
set u = FirstOfGroup(ENUM_GROUP)
exitwhen u == null
call SetUnitColor(u, c)
call GroupRemoveUnit(ENUM_GROUP, u)
endloop
endmethod
static method onLeave takes nothing returns boolean
local thistype p = thistype[GetTriggerPlayer()]
local integer i = .PlayingPlayerIndex[p.id]
// clean up
call ForceRemovePlayer(FORCE_PLAYING, p.toPlayer())
// recycle index
set .AmountPlaying = .AmountPlaying - 1
set .PlayingPlayerIndex[i] = .PlayingPlayerIndex[.AmountPlaying]
set .PlayingPlayer[i] = .PlayingPlayer[.AmountPlaying]
if (.AmountPlaying == 1) then
set p.prev.next = User.NULL
set p.next.prev = User.NULL
else
set p.prev.next = p.next
set p.next.prev = p.prev
endif
set .last = .PlayingPlayer[.AmountPlaying]
set p.isPlaying = false
return false
endmethod
implement PlayerUtilsInit
endstruct
private module PlayerUtilsInit
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
local thistype p
set thistype.Local = GetLocalPlayer()
set thistype.LocalId = GetPlayerId(thistype.Local)
set OriginalHex[0] = "|cffff0303"
set OriginalHex[1] = "|cff0042ff"
set OriginalHex[2] = "|cff1ce6b9"
set OriginalHex[3] = "|cff540081"
set OriginalHex[4] = "|cfffffc01"
set OriginalHex[5] = "|cfffe8a0e"
set OriginalHex[6] = "|cff20c000"
set OriginalHex[7] = "|cffe55bb0"
set OriginalHex[8] = "|cff959697"
set OriginalHex[9] = "|cff7ebff1"
set OriginalHex[10] = "|cff106246"
set OriginalHex[11] = "|cff4e2a04"
if (bj_MAX_PLAYERS > 12) then
set OriginalHex[12] = "|cff9B0000"
set OriginalHex[13] = "|cff0000C3"
set OriginalHex[14] = "|cff00EAFF"
set OriginalHex[15] = "|cffBE00FE"
set OriginalHex[16] = "|cffEBCD87"
set OriginalHex[17] = "|cffF8A48B"
set OriginalHex[18] = "|cffBFFF80"
set OriginalHex[19] = "|cffDCB9EB"
set OriginalHex[20] = "|cff282828"
set OriginalHex[21] = "|cffEBF0FF"
set OriginalHex[22] = "|cff00781E"
set OriginalHex[23] = "|cffA46F33"
endif
set thistype.first = User.NULL
loop
exitwhen i == bj_MAX_PLAYERS
set p = User(i)
set p.handle = Player(i)
set p.id = i
set thistype.Color[i] = GetPlayerColor(p.handle)
set CurrentColor[i] = thistype.Color[i]
if (GetPlayerController(p.handle) == MAP_CONTROL_USER and GetPlayerSlotState(p.handle) == PLAYER_SLOT_STATE_PLAYING) then
set .PlayingPlayer[AmountPlaying] = p
set .PlayingPlayerIndex[i] = .AmountPlaying
set .last = i
if (.first == User.NULL) then
set .first = i
set User(i).next = User.NULL
set User(i).prev = User.NULL
else
set User(i).prev = PlayingPlayer[AmountPlaying-1].id
set PlayingPlayer[AmountPlaying-1].next = User(i)
set User(i).next = User.NULL
endif
set p.isPlaying = true
call TriggerRegisterPlayerEvent(t, p.handle, EVENT_PLAYER_LEAVE)
call ForceAddPlayer(FORCE_PLAYING, p.handle)
set Hex[p] = OriginalHex[GetHandleId(thistype.Color[i])]
set .AmountPlaying = .AmountPlaying + 1
endif
set Name[p] = GetPlayerName(p.handle)
set p.originalName=Name[p]
set i = i + 1
endloop
call TriggerAddCondition(t, Filter(function thistype.onLeave))
endmethod
endmodule
//===========================================================================
static if (ARRAY_LOOKUP) then
static if (HOOK_SAFETY) then
private function SetPlayerNameHook takes player whichPlayer, string name returns nothing
set Name[GetPlayerId(whichPlayer)] = name
endfunction
private function SetPlayerColorHook takes player whichPlayer, playercolor color returns nothing
local User p = User[whichPlayer]
set Hex[p] = OriginalHex[GetHandleId(color)]
set CurrentColor[p] = color
static if (AUTO_COLOR_UNITS) then
call p.colorUnits(color)
endif
endfunction
hook SetPlayerName SetPlayerNameHook
hook SetPlayerColor SetPlayerColorHook
endif
endif
endlibrary
library Table /* made by Bribe, special thanks to Vexorian & Nestharus, version 4.1.0.1.
One map, one hashtable. Welcome to NewTable 4.1.0.1
This newest iteration of Table introduces the new HashTable struct.
You can now instantiate HashTables which enables the use of large
parent and large child keys, just like a standard hashtable. Previously,
the user would have to instantiate a Table to do this on their own which -
while doable - is something the user should not have to do if I can add it
to this resource myself (especially if they are inexperienced).
This library was originally called NewTable so it didn't conflict with
the API of Table by Vexorian. However, the damage is done and it's too
late to change the library name now. To help with damage control, I
have provided an extension library called TableBC, which bridges all
the functionality of Vexorian's Table except for 2-D string arrays &
the ".flush(integer)" method. I use ".flush()" to flush a child hash-
table, because I wanted the API in NewTable to reflect the API of real
hashtables (I thought this would be more intuitive).
API
------------
struct Table
| static method create takes nothing returns Table
| create a new Table
|
| method destroy takes nothing returns nothing
| destroy it
|
| method flush takes nothing returns nothing
| flush all stored values inside of it
|
| method remove takes integer key returns nothing
| remove the value at index "key"
|
| method operator []= takes integer key, $TYPE$ value returns nothing
| assign "value" to index "key"
|
| method operator [] takes integer key returns $TYPE$
| load the value at index "key"
|
| method has takes integer key returns boolean
| whether or not the key was assigned
|
----------------
struct TableArray
| static method operator [] takes integer array_size returns TableArray
| create a new array of Tables of size "array_size"
|
| method destroy takes nothing returns nothing
| destroy it
|
| method flush takes nothing returns nothing
| flush and destroy it
|
| method operator size takes nothing returns integer
| returns the size of the TableArray
|
| method operator [] takes integer key returns Table
| returns a Table accessible exclusively to index "key"
*/
globals
private integer less = 0 //Index generation for TableArrays (below 0).
private integer more = 8190 //Index generation for Tables.
//Configure it if you use more than 8190 "key" variables in your map (this will never happen though).
private hashtable ht = InitHashtable()
private key sizeK
private key listK
endglobals
private struct dex extends array
static method operator size takes nothing returns Table
return sizeK
endmethod
static method operator list takes nothing returns Table
return listK
endmethod
endstruct
private struct handles extends array
method has takes integer key returns boolean
return HaveSavedHandle(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSavedHandle(ht, this, key)
endmethod
endstruct
private struct agents extends array
method operator []= takes integer key, agent value returns nothing
call SaveAgentHandle(ht, this, key, value)
endmethod
endstruct
//! textmacro NEW_ARRAY_BASIC takes SUPER, FUNC, TYPE
private struct $TYPE$s extends array
method operator [] takes integer key returns $TYPE$
return Load$FUNC$(ht, this, key)
endmethod
method operator []= takes integer key, $TYPE$ value returns nothing
call Save$FUNC$(ht, this, key, value)
endmethod
method has takes integer key returns boolean
return HaveSaved$SUPER$(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSaved$SUPER$(ht, this, key)
endmethod
endstruct
private module $TYPE$m
method operator $TYPE$ takes nothing returns $TYPE$s
return this
endmethod
endmodule
//! endtextmacro
//! textmacro NEW_ARRAY takes FUNC, TYPE
private struct $TYPE$s extends array
method operator [] takes integer key returns $TYPE$
return Load$FUNC$Handle(ht, this, key)
endmethod
method operator []= takes integer key, $TYPE$ value returns nothing
call Save$FUNC$Handle(ht, this, key, value)
endmethod
method has takes integer key returns boolean
return HaveSavedHandle(ht, this, key)
endmethod
method remove takes integer key returns nothing
call RemoveSavedHandle(ht, this, key)
endmethod
endstruct
private module $TYPE$m
method operator $TYPE$ takes nothing returns $TYPE$s
return this
endmethod
endmodule
//! endtextmacro
//Run these textmacros to include the entire hashtable API as wrappers.
//Don't be intimidated by the number of macros - Vexorian's map optimizer is
//supposed to kill functions which inline (all of these functions inline).
//! runtextmacro NEW_ARRAY_BASIC("Real", "Real", "real")
//! runtextmacro NEW_ARRAY_BASIC("Boolean", "Boolean", "boolean")
//! runtextmacro NEW_ARRAY_BASIC("String", "Str", "string")
//New textmacro to allow table.integer[] syntax for compatibility with textmacros that might desire it.
//! runtextmacro NEW_ARRAY_BASIC("Integer", "Integer", "integer")
//! runtextmacro NEW_ARRAY("Player", "player")
//! runtextmacro NEW_ARRAY("Widget", "widget")
//! runtextmacro NEW_ARRAY("Destructable", "destructable")
//! runtextmacro NEW_ARRAY("Item", "item")
//! runtextmacro NEW_ARRAY("Unit", "unit")
//! runtextmacro NEW_ARRAY("Ability", "ability")
//! runtextmacro NEW_ARRAY("Timer", "timer")
//! runtextmacro NEW_ARRAY("Trigger", "trigger")
//! runtextmacro NEW_ARRAY("TriggerCondition", "triggercondition")
//! runtextmacro NEW_ARRAY("TriggerAction", "triggeraction")
//! runtextmacro NEW_ARRAY("TriggerEvent", "event")
//! runtextmacro NEW_ARRAY("Force", "force")
//! runtextmacro NEW_ARRAY("Group", "group")
//! runtextmacro NEW_ARRAY("Location", "location")
//! runtextmacro NEW_ARRAY("Rect", "rect")
//! runtextmacro NEW_ARRAY("BooleanExpr", "boolexpr")
//! runtextmacro NEW_ARRAY("Sound", "sound")
//! runtextmacro NEW_ARRAY("Effect", "effect")
//! runtextmacro NEW_ARRAY("UnitPool", "unitpool")
//! runtextmacro NEW_ARRAY("ItemPool", "itempool")
//! runtextmacro NEW_ARRAY("Quest", "quest")
//! runtextmacro NEW_ARRAY("QuestItem", "questitem")
//! runtextmacro NEW_ARRAY("DefeatCondition", "defeatcondition")
//! runtextmacro NEW_ARRAY("TimerDialog", "timerdialog")
//! runtextmacro NEW_ARRAY("Leaderboard", "leaderboard")
//! runtextmacro NEW_ARRAY("Multiboard", "multiboard")
//! runtextmacro NEW_ARRAY("MultiboardItem", "multiboarditem")
//! runtextmacro NEW_ARRAY("Trackable", "trackable")
//! runtextmacro NEW_ARRAY("Dialog", "dialog")
//! runtextmacro NEW_ARRAY("Button", "button")
//! runtextmacro NEW_ARRAY("TextTag", "texttag")
//! runtextmacro NEW_ARRAY("Lightning", "lightning")
//! runtextmacro NEW_ARRAY("Image", "image")
//! runtextmacro NEW_ARRAY("Ubersplat", "ubersplat")
//! runtextmacro NEW_ARRAY("Region", "region")
//! runtextmacro NEW_ARRAY("FogState", "fogstate")
//! runtextmacro NEW_ARRAY("FogModifier", "fogmodifier")
//! runtextmacro NEW_ARRAY("Hashtable", "hashtable")
struct Table extends array
// Implement modules for intuitive syntax (tb.handle; tb.unit; etc.)
implement realm
implement integerm
implement booleanm
implement stringm
implement playerm
implement widgetm
implement destructablem
implement itemm
implement unitm
implement abilitym
implement timerm
implement triggerm
implement triggerconditionm
implement triggeractionm
implement eventm
implement forcem
implement groupm
implement locationm
implement rectm
implement boolexprm
implement soundm
implement effectm
implement unitpoolm
implement itempoolm
implement questm
implement questitemm
implement defeatconditionm
implement timerdialogm
implement leaderboardm
implement multiboardm
implement multiboarditemm
implement trackablem
implement dialogm
implement buttonm
implement texttagm
implement lightningm
implement imagem
implement ubersplatm
implement regionm
implement fogstatem
implement fogmodifierm
implement hashtablem
method operator handle takes nothing returns handles
return this
endmethod
method operator agent takes nothing returns agents
return this
endmethod
//set this = tb[GetSpellAbilityId()]
method operator [] takes integer key returns Table
return LoadInteger(ht, this, key) //return this.integer[key]
endmethod
//set tb[389034] = 8192
method operator []= takes integer key, Table tb returns nothing
call SaveInteger(ht, this, key, tb) //set this.integer[key] = tb
endmethod
//set b = tb.has(2493223)
method has takes integer key returns boolean
return HaveSavedInteger(ht, this, key) //return this.integer.has(key)
endmethod
//call tb.remove(294080)
method remove takes integer key returns nothing
call RemoveSavedInteger(ht, this, key) //call this.integer.remove(key)
endmethod
//Remove all data from a Table instance
method flush takes nothing returns nothing
call FlushChildHashtable(ht, this)
endmethod
//local Table tb = Table.create()
static method create takes nothing returns Table
local Table this = dex.list[0]
if this == 0 then
set this = more + 1
set more = this
else
set dex.list[0] = dex.list[this]
call dex.list.remove(this) //Clear hashed memory
endif
debug set dex.list[this] = -1
return this
endmethod
// Removes all data from a Table instance and recycles its index.
//
// call tb.destroy()
//
method destroy takes nothing returns nothing
debug if dex.list[this] != -1 then
debug call BJDebugMsg("Table Error: Tried to double-free instance: " + I2S(this))
debug return
debug endif
call this.flush()
set dex.list[this] = dex.list[0]
set dex.list[0] = this
endmethod
//! runtextmacro optional TABLE_BC_METHODS()
endstruct
//! runtextmacro optional TABLE_BC_STRUCTS()
struct TableArray extends array
//Returns a new TableArray to do your bidding. Simply use:
//
// local TableArray ta = TableArray[array_size]
//
static method operator [] takes integer array_size returns TableArray
local Table tb = dex.size[array_size] //Get the unique recycle list for this array size
local TableArray this = tb[0] //The last-destroyed TableArray that had this array size
debug if array_size <= 0 then
debug call BJDebugMsg("TypeError: Invalid specified TableArray size: " + I2S(array_size))
debug return 0
debug endif
if this == 0 then
set this = less - array_size
set less = this
else
set tb[0] = tb[this] //Set the last destroyed to the last-last destroyed
call tb.remove(this) //Clear hashed memory
endif
set dex.size[this] = array_size //This remembers the array size
return this
endmethod
//Returns the size of the TableArray
method operator size takes nothing returns integer
return dex.size[this]
endmethod
//This magic method enables two-dimensional[array][syntax] for Tables,
//similar to the two-dimensional utility provided by hashtables them-
//selves.
//
//ta[integer a].unit[integer b] = unit u
//ta[integer a][integer c] = integer d
//
//Inline-friendly when not running in debug mode
//
method operator [] takes integer key returns Table
static if DEBUG_MODE then
local integer i = this.size
if i == 0 then
call BJDebugMsg("IndexError: Tried to get key from invalid TableArray instance: " + I2S(this))
return 0
elseif key < 0 or key >= i then
call BJDebugMsg("IndexError: Tried to get key [" + I2S(key) + "] from outside TableArray bounds: " + I2S(i))
return 0
endif
endif
return this + key
endmethod
//Destroys a TableArray without flushing it; I assume you call .flush()
//if you want it flushed too. This is a public method so that you don't
//have to loop through all TableArray indices to flush them if you don't
//need to (ie. if you were flushing all child-keys as you used them).
//
method destroy takes nothing returns nothing
local Table tb = dex.size[this.size]
debug if this.size == 0 then
debug call BJDebugMsg("TypeError: Tried to destroy an invalid TableArray: " + I2S(this))
debug return
debug endif
if tb == 0 then
//Create a Table to index recycled instances with their array size
set tb = Table.create()
set dex.size[this.size] = tb
endif
call dex.size.remove(this) //Clear the array size from hash memory
set tb[this] = tb[0]
set tb[0] = this
endmethod
private static Table tempTable
private static integer tempEnd
//Avoids hitting the op limit
private static method clean takes nothing returns nothing
local Table tb = .tempTable
local integer end = tb + 0x1000
if end < .tempEnd then
set .tempTable = end
call ForForce(bj_FORCE_PLAYER[0], function thistype.clean)
else
set end = .tempEnd
endif
loop
call tb.flush()
set tb = tb + 1
exitwhen tb == end
endloop
endmethod
//Flushes the TableArray and also destroys it. Doesn't get any more
//similar to the FlushParentHashtable native than this.
//
method flush takes nothing returns nothing
debug if this.size == 0 then
debug call BJDebugMsg("TypeError: Tried to flush an invalid TableArray instance: " + I2S(this))
debug return
debug endif
set .tempTable = this
set .tempEnd = this + this.size
call ForForce(bj_FORCE_PLAYER[0], function thistype.clean)
call this.destroy()
endmethod
endstruct
//NEW: Added in Table 4.0. A fairly simple struct but allows you to do more
//than that which was previously possible.
struct HashTable extends array
//Enables myHash[parentKey][childKey] syntax.
//Basically, it creates a Table in the place of the parent key if
//it didn't already get created earlier.
method operator [] takes integer index returns Table
local Table t = Table(this)[index]
if t == 0 then
set t = Table.create()
set Table(this)[index] = t //whoops! Forgot that line. I'm out of practice!
endif
return t
endmethod
//You need to call this on each parent key that you used if you
//intend to destroy the HashTable or simply no longer need that key.
method remove takes integer index returns nothing
local Table t = Table(this)[index]
if t != 0 then
call t.destroy()
call Table(this).remove(index)
endif
endmethod
//Added in version 4.1
method has takes integer index returns boolean
return Table(this).has(index)
endmethod
//HashTables are just fancy Table indices.
method destroy takes nothing returns nothing
call Table(this).destroy()
endmethod
//Like I said above...
static method create takes nothing returns thistype
return Table.create()
endmethod
endstruct
endlibrary