• 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!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Relativistic Missiles [vJASS][LUA][GUI]

This bundle is marked as high quality. It exceeds standards and is highly desirable.
Relativistic Missiles
v2.8 by Chopinski
Introduction
First of all, Credits and thanks to BPower, Dirac, and Vexorian for their missile systems at which I based this system upon, and to AGD for the help with effect orientation methods.

This is a Missile system that I put together initially to fulfill my resources needs. Very often while I was creating system, spells and maps I found myself in need of a such systems, but all the available options usually have a little flaw that forced me to used something else.

For example, let's say I wanted a missile that can arc and homing to a target, well there goes BPower's system. It can arc/curve but can't do homing with arc/curve natively. So the options left are Vexorian xemissile which can arc and do homing but cant curve, and Dirac's Missile system. Then again more problems with those, because Vexorian system do not have a lot of the useful events like Dirac's and BPower's systems. Dirac's system can arc/curve and do homing but it's T32 timer is never stopped and it do not have some useful events that the BPower system has. So I decided to get all three system together and build my own system with the stuff I think is useful and with the syntax I think is the most friendly, because I'm not a genius of vJASS myself.

What's different in this system?
Ok, so why it's called "Relativistic Missiles"? Well because mid development I realize that the way missiles were being processed could be optimized and the Einstein postulates about Time Dilation by Gravity gave the idea behind the implementation. Yeah, I know, WTH?

When it comes to Missile systems, performance is everything, and all missiles systems do basically the same thing when processing missiles instances, they loop every set period, which is usually 1/32, through all instances and do their calculations and event calls. The problem with it, is that the more instances existing at a given moment the greater will be the tanking of the game frame rate because the game will lower its fps so all that's need to be done before the next frame gets drawn have time to do so, and that's where the Einstein postulates gave me an idea.

See, when we study Relativity, we learn that gravity dilates time, the greater the gravitational potential (more or less mass) the slower time passes relative to an outside point of reference. Gravity in this analogy would be the amount of missiles instances currently existing, so instead of letting the game frame rate drops drastically to move all those instances, I make the missile instances have their time dilated.

Ok, but how?? Simple, first we need to find what I'll be calling the system Sweet Spot, which is the amount of missiles the game can handle without dropping to much performance per given period, which I found out to be between 150 and 200 missiles. Then we limit the amount of missiles processed per period to this sweet spot, and move the next missile in the line to be processed and all other behind it to the front, In terms of data structures, think of a circular list with a head and tail, and we move the head and tail to change the initial and final positions. I did it with arrays because they are a bit faster and because I'm lazy :p.

But that's not all, because by limiting the amount of missiles processed, we delay their next process call by (total amount)/(sweet spot), so now their speed needs to be corrected and relativity comes full circle now, because time dilation has it's relation with Length Contraction, so we increment the missiles speed by this factor.

Also, something very important is that this system is using only effects as missiles, thanks to the new natives introduced in 1.31, so no dummy units, no CreateUnit() and SetUnitFacing() blasphemy. I've included in the test map a version of this system that do use the dummy method for those that do not have the newer versions of the game. I Also included a version of this system that uses the usual process method, so processing all missiles in a single blow.

Results
I've taken the liberty to test this system against the king of Missile systems for some time, BPower's System. Below, there are 3 videos I make for stress test. The first from the left is BPower's Missile System reworked by AGD. Amazing job btw. You will be able to notice what I was talking about earlier about the sweet spot, when there are more than 150 or so missiles being processed, the fps goes basically to 0 and it freezes until the missiles are finished.

