Thank you. I see that I made some stupid mistakes, which bugged the trigger.Nah, what laziness, also I wanna @maxodors explains me what is that but well,
@maxodors, also I made my best to fix the code and I think is done, because now it can be multicasted without problem
The main things I changed are:
1) I added this functionto the first if block, just in case, because the stun is not removed automatically if the unit is paused.vJASS:call UnitRemoveBuffBJ( 'B00C', TG_Stunned_U[TG_Loop_Int] )
2) In the part ofis a mistake, you wrote "TG_Index" instead of "TG_Loop_Int" in some part.vJASS:if GetWidgetLife(TG_Target[TG_Loop_Int]) > 0.405 and not IsUnitType(TG_Target[TG_Loop_Int], UNIT_TYPE_MAGIC_IMMUNE) and IsUnitEnemy(TG_Target[TG_Loop_Int], GetOwningPlayer(TG_Caster[TG_Index])) and IsUnitType(TG_Target[TG_Loop_Int], UNIT_TYPE_STRUCTURE) == false then
3) I add tothis partvJASS:elseif TG_Unit_Is_Grappled[TG_Loop_Int] and UnitHasBuffBJ(TG_Stunned_U[TG_Loop_Int], 'B00C') and TG_Stun_Dur[TG_Loop_Int] < TG_Stun_Max_Dur then
because you can't check if has a buff a no unitvJASS:TG_Stunned_U[TG_Loop_Int] != null
4) I changedforvJASS:elseif GetUnitCurrentOrder(TG_Caster[TG_Loop_Int]) != String2OrderIdBJ("absorb") or TG_Process[TG_Loop_Int] > TG_Dist or TG_Unit_Is_Grappled[TG_Loop_Int] and not UnitHasBuffBJ(TG_Stunned_U[TG_Loop_Int], 'B00C') then
because is better end the spell if some of the unique two variable conditions to end you have are true.vJASS:elseif GetUnitCurrentOrder(TG_Caster[TG_Loop_Int]) != String2OrderIdBJ("absorb") or TG_Process[TG_Loop_Int] > TG_Dist or TG_Stun_Finished[TG_Loop_Int] or TG_Stun_Removed[TG_Loop_Int] then
5) I changed
forvJASS:if TG_Loop_Int == 0 then call PauseTimer(TG_Timer) endif
because that was a mistakevJASS:if TG_Index == 0 then call PauseTimer(TG_Timer) endif
6) I addedto the part of the group loop, just in case.vJASS:call GroupClear(TG_Group)
JASS:globals integer TG_Index = 0 unit array TG_Caster unit array TG_Dummy unit array TG_Dummy_Effect unit array TG_Grappled_U unit array TG_Target unit array TG_Stun_Dummy unit array TG_Stunned_U unit TG_Effect real array TG_Angel real array TG_Process real array TG_Stun_Dur real array TG_Max_Targets integer array TG_Counter timer TG_Timer = CreateTimer() timer TG_Stun_Timer = CreateTimer() integer TG_Loop_Int = 0 integer TG_Hash = 0 group TG_Group = CreateGroup() group TG_Effects_Group = CreateGroup() boolean array TG_Unit_Is_Grappled boolean array TG_Stun_Removed boolean array TG_Stun_Finished //configurations real TG_Stun_Max_Dur = 3.0 real TG_Dmg = 100 * 0.0312500 / TG_Stun_Max_Dur real TG_Dist = 800 real TG_Speed = 1300 * 0.0312500 real TG_Aoe = 64 endglobals function Trig_Tentacle_Grapple_ActionsV2 takes nothing returns nothing set TG_Loop_Int = 1 loop exitwhen TG_Loop_Int > TG_Index if TG_Stun_Dur[TG_Loop_Int] >= TG_Stun_Max_Dur and not TG_Stun_Finished[TG_Loop_Int] then call UnitRemoveBuffBJ( 'B00C', TG_Stunned_U[TG_Loop_Int] ) call IssueImmediateOrder(TG_Caster[TG_Loop_Int], "stop") call BJDebugMsg("StunFinished") set TG_Stun_Finished[TG_Loop_Int] = true elseif GetUnitCurrentOrder(TG_Caster[TG_Loop_Int]) != String2OrderIdBJ("absorb") and TG_Unit_Is_Grappled[TG_Loop_Int] and not TG_Stun_Removed[TG_Loop_Int] and not TG_Stun_Finished[TG_Loop_Int] then call UnitRemoveBuffBJ( 'B00C', TG_Stunned_U[TG_Loop_Int] ) call BJDebugMsg("RemoveStun") set TG_Stun_Removed[TG_Loop_Int] = true elseif GetUnitCurrentOrder(TG_Caster[TG_Loop_Int]) != String2OrderIdBJ("absorb") or TG_Process[TG_Loop_Int] > TG_Dist or TG_Stun_Finished[TG_Loop_Int] or TG_Stun_Removed[TG_Loop_Int] then //after the stun finished, return the dummy and delete Effects set TG_Effect = LoadUnitHandle(Hash, TG_Loop_Int, TG_Counter[TG_Loop_Int]) set TG_Counter[TG_Loop_Int] = TG_Counter[TG_Loop_Int] - 1 //set TG_Effect = LoadUnitHandleBJ((TG_Counter[TG_Loop_Int] + 1 ), TG_Loop_Int, Hash) call RemoveUnit(TG_Effect) call GroupRemoveUnit(TG_Effects_Group,TG_Effect) call SetUnitX(TG_Dummy[TG_Loop_Int], GetUnitX(TG_Dummy[TG_Loop_Int]) + TG_Speed * Cos((TG_Angel[TG_Loop_Int] - 180) * bj_DEGTORAD)) call SetUnitY(TG_Dummy[TG_Loop_Int], GetUnitY(TG_Dummy[TG_Loop_Int]) + TG_Speed * Sin((TG_Angel[TG_Loop_Int] - 180) * bj_DEGTORAD)) if TG_Counter[TG_Loop_Int] == 0 then call RemoveUnit(TG_Dummy[TG_Loop_Int]) set TG_Caster[TG_Loop_Int] = TG_Caster[TG_Index] set TG_Dummy[TG_Loop_Int] = TG_Dummy[TG_Index] set TG_Process[TG_Loop_Int] = TG_Process[TG_Index] set TG_Unit_Is_Grappled[TG_Loop_Int] = TG_Unit_Is_Grappled[TG_Index] set TG_Stun_Removed[TG_Loop_Int] = TG_Stun_Removed[TG_Index] set TG_Stun_Finished[TG_Loop_Int] = TG_Stun_Finished[TG_Index] set TG_Dummy_Effect[TG_Loop_Int] = TG_Dummy_Effect[TG_Index] set TG_Grappled_U[TG_Loop_Int] = TG_Grappled_U[TG_Index] set TG_Target[TG_Loop_Int] = TG_Target[TG_Index] set TG_Stun_Dummy[TG_Loop_Int] = TG_Stun_Dummy[TG_Index] set TG_Stunned_U[TG_Loop_Int] = TG_Stunned_U[TG_Index] set TG_Angel[TG_Loop_Int] = TG_Angel[TG_Index] set TG_Process[TG_Loop_Int] = TG_Process[TG_Index] set TG_Stun_Dur[TG_Loop_Int] = TG_Stun_Dur[TG_Index] set TG_Counter[TG_Loop_Int] = TG_Counter[TG_Index] set TG_Max_Targets[TG_Loop_Int] = TG_Max_Targets[TG_Index] set TG_Hash=1 loop exitwhen TG_Hash>TG_Counter[TG_Index] call SaveUnitHandle(Hash, TG_Loop_Int, TG_Hash, LoadUnitHandle(Hash, TG_Index, TG_Hash)) set TG_Hash=TG_Hash+1 endloop set TG_Index = TG_Index - 1 set TG_Loop_Int = TG_Loop_Int - 1 if TG_Index == 0 then call PauseTimer(TG_Timer) endif endif elseif TG_Unit_Is_Grappled[TG_Loop_Int] and TG_Stunned_U[TG_Loop_Int] != null and UnitHasBuffBJ(TG_Stunned_U[TG_Loop_Int], 'B00C') and TG_Stun_Dur[TG_Loop_Int] < TG_Stun_Max_Dur then set TG_Stun_Dur[TG_Loop_Int] = TG_Stun_Dur[TG_Loop_Int] + 0.0312500 call UnitDamageTarget(TG_Caster[TG_Loop_Int], TG_Stunned_U[TG_Loop_Int], TG_Dmg, false, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, null) else //Move Dummy and Create Effects set TG_Counter[TG_Loop_Int] = TG_Counter[TG_Loop_Int] + 1 set TG_Process[TG_Loop_Int] = TG_Process[TG_Loop_Int] + TG_Speed set TG_Dummy_Effect[TG_Loop_Int] = CreateUnit(GetOwningPlayer(TG_Caster[TG_Loop_Int]), 'h003', GetUnitX(TG_Dummy[TG_Loop_Int]), GetUnitY(TG_Dummy[TG_Loop_Int]), TG_Angel[TG_Loop_Int]) call GroupAddUnit(TG_Effects_Group, TG_Dummy_Effect[TG_Loop_Int]) call SaveUnitHandle(Hash, TG_Loop_Int, TG_Counter[TG_Loop_Int], TG_Dummy_Effect[TG_Loop_Int]) call SetUnitX(TG_Dummy[TG_Loop_Int], GetUnitX(TG_Dummy[TG_Loop_Int]) + TG_Speed * Cos(TG_Angel[TG_Loop_Int] * bj_DEGTORAD)) call SetUnitY(TG_Dummy[TG_Loop_Int], GetUnitY(TG_Dummy[TG_Loop_Int]) + TG_Speed * Sin(TG_Angel[TG_Loop_Int] * bj_DEGTORAD)) //Pick Units Around Dummy call GroupEnumUnitsInRange(TG_Group, GetUnitX(TG_Dummy[TG_Loop_Int]), GetUnitY(TG_Dummy[TG_Loop_Int]), TG_Aoe, null) loop set TG_Target[TG_Loop_Int] = FirstOfGroup(TG_Group) exitwhen TG_Max_Targets[TG_Loop_Int] == 0 or TG_Target[TG_Loop_Int] == null if GetWidgetLife(TG_Target[TG_Loop_Int]) > 0.405 and not IsUnitType(TG_Target[TG_Loop_Int], UNIT_TYPE_MAGIC_IMMUNE) and IsUnitEnemy(TG_Target[TG_Loop_Int], GetOwningPlayer(TG_Caster[TG_Loop_Int])) and not IsUnitType(TG_Target[TG_Loop_Int], UNIT_TYPE_STRUCTURE) then set TG_Stunned_U[TG_Loop_Int] = TG_Target[TG_Loop_Int] set TG_Unit_Is_Grappled[TG_Loop_Int] = true set TG_Max_Targets[TG_Loop_Int] = TG_Max_Targets[TG_Loop_Int] - 1 set TG_Stun_Dummy[TG_Loop_Int] = CreateUnit(GetOwningPlayer(TG_Caster[TG_Loop_Int]), 'h001', GetUnitX(TG_Caster[TG_Loop_Int]), GetUnitY(TG_Caster[TG_Loop_Int]), 270) call UnitAddAbilityBJ( 'A00K', TG_Stun_Dummy[TG_Loop_Int]) call IssueTargetOrder(TG_Stun_Dummy[TG_Loop_Int], "thunderbolt", TG_Target[TG_Loop_Int]) call GroupClear(TG_Group) endif call GroupRemoveUnit(TG_Group, TG_Target[TG_Loop_Int]) endloop endif set TG_Loop_Int = TG_Loop_Int + 1 endloop endfunction function Trig_Tentacle_Grapple_Actions takes nothing returns nothing local real xCaster = GetUnitX(TG_Caster[TG_Index]) local real yCaster = GetUnitY(TG_Caster[TG_Index]) local real xTarget = GetSpellTargetX() local real yTarget = GetSpellTargetY() set TG_Angel[TG_Index] = bj_RADTODEG * Atan2(yTarget - yCaster, xTarget - xCaster) set TG_Dummy[TG_Index] = CreateUnit(GetOwningPlayer(TG_Caster[TG_Index]), 'h003', xCaster + 0 * Cos(TG_Angel[TG_Index] * bj_DEGTORAD), yCaster + 0 * Sin(TG_Angel[TG_Index] * bj_DEGTORAD), TG_Angel[TG_Index]) call SetUnitPathing(TG_Dummy[TG_Index], false) //Animation, Sounds call SetUnitAnimationByIndex(TG_Caster[TG_Index], 5) //Addtional Settings set TG_Process[TG_Index] = 0 set TG_Counter[TG_Index] = 0 set TG_Unit_Is_Grappled[TG_Index] = false set TG_Grappled_U[TG_Index] = null set TG_Stun_Removed[TG_Index] = false set TG_Stun_Finished[TG_Index] = false set TG_Target[TG_Index] = null set TG_Dummy_Effect[TG_Index] = null set TG_Stun_Dummy[TG_Index] = null set TG_Stunned_U[TG_Index] = null set TG_Stun_Dur[TG_Index] = 0 set TG_Max_Targets[TG_Index] = 1 //Timer if TG_Index == 1 then call TimerStart(TG_Timer, 0.0312500, true, function Trig_Tentacle_Grapple_ActionsV2) endif endfunction function Trig_Tentacle_Grapple_Conditions takes nothing returns boolean if GetSpellAbilityId() == 'A00J' then set TG_Index = (TG_Index + 1) set TG_Caster[TG_Index] = GetTriggerUnit() return true endif return false endfunction //=========================================================================== function InitTrig_Tentacle_Grapple takes nothing returns nothing set gg_trg_Tentacle_Grapple = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Tentacle_Grapple, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_Tentacle_Grapple, Condition( function Trig_Tentacle_Grapple_Conditions ) ) call TriggerAddAction( gg_trg_Tentacle_Grapple, function Trig_Tentacle_Grapple_Actions ) endfunction
One problem is if the target dies while is stunned the chains continues the process like anything happens but it can't grab another unit, but I think you can solve it easily.
Also:
For this you have to do A LOT of extra work, I don't know if you wanna, but lets see
For this you just have to comparte the path of the terrain your dummy is gonna move
Sorry, I completely forgot about the hashtable. I am planning to utilise cJass in all my future code because it is easier to understand and faster to make.
There are still some problems:
1. For some reason, the dummy is created with a different distance from the unit, depending on the direction of the cast. I want it to look like the hook comes out of his mouth. However, this dislocation of the dummy ruins it.
2. If you cast a spell and instantly stop it, it bugs sometimes. If you do it multiple times, you get a fatal error.
I do want extra work, as I want to make a great map rather than a mediocre one. However, I do not want to burden you or other people too much. Maybe there is an example of something similar somewhere? These are my first spells, so I just started learning.