1
1337D00D
Guest
The Particle System
Table of Contents:
What is it?
Requirements and installation
Basic functions
Creating a grenade
Creating a bullet
[del]More fun uses[/del]
I apologize for not linking, but anchor tags are removed.
What is it?
The Particle System, created by iNfraNe, is for moving units as if they were particles. It uses Anitarf's Vector System, which is pretty much the base to the Particle System. The Particle System is basically a simpler way to use the Vector System (All the heavy math....) .
Requirements and Installation
Requires:
-iNfraNe's Particle System
-Moderate knowledge of JASS
-Wc3
-A map editor
-Computer
-Brain
Installation:
-Copy ALL stuff in the Map Header into your map's Map Header
-Copy the triggers in the Particle System folder.
-With "Automatically create unknown variables when pasting in the Trigger Editor" ticked in preferences, copy and paste the GUI Variables trigger into your map. You can then delete it.
-Save your map.
You're done!
The Basic Functions
Here's a list of functions you can use, along with what they do.
Natives List:
Chief Speedy Turtle
Running Bear
Swift Fox
Giant Boar
Haha, I'm funny.
Functions:
CreateParticle(...) Takes player p, integer utype, real x, real y, real facing returns unit. This function creates a unit as a particle.
ParticleSetSpeed(...) Takes unit u, real x, real y, real z returns nothing. This function sets the x, y, and z target points of a particle. If x != 0 and y=0 and z=0, the particle will move to the right. To make a particle move towards a point, use the formula (GetLocationX(fromposition)-GetLocationX(toposition)). Replace the X with Y or Z for other values.
ParticleLinkConditionTrigger2Func(...) Takes unit u, trigger t, string s returns nothing. This links a condition and an action to be taken, to a unit. When trigger t returns true, the function with the name of string s will be called. See below for pre-made actions and conditions.
ParticleUnlinkCondition(...) Takes unit u, trigger t returns nothing. Undoes the function above.
ParticleAddForce(...) Takes unit u, integer vector returns nothing. Adds a force like gravity or wind. Use G() for gravity and Wind() for wind (these are the integers). You can also add your own.
ParticleRemoveForce(...) Takes unit u, integer vector returns nothing. Undoes the above function.
Linkable Conditions
ParticleGroundHit() Checks when the particle collides with the ground. Including cliffs.
ParticleDeath() Checks when the particle dies.
Linkable Actions
Death_Remove - Removes the particle. Designed for use with ParticleDeath()
GroundHit_Bounce - Makes the particle bounce depending on its speed, the terrain angle, and the force of gravity. Desined for use with ParticleGroundHit()
Creating A Grenade
Now it's time to have some fun. Here's a guide that can help you make your own realistic grenade.
First, you'll need a dummy unit. It can look like whatever you want. Give it a -1 regeneration rate, and about 4 hp so it will detonate on its own. Also make an AoE damage upon death and give it that, too. Then, make an ability to throw the grenade. I based mine off of Far Sight, only with no reveal and a range of 1000.
Now for coding part.
Here we have our function.
It has the event "Unit starts the effect of an ability." You will probably have to change the ability raw code in the condition.
Next, let's look at our actions.
First things first. We need to create local variables for our two locations, and one for our unit. The unit will be our grenade.
Next, we will use CreateParticle(...) to create the grenade.
My grenade dummy's ID is 'h001'. Yours might be different. You will need to change it. There is now a grenade at the position of our caster.
Now we need to make it move.
Remember the formula to set the particle's speed to move towards a point? If you didn't, just copy what I did. My z speed is 1200, but it can be whatever you want it to be.
Now to add the conditions, and to apply gravity.
Now our grenade will bounce when it hits the ground, and it will be removed when it dies. The grenade will also be affected by gravity. You can change the force of gravity in the G() function, found in the trigger Particle Supplement Functions.
There's one tiny problem: This grenade dosen't make a big boom. . So, we can fix that by creating our own function. What I did here is I copied the existing Death_Remove, renamed it, and added a special effect. If you use a custom one, remember to replace Death_Remove in the grenade trigger with the one you created.
Ka-boom! . But wait--we're still not done here. Our trigger leaks, and that's a bad thing. Let's clean those up.
Tadaa! A grenade spell! Have fun blowing things up.
Creating A Bullet
Creating a bullet is almost the same as creating a grenade, however with a bullet we don't want it to bounce off of the ground or be affected by gravity. We also want it to collide with units.
We can simply add these functions into the Particle Supplement Functions trigger to check for collision. Remember, this projectile can move in 3 dimensions. So we also need to check if the projectile is high or low enough to hit the unit. It checks that the unit is within a sphere with a radius of 60 degrees. You can change the radius of the sphere by editing the bold parts.
We will also need two global variables:
conditionCollision, which is a trigger variable, and
TUnit, which is a unit variable.
We can now link the condition ParticleCollision() to a particle!
Now all we need is a modified version of our grenade function.
I'm using a missile as a projectile in this example. Be sure to change the spell raw code and the projectile raw code.
There are a few differences from the grenade function. In this function, the target position is a set point. The grenade function sets the target position to the target of the spell, thus making the grenade travel slower the closer the target is to the caster. Here, we set it to the caster's position offset by 1000. The only thing the player can choose is the direction of the missile.
The linked conditions are also different. The particle will be removed when it hits the ground or dies. There's also a third condition, ParticleCollision(), which is what you added in earlier. It checks for when it hits a unit.
You probably see a different action, too. Collision_Damage80 is a custom action that I made. You can create your own, too.
This is the one I used:
It also creates a special effect on the unit it damages. You can change both the damage and effect created.
And now you have a realistic projectile. Don't shoot your eye out....
More stuff coming tomorrow, it's a Work In Progress!
Table of Contents:
What is it?
Requirements and installation
Basic functions
Creating a grenade
Creating a bullet
[del]More fun uses[/del]
I apologize for not linking, but anchor tags are removed.
What is it?
The Particle System, created by iNfraNe, is for moving units as if they were particles. It uses Anitarf's Vector System, which is pretty much the base to the Particle System. The Particle System is basically a simpler way to use the Vector System (All the heavy math....) .
Requirements and Installation
Requires:
-iNfraNe's Particle System
-Moderate knowledge of JASS
-Wc3
-A map editor
-Computer
-Brain
Installation:
-Copy ALL stuff in the Map Header into your map's Map Header
-Copy the triggers in the Particle System folder.
-With "Automatically create unknown variables when pasting in the Trigger Editor" ticked in preferences, copy and paste the GUI Variables trigger into your map. You can then delete it.
-Save your map.
You're done!
The Basic Functions
Here's a list of functions you can use, along with what they do.
Natives List:
Chief Speedy Turtle
Running Bear
Swift Fox
Giant Boar
Haha, I'm funny.
Functions:
CreateParticle(...) Takes player p, integer utype, real x, real y, real facing returns unit. This function creates a unit as a particle.
ParticleSetSpeed(...) Takes unit u, real x, real y, real z returns nothing. This function sets the x, y, and z target points of a particle. If x != 0 and y=0 and z=0, the particle will move to the right. To make a particle move towards a point, use the formula (GetLocationX(fromposition)-GetLocationX(toposition)). Replace the X with Y or Z for other values.
ParticleLinkConditionTrigger2Func(...) Takes unit u, trigger t, string s returns nothing. This links a condition and an action to be taken, to a unit. When trigger t returns true, the function with the name of string s will be called. See below for pre-made actions and conditions.
ParticleUnlinkCondition(...) Takes unit u, trigger t returns nothing. Undoes the function above.
ParticleAddForce(...) Takes unit u, integer vector returns nothing. Adds a force like gravity or wind. Use G() for gravity and Wind() for wind (these are the integers). You can also add your own.
ParticleRemoveForce(...) Takes unit u, integer vector returns nothing. Undoes the above function.
Linkable Conditions
ParticleGroundHit() Checks when the particle collides with the ground. Including cliffs.
ParticleDeath() Checks when the particle dies.
Linkable Actions
Death_Remove - Removes the particle. Designed for use with ParticleDeath()
GroundHit_Bounce - Makes the particle bounce depending on its speed, the terrain angle, and the force of gravity. Desined for use with ParticleGroundHit()
Creating A Grenade
Now it's time to have some fun. Here's a guide that can help you make your own realistic grenade.
First, you'll need a dummy unit. It can look like whatever you want. Give it a -1 regeneration rate, and about 4 hp so it will detonate on its own. Also make an AoE damage upon death and give it that, too. Then, make an ability to throw the grenade. I based mine off of Far Sight, only with no reveal and a range of 1000.
Now for coding part.
Here we have our function.
Code:
function Trig_ThrowGrenade_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A000'
endfunction
function Trig_ThrowGrenade_Actions takes nothing returns nothing
endfunction
//===========================================================================
function InitTrig_ThrowGrenade takes nothing returns nothing
set gg_trg_ThrowGrenade = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_ThrowGrenade, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_ThrowGrenade, Condition( function Trig_ThrowGrenade_Conditions ) )
call TriggerAddAction( gg_trg_ThrowGrenade, function Trig_ThrowGrenade_Actions )
endfunction
It has the event "Unit starts the effect of an ability." You will probably have to change the ability raw code in the condition.
Next, let's look at our actions.
Code:
function Trig_ThrowGrenade_Actions takes nothing returns nothing
local location casterpos = GetUnitLoc(GetSpellAbilityUnit())
local location topos = GetSpellTargetLoc()
local unit u
endfunction
First things first. We need to create local variables for our two locations, and one for our unit. The unit will be our grenade.
Next, we will use CreateParticle(...) to create the grenade.
Code:
function Trig_ThrowGrenade_Actions takes nothing returns nothing
local location casterpos = GetUnitLoc(GetSpellAbilityUnit())
local location topos = GetSpellTargetLoc()
local unit u = CreateParticle(GetOwningPlayer(GetSpellAbilityUnit()),'h001',GetLocationX(casterpos),GetLocationY(casterpos),GetUnitFacing(GetSpellAbilityUnit()))
endfunction
My grenade dummy's ID is 'h001'. Yours might be different. You will need to change it. There is now a grenade at the position of our caster.
Now we need to make it move.
Code:
function Trig_ThrowGrenade_Actions takes nothing returns nothing
local location casterpos = GetUnitLoc(GetSpellAbilityUnit())
local location topos = GetSpellTargetLoc()
local unit u = CreateParticle(GetOwningPlayer(GetSpellAbilityUnit()),'h001',GetLocationX(casterpos),GetLocationY(casterpos),GetUnitFacing(GetSpellAbilityUnit()))
call ParticleSetSpeed(u,GetLocationX(topos)-GetLocationX(casterpos),GetLocationY(topos)-GetLocationY(casterpos),1200)
endfunction
Remember the formula to set the particle's speed to move towards a point? If you didn't, just copy what I did. My z speed is 1200, but it can be whatever you want it to be.
Now to add the conditions, and to apply gravity.
Code:
function Trig_ThrowGrenade_Actions takes nothing returns nothing
local location casterpos = GetUnitLoc(GetSpellAbilityUnit())
local location topos = GetSpellTargetLoc()
local unit u = CreateParticle(GetOwningPlayer(GetSpellAbilityUnit()),'h001',GetLocationX(casterpos),GetLocationY(casterpos),GetUnitFacing(GetSpellAbilityUnit()))
call ParticleSetSpeed(u,GetLocationX(topos)-GetLocationX(casterpos),GetLocationY(topos)-GetLocationY(casterpos),1200)
call ParticleLinkConditionTrigger2Func(u, ParticleGroundHit(), "GroundHit_Bounce")
call ParticleLinkConditionTrigger2Func(u, ParticleDeath(), "Death_Remove")
call ParticleAddForce(u, G())
endfunction
Now our grenade will bounce when it hits the ground, and it will be removed when it dies. The grenade will also be affected by gravity. You can change the force of gravity in the G() function, found in the trigger Particle Supplement Functions.
There's one tiny problem: This grenade dosen't make a big boom. . So, we can fix that by creating our own function. What I did here is I copied the existing Death_Remove, renamed it, and added a special effect. If you use a custom one, remember to replace Death_Remove in the grenade trigger with the one you created.
Code:
function Death_RemoveBoom takes nothing returns nothing
local location upos = GetUnitLoc(GetEnumUnit())
local effect eff = AddSpecialEffectLocBJ(upos, "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl")
call DestroyEffect(eff)
call RemoveParticle(GetEnumUnit(),true)
call RemoveLocation(upos)
set upos=null
endfunction
Ka-boom! . But wait--we're still not done here. Our trigger leaks, and that's a bad thing. Let's clean those up.
Code:
function Trig_ThrowGrenade_Actions takes nothing returns nothing
local location casterpos = GetUnitLoc(GetSpellAbilityUnit())
local location topos = GetSpellTargetLoc()
local unit u = CreateParticle(GetOwningPlayer(GetSpellAbilityUnit()),'h001',GetLocationX(casterpos),GetLocationY(casterpos),GetUnitFacing(GetSpellAbilityUnit()))
call ParticleSetSpeed(u,GetLocationX(topos)-GetLocationX(casterpos),GetLocationY(topos)-GetLocationY(casterpos),1200)
call ParticleLinkConditionTrigger2Func(u, ParticleGroundHit(), "GroundHit_Bounce")
call ParticleLinkConditionTrigger2Func(u, ParticleDeath(), "Death_Remove")
call ParticleAddForce(u, G())
call RemoveLocation(casterpos)
call RemoveLocation(topos)
set casterpos=null
set topos=null
set u = null
endfunction
Tadaa! A grenade spell! Have fun blowing things up.
Code:
function Trig_ThrowGrenade_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A000'
endfunction
function Trig_ThrowGrenade_Actions takes nothing returns nothing
local location casterpos = GetUnitLoc(GetSpellAbilityUnit())
local location topos = GetSpellTargetLoc()
local unit u = CreateParticle(GetOwningPlayer(GetSpellAbilityUnit()),'h001',GetLocationX(casterpos),GetLocationY(casterpos),GetUnitFacing(GetSpellAbilityUnit()))
call ParticleSetSpeed(u,GetLocationX(topos)-GetLocationX(casterpos),GetLocationY(topos)-GetLocationY(casterpos),1200)
call ParticleLinkConditionTrigger2Func(u, ParticleGroundHit(), "GroundHit_Bounce")
call ParticleLinkConditionTrigger2Func(u, ParticleDeath(), "Death_Remove")
call ParticleAddForce(u, G())
call RemoveLocation(casterpos)
call RemoveLocation(topos)
set casterpos=null
set topos=null
set u = null
endfunction
//===========================================================================
function InitTrig_ThrowGrenade takes nothing returns nothing
set gg_trg_ThrowGrenade = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_ThrowGrenade, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_ThrowGrenade, Condition( function Trig_ThrowGrenade_Conditions ) )
call TriggerAddAction( gg_trg_ThrowGrenade, function Trig_ThrowGrenade_Actions )
endfunction
Creating A Bullet
Creating a bullet is almost the same as creating a grenade, however with a bullet we don't want it to bounce off of the ground or be affected by gravity. We also want it to collide with units.
We can simply add these functions into the Particle Supplement Functions trigger to check for collision. Remember, this projectile can move in 3 dimensions. So we also need to check if the projectile is high or low enough to hit the unit. It checks that the unit is within a sphere with a radius of 60 degrees. You can change the radius of the sphere by editing the bold parts.
Code:
function ParticleCollisionCond takes nothing returns boolean
local group g = CreateGroup()
local unit u = GetEnumUnit()
local unit f
local integer p = udg_clsParticlePlace[GetUnitUserData(u)]
local integer tv
local location l
call GroupEnumUnitsInRange(g, udg_vectorX[p], udg_vectorY[p], [B]60[/B], null)
loop
set f = FirstOfGroup(g)
exitwhen f == null
set l = GetUnitLoc(f)
set tv = VectorCreate(GetLocationX(l), GetLocationY(l), GetLocationZ(l)+GetUnitFlyHeight(f))
call RemoveLocation(l)
if IsPointInSphere(tv, p, [B]60[/B]) then
call VectorDestroy(tv)
set udg_TUnit = f //This is a temp global to be used in the conditionfuncs
if IsPlayerAlly(GetOwningPlayer(f),GetOwningPlayer(u))==false then
set u = null
set l = null
set f = null
return true
endif
endif
call VectorDestroy(tv)
call GroupRemoveUnit(g,f)
endloop
set u = null
set l = null
set f = null
return false
endfunction
Code:
function ParticleCollision takes nothing returns trigger
if udg_conditionCollision == null then
set udg_conditionCollision = CreateEvalTrig(function ParticleCollisionCond)
endif
return udg_conditionCollision
endfunction
We will also need two global variables:
conditionCollision, which is a trigger variable, and
TUnit, which is a unit variable.
We can now link the condition ParticleCollision() to a particle!
Now all we need is a modified version of our grenade function.
Code:
function Trig_ShootMissile_Conditions takes nothing returns boolean
return GetSpellAbilityId() == [B]'A002'[/B]
endfunction
function Trig_ShootMissile_Actions takes nothing returns nothing
local location cpos = GetUnitLoc(GetSpellAbilityUnit())
local location tpos = GetSpellTargetLoc()
local location npos = PolarProjectionBJ(cpos,1000,AngleBetweenPoints(cpos,tpos))
local unit u = CreateParticle(GetOwningPlayer(GetSpellAbilityUnit()),[B]'h002'[/B],GetLocationX(cpos),GetLocationY(cpos),AngleBetweenPoints(cpos,tpos))
call ParticleSetSpeed(u,GetLocationX(npos)-GetLocationX(cpos),GetLocationY(npos)-GetLocationY(cpos),GetLocationZ(tpos)-GetLocationZ(cpos))
call ParticleLinkConditionTrigger2Func(u, ParticleGroundHit(), "Death_Remove")
call ParticleLinkConditionTrigger2Func(u, ParticleDeath(), "Death_Remove")
call ParticleLinkConditionTrigger2Func(u, ParticleCollision(), "Collision_Damage80")
call RemoveLocation(cpos)
call RemoveLocation(tpos)
call RemoveLocation(npos)
set cpos=null
set tpos=null
set npos=null
set u = null
endfunction
//===========================================================================
function InitTrig_ShootMissile takes nothing returns nothing
set gg_trg_ShootMissile = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_ShootMissile, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_ShootMissile, Condition( function Trig_ShootMissile_Conditions ) )
call TriggerAddAction( gg_trg_ShootMissile, function Trig_ShootMissile_Actions )
endfunction
I'm using a missile as a projectile in this example. Be sure to change the spell raw code and the projectile raw code.
There are a few differences from the grenade function. In this function, the target position is a set point. The grenade function sets the target position to the target of the spell, thus making the grenade travel slower the closer the target is to the caster. Here, we set it to the caster's position offset by 1000. The only thing the player can choose is the direction of the missile.
The linked conditions are also different. The particle will be removed when it hits the ground or dies. There's also a third condition, ParticleCollision(), which is what you added in earlier. It checks for when it hits a unit.
You probably see a different action, too. Collision_Damage80 is a custom action that I made. You can create your own, too.
This is the one I used:
Code:
function Collision_Damage80 takes nothing returns nothing
local unit u = GetEnumUnit()
call UnitDamageTarget(u, udg_TUnit, 80, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\CannonTowerMissile\\CannonTowerMissile.mdl", udg_TUnit, "chest"))
call KillUnit(u)
call RemoveParticle(u,true)
set u = null
endfunction
It also creates a special effect on the unit it damages. You can change both the damage and effect created.
And now you have a realistic projectile. Don't shoot your eye out....
More stuff coming tomorrow, it's a Work In Progress!