• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

V3H's Trick'N'Shoot System V,5

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
Well to start it off, I couldn't find a decent enough projectile system that is in GUI for people so I decided to make one....

What I mean by decent is, something that isn't poor or too complex but something nice....

What this has to offer currently is;

Quite easy to configure and learn
Units fire at each other and can't manipulate the stop command.
Your projectile can hit random parts of the unit meaning feet-shots or head shots.
Technically this system is 3D.
A lot of units can be used with it.
Leak free and no lag unless too many units using the system at once.
String based model configuration meaning no more requirement of 100 projectile dummy units but only one.
Ability example
Projectile now collides with trees.


What is yet to come;

Allowing of shooting aerial units.
A better shooting ability so if you select a unit that is a bit higher in the air it can hit it.
More types of examples for the ability.
More will hopefully come from you guys...

READ!:
For people who are using the older system of this, I highly advise re downloading for I didn't fix projectile collision meaning bullets collide with each other making unneeded special effects costing more memory.

A special thanks goes to D4RK_G4ND4LF for I stumbled upon one of his examples of detection of trees in GUI.


[trigger=Prosystem]
Events
Map initialization
Actions
-------- Tree Detection Initalization. --------
Set loc = (Point(0.00, 0.00))
Unit - Create 1 Peasant for Neutral Passive at loc facing 0.00 degrees
Unit - Hide (Last created unit)
-------- We hide it so nobody sees a peasant walking around. --------
Unit - Make (Last created unit) Invulnerable
-------- We make it invulnerable to all harm as well. --------
Set harvester = (Last created unit)
Custom script: call RemoveLocation(udg_loc)
-------- Setting the damage --------
Set wdmg[1] = 50.00
Set wdmg[2] = 120.00
Set wdmg[3] = 200.00
Set wdmg[4] = 400.00
-------- What the projectiles will look like. --------
Set wsfx[1] = Abilities\Weapons\RedDragonBreath\RedDragonMissile.mdl
Set wsfx[2] = Abilities\Weapons\BloodElfMissile\BloodElfMissile.mdl
-------- If you want more effects in there do not use wsfx[3 or 4 or 5 or 6] --------
-------- This is where we set the speed for the projectiles. --------
Set wspeed = 20.00
Set wsfx[3] = Abilities\Spells\Other\Incinerate\IncinerateBuff.mdl
Set wsfx[4] = Abilities\Spells\Orc\FeralSpirit\feralspiritdone.mdl
Set wsfx[5] = Objects\Spawnmodels\Undead\UndeadLargeDeathExplode\UndeadLargeDeathExplode.mdl
Set wsfx[6] = Objects\Spawnmodels\Human\HumanLargeDeathExplode\HumanLargeDeathExplode.mdl
-------- Here we set the effects for the different impacts so you don't have to scroll all the way down to alter it. --------
Set wbodyshots[1] = 20.00
Set wbodyshots[2] = 45.00
Set wbodyshots[3] = 60.00
Set wbodyshots[4] = 65.00
-------- Here we set where the projectile hits on a unit. --------
-------- We set it so the group we create is cleaned up after. --------
Custom script: set bj_wantDestroyGroup = true
Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
Loop - Actions
-------- We check if the global unit wasn't already added to the setup trigger. --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
And - All (Conditions) are true
Conditions
((Triggering unit) is in wugroup[3]) Not equal to True
(Unit-type of (Triggering unit)) Not equal to oooo
Then - Actions
Trigger - Add to attack <gen> the event (Unit - (Picked unit) Takes damage)
Trigger - Add to collision <gen> the event (Unit - A unit comes within 80.00 of (Picked unit))
Unit Group - Add (Picked unit) to wugroup[3]
Else - Actions
-------- We pick all the pre-generated units on the map which are also called globals. --------
-------- and we add them to our damage detection trigger. --------
-------- We also add the globals to the collision trigger to allow collision of the almost 3d projectile system. --------
Custom script: call DestroyTrigger(GetTriggeringTrigger())
-------- We get rid of this trigger for a attempt to free up more memory. --------[/trigger]


