- Joined
- Nov 2, 2004
- Messages
- 1,993
This system is finished as far as I'm concerned. Submitted it to the JASS section, but still awaiting further review.
So yeah, question in the title
Want to know if there's anything else I can do to improve it.
thanks!
So yeah, question in the title
JASS:
library RevivableUnits initializer InitRevivable
globals
private string array playerColor
//revivable unit storage
private integer array revUnits
private integer array revPlayers
private integer revSize = 0
//dissipating unit storage
private hashtable dTable = InitHashtable()
//sounds
private sound dSoundO
private sound dSoundNE
private sound dSoundH
private sound rSound
//configure dissipate effect
private real confDelay = 2 //delay after start of death animation before dissipating
private integer confOpacity = 150 //starting opacity after ^
private real confDuration = 1.5 //duration of the dissipate effect
private real confIncrement = 0.03 //timer duration for the fade effect
private real confHeight = 350 //flyheight
private integer opacityIncrement = R2I(I2R(confOpacity)*confIncrement/confDuration)
endglobals
//===========================================================================
// Preset teamcolors
//===========================================================================
private function initPC takes nothing returns nothing
set playerColor[0] = "00FF0202"
set playerColor[1] = "000041FF"
set playerColor[2] = "001BE5B8"
set playerColor[3] = "00530080"
set playerColor[4] = "00FFFF00"
set playerColor[5] = "00FE890D"
set playerColor[6] = "001FBF00"
set playerColor[7] = "00E45AAA"
set playerColor[8] = "00949596"
set playerColor[9] = "007DBEF1"
set playerColor[10] = "000F6145"
set playerColor[11] = "004D2903"
set playerColor[12] = "00000000"
set playerColor[13] = "00000000"
set playerColor[14] = "00000000"
set playerColor[15] = "00000000"
endfunction
//===========================================================================
// Configuration functions
//===========================================================================
//===========================================================================
// Configure dissipate effect
//===========================================================================
function configureDissipate takes real wDelay, integer wOpac, real wDur, real wIncr, integer wHeight returns boolean
if(wDelay < 0 or wOpac < 0 or wOpac > 255 or wDur < 0 or wIncr < 0.01 or wIncr > wDur or wHeight < 0 or wHeight > 1000) then
return false
endif
if(wDelay != null) then
set confDelay = wDelay
endif
if(wOpac != null) then
set confOpacity = wOpac
endif
if(wDur != null) then
set confDuration = wDur
endif
if(wIncr != null) then
set confIncrement = wIncr
endif
if(wHeight != null) then
set confHeight = wHeight
endif
return true
endfunction
//===========================================================================
// Make unit revivable
//===========================================================================
function MakeUnitRevivable takes integer wUnit, integer wPlayer returns nothing
local integer iPlayer = 0
local integer iSize
local integer revAllow
//Limit training
loop
//Decide if player can build unit
if(wPlayer == 0 or wPlayer == iPlayer+1) then
set revAllow = 1
else
set revAllow = 0
//Check if other players have been previously been set to build unit
set iSize = 0
loop
if(revUnits[iSize] == wUnit and revPlayers[iSize] == iPlayer+1) then
set revAllow = 1
endif
set iSize = iSize + 1
exitwhen iSize >= revSize
endloop
endif
call SetPlayerTechMaxAllowed(Player(iPlayer), wUnit, revAllow)
set iPlayer = iPlayer + 1
exitwhen iPlayer >= bj_MAX_PLAYER_SLOTS
endloop
set revUnits[revSize] = wUnit
set revPlayers[revSize] = wPlayer
set revSize = revSize + 1
endfunction
//===========================================================================
// End Configuration functions
//===========================================================================
//===========================================================================
// Check if unit is revivable
//===========================================================================
private function IsRevivable takes unit wUnit returns boolean
local integer iSize = 0
local boolean tResult = false
loop
if(revUnits[iSize] == GetUnitTypeId(wUnit)) then
//set for individual players -> cannot be overridden with subsequent MakeUnitRevivable calls
if(revPlayers[iSize] == GetPlayerId(GetOwningPlayer(wUnit))+1) then
return true
//set for all players -> overridden when individual player is set later
elseif(revPlayers[iSize] == 0) then
set tResult = true
//unit has been set but not (yet) for owning player -> override if set for ALL players previously
else
set tResult = false
endif
endif
set iSize = iSize + 1
exitwhen iSize >= revSize
endloop
return tResult
endfunction
//===========================================================================
// Dissipate Conditions & Actions
//===========================================================================
private function Dissipate_Conditions takes nothing returns boolean
return ( IsRevivable(GetDyingUnit()) )
endfunction
private function Dissipate_Fade takes nothing returns nothing
local timer dTimer = GetExpiredTimer()
local integer dTimerId = GetHandleId(dTimer)
local unit dUnit = LoadUnitHandle(dTable, dTimerId, 'unit')
local integer opacity = LoadInteger(dTable, dTimerId, 'opac')
//Increment opacity
set opacity = ( opacity - opacityIncrement)
call SetUnitVertexColor( dUnit, 255, 255, 255, opacity )
//Fading complete
if ( opacity < opacityIncrement ) then
//Clean up
call RemoveUnit(dUnit)
call DestroyTimer(dTimer)
call FlushChildHashtable(dTable, dTimerId)
//Fading continues
else
call SaveInteger(dTable, dTimerId, 'opac', opacity)
endif
//Clean up
set dTimer = null
set dUnit = null
endfunction
private function Dissipate_Effect takes nothing returns nothing
local timer dTimer = GetExpiredTimer()
local integer dTimerId = GetHandleId(dTimer)
local unit dUnit = LoadUnitHandle(dTable, dTimerId, 'unit')
local race dRace = GetUnitRace(dUnit)
local player dOwner = GetOwningPlayer(dUnit)
local player localPlayer = GetLocalPlayer()
local force dAllies = CreateForce()
//Set up player allies Force
call ForceEnumAllies(dAllies, dOwner, null)
//Display death message to owner and allies
if (IsPlayerInForce(localPlayer, dAllies)) then
call DisplayTextToPlayer(localPlayer, 0, 0, ( "|c" + playerColor[GetPlayerId(dOwner)] + GetUnitName(dUnit) + "|r has fallen." ))
endif
//Start fading
call SaveInteger(dTable, dTimerId, 'opac', confOpacity)
call SetUnitVertexColor(dUnit, 255, 255, 255, confOpacity)
call TimerStart(dTimer, confIncrement, true, function Dissipate_Fade)
//Lift unit
if UnitAddAbility(dUnit,'Arav') then
call UnitRemoveAbility(dUnit,'Arav')
endif
call SetUnitFlyHeight(dUnit, confHeight, confHeight/confDuration)
//Set race-specific dissipate effect & sound
if ( dRace == RACE_ORC ) then
call AttachSoundToUnit(dSoundO, dUnit)
call StartSound(dSoundO)
elseif ( dRace == RACE_UNDEAD ) then
//Only Undead has an actual dissipate model, with sound already attached
call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Undead\\UndeadDissipate\\UndeadDissipate.mdl", dUnit, "origin"))
elseif ( dRace == RACE_NIGHTELF ) then
call AttachSoundToUnit(dSoundNE, dUnit)
call StartSound(dSoundNE)
else
call AttachSoundToUnit(dSoundH, dUnit)
call StartSound(dSoundH)
endif
//Clean up
set dUnit = null
set dTimer = null
call DestroyForce(dAllies)
set dAllies = null
endfunction
private function Dissipate_Death takes nothing returns nothing
local unit dyingUnit = GetDyingUnit()
local unit dUnit
local location dLoc = GetUnitLoc(dyingUnit)
local timer dTimer = CreateTimer()
//Replace dying unit
set dUnit = CreateUnitAtLoc(GetOwningPlayer(dyingUnit), GetUnitTypeId(dyingUnit), dLoc, GetUnitFacing(dyingUnit))
call RemoveUnit( dyingUnit )
call UnitAddAbility(dUnit,'Aloc') //make unit unselectable
call UnitRemoveAbility(dUnit,'Ashm') //make sure unit isn't melded
call UnitRemoveAbility(dUnit,'Sshm') // ^
call UnitRemoveAbility(dUnit,'Ahid') // ^
//Play death animation
call SetUnitAnimation( dUnit, "Death" )
//Store unit & wait for death animation to finish
call SaveUnitHandle(dTable, GetHandleId(dTimer), 'unit', dUnit)
call TimerStart( dTimer, confDelay, false, function Dissipate_Effect)
//Destroy objects & handles
set dyingUnit = null
set dUnit = null
set dTimer = null
call RemoveLocation(dLoc)
set dLoc = null
endfunction
//===========================================================================
// End Dissipate Conditions & Actions
//===========================================================================
//===========================================================================
// Revive Conditions & Actions
//===========================================================================
private function Revive_Conditions takes nothing returns boolean
return ( IsRevivable(GetTrainedUnit()) )
endfunction
private function Revive_Effect takes nothing returns nothing
local unit rUnit = GetTrainedUnit()
local race rRace = GetUnitRace(rUnit)
local string rEffect
if ( rRace == RACE_ORC ) then
set rEffect = "Abilities\\Spells\\Orc\\ReviveOrc\\ReviveOrc.mdl"
elseif ( rRace == RACE_UNDEAD ) then
set rEffect = "Abilities\\Spells\\Undead\\ReviveUndead\\ReviveUndead.mdl"
elseif ( rRace == RACE_NIGHTELF ) then
set rEffect = "Abilities\\Spells\\NightElf\\ReviveNightElf\\ReviveNightElf.mdl"
elseif ( rRace == RACE_DEMON ) then
set rEffect = "Abilities\\Spells\\Demon\\ReviveDemon\\ReviveDemon.mdl"
//Demon revive model has no sound attached
call AttachSoundToUnit(rSound, rUnit)
call StartSound(rSound)
else
set rEffect = "Abilities\\Spells\\Human\\ReviveHuman\\ReviveHuman.mdl"
endif
call DestroyEffect(AddSpecialEffectTarget(rEffect, rUnit, "origin"))
//Destroy objects & handles
set rUnit = null
endfunction
//===========================================================================
// Set up triggers
//===========================================================================
private function InitRevivable takes nothing returns nothing
local trigger trg_Dissipate = CreateTrigger( )
local trigger trg_Revive = CreateTrigger( )
local integer iPlayer = 0
//Init teamcolors
call initPC()
//Create sounds
set rSound = CreateSound("Abilities\\Spells\\Human\\ReviveHuman\\ReviveHuman.wav", false, true, true, 10, 10, "SpellsEAX")
call SetSoundParamsFromLabel(rSound, "ReviveHuman")
call SetSoundDuration(rSound, 3196)
set dSoundH = CreateSound("Sound\\Units\\Human\\HumanDissipate1.wav", false, true, true, 10, 10, "SpellsEAX")
call SetSoundParamsFromLabel(dSoundH, "HumanDissipate")
call SetSoundDuration(dSoundH, 2270)
set dSoundNE = CreateSound("Sound\\Units\\NightElf\\NightElfDissipate1.wav", false, true, true, 10, 10, "SpellsEAX")
call SetSoundParamsFromLabel(dSoundNE, "NightElfDissipate")
call SetSoundDuration(dSoundNE, 2270)
set dSoundO = CreateSound("Sound\\Units\\Orc\\OrcDissipate1.wav", false, true, true, 10, 10, "SpellsEAX")
call SetSoundParamsFromLabel(dSoundO, "OrcDissipate")
call SetSoundDuration(dSoundO, 2270)
//Register events for all players
loop
//Dissipate trigger
call TriggerRegisterPlayerUnitEvent(trg_Dissipate, Player(iPlayer), EVENT_PLAYER_UNIT_DEATH, null)
//Revive trigger
call TriggerRegisterPlayerUnitEvent(trg_Revive, Player(iPlayer), EVENT_PLAYER_UNIT_TRAIN_FINISH, null)
set iPlayer = iPlayer + 1
exitwhen iPlayer >= bj_MAX_PLAYER_SLOTS
endloop
//Dissipate trigger
call TriggerAddCondition( trg_Dissipate, Condition( function Dissipate_Conditions ) )
call TriggerAddAction( trg_Dissipate, function Dissipate_Death )
//Revive trigger
call TriggerAddCondition( trg_Revive, Condition( function Revive_Conditions ) )
call TriggerAddAction( trg_Revive, function Revive_Effect )
endfunction
endlibrary
thanks!
Last edited: