Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
Hi all, this is my first system.
Yes i know there are alot of missile system out there. But i wanted to share mine up here. I also hope to get some useful feedbacks and comments so that i can improve myself.
This System is fully GUI and MUI.
The map contains 5 example spells on how to use this system.
Each cast range is 9999. So you can spam the skills from 1 edge to another and see will it lag or not. So far for me no [:
Below is the code of my System:
Yes.. theres a long line of Convert Attack and Damage ID to Type. Because Blizzard didn't have their own. If i can improve on this please let me know. Please don't ask me to convert the whole thing to JASS. I just wanted to try out GUI to improve myself and also to help people that don't know JASS to be able to use it.
QJ Hash Table
Events
Map initialization
Conditions
Actions
Hashtable - Create a hashtable
Set QJS_arrowTable = (Last created hashtable)
QJS AttackDamageType
Events
Time - Elapsed game time is 0.00 seconds
Conditions
Actions
-------- Attack Type Presets --------
Set QJS_atkTypePreset[0] = Spells
Set QJS_atkTypePreset[1] = Normal
Set QJS_atkTypePreset[2] = Pierce
Set QJS_atkTypePreset[3] = Siege
Set QJS_atkTypePreset[4] = Magic
Set QJS_atkTypePreset[5] = Chaos
Set QJS_atkTypePreset[6] = Hero
-------- Damage Type Presets --------
Set QJS_dmgTypePreset[0] = Unknown
Set QJS_dmgTypePreset[1] = Normal
Set QJS_dmgTypePreset[2] = Enhanced
Set QJS_dmgTypePreset[3] = Fire
Set QJS_dmgTypePreset[4] = Cold
Set QJS_dmgTypePreset[5] = Lightning
Set QJS_dmgTypePreset[6] = Poison
Set QJS_dmgTypePreset[7] = Disease
Set QJS_dmgTypePreset[8] = Divine
Set QJS_dmgTypePreset[9] = Magic
Set QJS_dmgTypePreset[10] = Sonic
Set QJS_dmgTypePreset[11] = Acid
Set QJS_dmgTypePreset[12] = Force
Set QJS_dmgTypePreset[13] = Death
Set QJS_dmgTypePreset[14] = Mind
Set QJS_dmgTypePreset[15] = Plant
Set QJS_dmgTypePreset[16] = Defensive
Set QJS_dmgTypePreset[17] = Demolition
Set QJS_dmgTypePreset[18] = Slow Poison
Set QJS_dmgTypePreset[19] = Spirit Link
Set QJS_dmgTypePreset[20] = Shadow Strike
Set QJS_dmgTypePreset[21] = Universal
Arrow Create
Events
Conditions
Actions
Set QJS_tempPos = (Position of QJ_Caster)
-------- Create Arrow Unit for Caster --------
Unit - Create 1 QJ_Model for (Owner of QJ_Caster) at QJS_tempPos facing (Facing of QJ_Caster) degrees
Animation - Change (Last created unit)'s size to ((100.00 x QJ_Size)%, (100.00 x QJ_Size)%, ((100.00 x QJ_Size) + 1.00)%) of its original size
-------- Homing Limit for Target Unit only --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_TargetUnit Equal to No unit
Then - Actions
Set QJ_Homing = False
Else - Actions
-------- Attack Type ID Limit --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
Or - Any (Conditions) are true
Conditions
QJ_attackTypeID Greater than 6
QJ_attackTypeID Less than 0
Then - Actions
Set QJ_attackTypeID = 0
Else - Actions
-------- Damage Type Limit --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
Or - Any (Conditions) are true
Conditions
QJ_damageTypeID Greater than 21
QJ_attackTypeID Less than 0
Then - Actions
Set QJ_damageTypeID = 0
Else - Actions
-------- Save stuff to hashtable of Arrow System --------
-------- Target Unit or Target Position --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_TargetUnit Equal to No unit
Then - Actions
-------- Target Point --------
-------- Calculate Distance and Angle --------
Set QJS_Angle = (Angle from QJS_tempPos to QJ_TargetPoint)
Set QJS_Distance = (Distance between QJS_tempPos and QJ_TargetPoint)
Else - Actions
Set QJS_tempPos_Target = (Position of QJ_TargetUnit)
-------- Target Unit --------
Set QJS_Angle = (Angle from QJS_tempPos to QJS_tempPos_Target)
Set QJS_Distance = (Distance between QJS_tempPos and QJS_tempPos_Target)
-------- Save Victim --------
Hashtable - Save Handle OfQJ_TargetUnit as (Key victim) of (Key (Last created unit)) in QJS_arrowTable
Set QJS_Angle = (Load (Key angle) of (Key (Picked unit)) from QJS_arrowTable)
-------- Load Distance --------
Set QJS_Distance = (Load (Key dist) of (Key (Picked unit)) from QJS_arrowTable)
-------- Load Pierce --------
Set QJ_Pierce = (Load (Key pierce) of (Key (Picked unit)) from QJS_arrowTable)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_Pierce Equal to True
Then - Actions
Set QJS_DamagedGroup = (Load (Key dgroup) of (Key (Picked unit)) in QJS_arrowTable)
Else - Actions
-------- Movement --------
Set QJS_tempPos = (Position of (Picked unit))
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJS_Distance Greater than 0.00
Then - Actions
-------- Move Position --------
Set QJS_movePos = (QJS_tempPos offset by QJ_Speed towards QJS_Angle degrees)
-------- Collision --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_Collision Equal to True
Then - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Terrain pathing at QJS_movePos of type Walkability is off) Equal to True
Then - Actions
-------- Hit Cliff/Rock --------
Floating Text - Create floating text that reads Hit Obstacle! at QJS_movePos with Z offset 0.00, using font size 10.00, color (100.00%, 0.00%, 0.00%), and 0.00% transparency
Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
Floating Text - Change (Last created floating text): Disable permanence
Floating Text - Change the fading age of (Last created floating text) to 1.00 seconds
Floating Text - Change the lifespan of (Last created floating text) to 1.50 seconds
-------- If Pierce = False --------
-------- Don't Do damage as pierce arrow will do damage while moving. --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_Pierce Equal to False
Then - Actions
-------- Deal Damage If AoE is On --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_AoE Equal to True
Then - Actions
-------- Attack Type ID Coversion --------
Set QJS_AttackType = QJS_atkTypePreset[QJ_attackTypeID]
-------- Damage Type ID Coversion --------
Set QJS_DamageType = QJS_dmgTypePreset[QJ_damageTypeID]
-------- Load AoE Radius --------
Set QJ_AoERadius = (Load (Key aoeradius) of (Key (Picked unit)) from QJS_arrowTable)
-------- Load Effect --------
Set QJ_AoESFX = (Load (Key aoesfx) of (Key (Picked unit)) from QJS_arrowTable)
-------- Create AoE Effect --------
Special Effect - Create a special effect at QJS_movePos using QJ_AoESFX
Special Effect - Destroy (Last created special effect)
-------- Set Victim Group in AoE Range --------
Set QJS_victimGroup = (Units within QJ_AoERadius of QJS_movePos matching ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of (Owner of QJ_Caster)) Equal to True)))
-------- Damage --------
Unit Group - Pick every unit in QJS_victimGroup and do (Actions)
Loop - Actions
Unit - Cause QJ_Caster to damage (Picked unit), dealing QJ_Damage damage of attack type QJS_AttackType and damage type QJS_DamageType
Else - Actions
-------- No Damage if AoE off --------
Else - Actions
-------- If Pierce True, clear off Damaged Group --------
Unit Group - Remove all units from QJS_DamagedGroup
Unit - Move (Picked unit) instantly to QJS_movePos, facing QJS_Angle degrees
-------- Update Distance --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_Homing Equal to False
Then - Actions
Hashtable - Save (QJS_Distance - QJ_Speed) as (Key dist) of (Key (Picked unit)) in QJS_arrowTable
Else - Actions
-------- If Pierce = True --------
-------- Do Damage --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_Pierce Equal to True
Then - Actions
-------- Attack Type ID Coversion --------
Set QJS_AttackType = QJS_atkTypePreset[QJ_attackTypeID]
-------- Damage Type ID Coversion --------
Set QJS_DamageType = QJS_dmgTypePreset[QJ_damageTypeID]
-------- Check for AoE --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_AoE Equal to True
Then - Actions
-------- Load AoE Radius --------
Set QJ_AoERadius = (Load (Key aoeradius) of (Key (Picked unit)) from QJS_arrowTable)
-------- Load Effect --------
Set QJ_AoESFX = (Load (Key aoesfx) of (Key (Picked unit)) from QJS_arrowTable)
Else - Actions
-------- AoE Radius = Default, 150 --------
Set QJ_AoERadius = 150.00
-------- Set Victim Group --------
Set QJS_victimGroup = (Units within QJ_AoERadius of QJS_movePos matching ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an enemy of (Owner of QJ_Caster)) Equal to True) and (((Matching unit) is in QJS_DamagedGroup) Equal to False))))
Unit Group - Pick every unit in QJS_victimGroup and do (Actions)
Loop - Actions
Set QJS_victimPos = (Position of (Picked unit))
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_AoE Equal to True
Then - Actions
-------- Create AoE Effect --------
Special Effect - Create a special effect at QJS_victimPos using QJ_AoESFX
Special Effect - Destroy (Last created special effect)
Else - Actions
-------- Damage --------
Unit - Cause QJ_Caster to damage (Picked unit), dealing QJ_Damage damage of attack type QJS_AttackType and damage type QJS_DamageType
-------- Damage Text --------
Floating Text - Create floating text that reads Hit! at QJS_victimPos with Z offset 0.00, using font size 10.00, color (100.00%, 0.00%, 0.00%), and 0.00% transparency
Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
Floating Text - Change (Last created floating text): Disable permanence
Floating Text - Change the fading age of (Last created floating text) to 1.00 seconds
Floating Text - Change the lifespan of (Last created floating text) to 1.50 seconds
-------- Add to Damage Group --------
Unit Group - Add (Picked unit) to QJS_DamagedGroup
Unit - Move (Picked unit) instantly to QJS_movePos, facing QJS_Angle degrees
-------- Update Distance --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_Homing Equal to False
Then - Actions
Hashtable - Save (QJS_Distance - QJ_Speed) as (Key dist) of (Key (Picked unit)) in QJS_arrowTable
Else - Actions
-------- If Pierce = True --------
-------- Do Damage --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_Pierce Equal to True
Then - Actions
-------- Attack Type ID Coversion --------
Set QJS_AttackType = QJS_atkTypePreset[QJ_attackTypeID]
-------- Damage Type ID Coversion --------
Set QJS_DamageType = QJS_dmgTypePreset[QJ_damageTypeID]
-------- Check for AoE --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_AoE Equal to True
Then - Actions
-------- Load AoE Radius --------
Set QJ_AoERadius = (Load (Key aoeradius) of (Key (Picked unit)) from QJS_arrowTable)
-------- Load Effect --------
Set QJ_AoESFX = (Load (Key aoesfx) of (Key (Picked unit)) from QJS_arrowTable)
Else - Actions
-------- AoE Radius = Default, 150 --------
Set QJ_AoERadius = 150.00
-------- Set Victim Group --------
Set QJS_victimGroup = (Units within QJ_AoERadius of QJS_movePos matching ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an enemy of (Owner of QJ_Caster)) Equal to True) and (((Matching unit) is in QJS_DamagedGroup) Equal to False))))
Unit Group - Pick every unit in QJS_victimGroup and do (Actions)
Loop - Actions
Set QJS_victimPos = (Position of (Picked unit))
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_AoE Equal to True
Then - Actions
-------- Create AoE Effect --------
Special Effect - Create a special effect at QJS_victimPos using QJ_AoESFX
Special Effect - Destroy (Last created special effect)
Else - Actions
-------- Damage --------
Unit - Cause QJ_Caster to damage (Picked unit), dealing QJ_Damage damage of attack type QJS_AttackType and damage type QJS_DamageType
-------- Damage Text --------
Floating Text - Create floating text that reads Hit! at QJS_victimPos with Z offset 0.00, using font size 10.00, color (100.00%, 0.00%, 0.00%), and 0.00% transparency
Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
Floating Text - Change (Last created floating text): Disable permanence
Floating Text - Change the fading age of (Last created floating text) to 1.00 seconds
Floating Text - Change the lifespan of (Last created floating text) to 1.50 seconds
-------- Add to Damage Group --------
Unit Group - Add (Picked unit) to QJS_DamagedGroup
-------- Remove End Damage as Moving will do Damage --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_Pierce Equal to False
Then - Actions
-------- Attack Type ID Coversion --------
Set QJS_AttackType = QJS_atkTypePreset[QJ_attackTypeID]
-------- Damage Type ID Coversion --------
Set QJS_DamageType = QJS_dmgTypePreset[QJ_damageTypeID]
-------- Position of Arrow --------
Set QJS_arrowPos = (Position of (Picked unit))
-------- Deal Damage --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_TargetUnit Equal to No unit
Then - Actions
-------- Target Point --------
-------- Check for AoE or Single Target --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_AoE Equal to True
Then - Actions
-------- AOE --------
-------- Load AoE Radius --------
Set QJ_AoERadius = (Load (Key aoeradius) of (Key (Picked unit)) from QJS_arrowTable)
-------- Load Effect --------
Set QJ_AoESFX = (Load (Key aoesfx) of (Key (Picked unit)) from QJS_arrowTable)
-------- Create AoE Effect --------
Special Effect - Create a special effect at QJS_arrowPos using QJ_AoESFX
Special Effect - Destroy (Last created special effect)
-------- Set Victim Group in AoE Range --------
Set QJS_victimGroup = (Units within QJ_AoERadius of QJS_arrowPos matching ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of (Owner of QJ_Caster)) Equal to True)))
-------- Damage --------
Unit Group - Pick every unit in QJS_victimGroup and do (Actions)
Loop - Actions
Unit - Cause QJ_Caster to damage (Picked unit), dealing QJ_Damage damage of attack type QJS_AttackType and damage type QJS_DamageType
Set QJS_victimGroup = (Units within 150.00 of QJS_arrowPos matching ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of (Owner of QJ_Caster)) Equal to True)))
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Number of units in QJS_victimGroup) Greater than 0
Then - Actions
Unit - Cause QJ_Caster to damage (Random unit from QJS_victimGroup), dealing QJ_Damage damage of attack type QJS_AttackType and damage type QJS_DamageType
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
QJ_AoE Equal to True
Then - Actions
-------- AOE --------
-------- Load AoE Radius --------
Set QJ_AoERadius = (Load (Key aoeradius) of (Key (Picked unit)) from QJS_arrowTable)
-------- Load Effect --------
Set QJ_AoESFX = (Load (Key aoesfx) of (Key (Picked unit)) from QJS_arrowTable)
-------- Create AoE Effect --------
Special Effect - Create a special effect at QJS_arrowPos using QJ_AoESFX
Special Effect - Destroy (Last created special effect)
-------- Set Victim Group in AoE Range --------
Set QJS_victimGroup = (Units within QJ_AoERadius of QJS_arrowPos matching ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of (Owner of QJ_Caster)) Equal to True)))
-------- Damage --------
Unit Group - Pick every unit in QJS_victimGroup and do (Actions)
Loop - Actions
Unit - Cause QJ_Caster to damage (Picked unit), dealing QJ_Damage damage of attack type QJS_AttackType and damage type QJS_DamageType
Set QJS_victimGroup = (Units within 150.00 of QJS_arrowPos matching ((Matching unit) Equal to QJ_TargetUnit))
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(QJ_TargetUnit is alive) Equal to True
(Number of units in QJS_victimGroup) Greater than 0
Then - Actions
Unit - Cause QJ_Caster to damage QJ_TargetUnit, dealing QJ_Damage damage of attack type QJS_AttackType and damage type QJS_DamageType
Else - Actions
-------- Miss. --------
Floating Text - Create floating text that reads Miss! at QJS_arrowPos with Z offset 0.00, using font size 10.00, color (100.00%, 0.00%, 0.00%), and 0.00% transparency
Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
Floating Text - Change (Last created floating text): Disable permanence
Floating Text - Change the fading age of (Last created floating text) to 1.00 seconds
Floating Text - Change the lifespan of (Last created floating text) to 1.50 seconds
==================
Customizable Features
==================
- Homing
- Collision with Terrain
- AoE
- Effects for AoE
- Model
- Model Size
- Damage
- Attack Type & Damage Type
- Missile Speed
- Piercing
- Target Unit or Target Point
===================
Not Supported Yet
===================
- This system currently don't support a missle from a spell that shoots different direction. Eg: A hero shoots 3 arrow at 3 direction at a single cast
- No Parabola Supported, Meaning all missile are straight.
**Implementation
There are 5 examples on how to implement this in the map. Also there is a README in the map trigger. So please do give it a read [: In Short: QJ_varName, Only change this. QJS_varName is the system variables, so don't even touch it.
v1.01a, 19 January, 2010
- Used prefix of attack type damage instead of tons of nested if to make it alilbit more efficient. Thanks to Kingz.
- A new Trigger that holds the prefix of attack and damage type which you will need to copy.
- Arrow Move Code Updated, should be way shorter now.
v1.01, 18 January, 2010
- 1st version released
Keywords:
system, missile, projectile, arrow, target, unit, point, jeff, q, jeffrey, homing, pierce, custom
why the fuck is everyone using hashtables??
they are
-more complicated
-slower
-and you can't save attack types
if you are doing something that requires dynamic 2d arrays like triggering a really complicated spell like a pudge wars hook or something hashtables are the easier solution but for that...
when setting a damage type just compare it to a preset
Example in jass:
JASS:
set DAMAGE_TYPE[0] = DAMAGE_TYPE_ACID
set DAMAGE_TYPE[1] = DAMAGE_TYPE_UNKNOWN
...
set DAMAGE_TYPE[x] = DAMAGE_TYPE_UNIVERSAL
Then when checking if for example damage type integer equal to n:
JASS:
set DamageType = DAMAGE_TYPE[n]
That is far more efficent that the crappy if/then/else you are using.
Same aplies for the crappy attack type if/then/else branch.
EDIT:
Lol when you said terrain colisions i thought you actualy do something other than destroying the missile upon hiting a terrain(bounce anyone?).
Anyway better systems are present on the hive and the current state of the system is extremely unnefficent due to the if/then/else branches and the use of hashtables.
wow ive never seen so many if then else statements used in my life @_@ there is no way you should need that many. if your gonna do that then at least use a loop to loop through it all. but get rid of that. 2/5.
to many of these on hive -.5
to many if then else statements -1.
no extra features to make it stand out -1
code could be much shorter. -.5
@Kingz
That's a good idea. I almost gave up on the attack type and wrote a system for it to convert instead of so many if, else. I will change it to your idea right away and upload the next version.
What is coming next:
- Supports Angle
- Supports on Hit (Missile will be destroy on 1st encounter of nearest unit)
- Supports Bounce [:
**Although once i add bounce, the system won't be as flexible as now. For example now i can set everything to true, or everything to false or mix anything i like and works perfectly. But if i add bounce, collision can't be true anymore. I will see what i can work on it [:
Once again, thanks for the useful feedback. Gotta love those.
EDIT: Updated to version 1.01a to fix the attack and damage type to make it alilbit more efficient.
@Kingz
That's a good idea. I almost gave up on the attack type and wrote a system for it to convert instead of so many if, else. I will change it to your idea right away and upload the next version.
What is coming next:
- Supports Angle
- Supports on Hit (Missile will be destroy on 1st encounter of nearest unit)
- Supports Bounce [:
**Although once i add bounce, the system won't be as flexible as now. For example now i can set everything to true, or everything to false or mix anything i like and works perfectly. But if i add bounce, collision can't be true anymore. I will see what i can work on it [:
Once again, thanks for the useful feedback. Gotta love those.
EDIT: Updated to version 1.01a to fix the attack and damage type to make it alilbit more efficient.
I am trying to learn indexing which is confusing ><. And i will be able to overhaul the whole system. But for now, i just want to get the basic idea of how a system can be made.
I found 1 leak in the implementation while i was updating and polishing my code.
If the spell is target point.
User need to set QJ_TargetPoint = Target Point of Ability Being Cast
I can't call RemoveLocation. How do i clear this leak?
i must say agree making complicated spell in hashtable is only a waste of space ... i rather use Dynamic hashtable & there is a good template made by Hanke that's how i learned mui
can't open the map ... WE 1.24 or WE from JNGP say same error:
"Function does not exist in database: InitHashtableBJ"
"Function does not exist in database: GetLastCreatedHashtableBJ"
"Function does not exist in database: SaveUnitHandleBJ"
I don't no why, other systems and maps with the same function could be opened, but this don't want to be opened.
can't open the map ... WE 1.24 or WE from JNGP say same error:
"Function does not exist in database: InitHashtableBJ"
"Function does not exist in database: GetLastCreatedHashtableBJ"
"Function does not exist in database: SaveUnitHandleBJ"
I don't no why, other systems and maps with the same function could be opened, but this don't want to be opened.
all is up-to-date ... also the new blizzard.j and common.j is used by the jasshelper, tesh got also the new funclist.database ...
I don't know why the heck this map won't open. oO
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.