[trigger=Addition of units]
Events
Unit - A unit enters (Playable map area)
Conditions
((Triggering unit) is in wugroup[3]) Not equal to True
Actions
-------- We check if the unit wasn't already added to the setup trigger. --------
Trigger - Add to attack <gen> the event (Unit - (Triggering unit) Takes damage)
-------- When a unit is summoned or spawned or trained into the map then we add it here. --------
Trigger - Add to collision <gen> the event (Unit - A unit comes within 80.00 of (Triggering unit))
-------- We also add the globals to the collision trigger to allow collision of the almost 3d projectile system. --------
Unit Group - Add (Triggering unit) to wugroup[3]
-------- This is to confirm if it re-enters the map it doesn't make more then one event for the unit. --------
-------- Useful to stop hero manuiplation. --------[/trigger]


[trigger=Damaging units]
Actions
-------- The event is added by actions for a better damage detection. --------
-------- Since unit is attacked can be easily glitched and it takes a lot to stop the cheating of it. --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
((Damage source) is in wugroup[1]) Equal to True
Then - Actions
Unit - Set life of (Triggering unit) to ((Life of (Triggering unit)) + (Damage taken))
Set wleak[4] = (Position of (Damage source))
Set wleak[5] = (Position of (Triggering unit))
Unit - Create 1 oooo for (Owner of (Damage source)) at wleak[4] facing (Angle from wleak[4] to wleak[5]) degrees
Special Effect - Create a special effect attached to the chest of (Last created unit) using wsfx[2]
Animation - Change (Last created unit) flying height to (Random real number between 10.00 and 115.00) at 0.00
Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
Unit Group - Add (Last created unit) to wugroup[2]
Custom script: call RemoveLocation(udg_wleak[4])
Custom script: call RemoveLocation(udg_wleak[5])
Else - Actions
-------- We find the damage source which is the attacking unit and we start from there. --------
-------- Then we make sure the units cant't deal normal damage. --------
-------- We set a point variable to remove the location leak. --------
-------- We create our projectile and set it at a random flying height to allow headshots or other bodyshots. --------
-------- We add a life timer so it cleans itself up after as well limit the range. --------
-------- Then we start the cleaning of the unit leak as well add it to the movement group and remove the location leak. --------[/trigger]


[trigger=loop]
Events
Time - Every 0.04 seconds of game time
Conditions
(Number of units in wugroup[2]) Greater than 0
Actions
-------- Suggested timer event is 0.04 to 0.06 for best use and less lag. --------
-------- We check to see if theres any projectiles running with the group check. --------
Unit Group - Pick every unit in wugroup[2] and do (Actions)
Loop - Actions
Set loc = (Position of (Picked unit))
Set wleak[2] = (Position of (Picked unit))
Set wleak[3] = (wleak[2] offset by wspeed towards (Facing of (Picked unit)) degrees)
Unit - Move (Picked unit) instantly to wleak[3]
Destructible - Pick every destructible within 150.00 of loc and do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Current life of (Picked destructible)) Greater than 0.00
Then - Actions
Unit - Order harvester to Harvest (Picked destructible)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Current order of harvester) Equal to (Order(harvest))
Then - Actions
Destructible - Set life of (Picked destructible) to ((Current life of (Picked destructible)) - 5.00)
Unit - Kill (Picked unit)
Else - Actions
Unit - Order harvester to Stop
Else - Actions
Custom script: call RemoveLocation(udg_wleak[2])
Custom script: call RemoveLocation(udg_wleak[3])
Custom script: call RemoveLocation(udg_loc)
-------- We pick all the projectiles and constantly move them. --------
-------- We remove the bullet that hits the tree in range. --------
-------- We set two more points for leak removal and easier to customize the movement. --------[/trigger]



