| 06-27-2008, 08:46 AM | #1 |
I need help with this new spell that I have been working on, although it never seems to work correctly no matter how hard I tried. The following are characteristics of the said spell
here's what I have gotten to so far 4 separate triggers(which is bad( i think?)) JASS://TESH.scrollpos=11 //TESH.alwaysfold=0 function Trig_TidePoolInit_Conditions takes nothing returns boolean return GetSpellAbilityId() == 'A005' endfunction function Trig_TidePoolInit_Action1 takes nothing returns nothing local integer i = 1 local unit F= GetTriggerUnit() local unit array E set udg_Vrtxcaster= GetTriggerUnit() set udg_rotation2= 0 loop exitwhen i > 45 call CreateNUnitsAtLoc( 1, 'h004', GetOwningPlayer(F), PolarProjectionBJ(GetUnitLoc(F), 800, ( 45 * I2R(i) )), bj_UNIT_FACING ) set udg_Vrtx_Unit[i] = GetLastCreatedUnit() set i = i + 1 endloop call EnableTrigger( gg_trg_Tide_PoolMovement ) call EnableTrigger( gg_trg_Tide_Pool_damage ) endfunction //=========================================================================== function InitTrig_TidePoolInit takes nothing returns nothing set gg_trg_TidePoolInit = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_TidePoolInit, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_TidePoolInit, Condition( function Trig_TidePoolInit_Conditions ) ) call TriggerAddAction( gg_trg_TidePoolInit, function Trig_TidePoolInit_Action1 ) endfunction //2nd trigger //TESH.scrollpos=0 //TESH.alwaysfold=0 function Trig_Tide_PoolMovement_Actions takes nothing returns nothing local integer i=1 local location loc=GetUnitLoc(udg_Vrtxcaster) local location loc2 set udg_rotation2=udg_rotation2+5 loop exitwhen i>45 set loc2=GetUnitLoc(udg_Vrtx_Unit[i]) // Replace DistanceBetweenPoints with 400 ? call SetUnitPositionLoc( udg_Vrtx_Unit[i], PolarProjectionBJ(loc, 800, udg_rotation + i*15 )) call RemoveLocation(loc2) set i=i+1 endloop endfunction //=========================================================================== function InitTrig_Tide_PoolMovement takes nothing returns nothing set gg_trg_Tide_PoolMovement = CreateTrigger( ) call TriggerRegisterTimerEventPeriodic( gg_trg_Tide_PoolMovement, 0.04 ) call TriggerAddAction( gg_trg_Tide_PoolMovement, function Trig_Tide_PoolMovement_Actions ) endfunction //third //TESH.scrollpos=13 //TESH.alwaysfold=0 function Trig_Tide_Pool_damage_Func001C takes nothing returns boolean if ( not ( IsUnitEnemy(GetTriggerUnit(), GetOwningPlayer(udg_Vrtxcaster)) == true ) ) then return false endif return true endfunction function Trig_Tide_Pool_damage_Func001D takes nothing returns boolean if ( not ( IsUnitAlly(GetTriggerUnit(), GetOwningPlayer(udg_Vrtxcaster)) == true ) ) then return false endif return true endfunction function Trig_Tide_Pool_damage_Actions takes nothing returns nothing if ( Trig_Tide_Pool_damage_Func001C() ) then call CreateNUnitsAtLoc( 1, 'h001', GetOwningPlayer(udg_Vrtxcaster), GetUnitLoc(GetTriggerUnit()), 0.00 ) call UnitApplyTimedLifeBJ( 3, 'BTLF', GetLastCreatedUnit() ) call UnitAddAbilityBJ( 'A007', GetLastCreatedUnit() ) call IssueTargetOrderBJ( GetLastCreatedUnit(), "frostnova", GetTriggerUnit() ) else if ( Trig_Tide_Pool_damage_Func001D()) then call CreateNUnitsAtLoc( 1, 'h001', GetOwningPlayer(udg_Vrtxcaster), GetUnitLoc(GetTriggerUnit()), 0.00 ) call UnitApplyTimedLifeBJ( 3, 'BTLF', GetLastCreatedUnit() ) call UnitAddAbilityBJ( 'A006', GetLastCreatedUnit() ) call IssueTargetOrderBJ( GetLastCreatedUnit(), "rejuvination", GetTriggerUnit() ) endif endif endfunction //=========================================================================== function InitTrig_Tide_Pool_damage takes nothing returns nothing set gg_trg_Tide_Pool_damage = CreateTrigger( ) call TriggerRegisterUnitInRangeSimple(gg_trg_Tide_Pool_damage,800,udg_Vrtxcaster) call TriggerAddAction( gg_trg_Tide_Pool_damage, function Trig_Tide_Pool_damage_Actions ) endfunction //last //TESH.scrollpos=7 //TESH.alwaysfold=0 function Trig_TidePool_End_Conditions takes nothing returns boolean return GetSpellAbilityId() == 'A005' endfunction function Trig_TidePool_End_Actions takes nothing returns nothing local integer i=1 loop exitwhen i>45 call RemoveUnit(udg_Vrtx_Unit[i]) set udg_Vrtx_Unit[i] = null set i=i+1 endloop set udg_Vrtxcaster = null endfunction //=========================================================================== function InitTrig_TidePool_End takes nothing returns nothing set gg_trg_TidePool_End = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_TidePool_End, EVENT_PLAYER_UNIT_SPELL_ENDCAST ) call TriggerAddCondition( gg_trg_TidePool_End, Condition( function Trig_TidePool_End_Conditions ) ) call TriggerAddAction( gg_trg_TidePool_End, function Trig_TidePool_End_Actions ) endfunction these are the problems i have encountered
additional help appreciated:
any help GUI/JASS/vJASS will be appreciated |
| 06-27-2008, 08:58 AM | #2 |
Well, there's a lot I'd like to help you with here (I'll go through step-by-step building the spell), but I need to know one thing first: what do you know about vJASS/coding in vJASS, and do you mind if I introduce you to structs? Or would you rather I stuck to handle variables/that sort of thing? Edit: One more thing: By "damages enemy units w/in range for 25x current level" did you mean it did 25xlevel damage per second, or just when the spell was cast? |
| 06-27-2008, 09:03 AM | #3 |
I meant the one you said 25x current level damage per second and i have only the very basic knowledge or vJass but I'm a fast learner I'm a consistent honor student in my school not that i'm bragging or anything |
| 06-27-2008, 09:04 AM | #4 |
lulz. Give me a bit. |
| 06-27-2008, 09:14 AM | #5 |
ok, I reaaallllllyyyyyyy need this |
| 06-27-2008, 11:46 AM | #6 |
Okay, so the first thing to note is this: in JASS, 'trigger' generally only refers to the actual variable type trigger because, well, any and all JASS 'triggers' (meaning things with events, conditions, and actions) can all be condensed into one GUI 'trigger' (meaning the things you see in the Trigger Editor). To do that, we have to use a globals block for the other triggers (the variable type) and we end up with this: JASS://Note that we've now renamed the 'GUI trigger' to "TidePool" //And I've given all the functions relevant names //And we're moving the globals out of the Variable Editor globals trigger TidePoolMovementTrig trigger TidePoolDamageTrig trigger TidePoolEndTrig unit Caster unit Unit unit array Effect_Units integer Rotation2 integer Rotation endglobals //1st trigger function TidePool_CastConditions takes nothing returns boolean return GetSpellAbilityId() == 'A005' endfunction function TidePool_Cast takes nothing returns nothing local integer i = 1 local unit F= GetTriggerUnit() local unit array E set Caster= GetTriggerUnit() set Rotation2= 0 loop exitwhen i > 45 call CreateNUnitsAtLoc( 1, 'h004', GetOwningPlayer(F), PolarProjectionBJ(GetUnitLoc(F), 800, ( 45 * I2R(i) )), bj_UNIT_FACING ) set Effect_Units[i] = GetLastCreatedUnit() set i = i + 1 endloop call EnableTrigger( TidePoolMovementTrig ) call EnableTrigger( TidePoolDamageTrig ) endfunction //2nd trigger function TidePool_Movement takes nothing returns nothing local integer i=1 local location loc=GetUnitLoc(Caster) local location loc2 set Rotation2=Rotation2+5 loop exitwhen i>45 set loc2=GetUnitLoc(Effect_Units[i]) // Replace DistanceBetweenPoints with 400 ? call SetUnitPositionLoc( Effect_Units[i], PolarProjectionBJ(loc, 800, Rotation + i*15 )) call RemoveLocation(loc2) set i=i+1 endloop endfunction //third function Trig_Tide_Pool_damage_Func001C takes nothing returns boolean if ( not ( IsUnitEnemy(GetTriggerUnit(), GetOwningPlayer(Caster)) == true ) ) then return false endif return true endfunction function Trig_Tide_Pool_damage_Func001D takes nothing returns boolean if ( not ( IsUnitAlly(GetTriggerUnit(), GetOwningPlayer(Caster)) == true ) ) then return false endif return true endfunction function TidePool_Damage takes nothing returns nothing if ( Trig_Tide_Pool_damage_Func001C() ) then call CreateNUnitsAtLoc( 1, 'h001', GetOwningPlayer(Caster), GetUnitLoc(GetTriggerUnit()), 0.00 ) call UnitApplyTimedLifeBJ( 3, 'BTLF', GetLastCreatedUnit() ) call UnitAddAbilityBJ( 'A007', GetLastCreatedUnit() ) call IssueTargetOrderBJ( GetLastCreatedUnit(), "frostnova", GetTriggerUnit() ) else if ( Trig_Tide_Pool_damage_Func001D()) then call CreateNUnitsAtLoc( 1, 'h001', GetOwningPlayer(Caster), GetUnitLoc(GetTriggerUnit()), 0.00 ) call UnitApplyTimedLifeBJ( 3, 'BTLF', GetLastCreatedUnit() ) call UnitAddAbilityBJ( 'A006', GetLastCreatedUnit() ) call IssueTargetOrderBJ( GetLastCreatedUnit(), "rejuvination", GetTriggerUnit() ) endif endif endfunction //last function TidePool_EndCastConditions takes nothing returns boolean return GetSpellAbilityId() == 'A005' endfunction function TidePool_EndCast takes nothing returns nothing local integer i=1 loop exitwhen i>45 call RemoveUnit(Effect_Units[i]) set Effect_Units[i] = null set i=i+1 endloop set Caster = null endfunction //=========================================================================== function InitTrig_TidePool takes nothing returns nothing set gg_trg_TidePool = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(gg_trg_TidePool, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(gg_trg_TidePool, Condition(function TidePool_CastConditions)) call TriggerAddAction(gg_trg_TidePool, function TidePool_Cast) set TidePoolMovementTrig = CreateTrigger() call TriggerRegisterTimerEventPeriodic(TidePoolMovementTrig, 0.04) call TriggerAddAction(TidePoolMovementTrig, function TidePool_Movement) set TidePoolDamageTrig = CreateTrigger() call TriggerRegisterUnitInRangeSimple(TidePoolDamageTrig,800,Caster) call TriggerAddAction(TidePoolDamageTrig, function TidePool_Damage) set TidePoolEndTrig = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(TidePoolEndTrig, EVENT_PLAYER_UNIT_SPELL_ENDCAST) call TriggerAddCondition(TidePoolEndTrig, Condition(function TidePool_EndCastConditions)) call TriggerAddAction(TidePoolEndTrig, function TidePool_EndCast) endfunction Before we go into fixing the periodic stuff, let's optimize your cast function (the red is what we'll change): JASS:function TidePool_Cast takes nothing returns nothing local integer i = 1 local unit F= GetTriggerUnit() local unit array E set Caster= GetTriggerUnit() set Rotation2= 0 loop exitwhen i > 45 call CreateNUnitsAtLoc( 1, 'h004', GetOwningPlayer(F), PolarProjectionBJ(GetUnitLoc(F), 800, ( 45 * I2R(i) )), bj_UNIT_FACING ) set Effect_Units[i] = GetLastCreatedUnit() set i = i + 1 endloop call EnableTrigger(TidePoolMovementTrig) call EnableTrigger(TidePoolDamageTrig) endfunction JASS:function TidePool_Cast takes nothing returns nothing local integer i = 1 set Caster = GetTriggerUnit() set Rotation2 = 0.00 loop exitwhen i>8 set Effect_Units[i] = CreateUnitAtLoc(GetOwningPlayer(Caster), 'h004', PolarProjectionBJ(GetUnitLoc(Caster), 800, 45*i)), 0.00) set i = i + 1 endloop call EnableTrigger(TidePoolMovementTrig) call EnableTrigger(TidePoolDamageTrig) endfunction PolarProjectionBJ:function PolarProjectionBJ takes location source, real dist, real angle returns location local real x = GetLocationX(source) + dist * Cos(angle * bj_DEGTORAD) local real y = GetLocationY(source) + dist * Sin(angle * bj_DEGTORAD) return Location(x, y) endfunction JASS:function TidePool_Cast takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) set Caster = GetTriggerUnit() set Rotation2 = 0 loop exitwhen i>8 set Effect_Units[i] = CreateUnit(GetOwningPlayer(Caster), 'h004', CX+800.00*Cos(45.00*i*bj_DEGTORAD), CY+800.00*Sin(45.00*i*bj_DEGTORAD), 0.00) set i = i + 1 endloop call EnableTrigger(TidePoolMovementTrig) call EnableTrigger(TidePoolDamageTrig) endfunction That's great, so let's see what it looks like all together now: JASS:globals trigger TidePoolMovementTrig trigger TidePoolDamageTrig trigger TidePoolEndTrig unit Caster unit Unit unit array Effect_Units real Rotation2 real Rotation endglobals //1st trigger function TidePool_CastConditions takes nothing returns boolean return GetSpellAbilityId() == 'A005' endfunction function TidePool_Cast takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) set Caster = GetTriggerUnit() set Rotation2 = 0 loop exitwhen i>8 set Effect_Units[i] = CreateUnit(GetOwningPlayer(Caster), 'h004', CX+800.00*Cos(45.00*i*bj_DEGTORAD), CY+800.00*Sin(45.00*i*bj_DEGTORAD), 0.00) set i = i + 1 endloop call EnableTrigger(TidePoolMovementTrig) call EnableTrigger(TidePoolDamageTrig) endfunction //2nd trigger function TidePool_Movement takes nothing returns nothing local integer i=1 local location loc=GetUnitLoc(Caster) local location loc2 set Rotation2=Rotation2+5 loop exitwhen i>45 set loc2=GetUnitLoc(Effect_Units[i]) // Replace DistanceBetweenPoints with 400 ? call SetUnitPositionLoc( Effect_Units[i], PolarProjectionBJ(loc, 800, Rotation + i*15 )) call RemoveLocation(loc2) set i=i+1 endloop endfunction //third function Trig_Tide_Pool_damage_Func001C takes nothing returns boolean if ( not ( IsUnitEnemy(GetTriggerUnit(), GetOwningPlayer(Caster)) == true ) ) then return false endif return true endfunction function Trig_Tide_Pool_damage_Func001D takes nothing returns boolean if ( not ( IsUnitAlly(GetTriggerUnit(), GetOwningPlayer(Caster)) == true ) ) then return false endif return true endfunction function TidePool_Damage takes nothing returns nothing if ( Trig_Tide_Pool_damage_Func001C() ) then call CreateNUnitsAtLoc( 1, 'h001', GetOwningPlayer(Caster), GetUnitLoc(GetTriggerUnit()), 0.00 ) call UnitApplyTimedLifeBJ( 3, 'BTLF', GetLastCreatedUnit() ) call UnitAddAbilityBJ( 'A007', GetLastCreatedUnit() ) call IssueTargetOrderBJ( GetLastCreatedUnit(), "frostnova", GetTriggerUnit() ) else if ( Trig_Tide_Pool_damage_Func001D()) then call CreateNUnitsAtLoc( 1, 'h001', GetOwningPlayer(Caster), GetUnitLoc(GetTriggerUnit()), 0.00 ) call UnitApplyTimedLifeBJ( 3, 'BTLF', GetLastCreatedUnit() ) call UnitAddAbilityBJ( 'A006', GetLastCreatedUnit() ) call IssueTargetOrderBJ( GetLastCreatedUnit(), "rejuvination", GetTriggerUnit() ) endif endif endfunction //last function TidePool_EndCastConditions takes nothing returns boolean return GetSpellAbilityId() == 'A005' endfunction function TidePool_EndCast takes nothing returns nothing local integer i=1 loop exitwhen i>45 call RemoveUnit(Effect_Units[i]) set Effect_Units[i] = null set i=i+1 endloop set Caster = null endfunction //=========================================================================== function InitTrig_TidePool takes nothing returns nothing set gg_trg_TidePool = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(gg_trg_TidePool, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(gg_trg_TidePool, Condition(function TidePool_CastConditions)) call TriggerAddAction(gg_trg_TidePool, function TidePool_Cast) set TidePoolMovementTrig = CreateTrigger() call TriggerRegisterTimerEventPeriodic(TidePoolMovementTrig, 0.04) call TriggerAddAction(TidePoolMovementTrig, function TidePool_Movement) set TidePoolDamageTrig = CreateTrigger() call TriggerRegisterUnitInRangeSimple(TidePoolDamageTrig,800,Caster) call TriggerAddAction(TidePoolDamageTrig, function TidePool_Damage) set TidePoolEndTrig = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(TidePoolEndTrig, EVENT_PLAYER_UNIT_SPELL_ENDCAST) call TriggerAddCondition(TidePoolEndTrig, Condition(function TidePool_EndCastConditions)) call TriggerAddAction(TidePoolEndTrig, function TidePool_EndCast) endfunction Then, a general flowchart of what the periodic spell will do is this: Is the unit's current order the order of the spell?Doing this, we'll reduce the number of triggers we must have to 2, so let's start building that periodic trigger (ignoring all the other stuff we've done so far): JASS:globals trigger TidePoolPeriodicTrig unit Caster endglobals function TidePool_Periodic takes nothing returns nothing endfunction function InitTrig_TidePool takes nothing returns nothing set TidePoolPeriodicTrig = CreateTrigger() call TriggerRegisterTimerEventPeriodic(TidePoolPeriodicTrig, 0.04) call TriggerAddAction(TidePoolPeriodicTrig, function TidePool_Periodic) endfunction JASS:globals //Only showing the new ones, the others remain trigger TidePoolPeriodicTrig //unit Caster //real Rotation //real Rotation2 endglobals function TidePool_Periodic takes nothing returns nothing local integer i = 1 local location loc = GetUnitLoc(Caster) local location loc2 set Rotation2 = Rotation2+5.00 loop exitwhen i>45 set loc2 = GetUnitLoc(Effect_Units[i]) call SetUnitPositionLoc(Effect_Units[i], PolarProjectionBJ(loc, 800, Rotation + i*15 )) call RemoveLocation(loc2) set i=i+1 endloop endfunction function InitTrig_TidePool takes nothing returns nothing set TidePoolPeriodicTrig = CreateTrigger() call TriggerRegisterTimerEventPeriodic(TidePoolPeriodicTrig, 0.04) call TriggerAddAction(TidePoolPeriodicTrig, function TidePool_Periodic) endfunction JASS:function TidePool_Periodic takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) set Rotation2 = Rotation2+5.00 loop exitwhen i>8 call SetUnitPosition(Effect_Units[i], CX+800.00*Cos((45.00*i+Rotation2)*bj_DEGTORAD), CY+800.00*Sin((45.00*i+Rotation2)*bj_DEGTORAD)) set i=i+1 endloop endfunction Now we've got to add in stuff for getting the units near the caster, and that looks like this: JASS:function TidePool_True takes nothing returns boolean return true endfunction function TidePool_Periodic takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) local group G = CreateGroup() local unit U set Rotation2 = Rotation2+5.00 loop exitwhen i>8 call SetUnitPosition(Effect_Units[i], CX+800.00*Cos((45.00*i+Rotation2)*bj_DEGTORAD), CY+800.00*Sin((45.00*i+Rotation2)*bj_DEGTORAD)) set i=i+1 endloop call GroupEnumUnitsInRange(G, CX, CY, 800.00, Condition(function TidePool_True)) loop set U = FirstOfGroup(G) exitwhen U == null //Do stuff with U call GroupRemoveUnit(G, U) endloop call DestroyGroup(G) set G = null //set U = null [not needed because U is going to be null when the loop exits] endfunction JASS:globals trigger TidePoolPeriodicTrig //unit Caster //real Rotation2 endglobals function Trig_Tide_Pool_damage_Func001C takes nothing returns boolean if ( not ( IsUnitEnemy(GetTriggerUnit(), GetOwningPlayer(Caster)) == true ) ) then return false endif return true endfunction function Trig_Tide_Pool_damage_Func001D takes nothing returns boolean if ( not ( IsUnitAlly(GetTriggerUnit(), GetOwningPlayer(Caster)) == true ) ) then return false endif return true endfunction function TidePool_True takes nothing returns boolean return true endfunction function TidePool_Periodic takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) local group G = CreateGroup() local unit U set Rotation2 = Rotation2+5.00 loop exitwhen i>8 call SetUnitPosition(Effect_Units[i], CX+800.00*Cos((45.00*i+Rotation2)*bj_DEGTORAD), CY+800.00*Sin((45.00*i+Rotation2)*bj_DEGTORAD)) set i=i+1 endloop call GroupEnumUnitsInRange(G, CX, CY, 800.00, Condition(function TidePool_True)) loop set U = FirstOfGroup(G) exitwhen U == null if ( Trig_Tide_Pool_damage_Func001C() ) then call CreateNUnitsAtLoc( 1, 'h001', GetOwningPlayer(Caster), GetUnitLoc(GetTriggerUnit()), 0.00 ) call UnitApplyTimedLifeBJ( 3, 'BTLF', GetLastCreatedUnit() ) call UnitAddAbilityBJ( 'A007', GetLastCreatedUnit() ) call IssueTargetOrderBJ( GetLastCreatedUnit(), "frostnova", GetTriggerUnit() ) else if ( Trig_Tide_Pool_damage_Func001D()) then call CreateNUnitsAtLoc( 1, 'h001', GetOwningPlayer(Caster), GetUnitLoc(GetTriggerUnit()), 0.00 ) call UnitApplyTimedLifeBJ( 3, 'BTLF', GetLastCreatedUnit() ) call UnitAddAbilityBJ( 'A006', GetLastCreatedUnit() ) call IssueTargetOrderBJ( GetLastCreatedUnit(), "rejuvination", GetTriggerUnit() ) endif endif call GroupRemoveUnit(G, U) endloop call DestroyGroup(G) set G = null endfunction JASS:function TidePool_Periodic takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) local group G = CreateGroup() local unit U set Rotation2 = Rotation2+5.00 loop exitwhen i>8 call SetUnitPosition(Effect_Units[i], CX+800.00*Cos((45.00*i+Rotation2)*bj_DEGTORAD), CY+800.00*Sin((45.00*i+Rotation2)*bj_DEGTORAD)) set i=i+1 endloop call GroupEnumUnitsInRange(G, CX, CY, 800.00, Condition(function TidePool_True)) loop set U = FirstOfGroup(G) exitwhen U == null if (IsUnitEnemy(U, GetOwningPlayer(Caster))) then call CreateUnit(GetOwningPlayer(Caster), 'h001', CX, CY, 0.00) call UnitApplyTimedLife(GetLastCreatedUnit(), 'BTLF', 3.00) call UnitAddAbility(GetLastCreatedUnit(), 'A007') call IssueTargetOrder(GetLastCreatedUnit(), "frostnova", U) else if (IsUnitAlly(U, GetOwningPlayer(Caster))) then call CreateUnit(GetOwningPlayer(Caster), 'h001', CX, CY, 0.00) call UnitApplyTimedLife(GetLastCreatedUnit(), 'BTLF', 3.00) call UnitAddAbility(GetLastCreatedUnit(), 'A007') call IssueTargetOrder(GetLastCreatedUnit(), "rejuvination", U) endif endif call GroupRemoveUnit(G, U) endloop call DestroyGroup(G) set G = null endfunction JASS:function TidePool_Periodic takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) local group G = CreateGroup() local unit U local unit Dummy local player P = GetOwningPlayer(Caster) set Rotation2 = Rotation2+5.00 loop exitwhen i>8 call SetUnitPosition(Effect_Units[i], CX+800.00*Cos((45.00*i+Rotation2)*bj_DEGTORAD), CY+800.00*Sin((45.00*i+Rotation2)*bj_DEGTORAD)) set i=i+1 endloop call GroupEnumUnitsInRange(G, CX, CY, 800.00, Condition(function TidePool_True)) loop set U = FirstOfGroup(G) exitwhen U == null if (IsUnitEnemy(U, P)) then set Dummy = CreateUnit(P, 'h001', CX, CY, 0.00) call UnitApplyTimedLife(Dummy, 'BTLF', 3.00) call UnitAddAbility(Dummy, 'A007') call IssueTargetOrder(Dummy, "frostnova", U) else set Dummy = CreateUnit(P, 'h001', CX, CY, 0.00) call UnitApplyTimedLife(Dummy, 'BTLF', 3.00) call UnitAddAbility(Dummy, 'A006') call IssueTargetOrder(Dummy, "rejuvination", U) endif call GroupRemoveUnit(G, U) endloop call DestroyGroup(G) set G = null set Dummy = null endfunction JASS:function TidePool_Periodic takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) local group G = CreateGroup() local unit U local player P = GetOwningPlayer(Caster) local integer Level = GetUnitAbilityLevel(U, 'A005') local real Damage = 25.00*Level*0.04 //We multiply by the timer period so that it heals per second properly local real Healing = 5.00*Level*0.04 set Rotation2 = Rotation2+5.00 loop exitwhen i>8 call SetUnitPosition(Effect_Units[i], CX+800.00*Cos((45.00*i+Rotation2)*bj_DEGTORAD), CY+800.00*Sin((45.00*i+Rotation2)*bj_DEGTORAD)) set i=i+1 endloop call GroupEnumUnitsInRange(G, CX, CY, 800.00, Condition(function TidePool_True)) loop set U = FirstOfGroup(G) exitwhen U == null if (IsUnitEnemy(U, P)) then call UnitDamageTarget(Caster, U, Damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null) else call SetWidgetLife(U, GetWidgetLife(U)+Healing) endif call GroupRemoveUnit(G, U) endloop call DestroyGroup(G) set G = null endfunction JASS:function TidePool_Cast takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) local integer Level = GetUnitAbilityLevel(U, 'A005') set Caster = GetTriggerUnit() set Rotation2 = 0 loop exitwhen i>8 set Effect_Units[i] = CreateUnit(GetOwningPlayer(Caster), 'h004', CX+800.00*Cos(45.00*i*bj_DEGTORAD), CY+800.00*Sin(45.00*i*bj_DEGTORAD), 0.00) set i = i + 1 endloop call UnitAddAbility(Caster, 'A009') //A009 being the allied disabled spellbook call SetUnitAbilityLevel(U, 'A009', Level) call UnitAddAbility(Caster, 'A00A') //A00A being the enemy disabled spellbook call SetUnitAbilityLevel(U, 'A00A', Level) call EnableTrigger(TidePoolPeriodicTrig) endfunction JASS:function TidePool_Periodic takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) local group G = CreateGroup() local unit U local player P = GetOwningPlayer(Caster) local integer Level = GetUnitAbilityLevel(U, 'A005') local real Damage = 25.00*Level*0.04 //We multiply by the timer period so that it heals per second properly local real Healing = 5.00*Level*0.04 if OrderId2String(GetUnitCurrentOrder(Caster)) == "starfall" then set Rotation2 = Rotation2+5.00 loop exitwhen i>8 call SetUnitPosition(Effect_Units[i], CX+800.00*Cos((45.00*i+Rotation2)*bj_DEGTORAD), CY+800.00*Sin((45.00*i+Rotation2)*bj_DEGTORAD)) set i=i+1 endloop call GroupEnumUnitsInRange(G, CX, CY, 800.00, Condition(function TidePool_True)) loop set U = FirstOfGroup(G) exitwhen U == null if (IsUnitEnemy(U, P)) then call UnitDamageTarget(Caster, U, Damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null) else call SetWidgetLife(U, GetWidgetLife(U)+Healing) endif call GroupRemoveUnit(G, U) endloop else loop exitwhen i>8 call KillUnit(Effect_Units[i]) set i=i+1 call DisableTrigger(TidePoolPeriodicTrig) call UnitRemoveAbility(Caster, 'A009') call UnitRemoveAbility(Caster, 'A00A') endloop endif call DestroyGroup(G) set G = null endfunction JASS:globals trigger TidePoolPeriodicTrig unit Caster unit Unit unit array Effect_Units real Rotation2 endglobals function TidePool_CastConditions takes nothing returns boolean return GetSpellAbilityId() == 'A005' endfunction function TidePool_True takes nothing returns boolean return true endfunction function TidePool_Cast takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) set Caster = GetTriggerUnit() set Rotation2 = 0 loop exitwhen i>8 set Effect_Units[i] = CreateUnit(GetOwningPlayer(Caster), 'h004', CX+800.00*Cos(45.00*i*bj_DEGTORAD), CY+800.00*Sin(45.00*i*bj_DEGTORAD), 0.00) set i = i + 1 endloop call EnableTrigger(TidePoolPeriodicTrig) endfunction function TidePool_Periodic takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) local group G = CreateGroup() local unit U local player P = GetOwningPlayer(Caster) local integer Level = GetUnitAbilityLevel(U, 'A005') local real Damage = 25.00*Level*0.04 //We multiply by the timer period so that it heals per second properly local real Healing = 5.00*Level*0.04 if OrderId2String(GetUnitCurrentOrder(Caster)) == "starfall" then set Rotation2 = Rotation2+5.00 loop exitwhen i>8 call SetUnitPosition(Effect_Units[i], CX+800.00*Cos((45.00*i+Rotation2)*bj_DEGTORAD), CY+800.00*Sin((45.00*i+Rotation2)*bj_DEGTORAD)) set i=i+1 endloop call GroupEnumUnitsInRange(G, CX, CY, 800.00, Condition(function TidePool_True)) loop set U = FirstOfGroup(G) exitwhen U == null if (IsUnitEnemy(U, P)) then call UnitDamageTarget(Caster, U, Damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null) else call SetWidgetLife(U, GetWidgetLife(U)+Healing) endif call GroupRemoveUnit(G, U) endloop else loop exitwhen i>8 call KillUnit(Effect_Units[i]) set i=i+1 call DisableTrigger(TidePoolPeriodicTrig) call UnitRemoveAbility(Caster, 'A009') call UnitRemoveAbility(Caster, 'A00A') endloop endif call DestroyGroup(G) set G = null endfunction //=========================================================================== function InitTrig_TidePool takes nothing returns nothing set gg_trg_TidePool = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(gg_trg_TidePool, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(gg_trg_TidePool, Condition(function TidePool_CastConditions)) call TriggerAddAction(gg_trg_TidePool, function TidePool_Cast) set TidePoolPeriodicTrig = CreateTrigger() call TriggerRegisterTimerEventPeriodic(TidePoolPeriodicTrig, 0.04) call TriggerAddAction(TidePoolPeriodicTrig, function TidePool_Periodic) endfunction
JASS:scope TidePool globals private trigger TidePoolPeriodicTrig private unit Caster private unit Unit private unit array Effect_Units private real Rotation2 private timer T endglobals private function CastConditions takes nothing returns boolean return GetSpellAbilityId() == 'A005' endfunction private function True takes nothing returns boolean return true endfunction private function Cast takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) set Caster = GetTriggerUnit() set Rotation2 = 0 loop exitwhen i>8 set Effect_Units[i] = CreateUnit(GetOwningPlayer(Caster), 'h004', CX+800.00*Cos(45.00*i*bj_DEGTORAD), CY+800.00*Sin(45.00*i*bj_DEGTORAD), 0.00) set i = i + 1 endloop call ResumeTimer(T) endfunction private function Periodic takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) local group G = CreateGroup() local unit U local player P = GetOwningPlayer(Caster) local integer Level = GetUnitAbilityLevel(U, 'A005') local real Damage = 25.00*Level*0.04 //We multiply by the timer period so that it heals per second properly local real Healing = 5.00*Level*0.04 if OrderId2String(GetUnitCurrentOrder(Caster)) == "starfall" then set Rotation2 = Rotation2+5.00 loop exitwhen i>8 call SetUnitPosition(Effect_Units[i], CX+800.00*Cos((45.00*i+Rotation2)*bj_DEGTORAD), CY+800.00*Sin((45.00*i+Rotation2)*bj_DEGTORAD)) set i=i+1 endloop call GroupEnumUnitsInRange(G, CX, CY, 800.00, Condition( private function True)) loop set U = FirstOfGroup(G) exitwhen U == null if (IsUnitEnemy(U, P)) then call UnitDamageTarget(Caster, U, Damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null) else call SetWidgetLife(U, GetWidgetLife(U)+Healing) endif call GroupRemoveUnit(G, U) endloop else loop exitwhen i>8 call KillUnit(Effect_Units[i]) set i=i+1 call PauseTimer(T) call UnitRemoveAbility(Caster, 'A009') call UnitRemoveAbility(Caster, 'A00A') endloop endif call DestroyGroup(G) set G = null endfunction //=========================================================================== public function InitTrig takes nothing returns nothing set gg_trg_TidePool = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(gg_trg_TidePool, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(gg_trg_TidePool, Condition(function CastConditions)) call TriggerAddAction(gg_trg_TidePool, function Cast) set T = CreateTimer() call TimerStart(T, 0.04, true, function Periodic) call PauseTimer(T) endfunction endscope |
| 06-27-2008, 11:49 AM | #7 |
thanks and maybe you can also teach me how to make the other three when you have the time |
| 06-27-2008, 12:08 PM | #8 |
[spam].summon Earth-Fury[/spam] |
| 06-27-2008, 12:25 PM | #9 |
He will come. Don't you worry. |
| 06-27-2008, 10:21 PM | #10 |
Thanks Pyrogasm, I really appreciate all the help, the spell works perfectly now, although i'm still having issues with making it MUI and having it follow the JESP standard |
| 07-01-2008, 08:16 AM | #11 | |
Hmmz.... Okay, so you want to make it MUI and follow the JESP standard? Well, the first thing to make it follow the JESP standard is that it needs configuration constants, so let's see how those work. Spells can have configuration through constant globals, constant functions, or a combination of both. Constant globals look much more elegant whereas constant functions usually look clunky and take up a lot of space. However, constant functions also allow arguments to be passed so that users can create their own formula for, say, calculating how much damage is done. Here are some examples: Constant Globals://Configuration globals private constant integer SpellId = 'A000' private constant real Damage = 25.00 //Damage per second, multiplied by the level of the ability private constant real AoE = 300.00 private constant real TimerPeriod = 0.04 endglobals Constant Functions://Configuration private constant function SpellId takes nothing returns integer return 'A000' endfunction private constant function Damage takes integer Level returns real return Level*25.00 //Damage per second endfunction private constant function AoE takes integer Level returns real return 300.00 endfunction private constant function TimerPeriod takes nothing returns real return 0.04 endfunction Hybrid://Configuration globals private constant integer SpellId = 'A000' private constant real TimerPeriod = 0.04 endglobals private constant function Damage takes integer Level returns real return Level*25.00 //Damage per second endfunction private constant function AoE takes integer Level returns real return 300.00
JASS:globals private constant integer SPELLID = 'A005' private constant integer AURAID1 = 'A009' private constant integer AURAID2 = 'A00A' private constant string CHANNELINGSTRING = "starfall" private constant integer EFFECTDUMMYID = 'h004' private constant real TIMERINTERVAL = 0.04 private constant attacktype ATTACK = ATTACK_TYPE_CHAOS private constant damagetype DAMAGE = DAMAGE_TYPE_UNIVERSAL private constant weapontype WEAPON = null endglobals JASS:private constant function AoE takes integer Level returns real return 300.00*Level endfunction private constant function DamagePerSecond takes integer Level returns real return 25.00*Level endfunction private constant function HealthPerSecond takes integer Level returns real return 5.00*Level endfunction private constant function NumberOfEffects takes integer Level returns integer return 8 endfunction private constant function AngleOffsetPerInterval takes integer Level returns real return 5.00 endfunction private constant function DamageFilter takes unit FilterUnit, player CasterOwner, integer Level returns boolean return IsUnitEnemy(FilterUnit, CasterOwner) endfunction private constant function HealFilter takes unit FilterUnit, player CasterOwner, integer Level returns boolean return IsUnitAlly(FilterUnit, CasterOwner) endfunction JASS:scope TidePool //I also fixed some minor technical errors in the code, so you ought to notice them //============================ //Start Configuration //============================ globals private constant integer SPELLID = 'A005' private constant integer AURAID1 = 'A009' private constant integer AURAID2 = 'A00A' private constant string CHANNELINGSRING = "starfall" private constant integer EFFECTDUMMYID = 'h004' private constant real TIMERINTERVAL = 0.04 private constant attacktype ATTACK = ATTACK_TYPE_CHAOS private constant damagetype DAMAGE = DAMAGE_TYPE_UNIVERSAL private constant weapontype WEAPON = null endglobals private constant function AoE takes integer Level returns real return 300.00*Level endfunction private constant function DamagePerSecond takes integer Level returns real return 25.00*Level endfunction private constant function HealthPerSecond takes integer Level returns real return 5.00*Level endfunction private constant function NumberOfEffects takes integer Level returns integer return 8 endfunction private constant function AngleOffsetPerInterval takes integer Level returns real return 5.00 endfunction private constant function DamageFilter takes unit FilterUnit, player CasterOwner, integer Level returns boolean return IsUnitEnemy(FilterUnit, CasterOwner) endfunction private constant function HealFilter takes unit FilterUnit, player CasterOwner, integer Level returns boolean return IsUnitAlly(FilterUnit, CasterOwner) endfunction //============================ //End Configuration //============================ globals private trigger TidePoolPeriodicTrig private unit Caster private unit Unit private unit array Effect_Units private real Rotation2 private timer T endglobals private function CastConditions takes nothing returns boolean return GetSpellAbilityId() == 'A005' endfunction private function True takes nothing returns boolean return true endfunction private function Cast takes nothing returns nothing local integer i = 1 local real CX local real CY local player P set Caster = GetTriggerUnit() set CX = GetUnitX(Caster) set CY = GetUnitY(Caster) set P = GetOwningPlayer(Caster) set Rotation2 = 0 loop exitwhen i>8 set Effect_Units[i] = CreateUnit(P, 'h004', CX+800.00*Cos(45.00*i*bj_DEGTORAD), CY+800.00*Sin(45.00*i*bj_DEGTORAD), 0.00) set i = i + 1 endloop call UnitAddAbility(Caster, 'A009') call UnitAddAbility(Caster, 'A00A') call ResumeTimer(T) endfunction private function Periodic takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) local group G = CreateGroup() local unit U local player P = GetOwningPlayer(Caster) local integer Level = GetUnitAbilityLevel(U, 'A005') local real Damage = 25.00*Level*0.04 //We multiply by the timer period so that it heals per second properly local real Healing = 5.00*Level*0.04 if OrderId2String(GetUnitCurrentOrder(Caster)) == "starfall" then set Rotation2 = Rotation2+5.00 loop exitwhen i>8 call SetUnitPosition(Effect_Units[i], CX+800.00*Cos((45.00*i+Rotation2)*bj_DEGTORAD), CY+800.00*Sin((45.00*i+Rotation2)*bj_DEGTORAD)) set i=i+1 endloop call GroupEnumUnitsInRange(G, CX, CY, 800.00, Condition(function True)) loop set U = FirstOfGroup(G) exitwhen U == null if IsUnitEnemy(U, P) then call UnitDamageTarget(Caster, U, Damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null) else call SetWidgetLife(U, GetWidgetLife(U)+Healing) endif call GroupRemoveUnit(G, U) endloop else loop exitwhen i>8 call KillUnit(Effect_Units[i]) set i=i+1 endloop call PauseTimer(T) call UnitRemoveAbility(Caster, 'A009') call UnitRemoveAbility(Caster, 'A00A') endif call DestroyGroup(G) set G = null endfunction //=========================================================================== public function InitTrig takes nothing returns nothing set gg_trg_TidePool = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(gg_trg_TidePool, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(gg_trg_TidePool, Condition(function CastConditions)) call TriggerAddAction(gg_trg_TidePool, function Cast) set T = CreateTimer() call TimerStart(T, 0.04, true, function Periodic) call PauseTimer(T) endfunction endscope JASS:scope TidePool //============================ //Start Configuration //============================ globals private constant integer SPELLID = 'A005' private constant integer AURAID1 = 'A009' private constant integer AURAID2 = 'A00A' private constant string CHANNELINGSTRING = "starfall" private constant integer EFFECTDUMMYID = 'h004' private constant real TIMERINTERVAL = 0.04 private constant attacktype ATTACK = ATTACK_TYPE_CHAOS private constant damagetype DAMAGE = DAMAGE_TYPE_UNIVERSAL private constant weapontype WEAPON = null endglobals private constant function AoE takes integer Level returns real return 300.00*Level endfunction private constant function DamagePerSecond takes integer Level returns real return 25.00*Level endfunction private constant function HealthPerSecond takes integer Level returns real return 5.00*Level endfunction private constant function NumberOfEffects takes integer Level returns integer return 8 endfunction private constant function AngleOffsetPerInterval takes integer Level returns real return 5.00 endfunction private constant function DamageFilter takes unit FilterUnit, player CasterOwner, integer Level returns boolean return IsUnitEnemy(FilterUnit, CasterOwner) endfunction private constant function HealFilter takes unit FilterUnit, player CasterOwner, integer Level returns boolean return IsUnitAlly(FilterUnit, CasterOwner) endfunction //============================ //End Configuration //============================ globals private trigger TidePoolPeriodicTrig private unit Caster private unit Unit private unit array Effect_Units private real Rotation2 private timer T endglobals private function CastConditions takes nothing returns boolean return GetSpellAbilityId() == SPELLID endfunction private function True takes nothing returns boolean return true endfunction private function Cast takes nothing returns nothing local integer i = 1 local real CX local real CY local player P local integer Level local real Offset local integer Num local real AngleIncrement set Caster = GetTriggerUnit() set CX = GetUnitX(Caster) set CY = GetUnitY(Caster) set P = GetOwningPlayer(Caster) set Level = GetUnitAbilityLevel(Caster, SPELLID) set Offset = AoE(Level) set Num = NumberOfEffects(Level) set AngleIncrement = 360.00/Num set Rotation2 = 0 loop exitwhen i>Num set Effect_Units[i] = CreateUnit(P, EFFECTDUMMYID, CX+Offset*Cos(AngleIncrement*i*bj_DEGTORAD), CY+Offset*Sin(AngleIncrement*i*bj_DEGTORAD), 0.00) set i = i + 1 endloop call UnitAddAbility(Caster, AURAID1) call UnitAddAbility(Caster, AURAID2) call ResumeTimer(T) endfunction private function Periodic takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) local group G = CreateGroup() local unit U local player P = GetOwningPlayer(Caster) local integer Level = GetUnitAbilityLevel(U, SPELLID) local real Damage = DamagePerSecond(Level)*TIMERINTERVAL //We multiply by the timer period so that it heals per second properly local real Healing = HealthPerSecond(Level)*TIMERINTERVAL local integer Num = NumberOfEffects(Level) local integer AngleIncrement = 360.00/Num local real Offset = AoE(Level) if OrderId2String(GetUnitCurrentOrder(Caster)) == CHANNELINGSTRING then set Rotation2 = Rotation2+AngleOffsetPerInterval(Level) loop exitwhen i>Num call SetUnitPosition(Effect_Units[i], CX+Offset*Cos((AngleIncrement*i+Rotation2)*bj_DEGTORAD), CY+Offset*Sin((AngleIncrement*i+Rotation2)*bj_DEGTORAD)) set i=i+1 endloop call GroupEnumUnitsInRange(G, CX, CY, Offset, Condition(function True)) loop set U = FirstOfGroup(G) exitwhen U == null if DamageFilter(U, P, Level) then call UnitDamageTarget(Caster, U, Damage, true, false, ATTACK, DAMAGE, WEAPON) elseif HealFilter(U, P, Level) then call SetWidgetLife(U, GetWidgetLife(U)+Healing) endif call GroupRemoveUnit(G, U) endloop else loop exitwhen i>Num call KillUnit(Effect_Units[i]) set i=i+1 endloop call PauseTimer(T) call UnitRemoveAbility(Caster, AURAID1) call UnitRemoveAbility(Caster, AURAID2) endif call DestroyGroup(G) set G = null endfunction //=========================================================================== public function InitTrig takes nothing returns nothing set gg_trg_TidePool = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(gg_trg_TidePool, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(gg_trg_TidePool, Condition(function CastConditions)) call TriggerAddAction(gg_trg_TidePool, function Cast) set T = CreateTimer() call TimerStart(T, TIMERINTERVAL, true, function Periodic) call PauseTimer(T) endfunction endscope
JASS:private struct TPStruct unit Caster player P integer Level real CX real CY real Damage real Healing integer Num real Rotation = 0.00 real RotationAdd real AngleIncrement real Offset unit array Effects[360] //We can do arrays this large because JASSHelper now supports arrays up to 65000 indexes endstruct //360 should be more than enough JASS:private struct TPStruct unit Caster player P integer Level real CX real CY real Damage real Healing integer Num real Rotation = 0.00 real RotationAdd real AngleIncrement real Offset unit array Effects[360] static method create takes unit Caster, integer Level returns TPStruct local integer i = 0 local TPStruct TP = TPStruct.allocate() set TP.Caster = Caster set TP.P = GetOwningPlayer(Caster) set TP.Level = Level set TP.CX = GetUnitX(Caster) set TP.CY = GetUnitY(Caster) set TP.Damage = DamagePerSecond(Level)*TIMERINTERVAL set TP.Healing = HealthPerSecond(Level)*TIMERINTERVAL set TP.Num = NumberOfEffects(Level) set TP.RotationAdd = AngleOffsetPerInterval(Level) set TP.AngleIncrement = 360.00/Num*bj_DEGTORAD //Converting to Radians now so we don't have to later set TP.Offset = AoE(Level) loop set i = i+1 exitwhen i>TP.Num set TP.Effects[i] = CreateUnit(TP.P, EFFECTDUMMYID, TP.CX+TP.Offset*Cos(TP.AngleIncrement*i), TP.CY+TP.Offset*Sin(TP.AngleIncrement*i), 0.00) endloop call UnitAddAbility(Caster, AURAID1) call UnitAddAbility(Caster, AURAID2) return TP endmethod endstruct JASS:private function Cast takes nothing returns nothing local unit U = GetTriggerUnit() local TPStruct TP = TPStruct.create(U, GetUnitAbilityLevel(U, SPELLID)) //Do some stuff regarding attaching the struct, but we're not there yet call ResumeTimer(T) set U = null endfunction JASS:private function Periodic takes nothing returns nothing local integer i = 1 local real CX = GetUnitX(Caster) local real CY = GetUnitY(Caster) local group G = CreateGroup() local unit U local player P = GetOwningPlayer(Caster) local integer Level = GetUnitAbilityLevel(U, SPELLID) local real Damage = DamagePerSecond(Level)*TIMERINTERVAL local real Healing = HealthPerSecond(Level)*TIMERINTERVAL local integer Num = NumberOfEffects(Level) local integer AngleIncrement = 360.00/Num local real Offset = AoE(Level) if OrderId2String(GetUnitCurrentOrder(Caster)) == CHANNELINGSTRING then set Rotation2 = Rotation2+AngleOffsetPerInterval(Level) loop exitwhen i>Num call SetUnitPosition(Effect_Units[i], CX+Offset*Cos((AngleIncrement*i+Rotation2)*bj_DEGTORAD), CY+Offset*Sin((AngleIncrement*i+Rotation2)*bj_DEGTORAD)) set i=i+1 endloop call GroupEnumUnitsInRange(G, CX, CY, Offset, Condition(function True)) loop set U = FirstOfGroup(G) exitwhen U == null if DamageFilter(U, P, Level) then call UnitDamageTarget(Caster, U, Damage, true, false, ATTACK, DAMAGE, WEAPON) elseif HealFilter(U, P, Level) then call SetWidgetLife(U, GetWidgetLife(U)+Healing) endif call GroupRemoveUnit(G, U) endloop else loop exitwhen i>Num call KillUnit(Effect_Units[i]) set i=i+1 endloop call PauseTimer(T) call UnitRemoveAbility(Caster, AURAID1) call UnitRemoveAbility(Caster, AURAID2) endif call DestroyGroup(G) set G = null endfunction JASS:globals private group G endglobals public function InitTrig takes nothing returns nothing set gg_trg_TidePool = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(gg_trg_TidePool, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(gg_trg_TidePool, Condition(function CastConditions)) call TriggerAddAction(gg_trg_TidePool, function Cast) set T = CreateTimer() call TimerStart(T, TIMERINTERVAL, true, function Periodic) call PauseTimer(T) set G = CreateGroup() endfunction JASS:method onDestroy takes nothing returns nothing local integer i = 0 call UnitRemoveAbility(this.Caster, AURAID1) call UnitRemoveAbility(this.Caster, AURAID2) loop set i = i+1 exitwhen i>this.Num call KillUnit(this.Effects[i]) endloop endmethod JASS:else call TP.destroy() //Ignore for now how we get "TP", that will be in a bit call PauseTimer(T) endif JASS:method Move takes nothing returns nothing local integer i = 0 set this.Rotation = this.Rotation+this.RotationAdd loop set i = i+1 exitwhen i>this.Num call SetUnitPosition(this.Effects[i], this.CX+this.Offset*Cos(this.AngleIncrement*i+this.Rotation), this.CY+this.Offset*Sin(this.AngleIncrement*i+this.Rotation)) endloop endmethod JASS:private function Periodic takes nothing returns nothing local integer i = 0 local unit U local TPStruct TP //We'll figure out how to get TP in a second if OrderId2String(GetUnitCurrentOrder(TP.Caster)) == CHANNELINGSTRING then call TP.Move() call GroupEnumUnitsInRange(G, TP.CX, TP.CY, TP.Offset, Condition(function True)) loop set U = FirstOfGroup(G) exitwhen U == null if DamageFilter(U, TP.P, TP.Level) then call UnitDamageTarget(TP.Caster, U, TP.Damage, true, false, ATTACK, DAMAGE, WEAPON) endif if HealFilter(U, TP.P, TP.Level) then call SetWidgetLife(U, GetWidgetLife(U)+TP.Healing) endif call GroupRemoveUnit(G, U) endloop else call TP.destroy() call PauseTimer(T) endif endfunction JASS:scope TidePool //============================ //Start Configuration //============================ globals private constant integer SPELLID = 'A005' private constant integer AURAID1 = 'A009' private constant integer AURAID2 = 'A00A' private constant string CHANNELINGSTRING = "starfall" private constant integer EFFECTDUMMYID = 'h004' private constant real TIMERINTERVAL = 0.04 private constant attacktype ATTACK = ATTACK_TYPE_CHAOS private constant damagetype DAMAGE = DAMAGE_TYPE_UNIVERSAL private constant weapontype WEAPON = null endglobals private constant function AoE takes integer Level returns real return 300.00*Level endfunction private constant function DamagePerSecond takes integer Level returns real return 25.00*Level endfunction private constant function HealthPerSecond takes integer Level returns real return 5.00*Level endfunction private constant function NumberOfEffects takes integer Level returns integer return 8 endfunction private constant function AngleOffsetPerInterval takes integer Level returns real return 5.00 endfunction private constant function DamageFilter takes unit FilterUnit, player CasterOwner, integer Level returns boolean return IsUnitEnemy(FilterUnit, CasterOwner) endfunction private constant function HealFilter takes unit FilterUnit, player CasterOwner, integer Level returns boolean return IsUnitAlly(FilterUnit, CasterOwner) endfunction //============================ //End Configuration //============================ globals private timer T private group G endglobals private struct TPStruct unit Caster player P integer Level real CX real CY real Damage real Healing integer Num real Rotation = 0.00 real RotationAdd real AngleIncrement real Offset unit array Effects[360] static method create takes unit Caster, integer Level returns TPStruct local integer i = 0 local TPStruct TP = TPStruct.allocate() set TP.Caster = Caster set TP.P = GetOwningPlayer(Caster) set TP.Level = Level set TP.CX = GetUnitX(Caster) set TP.CY = GetUnitY(Caster) set TP.Damage = DamagePerSecond(Level)*TIMERINTERVAL set TP.Healing = HealthPerSecond(Level)*TIMERINTERVAL set TP.Num = NumberOfEffects(Level) set TP.RotationAdd = AngleOffsetPerInterval(Level) set TP.AngleIncrement = 360.00/Num*bj_DEGTORAD set TP.Offset = AoE(Level) loop set i = i+1 exitwhen i>TP.Num set TP.Effects[i] = CreateUnit(TP.P, EFFECTDUMMYID, TP.CX+TP.Offset*Cos(TP.AngleIncrement*i), TP.CY+TP.Offset*Sin(TP.AngleIncrement*i), 0.00) endloop call UnitAddAbility(Caster, AURAID1) call UnitAddAbility(Caster, AURAID2) return TP endmethod method Move takes nothing returns nothing local integer i = 0 set this.Rotation = this.Rotation+this.RotationAdd loop set i = i+1 exitwhen i>this.Num call SetUnitPosition(this.Effects[i], this.CX+this.Offset*Cos(this.AngleIncrement*i+this.Rotation), this.CY+this.Offset*Sin(this.AngleIncrement*i+this.Rotation)) endloop endmethod method onDestroy takes nothing returns nothing local integer i = 0 call UnitRemoveAbility(this.Caster, AURAID1) call UnitRemoveAbility(this.Caster, AURAID2) loop set i = i+1 exitwhen i>this.Num call KillUnit(this.Effects[i]) endloop endmethod endstruct private function CastConditions takes nothing returns boolean return GetSpellAbilityId() == SPELLID endfunction private function True takes nothing returns boolean return true endfunction private function Cast takes nothing returns nothing local unit U = GetTriggerUnit() local TPStruct TP = TPStruct.create(U, GetUnitAbilityLevel(U, SPELLID)) //Do some stuff regarding attaching the struct, but we're not there yet call ResumeTimer(T) set U = null endfunction private function Periodic takes nothing returns nothing local integer i = 0 local unit U local TPStruct TP //We'll figure out how to get it in a second if OrderId2String(GetUnitCurrentOrder(TP.Caster)) == CHANNELINGSTRING then call TP.Move() call GroupEnumUnitsInRange(G, TP.CX, TP.CY, TP.Offset, Condition(function True)) loop set U = FirstOfGroup(G) exitwhen U == null if DamageFilter(U, TP.P, TP.Level) then call UnitDamageTarget(TP.Caster, U, TP.Damage, true, false, ATTACK, DAMAGE, WEAPON) endif if HealFilter(U, TP.P, TP.Level) then call SetWidgetLife(U, GetWidgetLife(U)+TP.Healing) endif call GroupRemoveUnit(G, U) endloop else call TP.destroy() call PauseTimer(T) endif endfunction //=========================================================================== public function InitTrig takes nothing returns nothing set gg_trg_TidePool = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(gg_trg_TidePool, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(gg_trg_TidePool, Condition(function CastConditions)) call TriggerAddAction(gg_trg_TidePool, function Cast) set T = CreateTimer() call TimerStart(T, TIMERINTERVAL, true, function Periodic) call PauseTimer(T) set G = CreateGroup() endfunction endscope How might we do that, you say? Well, here's the basic layout of what we're going to add: JASS:globals timer T integer N = 0 keyword Datas MyStruct array Datas endglobals struct MyStruct //... endstruct function Periodic takes nothing returns nothing //Looping through all the structs local integer i = 0 local MyStruct MS loop set i = i+1 exitwhen i>N set MS = Datas[i] if Finished(MS) then call MS.destroy() set N = N-1 if N > 0 then set Datas[i] = Datas[N+1] set i = i-1 else call PauseTimer(T) exitwhen true endif endif endloop endfunction function Add takes nothing returns nothing //Adding a new struct to the stack local MyStruct MS = MyStruct.create() //Or whatever set N = N+1 set Datas[N] = MS if N == 1 then call ResumeTimer(T) endif endfunction JASS:globals private timer T private group G private integer N = 0 private keyword TPStruct private TPStruct array TPs endglobals private function Cast takes nothing returns nothing local unit U = GetTriggerUnit() local TPStruct TP = TPStruct.create(U, GetUnitAbilityLevel(U, SPELLID)) set N = N+1 set TPs[N] = TP if N == 1 then call ResumeTimer(T) endif set U = null endfunction
While that's a bit technical, the important part is this: we can use TPStruct before it is declared. This saves us from having to use another globals block below the struct, making things look retarded. Moving on, the "Periodic" function will be a bit more involved to modify, but still simple: JASS:private function Periodic takes nothing returns nothing local integer i = 0 local unit U local TPStruct TP loop set i = i+1 exitwhen i>N set TP = TPs[N] if OrderId2String(GetUnitCurrentOrder(TP.Caster)) == CHANNELINGSTRING then call TP.Move() call GroupEnumUnitsInRange(G, TP.CX, TP.CY, TP.Offset, Condition(function True)) loop set U = FirstOfGroup(G) exitwhen U == null if DamageFilter(U, TP.P, TP.Level) then call UnitDamageTarget(TP.Caster, U, TP.Damage, true, false, ATTACK, DAMAGE, WEAPON) endif if HealFilter(U, TP.P, TP.Level) then call SetWidgetLife(U, GetWidgetLife(U)+TP.Healing) endif call GroupRemoveUnit(G, U) endloop else call TP.destroy() set N = N-1 if N > 0 then set TPs[i] = TPs[N+1] set i = i-1 else call PauseTimer(T) exitwhen true endif endif endloop endfunction Tide Pool:scope TidePool //============================ //Start Configuration //============================ globals private constant integer SPELLID = 'A005' private constant integer AURAID1 = 'A009' private constant integer AURAID2 = 'A00A' private constant string CHANNELINGSTRING = "starfall" private constant integer EFFECTDUMMYID = 'h004' private constant real TIMERINTERVAL = 0.04 private constant attacktype ATTACK = ATTACK_TYPE_CHAOS private constant damagetype DAMAGE = DAMAGE_TYPE_UNIVERSAL private constant weapontype WEAPON = null endglobals private constant function AoE takes integer Level returns real return 300.00*Level endfunction private constant function DamagePerSecond takes integer Level returns real return 25.00*Level endfunction private constant function HealthPerSecond takes integer Level returns real return 5.00*Level endfunction private constant function NumberOfEffects takes integer Level returns integer return 8 endfunction private constant function AngleOffsetPerInterval takes integer Level returns real return 5.00 endfunction private constant function DamageFilter takes unit FilterUnit, player CasterOwner, integer Level returns boolean return IsUnitEnemy(FilterUnit, CasterOwner) endfunction private constant function HealFilter takes unit FilterUnit, player CasterOwner, integer Level returns boolean return IsUnitAlly(FilterUnit, CasterOwner) endfunction //============================ //End Configuration //============================ globals private timer T private group G private integer N = 0 private keyword TPStruct private TPStruct array TPs endglobals private struct TPStruct unit Caster player P integer Level real CX real CY real Damage real Healing integer Num real Rotation = 0.00 real RotationAdd real AngleIncrement real Offset unit array Effects[360] static method create takes unit Caster, integer Level returns TPStruct local integer i = 0 local TPStruct TP = TPStruct.allocate() set TP.Caster = Caster set TP.P = GetOwningPlayer(Caster) set TP.Level = Level set TP.CX = GetUnitX(Caster) set TP.CY = GetUnitY(Caster) set TP.Damage = DamagePerSecond(Level)*TIMERINTERVAL set TP.Healing = HealthPerSecond(Level)*TIMERINTERVAL set TP.Num = NumberOfEffects(Level) set TP.RotationAdd = AngleOffsetPerInterval(Level) set TP.AngleIncrement = 360.00/Num*bj_DEGTORAD set TP.Offset = AoE(Level) loop set i = i+1 exitwhen i>TP.Num set TP.Effects[i] = CreateUnit(TP.P, EFFECTDUMMYID, TP.CX+TP.Offset*Cos(TP.AngleIncrement*i), TP.CY+TP.Offset*Sin(TP.AngleIncrement*i), 0.00) endloop call UnitAddAbility(Caster, AURAID1) call UnitAddAbility(Caster, AURAID2) return TP endmethod method Move takes nothing returns nothing local integer i = 0 set this.Rotation = this.Rotation+this.RotationAdd loop set i = i+1 exitwhen i>this.Num call SetUnitPosition(this.Effects[i], this.CX+this.Offset*Cos(this.AngleIncrement*i+this.Rotation), this.CY+this.Offset*Sin(this.AngleIncrement*i+this.Rotation)) endloop endmethod method onDestroy takes nothing returns nothing local integer i = 0 call UnitRemoveAbility(this.Caster, AURAID1) call UnitRemoveAbility(this.Caster, AURAID2) loop set i = i+1 exitwhen i>Num call KillUnit(this.Effects[i]) endloop endmethod endstruct private function CastConditions takes nothing returns boolean return GetSpellAbilityId() == SPELLID endfunction private function True takes nothing returns boolean return true endfunction private function Cast takes nothing returns nothing local unit U = GetTriggerUnit() local TPStruct TP = TPStruct.create(U, GetUnitAbilityLevel(U, SPELLID)) set N = N+1 set TPs[N] = TP if N == 1 then call ResumeTimer(T) endif set U = null endfunction private function Periodic takes nothing returns nothing local integer i = 0 local unit U local TPStruct TP loop set i = i+1 exitwhen i>N set TP = TPs[N] if OrderId2String(GetUnitCurrentOrder(TP.Caster)) == CHANNELINGSTRING then call TP.Move() call GroupEnumUnitsInRange(G, TP.CX, TP.CY, TP.Offset, Condition(function True)) loop set U = FirstOfGroup(G) exitwhen U == null if DamageFilter(U, TP.P, TP.Level) then call UnitDamageTarget(TP.Caster, U, TP.Damage, true, false, ATTACK, DAMAGE, WEAPON) endif if HealFilter(U, TP.P, TP.Level) then call SetWidgetLife(U, GetWidgetLife(U)+TP.Healing) endif call GroupRemoveUnit(G, U) endloop else call TP.destroy() set N = N-1 if N > 0 then set TPs[i] = TPs[N+1] set i = i-1 else call PauseTimer(T) exitwhen true endif endif endloop endfunction //=========================================================================== public function InitTrig takes nothing returns nothing set gg_trg_TidePool = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(gg_trg_TidePool, EVENT_PLAYER_UNIT_SPELL_EFFECT) call TriggerAddCondition(gg_trg_TidePool, Condition(function CastConditions)) call TriggerAddAction(gg_trg_TidePool, function Cast) set T = CreateTimer() call TimerStart(T, TIMERINTERVAL, true, function Periodic) call PauseTimer(T) set G = CreateGroup() endfunction endscope |
| 07-03-2008, 10:28 AM | #12 |
thanks pyrogasm for all the help |
| 07-03-2008, 10:32 PM | #13 |
Sure thing... as long as you learned from it instead of just using the end result! |
| 07-04-2008, 05:00 AM | #14 |
heh. no I learned cuz even when I'm not listening I still absorb most of the stuff, even when skimming |
| 07-06-2008, 01:57 AM | #15 |
WAAAAHHHH!!!! problem with script i was able to save it once and it worked correctly then right after that things started getting out of hand |
