library UnitSoundSets initializer Init requires GetMainSelectedUnit, optional UnitSoundSetsPerUnit
/**
* Baradé's Unit Sound Sets 1.0
*
* Allows using custom unit sound sets without replacing existing ones or using a custom SLK file.
*
* Usage:
* - Disable the sound set of your unit type and then register the sounds using this system.
* - Import custom soundset files into your map.
* - Call this JASS code during the map initialization:
* call AddUnitSoundSetFromFiles('H0F2', "war3Imported\\HeroPaladin", "flac")
*
* 'H0F2' should be the raw code of your custom hero unit type.
* "war3Imported\\HeroPaladin" should be the prefix for all unit sound set files.
* "flac" should be the file extension for all unit sound set files.
*
* - Optional: If you want to have the talk animation in the portrait like in Warcraft III cinematics,
* use the following JASS code to configure it:
* call SetUnitSoundSetAnimationType('H0F2', PORTRAIT_ANIMATION_TYPE_CINEMATIC)
*
* - Optional: If you want to have the talk animation in the portrait with a prepared portrait model,
* use the following JASS code to configure it:
* call SetUnitSoundSetAnimationType('H0F2', PORTRAIT_ANIMATION_TYPE_ANIMATION)
* call SetUnitSoundSetPortraitModel('H0F2', "war3mapImported\\EasterBunny_Portrait.mdx")
* Modify the portrait model and rename "Portrait Talk" into "morph" and the other animations into "stand".
*
* - Optional: If you have shop buildings which should play custom sounds when selected by other
* players, use the following JASS code to register them:
* call AddUnitShopSoundSet('ngme')
*
* Replace the raw code with the one of your shop building type.
*
* The following suffixes for sound files are supported:
* Death
* What
* Yes
* YesAttack
* Ready
* WarCry
* Pissed
*
* Disable cinematic sub titles with ForceCinematicSubtitles or in the game settings.
* Selecting the same unit again will not play the next sound immediately but wait for the current sound
* to be finished. Selecting another unit will immediately play the sound of the other unit. This seems to be
* Warcraft's behavior.
*/
globals
// You will hear the pissed sounds after this number of clicks on the same unit.
constant integer PISSED_COUNTER = 3
// Shows no talk animation in the portrait (default).
constant integer PORTRAIT_ANIMATION_TYPE_NONE = 0
// Uses custom portrait frames without hidden HP and mana.
constant integer PORTRAIT_ANIMATION_TYPE_ANIMATION = 1
// Shows talk animations during the sounds as long as the unit is selected if this value is true.
constant integer PORTRAIT_ANIMATION_TYPE_CINEMATIC = 2
// Death : Whenver the unit dies, the Death Sound will be played.
constant integer array SOUND_DEATH
// What : Occurs when you click on the unit only. Replaced by Pissed Sounds if you click multiple times on the unit in a short time.
constant integer array SOUND_WHAT
// Yes : Occurs when you order the unit to do a "Friendly" Action.
constant integer array SOUND_YES
// YesAttack : Occurs when you order the unit to "Attack-Move", or an order similar to it.
constant integer array SOUND_YES_ATTACK
// Ready : Occurs only one time for a single unit, it is played when the unit is spawned by a building (Example : Barracks for Rifleman), or when they got revived by an Altar (Example : Paladin).
constant integer array SOUND_READY
// Warcry : Occurs when you order the unit to attack a specific unit.
constant integer array SOUND_WARCRY
// Pissed : When you click a lot of times on the unit, weird sounds will be played instead of normals, which are called Pissed Sounds.
constant integer array SOUND_PISSED
// Attack : Occurs when the unit starts attacking an enemy. (You don't have to click on the unit)
constant integer KEY_HAS_CUSTOM_SOUNDSET = 39
constant integer KEY_HAS_SHOP_SOUNDSET = 40
constant integer KEY_PORTRAIT_ANIMATION_TYPE = 41
constant integer KEY_PORTRAIT_MODEL = 42
private constant integer ORDER_ID_ATTACK = 851983
private constant integer ORDER_ID_ATTACK_GROUND = 851984
private constant integer ORDER_ID_ATTACK_ONCE = 851985
private constant integer ORDER_ID_MOVE = 851986
private constant integer ORDER_ID_PATROL = 851990
private constant integer ORDER_ID_SMART = 851971
private constant integer SOUND_PER_STACK=9
private hashtable h = InitHashtable()
private integer soundSetNb=0
// all this exists for the local player only and is never synchronized between players
private integer playerClickCounter = 0
private unit playerClickTarget = null
private sound playerSound = null
private unit playerSpeaker = null
private trigger selectionTrigger = CreateTrigger()
private trigger deselectionTrigger = CreateTrigger()
private trigger orderTrigger = CreateTrigger()
private trigger revivalTrigger = CreateTrigger()
private trigger trainTrigger = CreateTrigger()
private trigger hireTrigger = CreateTrigger()
private trigger deathTrigger = CreateTrigger()
endglobals
function RemoveAllUnitSoundSets takes nothing returns nothing
call FlushParentHashtable(h)
endfunction
function RemoveUnitSoundSet takes integer unitTypeId returns nothing
call FlushChildHashtable(h, unitTypeId)
endfunction
function AddUnitSoundSet takes integer unitTypeId, integer t, sound whichSound returns sound
if (whichSound != null) then
call SaveSoundHandle(h, unitTypeId, t, whichSound)
call SaveBoolean(h, unitTypeId, KEY_HAS_CUSTOM_SOUNDSET, true)
endif
return whichSound
endfunction
function HasUnitSoundSet takes integer unitTypeId returns boolean
return LoadBoolean(h, unitTypeId, KEY_HAS_CUSTOM_SOUNDSET)
endfunction
function SetUnitSoundSetById takes unit u, integer soundSetId returns nothing
call SaveInteger(h,GetHandleId(u),0,soundSetId)
endfunction
function GetSoundSetPath takes integer soundSetId returns string
return LoadStr(h,soundSetId,-1)
endfunction
// Returns 0 if not found
function GetSoundSetId takes string path returns integer
local integer i=1
loop
exitwhen i>soundSetNb
if GetSoundSetPath(i)==path then
return i
endif
set i=i+1
endloop
return 0 // not found
endfunction
function SetUnitSoundSet takes unit u, string path returns nothing
call SetUnitSoundSetById(u,GetSoundSetId(path))
endfunction
function GetSoundSoundSet takes sound s returns integer
return LoadInteger(h,GetHandleId(s),1)
endfunction
function GetSoundIndex takes sound s returns integer
return LoadInteger(h,GetHandleId(s),2)
endfunction
function AddSoundSetSound takes integer soundSetId, integer index, sound s returns sound
local integer sK=GetHandleId(s)
call SaveSoundHandle(h,soundSetId,index,s)
call SaveInteger(h,sK,1,soundSetId)
call SaveInteger(h,sK,2,index)
return s
endfunction
function AddSoundSetDeath takes integer soundSetId, sound whichSound, integer index returns sound
return AddSoundSetSound(soundSetId,SOUND_DEATH[index],whichSound)
endfunction
function AddSoundSetWhat takes integer soundSetId, sound whichSound, integer index returns sound
return AddSoundSetSound(soundSetId,SOUND_WHAT[index],whichSound)
endfunction
function AddSoundSetYes takes integer soundSetId, sound whichSound, integer index returns sound
return AddSoundSetSound(soundSetId,SOUND_YES[index], whichSound)
endfunction
function AddSoundSetYesAttack takes integer soundSetId, sound whichSound, integer index returns sound
return AddSoundSetSound(soundSetId,SOUND_YES_ATTACK[index],whichSound)
endfunction
function AddSoundSetReady takes integer soundSetId, sound whichSound, integer index returns sound
return AddSoundSetSound(soundSetId,SOUND_READY[index],whichSound)
endfunction
function AddSoundSetWarCry takes integer soundSetId, sound whichSound, integer index returns sound
return AddSoundSetSound(soundSetId,SOUND_WARCRY[index],whichSound)
endfunction
function AddSoundSetPissed takes integer soundSetId, sound whichSound, integer index returns sound
return AddSoundSetSound(soundSetId,SOUND_PISSED[index],whichSound)
endfunction
private function CreateSoundFromFile takes string filePath, string eaxSetting returns sound
local sound s = null
local integer duration = GetSoundFileDuration(filePath)
if duration>0 then
set s = CreateSound(filePath, false, false, true, 12700, 12700, eaxSetting)
call SetSoundDuration(s, duration)
endif
return s
endfunction
private function CreateSound3DFromFile takes string filePath, string eaxSetting returns sound
local sound soundHandle = null
local integer duration = GetSoundFileDuration(filePath)
if (duration > 0) then
set soundHandle = CreateSound(filePath, false, true, true, 12700, 12700, eaxSetting)
call SetSoundDuration(soundHandle, duration)
endif
return soundHandle
endfunction
function LoadSoundSetSub takes integer soundSetId, string extension returns nothing
local integer i=0
local string path=GetSoundSetPath(soundSetId)
if extension=="auto" then
call LoadSoundSetSub(soundSetId,"mp3")
call LoadSoundSetSub(soundSetId,"flac")
call LoadSoundSetSub(soundSetId,"wav")
else
loop
exitwhen i>=SOUND_PER_STACK
if i==0 then
if AddSoundSetDeath(soundSetId, CreateSound3DFromFile(path + "Death." + extension, "DefaultEAXON"),0)==null then
call AddSoundSetDeath(soundSetId, CreateSound3DFromFile(path + "Death1." + extension, "DefaultEAXON"),0)
endif
if AddSoundSetWarCry(soundSetId, CreateSoundFromFile(path + "WarCry." + extension, "DefaultEAXON"),0)==null then
call AddSoundSetWarCry(soundSetId, CreateSoundFromFile(path + "WarCry1." + extension, "DefaultEAXON"),0)
endif
if AddSoundSetReady(soundSetId, CreateSoundFromFile(path + "Ready." + extension, "DefaultEAXON"),0)==null then
call AddSoundSetReady(soundSetId, CreateSoundFromFile(path + "Ready1." + extension, "DefaultEAXON"),0)
endif
else
call AddSoundSetDeath(soundSetId, CreateSoundFromFile(path + "Death"+I2S(i+1)+"." + extension, "DefaultEAXON"),i)
call AddSoundSetReady(soundSetId, CreateSoundFromFile(path + "Ready"+I2S(i+1)+"." + extension, "HeroAcksEAX"),i)
call AddSoundSetWarCry(soundSetId, CreateSoundFromFile(path + "WarCry"+I2S(i+1)+"." + extension, "HeroAcksEAX"),i)
endif
call AddSoundSetWhat(soundSetId, CreateSoundFromFile(path + "What"+I2S(i+1)+"." + extension, "HeroAcksEAX"),i)
call AddSoundSetYes(soundSetId, CreateSoundFromFile(path + "Yes"+I2S(i+1)+"." + extension, "HeroAcksEAX"),i)
call AddSoundSetYesAttack(soundSetId, CreateSoundFromFile(path + "YesAttack"+I2S(i+1)+"." + extension, "HeroAcksEAX"),i)
call AddSoundSetPissed(soundSetId, CreateSoundFromFile(path + "Pissed"+I2S(i+1)+"." + extension, "HeroAcksEAX"),i)
set i=i+1
endloop
endif
endfunction
function IsSoundSetLoaded takes integer soundSetId returns boolean
return LoadBoolean(h,soundSetId,-2)
endfunction
function LoadSoundSet takes integer soundSetId returns integer
if soundSetId>0 and soundSetId<=soundSetNb and not IsSoundSetLoaded(soundSetId) then
call SaveBoolean(h,soundSetId,-2,true)
call LoadSoundSetSub(soundSetId,"auto")
endif
return soundSetId
endfunction
function CreateSoundSet takes string path returns integer
local integer soundSetId=GetSoundSetId(path)
if soundSetId==0 then
set soundSetNb=soundSetNb+1
call SaveStr(h,soundSetNb,-1,path)
set soundSetId=soundSetNb
endif
return soundSetId
endfunction
function GenerateSoundSet takes string path returns integer
return LoadSoundSet(CreateSoundSet(path))
endfunction
// Setting 0 for the unit will remove it
function SetUnitTypeSoundSetById takes integer uT, integer soundSetId returns nothing
call SaveInteger(h,uT,0,soundSetId)
endfunction
function SetUnitTypeSoundSet takes integer uT, string path returns nothing
call GenerateSoundSet(path)
call SetUnitTypeSoundSetById(uT,GetSoundSetId(path))
endfunction
function HasUnitShopSoundSet takes integer unitTypeId returns boolean
return LoadBoolean(h, unitTypeId, KEY_HAS_SHOP_SOUNDSET)
endfunction
function AddUnitShopSoundSet takes integer unitTypeId returns nothing
call SaveBoolean(h, unitTypeId, KEY_HAS_SHOP_SOUNDSET, true)
endfunction
function RemoveUnitShopSoundSet takes integer unitTypeId returns nothing
call SaveBoolean(h, unitTypeId, KEY_HAS_SHOP_SOUNDSET, false)
endfunction
private function HasControl takes player whichPlayer, unit whichUnit returns boolean
return GetOwningPlayer(whichUnit) == whichPlayer or GetPlayerAlliance(whichPlayer, GetOwningPlayer(whichUnit), ALLIANCE_SHARED_CONTROL)
endfunction
private function AlliesWithSharedControl takes player whichPlayer returns force
local force whichForce = CreateForce()
local integer i = 0
loop
exitwhen (i == bj_MAX_PLAYERS)
if (whichPlayer == Player(i) or GetPlayerAlliance(whichPlayer, Player(i), ALLIANCE_SHARED_CONTROL)) then
call ForceAddPlayer(whichForce, Player(i))
endif
set i = i + 1
endloop
return whichForce
endfunction
private function IsUnitSpeakingForPlayer takes unit whichUnit returns boolean
local boolean sameUnit = playerSpeaker == whichUnit
return sameUnit and playerSound != null and GetSoundIsPlaying(playerSound)
endfunction
function GetPlayerSoundTimer takes sound s, player p returns timer
return LoadTimerHandle(h,GetHandleId(p),GetHandleId(s))
endfunction
function IsSoundPlayedForPlayer takes sound s, player p returns boolean
return GetPlayerSoundTimer(s,p)!=null
endfunction
function GetPlayerLatestSound takes player p returns sound
return LoadSoundHandle(h,GetHandleId(p),0)
endfunction
function SoundExpire takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer kT=GetHandleId(t)
local player p=LoadPlayerHandle(h,kT,0)
local integer kP=GetHandleId(p)
if p==GetLocalPlayer() then
//call RemoveSavedHandle(h,kT,GetHandleId(LoadSoundHandle(h,kT,1)))
//call RemoveSavedHandle(h,kP,0)
endif
call PauseTimer(t)
call FlushChildHashtable(h,kT)
call DestroyTimer(t)
set t=null
endfunction
function PlaySoundForPlayer takes player p, sound s returns boolean
local timer t
local integer kT
if IsSoundPlayedForPlayer(s,p) or s==null then
return false
endif
if GetLocalPlayer()==p then
call StartSound(s)
set t=CreateTimer()
set kT=GetHandleId(t)
call SavePlayerHandle(h,kT,0,p)
call SaveSoundHandle(h,kT,1,s)
call SaveTimerHandle(h,GetHandleId(p),GetHandleId(s),t)
// Duration un milliseconds
call TimerStart(t,GetSoundDuration(s)*0.001,false,function SoundExpire)
call SaveSoundHandle(h,GetHandleId(p),0,s)
call SaveInteger(h,GetSoundSoundSet(s),-3,GetSoundIndex(s))
endif
set t=null
return true
endfunction
private function UpdatePlayerSound takes sound whichSound, unit whichUnit returns boolean
// only update if it is a different speaker or the current unit is not speaking
if (playerSpeaker == whichUnit and IsUnitSpeakingForPlayer(playerSpeaker)) then
return false
endif
set playerSound = whichSound
set playerSpeaker = whichUnit
call PlaySoundForPlayer(GetLocalPlayer(),whichSound)
return true
endfunction
function GetUnitSoundSetId takes unit u returns integer
local integer soundSetId=LoadInteger(h,GetHandleId(u),0)
if soundSetId==0 then
set soundSetId=LoadInteger(h,GetUnitTypeId(u),0)
endif
return soundSetId
endfunction
function GetSound takes integer soundSetId, integer index returns sound
return LoadSoundHandle(h,soundSetId,index)
endfunction
private function GetSoundSetLastPlayed takes integer soundSetId returns integer
return LoadInteger(h,soundSetId,-3)
endfunction
private function SetSoundSetLastPlayed takes integer soundSetId, integer index returns nothing
call SaveInteger(h,soundSetId,-3,index)
endfunction
private function GetRandomSound takes unit u, integer index, player p returns sound
local sound whichSound=null
local integer soundSetId=GetUnitSoundSetId(u)
local sound array sounds
local integer i=0
local integer j=0
if soundSetId!=0 then
loop
exitwhen i>=SOUND_PER_STACK
if (p==null or not IsSoundPlayedForPlayer(whichSound,p)) and index+i!=GetSoundSetLastPlayed(soundSetId) then
set sounds[j]=GetSound(soundSetId,index+i)
endif
if sounds[j]!=null then
set j=j+1
endif
set i=i+1
endloop
if j>1 then
set whichSound=sounds[GetRandomInt(0,j-1)]
endif
loop
exitwhen j<0
set sounds[j]=null
set j=j-1
endloop
// if not found, we do it again with one less condition
if whichSound==null then
set j=0
loop
exitwhen i>=SOUND_PER_STACK
if p==null or not IsSoundPlayedForPlayer(whichSound,p) then
set sounds[j]=GetSound(soundSetId,index+i)
endif
if sounds[j]!=null then
set j=j+1
endif
set i=i+1
endloop
if j>1 then
set whichSound=sounds[GetRandomInt(0,j-1)]
endif
loop
exitwhen j<0
set sounds[j]=null
set j=j-1
endloop
endif
endif
return whichSound
endfunction
private function UpdatePlayerSelect takes unit whichUnit returns nothing
if (playerClickTarget == whichUnit) then
set playerClickCounter = playerClickCounter + 1
else
set playerClickCounter = 1
endif
set playerClickTarget = whichUnit
endfunction
private function IsPlayerSelectionPissed takes unit whichUnit returns boolean
return playerClickTarget == whichUnit and playerClickCounter > PISSED_COUNTER
endfunction
private function IsSoundWhat takes integer t0 returns boolean
return t0>=SOUND_WHAT[0] and t0<=SOUND_WHAT[SOUND_PER_STACK-1]
endfunction
// this should be safe to use with GetLocalPlayer()
private function PlayRandomSound takes unit u, integer index, player p returns sound
local sound s=null
if GetLocalPlayer()==p then
set s=GetRandomSound(u,index,p)
if s!=null then
if UpdatePlayerSound(s,u) then
call SetSoundSetLastPlayed(GetUnitSoundSetId(u),GetSoundIndex(s))
if IsSoundWhat(index) then
call UpdatePlayerSelect(u)
endif
endif
// update selected unit for pissed even if it has no sound
elseif IsSoundWhat(index) then
call UpdatePlayerSelect(u)
endif
endif
return s
endfunction
function PlayRandomSoundForAllies takes unit u, integer index returns nothing
local force allies = AlliesWithSharedControl(GetOwningPlayer(u))
local player p=GetOwningPlayer(u)
local integer i=0
call ForceAddPlayer(allies,p)
loop
exitwhen i==24
if IsPlayerInForce(Player(i),allies) then
call PlayRandomSound(u,index,Player(i))
endif
set i=i+1
endloop
call ForceClear(allies)
call DestroyForce(allies)
set allies=null
set p=null
endfunction
private function StopUnitSound takes unit whichUnit returns nothing
// the death sound will stop any currently played sound from the unit
if (IsUnitSpeakingForPlayer(whichUnit)) then
call StopSound(playerSound, false, false)
endif
endfunction
private function PlayRandom3DDeathSound takes unit whichUnit returns nothing
local sound soundHandle = GetRandomSound(whichUnit, SOUND_DEATH[0],null)
if soundHandle!=null then
call StartSound(soundHandle)
call AttachSoundToUnit(soundHandle, whichUnit)
set soundHandle = null
endif
endfunction
public function PlayUnitYes takes unit u, player p returns sound
return PlayRandomSound(u,SOUND_YES[0],p)
endfunction
public function PlayUnitYesAttack takes unit u, player p returns sound
local sound whichSound=PlayRandomSound(u,SOUND_YES_ATTACK[0],p)
if whichSound==null then
return PlayUnitYes(u,p)
endif
return whichSound
endfunction
public function PlayUnitWhat takes unit u, player p returns sound
return PlayRandomSound(u,SOUND_WHAT[0],p)
endfunction
public function PlayUnitPissed takes unit u, player p returns sound
local sound whichSound=PlayRandomSound(u,SOUND_PISSED[0],p)
if whichSound==null then
return PlayUnitWhat(u,p)
endif
return whichSound
endfunction
public function PlayUnitReady takes unit u returns nothing
call PlayRandomSoundForAllies(u,SOUND_READY[0])
endfunction
public function PlayUnitWarCry takes unit u, player p returns sound
local sound whichSound=PlayRandomSound(u,SOUND_WARCRY[0],p)
if whichSound==null then
return PlayUnitYesAttack(u,p)
endif
return whichSound
endfunction
private function AfterSelect takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer kT=GetHandleId(t)
local unit u=LoadUnitHandle(h,kT,0)
local player p=LoadPlayerHandle(h,kT,1)
if p==GetLocalPlayer() then
set u=GetMainSelectedUnitEx()
if u!=null and u==GetMainSelectedUnitEx() and (HasControl(p,u) or HasUnitShopSoundSet(GetUnitTypeId(u))) then
if IsPlayerSelectionPissed(u) then
call PlayUnitPissed(u,p)
else
call PlayUnitWhat(u,p)
endif
endif
endif
call FlushChildHashtable(h,kT)
call RemoveSavedHandle(h,GetHandleId(u),0)
call PauseTimer(t)
call DestroyTimer(t)
set t=null
set u=null
set p=null
endfunction
private function TriggerActionSelect takes nothing returns nothing
local unit triggerUnit = GetTriggerUnit()
local integer kU=GetHandleId(triggerUnit)
local timer t=LoadTimerHandle(h,kU,0)
if t==null then
set t=CreateTimer()
call SaveTimerHandle(h,kU,0,t)
call SaveUnitHandle(h,GetHandleId(t),0,triggerUnit)
call SavePlayerHandle(h,GetHandleId(t),1,GetTriggerPlayer())
call TimerStart(t,0,false,function AfterSelect)
endif
set t=null
set triggerUnit=null
endfunction
private function TriggerActionOrder takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit target=GetOrderTargetUnit()
local integer orderId = 0
if (HasControl(GetLocalPlayer(), u) and GetMainSelectedUnitEx() == u) then
set orderId = GetIssuedOrderId()
if orderId==ORDER_ID_SMART then
if target!=null and IsUnitEnemy(u,GetOwningPlayer(target)) then
call PlayUnitYesAttack(u,GetLocalPlayer())
else
call PlayUnitYes(u,GetLocalPlayer())
endif
else
if orderId == ORDER_ID_ATTACK then
if IsUnitType(target,UNIT_TYPE_HERO) and GetRandomInt(0,5)==0 then
call PlayUnitWarCry(u,GetLocalPlayer())
else
call PlayUnitYesAttack(u,GetLocalPlayer())
endif
elseif (orderId == ORDER_ID_MOVE or orderId == ORDER_ID_PATROL or orderId == ORDER_ID_ATTACK_GROUND) then
call PlayUnitYes(u,GetLocalPlayer())
endif
endif
endif
set u=null
set target=null
endfunction
private function TriggerConditionReviveFinish takes nothing returns boolean
call PlayRandomSoundForAllies(GetRevivingUnit(), SOUND_READY[0])
return false
endfunction
private function TriggerConditionTrainFinish takes nothing returns boolean
call PlayRandomSoundForAllies(GetTrainedUnit(), SOUND_READY[0])
return false
endfunction
private function TriggerConditionHire takes nothing returns boolean
call PlayRandomSoundForAllies(GetSoldUnit(), SOUND_READY[0])
return false
endfunction
private function TriggerConditionDeath takes nothing returns boolean
call PlayRandom3DDeathSound(GetDyingUnit())
return false
endfunction
function SoundSetVolumeById takes integer soundSetId, integer volume returns nothing
local integer i=0
loop
exitwhen i>SOUND_PISSED[SOUND_PER_STACK-1]
call SetSoundVolume(LoadSoundHandle(h,soundSetId,i),volume)
set i=i+1
endloop
endfunction
function SoundSetVolume takes string path, integer volume returns nothing
local integer soundSetId=GetSoundSetId(path)
if soundSetId>0 then
call SoundSetVolumeById(soundSetId,volume)
endif
endfunction
private function Init takes nothing returns nothing
local integer i=0
loop
exitwhen i==bj_MAX_PLAYERS
call TriggerRegisterPlayerUnitEvent(selectionTrigger, Player(i), EVENT_PLAYER_UNIT_SELECTED, null)
call TriggerRegisterPlayerUnitEvent(deselectionTrigger, Player(i), EVENT_PLAYER_UNIT_DESELECTED, null)
set i=i+1
endloop
call TriggerAddAction(selectionTrigger, function TriggerActionSelect)
call TriggerRegisterAnyUnitEventBJ(orderTrigger, EVENT_PLAYER_UNIT_ISSUED_ORDER)
call TriggerRegisterAnyUnitEventBJ(orderTrigger, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
call TriggerRegisterAnyUnitEventBJ(orderTrigger, EVENT_PLAYER_UNIT_ISSUED_UNIT_ORDER)
call TriggerRegisterAnyUnitEventBJ(orderTrigger, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
call TriggerAddAction(orderTrigger, function TriggerActionOrder)
call TriggerRegisterAnyUnitEventBJ(revivalTrigger, EVENT_PLAYER_HERO_REVIVE_FINISH)
call TriggerAddCondition(revivalTrigger, Condition(function TriggerConditionReviveFinish))
call TriggerRegisterAnyUnitEventBJ(trainTrigger, EVENT_PLAYER_UNIT_TRAIN_FINISH)
call TriggerAddCondition(trainTrigger, Condition(function TriggerConditionTrainFinish))
call TriggerRegisterAnyUnitEventBJ(hireTrigger, EVENT_PLAYER_UNIT_SELL)
call TriggerAddCondition(hireTrigger, Condition(function TriggerConditionHire))
call TriggerRegisterAnyUnitEventBJ(deathTrigger, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(deathTrigger, Condition(function TriggerConditionDeath))
set i=0
loop
exitwhen i>=SOUND_PER_STACK
// +1 here because a 0 index corresponds to no previously played sound
set SOUND_DEATH[i] =i+1
set SOUND_WHAT[i] =SOUND_PER_STACK+i+1
set SOUND_YES[i] =SOUND_PER_STACK*2+i+1
set SOUND_YES_ATTACK[i] =SOUND_PER_STACK*3+i+1
set SOUND_READY[i] =SOUND_PER_STACK*4+i+1
set SOUND_WARCRY[i] =SOUND_PER_STACK*5+i+1
set SOUND_PISSED[i] =SOUND_PER_STACK*6+i+1
set i=i+1
endloop
endfunction
endlibrary