[trigger=Cleaning unit leaks]
Events
Unit - A unit Dies
Conditions
((Triggering unit) is in wugroup[2]) Equal to True
Actions
Unit Group - Remove (Triggering unit) from wugroup[2]
Unit - Remove (Triggering unit) from the game
-------- This removes the projectile when it dies. --------
-------- By doing this we fix the unit leak and corpse lag. --------[/trigger]



[trigger=Colliding]
Conditions
((Triggering unit) is in wugroup[2]) Equal to True
Actions
-------- The event is added by other actions to try to avoid timer lag. --------
-------- and increase efficiency --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Current flying height of (Triggering unit)) Less than or equal to wbodyshots[1]
Then - Actions
Set wleak[1] = (Position of (Triggering unit))
-------- We set it so the group we create is cleaned up after. --------
Custom script: set bj_wantDestroyGroup = true
Unit Group - Pick every unit in (Units within 95.00 of wleak[1]) and do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Owner of (Picked unit)) Not equal to (Owner of (Triggering unit))
((Picked unit) is alive) Equal to True
(Unit-type of (Picked unit)) Not equal to oooo
Then - Actions
Unit - Cause (Triggering unit) to damage (Picked unit), dealing wdmg[1] damage of attack type Chaos and damage type Normal
Special Effect - Create a special effect attached to the origin of (Picked unit) using wsfx[3]
Special Effect - Destroy (Last created special effect)
Else - Actions
Custom script: call RemoveLocation(udg_wleak[1])
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Current flying height of (Triggering unit)) Less than or equal to wbodyshots[2]
Then - Actions
Set wleak[1] = (Position of (Triggering unit))
-------- We set it so the group we create is cleaned up after. --------
Custom script: set bj_wantDestroyGroup = true
Unit Group - Pick every unit in (Units within 95.00 of wleak[1]) and do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Owner of (Picked unit)) Not equal to (Owner of (Triggering unit))
((Picked unit) is alive) Equal to True
(Unit-type of (Picked unit)) Not equal to oooo
Then - Actions
Unit - Cause (Triggering unit) to damage (Picked unit), dealing wdmg[2] damage of attack type Chaos and damage type Normal
Special Effect - Create a special effect attached to the origin of (Picked unit) using wsfx[4]
Special Effect - Destroy (Last created special effect)
Else - Actions
Custom script: call RemoveLocation(udg_wleak[1])
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Current flying height of (Triggering unit)) Less than or equal to wbodyshots[3]
Then - Actions
Set wleak[1] = (Position of (Triggering unit))
-------- We set it so the group we create is cleaned up after. --------
Custom script: set bj_wantDestroyGroup = true
Unit Group - Pick every unit in (Units within 95.00 of wleak[1]) and do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Owner of (Picked unit)) Not equal to (Owner of (Triggering unit))
((Picked unit) is alive) Equal to True
(Unit-type of (Picked unit)) Not equal to oooo
Then - Actions
Unit - Cause (Triggering unit) to damage (Picked unit), dealing wdmg[3] damage of attack type Chaos and damage type Normal
Special Effect - Create a special effect attached to the chest of (Picked unit) using wsfx[5]
Special Effect - Destroy (Last created special effect)
Else - Actions
Custom script: call RemoveLocation(udg_wleak[1])
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Current flying height of (Triggering unit)) Less than or equal to wbodyshots[4]
Then - Actions
Set wleak[1] = (Position of (Triggering unit))
-------- We set it so the group we create is cleaned up after. --------
Custom script: set bj_wantDestroyGroup = true
Unit Group - Pick every unit in (Units within 95.00 of wleak[1]) and do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Owner of (Picked unit)) Not equal to (Owner of (Triggering unit))
((Picked unit) is alive) Equal to True
(Unit-type of (Picked unit)) Not equal to oooo
Then - Actions
Unit - Cause (Triggering unit) to damage (Picked unit), dealing wdmg[4] damage of attack type Chaos and damage type Normal
Special Effect - Create a special effect attached to the head of (Picked unit) using wsfx[6]
Special Effect - Destroy (Last created special effect)
Else - Actions
Custom script: call RemoveLocation(udg_wleak[1])
Else - Actions[/trigger]




