l-hate_you
New Member
- Reaction score
- 6
Need help
I'm not Mr.JASS or anything but I've been pretty successful with this tutorial. The trigger will create a grenade at the correct spawn point and the grenade will explode in the alotted time but there is no arc [or bounce.] (There may be bounce but it has never arced correctly to allow me to see it happen.) When I cast the spell the grenade is created and simply moves straight upwards slowly before exploding correctly in a few seconds. There is no X or Y movement
Note: I have imported all the JASS native script into my map from both the vector and LinkedList systems, my prediction that either my trigger is wrong or the ParticleMain trigger is messed up (exact version from the map, which is in my map, is posted) So here they are. I based my casting trigger off of Chocobo's JASS because the original trigger only did what I stated above but... Chocobo's is no different. (I assume that it is intended that both triggers do the same thing but Chocobos is more interchangeable)
Main Trigger, Same as Chocobo's version but with my own Ability Raw Code
Exact character-for-character version of the first Particle System trigger from the map posted on the first post of this thread
Since I just copy-and-pasted is this expected? Is the grenade only supposed to rise up and explode and I have to change it myself? or should the grenade be thrown in an arc and bounce, deflecting off walls on the way (which I have the natives for- correct? The natives from Vector and LinkedList?)
Side Note: I assume LinkedList doesn't have much to do with physics but thats besides the point
Can somebody please point me in the right direction here (I actually know simple JASS and see how the casting trigger works, just not so much the ParticleMain and the loopy vector stuff )
P.S. If you want to see the other function from the Particle System just say so, it contains Gravity, Wind, Ground Hit, and Particle Death, things that don't concern me at the time being and hopefully never do
I'm not Mr.JASS or anything but I've been pretty successful with this tutorial. The trigger will create a grenade at the correct spawn point and the grenade will explode in the alotted time but there is no arc [or bounce.] (There may be bounce but it has never arced correctly to allow me to see it happen.) When I cast the spell the grenade is created and simply moves straight upwards slowly before exploding correctly in a few seconds. There is no X or Y movement
Note: I have imported all the JASS native script into my map from both the vector and LinkedList systems, my prediction that either my trigger is wrong or the ParticleMain trigger is messed up (exact version from the map, which is in my map, is posted) So here they are. I based my casting trigger off of Chocobo's JASS because the original trigger only did what I stated above but... Chocobo's is no different. (I assume that it is intended that both triggers do the same thing but Chocobos is more interchangeable)
Main Trigger, Same as Chocobo's version but with my own Ability Raw Code
JASS:
function Trig_Grenade_Conditions takes nothing returns boolean
return GetSpellAbilityId()==039;A00R039;
endfunction
function DestroyEffectTimed takes effect eff,real duration returns nothing
call PolledWait(duration)
call DestroyEffect(eff)
endfunction
function Trig_Grenade_Actions takes nothing returns nothing
local unit h=GetSpellAbilityUnit()
local location l=GetSpellTargetLoc()
local real x=GetLocationX(l)-GetUnitX(h)
local real y=GetLocationY(l)-GetUnitY(h)
local real a=Atan2BJ(y,x)
local real aoa
local unit u=CreateParticle(GetOwningPlayer(h),039;e000039;,GetUnitX(h),GetUnitY(h),a)
local real array r
local integer i=udg_clsParticlePlace[GetUnitUserData(u)]
set udg_vectorX<i>=udg_vectorX<i>-udg_vectorX[SpawnPlaceOffset()]*CosBJ(a)
set udg_vectorY<i>=udg_vectorY<i>-udg_vectorY[SpawnPlaceOffset()]*SinBJ(a)
set udg_vectorZ<i>=udg_vectorZ<i>-udg_vectorZ[SpawnPlaceOffset()]+1
set r[2]=750
set r[0]=RMinBJ(r[2],SquareRoot(x*x+y*y))
set r[1]=SquareRoot(r[2]*VectorGetLength(G()))
set aoa=(bj_PI/2)-(Asin((r[0]*VectorGetLength(G()))/(r[1]*r[1]))/2)
call SetUnitTimeScalePercent(u,10.00)
call ParticleSetSpeed(u,Cos(aoa)*CosBJ(a)*r[1],Cos(aoa)*SinBJ(a)*r[1],r[1]*Sin(aoa))
call ParticleAddForce(u,G())
call ParticleLinkConditionTrigger2Func(u,ParticleGroundHit(),"GroundHit_Bounce")
call ParticleLinkConditionTrigger2Func(u,ParticleDeath(),"Death_ExplodeNade")
call UnitApplyTimedLife(u,039;BTLF039;,2.)
set l=null
set h=null
set u=null
endfunction
function DamageArea takes unit source,real maxdmg,integer damageV,real radius returns nothing
local integer i=0
local integer originV
local real array r
local group g=CreateGroup()
local unit c
call GroupEnumUnitsInRange(g,udg_vectorX[damageV],udg_vectorY[damageV],radius,null)
loop
set c=FirstOfGroup(g)
exitwhen c==null
if GetUnitState(c,UNIT_STATE_LIFE)>0 then
set r[0]=GetUnitX(c)
set r[1]=GetUnitY(c)
set r[2]=GetZ(r[0],r[1])
set originV=VectorCreate(r[0],r[1],r[2])
if IsPointInSphere(originV,damageV,radius) then
call VectorSubtract(originV,damageV)
set r[5]=(radius-VectorGetLength(originV))/radius*maxdmg
call UnitDamageTarget(source,c,r[5],true,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
endif
call VectorDestroy(originV)
endif
call GroupRemoveUnit(g,c)
endloop
call DestroyGroup(g)
set g=null
set c=null
endfunction
function CreateExplosion takes player p,string path,real x,real y,real z,real facing,real size,real time returns nothing
local unit u=CreateUnit(p,039;e001039;,x,y,facing)
local effect e
call SetUnitX(u,x)
call SetUnitY(u,y)
call MakeUnitFlyable(u)
call SetUnitAnimationByIndex(u,90)
call SetUnitScale(u,size,size,size)
call SetUnitFlyHeight(u,z-GetZ(x,y),0)
if time==0 then
call DestroyEffect(AddSpecialEffectTarget(path,u,"origin"))
else
set e=AddSpecialEffectTarget(path,u,"origin")
endif
call KillUnit(u)
set u=null
if time>0 then
call DestroyEffectTimed(e,time)
endif
set e=null
endfunction
function Death_ExplodeNade takes nothing returns nothing
local unit u=GetEnumUnit()
local integer p=udg_clsParticlePlace[GetUnitUserData(u)]
call CreateExplosion(GetOwningPlayer(u),"Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl",udg_vectorX[p],udg_vectorY[p],udg_vectorZ[p],GetRandomReal(0,360),1.,5.)
call CreateExplosion(GetOwningPlayer(u),"Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl",udg_vectorX[p],udg_vectorY[p],udg_vectorZ[p],GetRandomReal(0,360),3.,0)
call DamageArea(u,275,p,256.)
call RemoveParticle(u,true)
set u=null
endfunction
//===========================================================================
function InitTrig_Grenade takes nothing returns nothing
set gg_trg_Grenade = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Grenade, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Grenade, Condition( function Trig_Grenade_Conditions ) )
call TriggerAddAction( gg_trg_Grenade, function Trig_Grenade_Actions )
endfunction</i></i></i></i></i></i>
Exact character-for-character version of the first Particle System trigger from the map posted on the first post of this thread
JASS:
// ************************************************************************************************************************
// ** **
// ** Particle Engine, moving objects dynamically **
// ** Created by iNfraNe **
// ** **
// ************************************************************************************************************************
// USER CHANGABLE CONSTANTS
constant function ParticlePeriod takes nothing returns real
return 0.025 //Warning: changing this value may cause lag.
endfunction
constant function DummyRawCode takes nothing returns integer
return 039;e000039; //Special dummy unit, having animations for changing angle on projectiles
endfunction
function SpawnPlaceOffset takes nothing returns integer
if udg_particleSpawnOffset == 0 then
set udg_particleSpawnOffset = VectorCreate(25,0,50) //X is parallel to the model, Y is perpendicular to the model
endif
return udg_particleSpawnOffset
endfunction
// INTERNAL FUNCTIONS
function H2I takes handle h returns integer
return h
return 0
endfunction
function I2TR takes integer i returns trigger
return i
return null
endfunction
function GetZ takes real x, real y returns real
local location loc = Location(x,y)
local real r = GetLocationZ(loc)
call RemoveLocation(loc)
set loc = null
return r
endfunction
function CreateEvalTrig takes code cb returns trigger
local trigger t = CreateTrigger()
call TriggerAddCondition(t,Condition(cb))
return t
endfunction
function MakeUnitFlyable takes unit u returns nothing
call UnitAddAbility(u, 039;Amrf039;)
call UnitRemoveAbility(u, 039;Amrf039;)
endfunction
function MapSizeXLow takes nothing returns real
if udg_MapSize[0] == 0. then
set udg_MapSize[0] = GetRectMinX(GetWorldBounds())
endif
return udg_MapSize[0]
endfunction
function MapSizeXHigh takes nothing returns real
if udg_MapSize[1] == 0. then
set udg_MapSize[1] = GetRectMaxX(GetWorldBounds())
endif
return udg_MapSize[1]
endfunction
function MapSizeYLow takes nothing returns real
if udg_MapSize[2] == 0. then
set udg_MapSize[2] = GetRectMinY(GetWorldBounds())
endif
return udg_MapSize[2]
endfunction
function MapSizeYHigh takes nothing returns real
if udg_MapSize[3] == 0. then
set udg_MapSize[3] = GetRectMaxY(GetWorldBounds())
endif
return udg_MapSize[3]
endfunction
//Do not try to init an empty string ("") it will lose its index.
function clsStringIndexInitString takes string s returns integer
local integer i = 0
local integer j = -1
loop
exitwhen i > 8191
if udg_clsStringIndexString<i> == "" or udg_clsStringIndexString<i> == null or udg_clsStringIndexString<i> == s then
set j = i
set i = 8192
endif
set i = i + 1
endloop
if j < 0 then
call BJDebugMsg("|cffff0000Critical Error:|r Could not add string to array, last added condition will fail.")
return -1
endif
set udg_clsStringIndexString[j] = s
return j
endfunction
function clsStringIndexGetString takes integer i returns string
return udg_clsStringIndexString<i>
endfunction
function clsParticleCreate takes unit u returns boolean
local integer i = 0
local integer j = -1
loop
exitwhen i > 8191
if not udg_clsParticleTaken<i> then
set j = i
set i = 8192
endif
set i = i + 1
endloop
if j < 0 then
return false
endif
set udg_clsParticleTaken[j] = true
set udg_clsParticlePlace[j] = VectorCreate(GetUnitX(u), GetUnitY(u), GetZ(GetUnitX(u), GetUnitY(u)) + VectorGetZ(SpawnPlaceOffset()))
set udg_clsParticleSpeed[j] = VectorCreate(0,0,0)
set udg_clsParticleForces[j] = LL_NewList(0)
set udg_clsParticleConditions[j] = LL_NewList(0)
set udg_clsParticleConditionStrings[j] = LL_NewList(0)
call SetUnitUserData(u,j)
return true
endfunction
function clsParticleDestroy takes unit u returns nothing
local integer i = GetUnitUserData(u)
if not udg_clsParticleTaken<i> then
return
endif
call VectorDestroy(udg_clsParticlePlace<i>)
call VectorDestroy(udg_clsParticleSpeed<i>)
call LL_DestroyList(udg_clsParticleForces<i>)
call LL_DestroyList(udg_clsParticleConditions<i>)
call LL_DestroyList(udg_clsParticleConditionStrings<i>)
set udg_clsParticleTaken<i> = false
endfunction
function GetAttachedDummyEffect takes integer i returns effect
return udg_clsParticleDummyEffect<i>
endfunction
// USER USABLE FUNCTIONS
function CreateParticle takes player p, integer utype, real x, real y, real facing returns unit
local unit u = CreateUnit(p, utype, x, y, facing)
set x = x+CosBJ(facing)*VectorGetX(SpawnPlaceOffset())+SinBJ(facing)*VectorGetY(SpawnPlaceOffset())
set y = y+SinBJ(facing)*VectorGetX(SpawnPlaceOffset())+CosBJ(facing)*VectorGetY(SpawnPlaceOffset())
call SetUnitX(u, x)
call SetUnitY(u, y)
if not clsParticleCreate(u) then
call BJDebugMsg("|cffff0000Error:|r could not initialize particle class in function |cffffcc00CreateParticle|r, see the documentation for help.")
call RemoveUnit(u)
return null
endif
call MakeUnitFlyable(u)
call GroupAddUnit(udg_particleGroup, u)
return u
endfunction
function CreateProjectile takes player p, string path, real x, real y, real facing returns unit
local unit u = CreateUnit(p, DummyRawCode(), x, y, facing)
local integer i
set x = x+CosBJ(facing)*VectorGetX(SpawnPlaceOffset())+SinBJ(facing)*VectorGetY(SpawnPlaceOffset())
set y = y+SinBJ(facing)*VectorGetX(SpawnPlaceOffset())+CosBJ(facing)*VectorGetY(SpawnPlaceOffset())
call SetUnitX(u, x)
call SetUnitY(u, y)
if not clsParticleCreate(u) then
call BJDebugMsg("|cffff0000Error:|r could not initialize particle class in function |cffffcc00CreateProjectile|r, see the documentation for help.")
call RemoveUnit(u)
return null
endif
set i = GetUnitUserData(u)
set udg_clsParticleDummyEffect<i> = AddSpecialEffectTarget(path, u, "origin")
call MakeUnitFlyable(u)
call GroupAddUnit(udg_particleGroup, u)
return u
endfunction
function MakeParticle takes unit u returns nothing
local integer p
if not clsParticleCreate(u) then
call BJDebugMsg("|cffff0000Error:|r could not initialize particle class in function |cffffcc00MakeParticle|r, see the documentation for help.")
return
endif
set p = udg_clsParticlePlace[GetUnitUserData(u)]
set udg_vectorZ[p] = udg_vectorZ[p] - udg_vectorZ[SpawnPlaceOffset()] + 1
call MakeUnitFlyable(u)
call GroupAddUnit(udg_particleGroup, u)
endfunction
function RemoveParticle takes unit u, boolean removeunit returns nothing
local effect e = GetAttachedDummyEffect(GetUnitUserData(u))
if e != null then
call DestroyEffect(e)
endif
//Destroy class, VERY important
call clsParticleDestroy(u)
call GroupRemoveUnit(udg_particleGroup, u)
if removeunit then
call KillUnit(u)
call RemoveUnit(u)
endif
set e = null
endfunction
function ParticleSetSpeed takes unit u, real x, real y, real z returns nothing
local integer i = GetUnitUserData(u)
local integer v = udg_clsParticleSpeed<i>
set udg_vectorX[v] = x
set udg_vectorY[v] = y
set udg_vectorZ[v] = z
if GetAttachedDummyEffect(i) != null then
set i = R2I(Atan2BJ(udg_vectorZ[v], SquareRoot(udg_vectorX[v]*udg_vectorX[v]+udg_vectorY[v]*udg_vectorY[v]))+0.5)+90
call SetUnitAnimationByIndex(u, i)
endif
endfunction
function ParticleLinkConditionTrigger2Func takes unit u, trigger t, string s returns nothing
local integer i = GetUnitUserData(u)
local integer hi = H2I(t)
if LL_GetListItem(udg_clsParticleConditions<i>, 0) == 0 then
call LL_UpdateListItem(udg_clsParticleConditions<i>, 0, hi)
call LL_UpdateListItem(udg_clsParticleConditionStrings<i>, 0, clsStringIndexInitString(s))
else
call LL_AddListItemFront(udg_clsParticleConditions<i>, hi)
call LL_AddListItemFront(udg_clsParticleConditionStrings<i>, clsStringIndexInitString(s))
endif
endfunction
function ParticleUnlinkCondition takes unit u, trigger t returns nothing
local integer i = GetUnitUserData(u)
local integer hi = H2I(t)
local location list = udg_clsParticleConditions<i>
local integer j = LL_FindListItem(list,hi,0)
call LL_RemoveListItem(list, j)
call LL_RemoveListItem(udg_clsParticleConditionStrings<i>, j)
set list = null
endfunction
function ParticleAddForce takes unit u, integer vector returns nothing
local integer i = GetUnitUserData(u)
if LL_GetListItem(udg_clsParticleForces<i>, 0) == 0 then
call LL_UpdateListItem(udg_clsParticleForces<i>, 0, vector)
else
call LL_AddListItemFront(udg_clsParticleForces<i>, vector)
endif
endfunction
function ParticleRemoveForce takes unit u, integer vector returns nothing
local integer i = GetUnitUserData(u)
local location list = udg_clsParticleForces<i>
local integer j = LL_FindListItem(list,vector,0)
call LL_RemoveListItem(list, j)
set list = null
endfunction
// INTERNAL FUNCTIONS
function CheckConditions takes integer i returns nothing
local location condlist = udg_clsParticleConditions<i>
local location strlist = udg_clsParticleConditionStrings<i>
local trigger t
local string s
loop
exitwhen condlist == null
set t = I2TR(LL_r2i(GetLocationX(condlist)))
if TriggerEvaluate(t) then
set s = clsStringIndexGetString(LL_r2i(GetLocationX(strlist)))
if s != "" and s != null then
call ExecuteFunc(s)
endif
endif
set condlist = LL_ly(condlist)
set strlist = LL_ly(strlist)
endloop
set t = null
set condlist = null
set strlist = null
endfunction
function CalcForces takes integer i returns integer
local location list = udg_clsParticleForces<i>
local integer a
local integer tv
local integer totv = VectorCreate(0,0,0)
loop
set a = LL_r2i(GetLocationX(list))
if a > 0 then
set tv = VectorAmplify(a, ParticlePeriod())
call VectorAdd(totv,tv)
call VectorDestroy(tv)
endif
set list = LL_ly(list)
exitwhen list == null
endloop
set list = null
return totv
endfunction
function MoveParticle takes unit u, integer i, integer dp returns nothing
local integer p = udg_clsParticlePlace<i>
local integer v = udg_clsParticleSpeed<i>
local integer tv
local integer j
set tv = VectorAmplify(v, ParticlePeriod())
call VectorAdd(p,tv)
call VectorAdd(p,dp)
call VectorDestroy(tv)
if udg_vectorX[p] < MapSizeXLow() or udg_vectorX[p] > MapSizeXHigh() or udg_vectorY[p] < MapSizeYLow() or udg_vectorY[p] > MapSizeYHigh() then
//Remove the particle before it is moved outside the map to stop crashes from happening
call RemoveParticle(u,true)
return
endif
call SetUnitX(u,udg_vectorX[p])
call SetUnitY(u,udg_vectorY[p])
call SetUnitFlyHeight(u,udg_vectorZ[p]-GetZ(udg_vectorX[p], udg_vectorY[p]),0.)
if GetAttachedDummyEffect(i) != null then
set j = R2I(Atan2BJ(udg_vectorZ[v], SquareRoot(udg_vectorX[v]*udg_vectorX[v]+udg_vectorY[v]*udg_vectorY[v]))+0.5)+90
call SetUnitAnimationByIndex(u, j)
endif
call SetUnitFacing(u, Atan2BJ(udg_vectorY[v], udg_vectorX[v]))
endfunction
function CalcSpeed takes integer i, integer dv returns nothing
local integer v = udg_clsParticleSpeed<i>
call VectorAdd(v, dv)
endfunction
function particleMainLoop takes nothing returns nothing
local unit u = GetEnumUnit()
local integer i = GetUnitUserData(u)
local integer forces = CalcForces(i)
local integer tv = VectorAmplify(forces, ParticlePeriod())
call VectorScale(tv, 0.5)
call MoveParticle(u,i,tv)
call CalcSpeed(i,forces)
call VectorDestroy(tv)
call VectorDestroy(forces)
call CheckConditions(i)
set u = null
endfunction
function Trig_ParticleMain_Actions takes nothing returns nothing
call ForGroup(udg_particleGroup, function particleMainLoop)
endfunction
function InitTrig_ParticleMain takes nothing returns nothing
set gg_trg_ParticleMain = CreateTrigger()
call TriggerRegisterTimerEventPeriodic(gg_trg_ParticleMain, ParticlePeriod())
call TriggerAddAction(gg_trg_ParticleMain, function Trig_ParticleMain_Actions)
endfunction
</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>
Since I just copy-and-pasted is this expected? Is the grenade only supposed to rise up and explode and I have to change it myself? or should the grenade be thrown in an arc and bounce, deflecting off walls on the way (which I have the natives for- correct? The natives from Vector and LinkedList?)
Side Note: I assume LinkedList doesn't have much to do with physics but thats besides the point
Can somebody please point me in the right direction here (I actually know simple JASS and see how the casting trigger works, just not so much the ParticleMain and the loopy vector stuff )
P.S. If you want to see the other function from the Particle System just say so, it contains Gravity, Wind, Ground Hit, and Particle Death, things that don't concern me at the time being and hopefully never do