The video in the middle is my system in its normal version (not relativistic). It performs a little better (I've build it a little differently), but in the same way, when the missile count near 250, the fps starts to go down hill real quick.

The video in the right is the relativistic version, notice the missile count and fps compared to the 2 other system. At about 600 missiles fps get really low, but not so much because of the amount of missiles being processed but because of the amount of visual effects in the screen. If the screen was moved to the side where not so many stuff is visible, fps goes up. In my internal tests I was reaching more than 1200 missiles with about 16 fps but with no screen freezes.

And Last but not Least, a video with the examples.

vJASS:
event onPeriod takes nothing returns boolean
    -> if declared will run whenever every missile period

event onHit takes unit hit returns boolean
    -> if declared and collision is greater than 0
    -> will run whenever the missile collides with a unit

event onMissile takes Missiles missile returns boolean
    -> if declared and collision is greater than 0
    -> will run whenever the missile collides with another missile

event onDestructable takes destructable dest returns boolean
    -> if declared and collision is greater than 0
    -> will run whenever the missile collides with a destructable

event onItem takes item i returns boolean
    -> if declared and collision is greater than 0
    -> will run whenever the missile collides with an item

event onCliff takes nothing returns boolean
    -> if declared, will run whenever the missile collides with a cliff wall
    -> with height greater than the current missile height

event onTerrain takes nothing returns boolean
    -> if declared, will run whenever the missile collides with terrain

event onTileset takes nothing returns boolean
    -> if declared, will run whenever the missile changes tileset types

event onFinish takes nothing returns boolean
    -> if declared, will run when the missiles reaches its destination

event onBoundaries takes nothing returns boolean
    -> if declared, will run whenever the missile tries to go out
    -> of the map boundaries.

event onPause takes nothing returns boolean
    -> if declared, will run when the missile is paused

event onResume takes nothing returns boolean
    -> if declared, will run when the missile is unpaused

event onRemove takes nothing returns nothing
    -> if declared, will run when the missile is removed
vJASS:
x             -> The current x coordinate of the missile (readonly)
y             -> The current y coordinate of the missile (readonly)
z             -> The current z coordinate of the missile (readonly)
prevX         -> The previous x coordinate of the missile (readonly)
prevY         -> The previous y coordinate of the missile (readonly)
prevZ         -> The previous z coordinate of the missile (readonly)
nextX         -> The next x coordinate of the missile (readonly)
nextY         -> The next y coordinate of the missile (readonly)
nextZ         -> The next z coordinate of the missile (readonly)
travel        -> The current traveled distance of the missile (readonly)
source        -> The source unit for the missile (read and write)
target        -> The target unit for the missile. If set the missile will be roaming (read and write)
owner         -> The owning player of the missile (read and write)
vision        -> The sight range of the missile (read and write)
collideZ      -> If true, the missile will take into consideration the unit collision size, destructable oclusion height and item size when running the onHit, onDestructable, onItem events (read and write)
collision     -> The collision size of the missile. If not set, the events onHit, onDestructable, onItem and onMissile will no run (read and write)
damage        -> Stores the amount of damage to be used inside an event (read and write)
acceleration  -> The missile acceleration (read and write)
data          -> Stores information to be used inside any event (read and write)
model         -> The model of the missile (read and write)
curve         -> The curve of the missile (read and write)
arc           -> The Arc of the missile (read and write)
scale         -> The scale of the missile (read and write)
speed         -> The speed of the missile (read and write)
duration      -> Set the speed of the missile to match a duration (read and write)
roll          -> If true, the missile will roll as well (1.31+ only) (read and write)
type          -> Integer that can be used to diferentiate missiles (read and write)
paused        -> True when the missile is paused, false otherwise (read and write)
tileset       -> The current terrain type under the missile (readonly)
timeScale     -> The time scale of the effect model (read and write) (1.31+ non dummmy version only)
alpha         -> The effect model alpha value (read and write) (1.31+ non dummmy version only)
playerColor   -> The effect model player color (read and write) (1.31+ non dummmy version only)
animation     -> The effect model animation type (read and write) (1.31+ non dummmy version only)
impact        -> The object representing the impact coordinates (x, y, z, angle, distance, square, slope, alpha) (read and write)
origin        -> The object representing the origin coordinates (x, y, z, angle, distance, square, slope, alpha) (read and write)
effect        -> The object representing the missile (size, yaw, pitch, roll, path, effect, attachments), and attachments has (x, y, z, size, yaw, pitch, roll, path, effect)
vJASS:
x             -> The current x coordinate of the missile (readonly)
y             -> The current y coordinate of the missile (readonly)
z             -> The current z coordinate of the missile (readonly)
prevX         -> The previous x coordinate of the missile (readonly)
prevY         -> The previous y coordinate of the missile (readonly)
prevZ         -> The previous z coordinate of the missile (readonly)
nextX         -> The next x coordinate of the missile (readonly)
nextY         -> The next y coordinate of the missile (readonly)
nextZ         -> The next z coordinate of the missile (readonly)
travel        -> The current traveled distance of the missile (readonly)
source        -> The source unit for the missile (read and write)
target        -> The target unit for the missile. If set the missile will be roaming (read and write)
owner         -> The owning player of the missile (read and write)
collideZ      -> If true, the missile will take into consideration the unit collision size, destructable oclusion height and item size when running the onHit, onDestructable, onItem events (read and write)
collision     -> The collision size of the missile. If not set, the events onHit, onDestructable, onItem and onMissile will no run (read and write)
damage        -> Stores the amount of damage to be used inside an event (read and write)
acceleration  -> The missile acceleration (read and write)
data          -> Stores information to be used inside any event (read and write)
model         -> The model of the missile (to set use yourMissile:model(string), to get use yourMissile.Model)
curve         -> The curve of the missile (to set use yourMissile:curve(real), to get use yourMissile.Curve)
arc           -> The Arc of the missile (to set use yourMissile:arc(real), to get use yourMissile.Arc)
scale         -> The scale of the missile (to set use yourMissile:scale(real), to get use yourMissile.Scale)
speed         -> The speed of the missile (to set use yourMissile:speed(real), to get use yourMissile.Speed)
duration      -> Set the speed of the missile to match a duration (to set use yourMissile:duration(real), to get use yourMissile.Duration)
vision        -> The sight range of the missile (to set use yourMissile:vision(real), to get use yourMissile.Vision)
roll          -> If true, the missile will roll as well (1.31+ only) (read and write)
type          -> Integer that can be used to diferentiate missiles (read and write)
paused        -> True when the missile is paused, false otherwise (read and write)
timeScale     -> The time scale of the effect model (to set use yourMissile:timeScale(real), to get use yourMissile.TimeScale)
alpha         -> The effect model alpha value (to set use yourMissile:alpha(integer), to get use yourMissile.Alpha)
playerColor   -> The effect model player color (to set use yourMissile:playerColor(integer), to get use yourMissile.playercolor)
animation     -> The effect model animation type (to set use yourMissile:animation(integer), to get use yourMissile.Animation)
tileset       -> The current terrain type under the missile (readonly)
impact        -> The object representing the impact coordinates (x, y, z, angle, distance, square, slope, alpha) (read and write)
origin        -> The object representing the origin coordinates (x, y, z, angle, distance, square, slope, alpha) (read and write)
effect        -> The object representing the missile (size, yaw, pitch, roll, path, effect, attachments), and attachments has (x, y, z, size, yaw, pitch, roll, path, effect)
vJASS:
Missile                 -> The missile
MissileDestroy          -> Set this variable to true inside a missile event trigger to destroy the missile
MissileStart            -> The starting point of the missile. Set this variable before running the MissileCreate trigger
MissileStartZ           -> The starting Z of the missile. Set this variable before running the MissileCreate trigger
MissileFinish           -> The end point of the missile. Set this variable before running the MissileCreate trigger
MissileFinishZ          -> The end Z of the missile. Set this variable before running the MissileCreate trigger
MissileModel            -> The missile model. Set this variable before running the MissileCreate trigger. You can set this varible to change the model at any point inside a missile event trigger
MissileScale            -> The missile model scale. Set this variable before running the MissileCreate trigger. You can set this varible to change the scale at any point inside a missile event trigger
MissileSpeed            -> The missile speed. Set this variable before running the MissileCreate trigger. You can set this varible to change the speed at any point inside a missile event trigger
MissileDuration         -> The missile duration. Set this variable before running the MissileCreate trigger. You can set this varible to change the duration at any point inside a missile event trigger
MissileArc              -> The missile arc. Set this variable before running the MissileCreate trigger. You can set this varible to change the arc at any point inside a missile event trigger
MissileCurve            -> The missile curve. Set this variable before running the MissileCreate trigger. You can set this varible to change the curve at any point inside a missile event trigger
MissileVision           -> The missile sight range. Set this variable before running the MissileCreate trigger. You can set this varible to change the sight range at any point inside a missile event trigger
MissileDamage           -> Stores the damage. Set this variable before running the MissileCreate trigger. You can set this varible to change the damage at any point inside a missile event trigger
MissileCollision        -> The missile collision size. Set this variable before running the MissileCreate trigger. You can set this varible to change the collision at any point inside a missile event trigger
MissileAcceleration     -> The missile acceleration. Set this variable before running the MissileCreate trigger. You can set this varible to change the acceleration at any point inside a missile event trigger
MissileCollideZ         -> If true, the missile will check Z height when colliding. Set this variable before running the MissileCreate trigger. You can set this varible to change the model at any point inside a missile event trigger
MissileSource           -> The missile source unit. Set this variable before running the MissileCreate trigger. You can set this varible to change the source at any point inside a missile event trigger
MissileTarget           -> The missile target unit. If set the missile will roam to the target. Set this variable before running the MissileCreate trigger. You can set this varible to change the target at any point inside a missile event trigger
MissileOwner            -> The owner of the missile. Set this variable before running the MissileCreate trigger. You can set this varible to change the owner at any point inside a missile event trigger
MissilePaused           -> True if the missile is paused, false otherwise
MissileRoll             -> If true the missile will use roll (1.31+)
MissileType             -> Set if you want to categorize the missile. Set this variable before running the MissileCreate trigger. You can set this varible to change the type at any point inside a missile event trigger
MissilePosition         -> The current missile position
MissileZ                -> The current missile Z
MissileLastPosition     -> The last missile position
MissilePrevZ            -> The last missile Z
MissileNextPosition     -> The next missile position
MissileNextZ            -> The next missile Z
MissileVelocity         -> The missile velocity. Velocity is the speed over the system period.
MissileTravelled        -> The missile travelled distance. It is reseted if you deflect or bounce the missile.
MissileRemoveLocations  -> Set to true before running MissileCreate trigger to remove the MissileStart and MissileFinish points automatically.
MissileHitUnit          -> The hitted unit inside an onHit event trigger
MissileHitDestructable  -> The hitted destructable inside an onDestructable event trigger
MissileHitItem          -> The hitted item inside an onItem event trigger
MissileHitMissile       -> The hitted missile inside an onMissile event trigger
MissileTileset          -> The terrain type under the missile
MissileData             -> The missile data variable can be used to hold information (integer)
MissileTimeScale        -> The missile effect time scale. Set this variable before running the MissileCreate trigger. You can set this varible to change the time scale at any point inside a missile event trigger (1.31+ non dummmy version only)
MissileAlpha            -> The missile effect alpha value. Set this variable before running the MissileCreate trigger. You can set this varible to change the alpha value at any point inside a missile event trigger (1.31+ non dummmy version only)
MissilePlayerColor      -> The missile effect player color. Set this variable before running the MissileCreate trigger. You can set this varible to change the player color of the effect at any point inside a missile event trigger (1.31+ non dummmy version only)
MissileAnimation        -> The missile effect animation type. Set this variable before running the MissileCreate trigger. You can set this varible to change the animation type of the effect at any point inside a missile event trigger (1.31+ non dummmy version only)
MissileDeflectTarget    -> Set this variable before running the MissileDeflectTarget trigger to deflect the missile to the unit assigned to this variable
MissileRed              -> Set this variable (and green and blue) after the missile is created and then run the MissileColor trigger to change the missile effect color values (1.31+ non dummmy version only)
MissileGreen            -> Set this variable (and red and blue) after the missile is created and then run the MissileColor trigger to change the missile effect color values (1.31+ non dummmy version only)
MissileBlue             -> Set this variable (and red and green) after the missile is created and then run the MissileColor trigger to change the missile effect color values (1.31+ non dummmy version only)
Missile_onPeriod        -> Set this variable to a trigger that you want to run on every missile period
Missile_onHit           -> Set this variable to a trigger that you want to run when the missile hits an unit. Use the MissileHitUnit variable to access the hitted unit
Missile_onDestructable  -> Set this variable to a trigger that you want to run when the missile hits a destructable. Use the MissileHitDestructable variable to access the hitted destructable
Missile_onItem          -> Set this variable to a trigger that you want to run when the missile hits an item. Use the MissileHitItem variable to access the hitted item
Missile_onMissile       -> Set this variable to a trigger that you want to run when the missile hits another Missile. Use the MissileHitMissile variable to access the hitted Missile
Missile_onCliff         -> Set this variable to a trigger that you want to run when the missile collides with a cliff wall with height greater than the current missile height
Missile_onTerrain       -> Set this variable to a trigger that you want to run when the missile collides with terrain
Missile_onTileset       -> Set this variable to a trigger that you want to run when the missile changes tileset types
Missile_onFinish        -> Set this variable to a trigger that you want to run when the missile reaches its destination
Missile_onBoundaries    -> Set this variable to a trigger that you want to run when the missile tries to leave the map
Missile_onPause         -> Set this variable to a trigger that you want to run when the missile is paused
Missile_onResume        -> Set this variable to a trigger that you want to run when the missile is unpaused
Missile_onRemove        -> Set this variable to a trigger that you want to run when the missile is removed
MissileEvent            -> This variable represents which event is being executed. Compere it to one of the following variables inside a trigger to decide what to do in each event
MissileOnPeriod         -> MissileEvent is set to the value of this variable when Missile_onPeriod is set to a trigger
MissileOnHit            -> MissileEvent is set to the value of this variable when Missile_onHit is set to a trigger
MissileOnDestructable   -> MissileEvent is set to the value of this variable when Missile_onDestructable is set to a trigger
MissileOnItem           -> MissileEvent is set to the value of this variable when Missile_onItem is set to a trigger
MissileOnMissile        -> MissileEvent is set to the value of this variable when Missile_onMissile is set to a trigger
MissileOnCliff          -> MissileEvent is set to the value of this variable when Missile_onCliff is set to a trigger
MissileOnTerrain        -> MissileEvent is set to the value of this variable when Missile_onTerrain is set to a trigger
MissileOnTileset        -> MissileEvent is set to the value of this variable when Missile_onTileset is set to a trigger
MissileOnFinish         -> MissileEvent is set to the value of this variable when Missile_onFinish is set to a trigger
MissileOnBoundaries     -> MissileEvent is set to the value of this variable when Missile_onBoundaries is set to a trigger
MissileOnPause          -> MissileEvent is set to the value of this variable when Missile_onPause is set to a trigger
MissileOnResume         -> MissileEvent is set to the value of this variable when Missile_onResume is set to a trigger
MissileOnRemove         -> MissileEvent is set to the value of this variable when Missile_onRemove is set to a trigger
vJASS:
method bounce takes nothing returns nothing
    -> Bounces the missile, reseting angles

method deflect takes real x, real y, real z returns nothing
    -> Deflects the missile to the x, y and z coordinates

method deflectTarget takes unit u returns nothing
    -> Deflects the missile to a unit

method flushAll takes nothing returns nothing
    -> Flushes the hit group for the missile

method flush takes widget w returns nothing
    -> Remove a unit, destructable, item or missile from the hit group

method hitted takes widget w returns boolean
    -> Returns true if the unit, destructable or item was hit by the missile

method attach takes string model, real dx, real dy, real dz, real scale returns effect
    -> Attach an effect to the missile and return the effect attached
    -> dx, dy, and dz are offsets from the main missile coordinates

method detach takes effect attachment returns nothing
    -> Detach an effect attached to the missile

method pause takes boolean flag returns nothing
    -> If true will pause the misisle, else will unpause it

method color takes integer red, integer green, integer blue returns nothing
    -> Changes the missile effect model color (1.31+ non dummy version only)
vJASS:
MissileDeflectPosition
MissileDeflectZ
MissileDeflectTarget
Set the above variables then run the MissileDeflect or MissileDeflectTarget triggers to deflect the missile

MissileFlushUnit
Set the above variable then run the MissileFlush to make the set unit be able to be hitted again by the missile

MissileHittedUnit
MissileHitted
Set the MissileHittedUnit to a unit then run the MissileHitted trigger. After that you can use the MissileHitted varible to check if the unit was already hitted by the missile

MissileAttachModel
MissileAttachX
MissileAttachY
MissileAttachZ
MissileAttachScale
MissileDetachEffect
Set the above varibles then run the MissileAttach trigger to attach an effect to the missile with MissileAttach(Model, X, Y, Z, Scale)

MissileDetachEffect
Set the above variable to the effect that was previously attached to the missile then run the MissileDetach trigger

Run the MissileBounce trigger to bounce the missile and reset its travalled distance

Run the MissileFlushAll trigger flush all units hitted by the missile

Run the MissilePause trigger pause the missile

Run the MissileResume trigger unpause the missile

Run the MissileBounce trigger to bounce the missile and reset its travalled distance

MissileRed
MissileGreen
MissileBlue
Set the above variables and then run the MissileColor trigger to change the missile effect model color (1.31+ non dummy version only)
vJASS:
function CreateMissileGroup takes nothing returns MissileGroup
    -> Creates a missile group and return it

function DestroyMissileGroup takes MissileGroup missiles returns nothing
    -> Destroys the misisle group

function MissileGroupGetSize takes MissileGroup missiles returns integer
    -> Returns the size of the missile group

function GroupMissileAt takes MissileGroup missiles, integer position returns Missiles
    -> Returns the missile at the given index.

function ClearMissileGroup takes MissileGroup missiles returns nothing
    -> Clear the missile group

function IsMissileInGroup takes Missiles missile, MissileGroup missiles returns boolean
    -> True if the missile is inside the missile group

function GroupRemoveMissile takes MissileGroup missiles, Missiles missile returns nothing
    -> Removes the missile from the missile group

function GroupAddMissile takes MissileGroup missiles, Missiles missile returns nothing
    -> Add the missile to the missile group

function GroupPickRandomMissile takes MissileGroup missiles returns Missiles
    -> Returns a random missile from the misisle group. 0 if empty

function FirstOfMissileGroup takes MissileGroup missiles returns Missiles
    -> Returns the first missile inside the missile group. 0 if empty

function GroupAddMissileGroup takes MissileGroup source, MissileGroup destiny returns nothing
    -> Add the missiles that are in the source group into the destiny group

function GroupRemoveMissileGroup takes MissileGroup source, MissileGroup destiny returns nothing
    -> Remove the missiles that are in the source group from the destiny group

function GroupEnumMissilesOfType takes MissileGroup missiles, integer whichType returns nothing
    -> Enumerates the missiles of matching type

function GroupEnumMissilesOfTypeCounted takes MissileGroup missiles, integer whichType, integer amount returns nothing
    -> Enumerates up to amount of missiles of matching type

function GroupEnumMissilesOfPlayer takes MissileGroup missiles, player p returns nothing
    -> Enumerates the missiles that belongs to a player

function GroupEnumMissilesOfPlayerCounted takes MissileGroup missiles, player p, integer amount returns nothing
    -> Enumerates up to amount of missiles that belongs to a player

function GroupEnumMissilesInRect takes MissileGroup missiles, rect r returns nothing
    -> Enumerates the missiles inside a region

function GroupEnumMissilesInRectCounted takes MissileGroup missiles, rect r, integer amount returns nothing
    -> Enumerates up to amount of missiles inside a region

function GroupEnumMissilesInRangeOfLoc takes MissileGroup missiles, location loc, real radius returns nothing
    -> Enumerates the missiles within range of a location

function GroupEnumMissilesInRangeOfLocCounted takes MissileGroup missiles, location loc, real radius, integer amount returns nothing
    -> Enumerates up to amount of missiles within range of a location

function GroupEnumMissilesInRange takes MissileGroup missiles, real x, real y, real radius returns nothing
    -> Enumerates the missiles within range of x, y

function GroupEnumMissilesInRangeCounted takes MissileGroup missiles, real x, real y, real radius, integer amount returns nothing
    -> Enumerates up to amount of missiles within range of x, y

  • BPower
  • Dirac
  • Vexorian
  • AGD
  • emjlr3
  • AceHart
  • Nestharus
  • Maghteridon96
  • Bribe
  • Flux
  • Forsakn

(v1.0)
  • Release
(v1.1)
  • Merged Normal and Relativistic code for both Legacy and Current versions.
  • You can use the SWEET_SPOT constant to determine the system behavior
    • SWEET_SPOT <= 0 -> normal method
    • SWEET_SPOT > 0 -> relativistic method
  • Included support for DummyRecycler by Flux for the Legacy version. This should improve its performance even further.
(v1.2)
  • Fixed a bug for homing missiles height
  • New configuration member boolean collideZ -> set to true to make the new missile consider z collisions
  • New Global Configuration constant boolean ROLL -> If true missile will consider roll in orientation. Roll can look really fishy for some users and was never possible until patch 1.31, so if you want it set it to true in the globlas block (1.31+ version only).
  • You can now attach effects to the main missile effect with an offset through 2 new methods (1.31+ version only)
    • // dx, dy, and dz are offsets from the main missile coordinates method attach takes string model, real dx, real dy, real dz, real scale returns effect
    • method detach takes effect attachment returns nothing
  • Few minor optmizations.
(v1.3)
  • Fix a minor rect leak
(v1.4)
  • Minor optmizations.
  • WorldBounds not required anymore.
(v1.5)
  • WorldBounds now is required (Centralized requirements and outsourced)
  • New optional event (See Available Events for more info)
    • method onBoundaries takes nothing returns boolean
  • Fixed a spelling mistake on the detach functionality.
(v1.6)
  • MissileEffect library updated to use the BlzSetSpecialEffectOrientation native. (v1.31+ only)
(v1.7)
  • Standardized getting and setting of the members speed, arc and curve. They now read and write in degrees.
(v1.8)
  • Made a system function (GetLocZ) private to avoid conflict with other resources.
(v1.9)
  • System ported to LUA (Credits to Forsakn for the first port).
  • Added instant facing when creating missiles instances.
  • Included a version of Missiles that uses the dummy method and a Dummy Pool utilizing the new natives. This version by default will not let missiles clip through terrain.
  • Code formatting and cleaning.
(v2.0)
  • System ported to GUI!
  • Implemented ways to enumerate missiles (Missile Groups)
  • New method: pause. When called pauses or unpauses the missile
  • 2 new events: onPause and onResume
  • 3 new members: roll, type and paused
  • Added the attach and detach methods to the LUA version
  • Fixed a bug on the collideZ
  • Fixed a bug when deflecting missiles
  • Refactored code to be more readable and easy to maintain
(v2.1)
  • Removed the usage of a post 1.30 native being used in the 1.30 version of the system. Now the 1.30- version should work for patches below that
  • Fixed a bug in the LUA GUI version for the onPause and the onRemove events
  • Added an alternative method of setting up events for the GUI version. It's more compact, you can set up all events you want inside only 1 trigger (See the Trigger Preview for examples on how to do it)
(v2.2)
  • Adjusted the initial position of the missile in the versions that use the dummy method.
(v2.3)
  • 2 new events:
    • onCliff -> Run whenever the missiles collides with a cliff wall and it's height is greater than the current missile height
    • onTileset -> Run whenever the missile changes terrain types
  • 4 new members
    • nextX -> The next missile x value
    • nextY -> The next missile y value
    • nextZ -> The next missile z value
    • tileset -> the current terrain type under the missile
  • Fixed the missile movement on higher ground levels
  • Fixed the movement of missiles when going over terrain/cliffs for the dummy versions
  • Separated the GUI version into vJASS and LUA implementations. For those who want to choose between them.
(v2.4)
  • Missiles can now grant vision using the new member "vision"
    • vJASS:
      // To set (The missile must have a source or a owner)
      yourMissile.vision = value
      
      // To get
      var = yourMissile.vision

    • Lua:
      -- To set (The missile must have a source or a owner)
      yourMissile:vision(value)
      
      -- To get
      var = yoruMissile.Vision
      • Example
        • Actions
          • -- Set the MissileVision variable before running the MissileCreate trigger ou at any event trigger (The missile must have a source or a owner) --
          • Set VariableSet MissileSource = (Triggering unit)
          • Set VariableSet MissileVision = 800.00
          • Creates the missile
          • Trigger - Run MissileCreate <gen> (ignoring conditions)
  • New required library: Alloc
  • Fixed a few bugs in the GUI version
(v2.5)
  • Missiles can now be paused within the onFinish event.
  • Removed the deflectZ method, now the deflect method expects x, y and z parameters
  • New method deflectTarget deflects the missile to a unit
  • New GUI variable MissileData can be used to store information as needed (integer type)
  • version 1.31+ non dummy only changes:
    • 4 new method operator (operators in vJASS, functions in Lua)
      • yourMissile.timeScale => changes the time scale of the effect model (animation speed)
      • yourMissile.alpha => changes the alpha value of the effect model (transparency)
      • yourMissile.playerColor => changes the player color of the effect model
      • yourMissile.animation => changes the animation type used by the effect model
    • 1 new method
      • yourMissile.color(integer, integer, integer) => changes the effect model color (vJASS)
      • yourMissile:color(integer, integer, integer) => changes the effect model color (Lua)
    • vJASS:
      // To set
          yourMissile.timeScale = 3.
          yourMissile.alpha = 128
          yourMissile.playerColor = GetPlayerId(GetOwningPlayer(unit))
          yourMisisle.animation = 3 // ConvertAnimType(3) under the hood
      // To get
          variable = yourMissile.timeScale
          variable = yourMissile.alpha
          variable = yourMissile.playerColor
          variable = yourMisisle.animation
    • Lua:
      -- To set
          yourMissile:timeScale(3.)
          yourMissile:alpha(128)
          yourMissile:playerColor(GetPlayerId(GetOwningPlayer(unit)))
          yourMisisle:animation(3) -- ConvertAnimType(3) under the hood
      -- To get
          variable = yourMissile.TimeScale
          variable = yourMissile.Alpha
          variable = yourMissile.playerColor
          variable = yourMisisle.Animation
      • GUIExamle
        • Actions
          • Set VariableSet MissileAnimation = 5
          • Set VariableSet MissileTimeScale = 3.00
          • Set VariableSet MissilePlayerColor = 3
          • Set VariableSet MissileAlpha = 128
          • Trigger - Run MissileCreate <gen> (ignoring conditions)
          • -------- CHANGING THE COLOR. MUST BE DONE AFTER THE MISSILE IS CREATED (1.31+ NON DUMMY VERSION ONLY) --------
          • Set VariableSet MissileRed = 123
          • Set VariableSet MissileGreen = 67
          • Set VariableSet MissileBlue = 32
          • Trigger - Run MissileColor <gen> (ignoring conditions)
(v2.6)
  • Fixed a bug when pausing missiles inside an onFinish event.
(v2.7)
  • Minor improvements.
(v2.8)
  • Fixed a bug in the deflect method when the onTerrain event is declared.
  • Fixed a bug in the flushAll method in the LUA version.
Contents

Missiles (Map)

Missiles (Map)

Missiles (Map)

Missiles (Map)

Reviews
Wrda
Upgraded to High quality due to how great the implementation and usefulness this offers.
Level 9
Joined
May 12, 2018
Messages
145
Hi guys, so i am using a type of spell from the template "R", and i want it to deal extra damage + a new effect if "Frost arrow" is on autocast, how can i detect and do that?
In Basic Hero Abilities List, there is a Slow Poison ability for hero version. It provides highly accurate event detection when used in conjunction with Bribe's damage engine.
After using the event that detects only normal attacks, you just need to add the condition to check if the target unit has its Slow Poison buff.

If you need only the detection about status of autocasting as you said, the following source will be good textbook for you.
Chopinski's Sylvanas Concept contains 'Black Arrow' - what you find.
But this is a bit incomplete. This only refers to the boolean for turning on/turning off autocasting, so we can turn on autocasting when the projectile of a normal attack is fired to operate the function without mana costs, or we can turn off autocasting when the projectile of a special attack is fired to intentionally fail it.
 
Level 9
Joined
Oct 20, 2010
Messages
228
The API members travel and duration are very helpful for utilizing this system as a means of creating a leap/travel spell. However, neither of them are useful for me unless I can also red the time elapsed or the total distance in a periodic function. Is there any way to gain this functionality? It would be useful to me if I had a way to have access to either distance travelled and total distance, or time elapsed and total time, as either data pair would allow simulating a leap.

Edit: Oh, how silly of me. I can just set the units Z, too!
 
Last edited:
Level 11
Joined
Dec 16, 2017
Messages
418
In Basic Hero Abilities List, there is a Slow Poison ability for hero version. It provides highly accurate event detection when used in conjunction with Bribe's damage engine.
After using the event that detects only normal attacks, you just need to add the condition to check if the target unit has its Slow Poison buff.

If you need only the detection about status of autocasting as you said, the following source will be good textbook for you.
Chopinski's Sylvanas Concept contains 'Black Arrow' - what you find.
But this is a bit incomplete. This only refers to the boolean for turning on/turning off autocasting, so we can turn on autocasting when the projectile of a normal attack is fired to operate the function without mana costs, or we can turn off autocasting when the projectile of a special attack is fired to intentionally fail it.
Thanks, sorry for late reply, it's been very useful!
 
Level 9
Joined
Oct 20, 2010
Messages
228
Love the system! I have been using the LUA version extensively to handle missiles in a grand strategy map I have been working on. However, something I've yet to use are Missile Groups and I'm not sure how to start with them either.

I'm looking to recreate a split-arrow (or volley, think Ashe from League of Legends) type ability that shoots out arrows in a fan. The issue I am running into is that it can 'shotgun' and hit the same enemy multiple times from one spell cast. How might I accomplish this?
 
However, something I've yet to use are Missile Groups and I'm not sure how to start with them either.
I use it for shurikens. A hero has one spell that throws 4 of them out (sticking around where they "end up" for a few seconds), and one spell that pulls all of them in. I use a group to track all of them.
I use jass, but I'd guess the APIs are similar enough.
First: I have a MissileGroup created for my hero and whenever I fire a projectile I want to be able to later pull, I do call <missile-group>.insert(missile). When I want to pull all projectiles in the group, I iterate through them all and, reset their internal hit-counters etc. and deflect them to their caster.
JASS:
        method pullShuriken takes nothing returns nothing
            call deflectTarget(caster)
            call pause(false)
            set timeScale = 1.0
            set targetsHit = 0
            call flushAll()
            if decayTimer != null then
                call ReleaseTimer(decayTimer)
                set decayTimer = null
            endif
        endmethod

        static method pullAll takes MissileGroup shurikens returns nothing
            local MGroup node = shurikens.group.next
            local integer i = 0
        
            if shurikens.size > 0 then
                loop
                    exitwhen i == shurikens.size
                    call Shuriken(node.missile).pullShuriken()
                    set node = node.next
                    set i = i + 1
                endloop
            endif
        endmethod

I'm looking to recreate a split-arrow (or volley, think Ashe from League of Legends) type ability that shoots out arrows in a fan. The issue I am running into is that it can 'shotgun' and hit the same enemy multiple times from one spell cast. How might I accomplish this?

I would have a "Spell Container" that manages all projectiles, with a group where you add the units that projectiles hit. When you hit a unit in this group, it has already been hit by another projectile and you can do whatever (deal no damage, deal reduced damage, whatever feels reasonable).


JASS:
struct Shuriken extends Missiles
    private group unitsHit //This is common for all within a "spell cast"
    
    method onHit takes unit hit returns boolean
        if IsUnitInGroup(hit, unitsHit) then
            return true //Do nothing, but continue... Or return false to just disappear. Whatever you want
        else
            //Deal damage
            call GroupAddUnit(unitsHit, hit)
            return false
        endif
    endmethod
endstruct

struct ShurikenSpell
    private group unitsHit //Needs to be cleared when all projectiles within a "spell cast" is "dead", maybe after a timer?

    public static method onCast takes nothing returns nothing
        //initial setup etc. get position of caster...
        this.unitsHit = CreateGroup()
        //Setup for each projectile supposed to be firerd or something
       missile.unitsHit = this.unitsHit //All missiles fired within this spell cast share the same unit group
       //Fire etc. Probably setup a timer or something to clean up the unitsHit group. Or it'll leak.
    endmethod

    private static method onInit takes nothing returns nothing
        call RegisterSpellEffectEvent(SHURIKEN_ABILITY_CODE, function thistype.onCast)
    endmethod
endstruct
 
Level 11
Joined
Dec 16, 2017
Messages
418
For the single target, if you want to use more missiles, you have to reacreate all the variables like this, or is there a better way?

My idea is to make more arrows, and each arrow would have a chance to deal the additional damage and a debuff from the CC system.

If i just use missile damage, arc and curve and onFinish and then i run the missilecreate, will it run ok, it will take the other variables as stated from the first missile created, or they will be null?

  • Double Strafe Config
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Double Strafe Archer
    • Actions
      • Set VariableSet MissileSource = (Triggering unit)
      • Set VariableSet MissileStart = (Position of (Triggering unit))
      • Set VariableSet MissileStartZ = 50.00
      • Set VariableSet MissileFinish = (Position of (Picked unit))
      • Set VariableSet MissileFinishZ = 50.00
      • Set VariableSet MissileModel = Abilities\Weapons\SearingArrow\SearingArrowMissile.mdl
      • Set VariableSet MissileSpeed = 1500.00
      • Set VariableSet MissileArc = 5.00
      • Set VariableSet MissileDamage = (120.00 + (50.00 x (Real((Level of (Ability being cast) for (Triggering unit))))))
      • Set VariableSet MissileScale = 2.00
      • Set VariableSet MissileCurve = (Random real number between 0.00 and 15.00)
      • Set VariableSet MissileTarget = (Target unit of ability being cast)
      • Set VariableSet Missile_onFinish = Double Strafe Damage <gen>
      • Trigger - Run MissileCreate <gen> (ignoring conditions)
      • Set VariableSet MissileAttachModel = Windwalk.mdl
      • Set VariableSet MissileAttachX = 50.00
      • Set VariableSet MissileAttachY = 50.00
      • Set VariableSet MissileAttachZ = 50.00
      • Set VariableSet MissileAttachScale = 2.00
      • Trigger - Run MissileAttach <gen> (ignoring conditions)
      • Set VariableSet Attachments[Missile] = (Last created special effect)
      • Set VariableSet Counter[Missile] = 0
      • -------- --- --------
      • Set VariableSet MissileSource = (Triggering unit)
      • Set VariableSet MissileStart = (Position of (Triggering unit))
      • Set VariableSet MissileStartZ = 50.00
      • Set VariableSet MissileFinish = (Position of (Picked unit))
      • Set VariableSet MissileFinishZ = 50.00
      • Set VariableSet MissileModel = Abilities\Spells\Human\SunderingBlades\SunderingBlades.mdl
      • Set VariableSet MissileSpeed = 1500.00
      • Set VariableSet MissileArc = 5.00
      • Set VariableSet MissileDamage = (120.00 + (50.00 x (Real((Level of (Ability being cast) for (Triggering unit))))))
      • Set VariableSet MissileScale = 2.00
      • Set VariableSet MissileCurve = (Random real number between -15.00 and 0.00)
      • Set VariableSet MissileTarget = (Target unit of ability being cast)
      • Set VariableSet Missile_onFinish = Double Strafe Damage <gen>
      • Trigger - Run MissileCreate <gen> (ignoring conditions)
  • Double Strafe Damage
    • Events
    • Conditions
      • (MissileTarget is alive) Equal to True
    • Actions
      • Unit - Cause MissileSource to damage MissileTarget, dealing (MissileDamage + 1.00) damage of attack type Spells and damage type Normal
      • Special Effect - Create a special effect attached to the origin of MissileTarget using Objects\Spawnmodels\Human\HumanLargeDeathExplode\HumanLargeDeathExplode.mdl
      • Special Effect - Destroy (Last created special effect)
      • Custom script: call CrowdControl.ensnare(udg_MissileTarget, 1, "", "origin" , false)
 
Top