[trigger=Ability Example]
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Fire
Actions
-------- We use the correct event to counteract order abuse. --------
-------- We have a condition that identifies the ability. --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
((Triggering unit) is in wugroup[1]) Equal to True
Then - Actions
Set wleak[4] = (Position of (Triggering unit))
Set wleak[5] = (Target point of ability being cast)
Unit - Create 1 oooo for (Owner of (Triggering unit)) at wleak[4] facing (Angle from wleak[4] to wleak[5]) degrees
Special Effect - Create a special effect attached to the chest of (Last created unit) using wsfx[2]
Animation - Change (Last created unit) flying height to (Random real number between 10.00 and 115.00) at 0.00
Unit - Add a 1.80 second Generic expiration timer to (Last created unit)
Trigger - Add to removal <gen> the event (Unit - (Last created unit) Dies)
Unit Group - Add (Last created unit) to wugroup[2]
Custom script: call RemoveLocation(udg_wleak[4])
Custom script: call RemoveLocation(udg_wleak[5])
Else - Actions
-------- We make sure it is in the group to allow for it to use the projectile system and we set the points to remove them later. --------
-------- We create the projectile and attach the effect we already set to it. --------[/trigger]






Keywords:
V, V3h, Vehster, Version, GUI, system, projectile, advanced, 3d, headshot, fun, extreme, hive, work, grid, movement, shooting, shoot, unit, trix
Contents

Vehster's Trix'n'Projectile V,5 (Map)

Reviews
12th Dec 2015 IcemanBo: For long time as NeedsFix. Rejected. 18th Jul 2011 Maker: Loop and removal triggers should be turned off when they are not needed. The projectiles behave in a wrong way near cliffs and hills. The projectile can spawn...

Moderator

M

Moderator

12th Dec 2015
IcemanBo: For long time as NeedsFix. Rejected.

18th Jul 2011
Maker:
Loop and removal triggers should be turned off when they are not needed.
The projectiles behave in a wrong way near cliffs and hills.
The projectile can spawn above the caster and the collision doesn't really work correctly.
I don't think using "unit comes within range" event is a good choise. It can add some lag, I didn't test that though.
Adding events like that kind of leaks since when the unit is removed from the game, the events are still there.
 
Level 1
Joined
Aug 9, 2009
Messages
275
Hmm, mind posting code?

And a thing that would be nice that i've seen some other projectile systems, is considering the Z and stuff, so, if that could be added, and that you improve things that might need to be improved, this might turn out quite good :p
 
Level 7
Joined
Apr 12, 2011
Messages
124
Not really, changing it would greatly increase your chance of approval on this. It's low from the start considering there's already a better system on hive.

And always post triggers, very few ppl care to download the system to see the triggering.



Edit(Avoiding Double-post):

Well, if there's a better system then people will probably use that and if you don't see many using it then it probably means it's not usefull for the majority of maps.
 
Level 7
Joined
Apr 11, 2011
Messages
173
I hardly care for approval, I care more for helping people on hive.....
I made this to be fully GUI and nothing more, doesn't matter how low it is.
Sure there's better systems but do you see people using them?
It isn't a rule tho, then what use is WC3? I would spend two minutes to check a map instead of reading it on a site...

I will post the code just so if a mod comes by, they can't complain on that reason and reject it for that.
Nice signature Manasurge.

EDIT: I do not know how to post the code...
 
Last edited:
To steer our discussion back to where it belongs, I'm replying to your visitor message here.

You should use "map initialization" as the init event and remove the wait as well, because if a unit is created within that 1 second it won't get registered by the system.

Setup trigger leaks twice here:

Unit - Create 1 oooo for (Owner of (Damage source)) at wleak[4] facing (Angle from (Position of (Damage source)) to (Position of (Triggering unit)))

>> What do you mean set the string if it has a model art?

You set the effect path to be the string you specified.

