• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] Special Effects Locally

Status
Not open for further replies.
Level 4
Joined
Sep 15, 2013
Messages
53
So I have a system that shows a special effect whoever kills a hero first in the game and after that a different effect for subsequent kills. If the dying unit is not a hero, it will also show a different effect.
JavaScript:
function KillA takes nothing returns nothing
local unit killer = GetKillingUnitBJ()
if IsUnitType(GetDyingUnit(), UNIT_TYPE_HERO) == true then
set firstcount = (firstcount + 1)
if firstcount == 1 then
if GetUnitTypeId(killer) == 'Udea' then
call TriggerSleepAction(1.50)
set FBSound=CreateSound("Sound\\Responses\\Abaddon\\abad_firstblood_01.mp3",false,false,false,10,10,"HeroAcksEAX")
call SetSoundDuration(FBSound,5)
call SetSoundParamsFromLabel(FBSound,"FB")
call SetSoundVolume(FBSound,150)
call PlaySoundBJ(FBSound)
endif
if GetUnitTypeId(killer) == 'Ulic' then
call TriggerSleepAction(1.50)
set FBSound=CreateSound("Sound\\Responses\\Lich\\lich_laugh_06.mp3",false,false,false,10,10,"HeroAcksEAX")
call SetSoundDuration(FBSound,5)
call SetSoundParamsFromLabel(FBSound,"FB")
call SetSoundVolume(FBSound,150)
call PlaySoundBJ(FBSound)
endif
else
if GetUnitTypeId(killer) == 'Udea' then
call DestroyEffect(AddSpecialEffectTargetUnitBJ("origin", killer, "Sound\\Model\\Kill\\Abaddon.mdx"))
endif
if GetUnitTypeId(killer) == 'Ulic' then
call DestroyEffect(AddSpecialEffectTargetUnitBJ("origin", killer, "Sound\\Model\\Kill\\Lich.mdx"))
endif
endif
elseif IsUnitType(GetDyingUnit(), UNIT_TYPE_STRUCTURE) == false then
set killcount[GetConvertedPlayerId(GetOwningPlayer(killer))] = (killcount[GetConvertedPlayerId(GetOwningPlayer(killer))] + 1)
if ModuloInteger(killcount[GetConvertedPlayerId(GetOwningPlayer(killer))], 2) == 0 then
if GetUnitTypeId(killer) == 'Udea' then
call DestroyEffect(AddSpecialEffectTargetUnitBJ("origin", killer, "Sound\\Model\\LastHit\\Abaddon.mdx"))
endif
if GetUnitTypeId(killer) == 'Ulic' then
call DestroyEffect(AddSpecialEffectTargetUnitBJ("origin", killer, "Sound\\Model\\LastHit\\Lich.mdx"))
endif
endif
endif
set killer = null
endfunction
function KillC takes nothing returns boolean
return IsPlayerEnemy(GetOwningPlayer(GetDyingUnit()), GetOwningPlayer(GetKillingUnitBJ())) == true
endfunction
function KillM takes nothing returns nothing
local trigger kill = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(kill, EVENT_PLAYER_UNIT_DEATH)
call TriggerAddCondition(kill, Condition(function KillC))
call TriggerAddAction(kill, function KillA)
endfunction

Now I want to show effects locally? Kindly help me since I dont know how to use getlocalplayer() properly without causing desync.. Thanks!
 
Level 13
Joined
May 10, 2009
Messages
868
The main idea is to not create them within a local player block. Instead, modify a string variable within it.
JASS:
function ...
    local unit killer = GetKillingUnit()
    local string sfx = "GenericSFX.mdl" // This will be shown to everybody, but a specific player

    if GetLocalPlayer() == GetOwningPlayer(killer) then
        set sfx = "SpecificSFX.mdl" // Killing player will see this effect instead
    endif
    call DestroyEffect( AddSpecialEffectTarget(sfx,  targetWidget, "origin") )

    set killer = null
endfunction
 
Level 4
Joined
Sep 15, 2013
Messages
53
If I understand it correctly, I should declare a model on the local string sfx? Then set a specific model every getlocalplayer condition?
 
If I understand it correctly, I should declare a model on the local string sfx? Then set a specific model every getlocalplayer condition?

Yep! Just like how BloodSoul showed in his example. Try writing the code for it, and then you can post it here and we'll double check that it is correct or if you need help.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
I am unsure but BloodSoul's approach has been reported to cause OOS errors in the past. The JASS string cache becomes out of sync, although I would imagine all the constants loaded at load time into the string cache.

The solution was to set a string variable to all the model paths at map initialization before the effect creation code is run. This way the model paths are already in the string cache, even if constants of them are assigned locally by the effect creation code.
 
Level 4
Joined
Sep 15, 2013
Messages
53
So say I use 1 model for each hero.. And I have 20 heroes, I will assign 20 string variables for each of them?
 
Level 7
Joined
Oct 19, 2015
Messages
286
The solution was to set a string variable to all the model paths at map initialization before the effect creation code is run. This way the model paths are already in the string cache, even if constants of them are assigned locally by the effect creation code.
It is good coding practice to have all your configurable strings defined in constants at the start of a script, anyway. Thus, good code is already immune to this problem by design.
 
Status
Not open for further replies.
Top