It looks like the damage amount also changes, not just the string art. So you want to set both a string and the damage variable, instead of duplicating every line of code. Code duplication in general is very bad practice because it adds to map file size, makes it hard to read and is also horrible to maintain.

You should also avoid using a location variable as an array. If you already know the index of an array (1, 2, 3, 4...) it should just be four variables var1, var2, var3.... Arrays are powerful objects and not to be treated as toys just for convenience (at least not in this case). The in-game execution of a single variable opposed to an array variable is also a big factor.
 
Level 7
Joined
Apr 11, 2011
Messages
173
How does my setup trigger leak?

I duplicate my code to allow for body detection...
What do you mean set the string if it has a model art?
The collision is more then just SFX, it makes my system go to a 3D like level.


Why is Map Init better then Time Elapsed? I was told it leaks somewhat and decided to use something else... the wait can't affect anything for it is used last.
So creating it for a player leaks and setting its facing leaks too?
I still don't get where you are trying to say this at....
"You set the effect path to be the string you specified."
It is not just pure duplication, if you can identify the heights better to fit the unit it runs into then please show me, in GUI that is.
I know it adds to file size and horrible to maintain but it isn't that bad to read.
Why avoid making less variables and better compression?
Four variables seem like a waste of space to me, yes arrays are powerful and nice to use if you can use them correctly... They work fine as they are, do they not?
I don't see a difference in the execution of the two.
 
IDK how this can be actually useful or provide an alternate for NFWar's system...

also the action Custom script is a part of GUI so its still GUI... but actually, GUI is just jass afterall...

and please post triggers... but considering that you said that this is FULL GUI, which by your standard does not use any Custom script action (though in reality, everything is changed to CS), then I would expect location leaks or using the move command...

anyway, lets see what will happen after you fix this... ^_^
 
arrays are pretty slower than normal variables and take more space... so if ur just using a few indexes, use different variables instead of arrays... you won't probably notice these thing early game, but as game time passes by, you'll more likely to see the effects... or I think, using /fps could actually show some effect early game...
 
Unit - Create 1 oooo for (Owner of (Damage source)) at wleak[4] facing (Angle from (Position of (Damage source)) to (Position of (Triggering unit)))

The two location leaks here are (Position of (Damage source)) and (Position of (Triggering unit))).

I didn't say to remove the four if-blocks, I know why you have them there, what I am saying is instead of copying the blocks four times over, only set the variables that need to be set (effect path and damage) and put the block at the bottom, so the one block of code will work for any of the four different possibilities that can emerge out of that trigger.

Instead of:
Code:
if condition1 then
    //a bunch of stuff
elseif condition2 then
    //a bunch of stuff identical to the last block except with two different things

Turn it into:

Code:
if condition1 then
    //Set a couple of things
elseif condition2 then
    //Set a couple of things slightly differently
endif
//a bunch of stuff here that can work with any of those variables

>> I don't see a difference in the execution of the two.

Usually you won't and usually it won't matter, but I have compared the difference between using arrays and no arrays with a very high-speed timer and the speed jump is measureable.

Also, map init does not leak. Whoever told you that either miscommunicated or quoted someone else out of context
 
Level 7
Joined
Apr 11, 2011
Messages
173
EDIT: I can't figure out how to fix projectile collision.....

Why must map init be used?

It is better then making a generic event and a condition for it to take up extra space for the dummy removal.
How can collision be simplified more?

All the other ands that only had one condition in them were removed though, I had them there by accident
 
1. Yes you can remove the first.
2. No I don't know everything but thank you for trying to be rude to me.
3. Map init doesn't create as many handles as the timer event.
4. "It is better then making a generic event and a condition for it to take up extra space for the dummy removal."

- Untrue, each time you create a new event it is taking up extra space in memory. When the dummy unit is removed, the event is not destroyed and exists as a memory leak, making this quite flawed.

5. Collision can be simplified by the method I showed you already, by setting a couple of variables and then having the one big block at the bottom.
 
Top