Spell Homing Missiles

Prometheus

Everything is mutable; nothing is sacred
Reaction score
589
Homing Missiles

Import Diff: 2/10 ~ Copying all the abilities
MUI: Yes
JESP: Yes
Constants: Yes
Units Affected: Enemy, Vulnerable
Target Type: Non-Target
Spell Info:

The caster shoots out a number of slow moving fire balls that last for 10 seconds. The fire balls will chase the randomly targeted units until they come it contact with them.

Level 1 - Shoots out 4 missiles, 100 damage if hit.
Level 2 - Shoots out 8 missiles, 200 damage if hit.
Level 3 - Shoots out 12 missiles, 300 damage if hit.

Screenie.jpg


JASS:
scope HM initializer Init
//***************************************
//      Spell Name: Homing Missiles     *
//      Spell Author: kc102/R34P3R      *
//      Optimized for vJass!            *
//***************************************

//*************************************
//    Start Configuration Functions
//*************************************
    globals
        private constant integer ABID = 'A000'
            //Replace A000 with your spell ID.
        private constant integer TRACK = 'n000'
            //The ID of the unit that follows the enemies so the flame can see them.
        private constant integer DUMID = 'n002'
            //The ID for the dummy unit.
        private constant integer DUMSPL = 'A003'
            //The ID for the dummy units spell.
        private constant integer BASENUM = 4
            //This is how many BASE units this spell will create. Meaning, at level 2 it will be 8.
        private constant real RANGE = 500
            //This is the BASE range in which we will grab a unit. Meaning, at level 2 it will be 1000.
        private constant string AUTOID = "selfdestructon"
            //The orderstring so the units autoexplodes.
        private constant string MOVE = "attackonce"
            //Makes the unit move.
        private constant string FX = "Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeTarget.mdl"
            //The effects attached to the unit.
        private constant string ATCHPNT = "origin"
            //Where the effect attaches to.
    endglobals
    // NoTe
    // Open up the object editor and find "Dummy Unit (Homing)", its ID is n002.
    // The tracking unit is called "Dummy Unit (Tracker)" and its ID is n000.
    // Created units last for 10 seconds, this is changable VIA the object editor.
    // They have 10 HP with a -1 regen.
    // The fields are Hit Points Maximum Base and Hit Points Regneration Rate.
    //                  The HP of the unit.             The units HP regen.
    // To edit damage, open up the object editor and find the ability "Homing Blowup (A003)"
    // Edit the level damage as you wish, it's called Full Damage Amount and Partial Damage Amount.
    // The missles have an immolation like spell.
    // To edit that find "Homing Damage (A001)" and edit the field "Damage per Interval".
    
    private constant function GetRange takes integer lvl returns real
        return RANGE*lvl
        //This function takes the above variable, RANGE, and multiplies it by the units spell level.
    endfunction
    private function GetNum takes integer lvl returns integer
        return BASENUM*lvl
        //This function takes the variable BASENUM, and multiplies it by the units spell level.
    endfunction
//*************************************
//     End Configuration Functions
//     Do not edit further unless you know what you're doing.
//*************************************
    
    globals
        private group g = CreateGroup()
        private unit caster
        private unit dummy
        private unit target
        private player pq
        private integer splvl
        private real cx
        private real cy
    endglobals
    
    private function FailSafe takes nothing returns boolean
        return true
    endfunction
    
    private function HIsAlly takes nothing returns boolean      
        if IsUnitEnemy(GetFilterUnit(),pq) and GetWidgetLife(GetFilterUnit()) > 0.405 then
            call DestroyEffect(AddSpecialEffectTarget(FX,caster,ATCHPNT))
            set dummy = CreateUnit(pq,DUMID,cx,cy,0.00)
            call SetUnitAbilityLevel(dummy,DUMSPL,splvl)
            set target = GetFilterUnit()
            call IssueImmediateOrder(dummy,AUTOID)
            call IssueTargetOrder(dummy,MOVE,target)
            set dummy = CreateUnit(pq,TRACK,GetUnitX(target),GetUnitY(target),0.00)
            call IssueTargetOrder(dummy, "move", target)
        endif
        return false
    endfunction
    
    private function HMC takes nothing returns boolean
        return GetSpellAbilityId() == ABID
    endfunction
    
    private function HMA takes nothing returns nothing
        set caster = GetTriggerUnit()
        set splvl = GetUnitAbilityLevel(caster,ABID)
        set cx = GetUnitX(caster)
        set cy = GetUnitY(caster)
        set pq = GetOwningPlayer(caster)
        
        call GroupEnumUnitsInRangeCounted(g,cx,cy,GetRange(splvl),Condition(function HIsAlly),GetNum(splvl))
    endfunction

    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
    
        loop
        exitwhen i > 11
            call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,Condition(function FailSafe))
            set i = i + 1
        endloop
    
        call TriggerAddAction(t,function HMA)
        call TriggerAddCondition(t,Condition(function HMC))
    endfunction
endscope


Code:
Changelog:
1.0 - Released
1.4 - Leak cleaned, Integrated flame life into spell, Locust re-added to the dummy units, Code improved
1.5 - Code improved at Rinpun's suggestion
2.0 - Missiles Blow Up Correctly, Added a tracking unit so the missile won't lose sight of the enemy, Various other changes
2.4 - Code is now JESP
2.5 - Some useless code removed
2.7 - Various Changes
4.0 - Changed to 4.0 because of major update. Uses vJass now.
4.1 - Further code improvements.
4.2 - Further, minor improvements.
4.3 -           ||
4.4 -           ||
4.5 - Global blocks split
 

Attachments

  • Homing Missiles.w3x
    42.4 KB · Views: 417

Prometheus

Everything is mutable; nothing is sacred
Reaction score
589
Good spell! :D

Thanks

Quite a good spell, but, the Fire balls can be selected.
You need to give them the locust ability to prevent that.

The balls also last a bit too long IMO.

Yea, I removed it for certain testing purposes and forgot to readd them.
You can change how long they last in the object editor, 100 seconds, 100hp with -hp per second regen.

a screenie?

I'll upload in a min.


Edit: Stuff done! SS added!

Edit2: Is this spell JESP?

Edit3: Code improved
 

Pyrogasm

There are some who would use any excuse to ban me.
Reaction score
134
kc102 said:
Edit2: Is this spell JESP?
You don't have nearly enough constants.

In addition, all of your constants (or at least the math-related ones) should take an integer argument "level", such that people can do things like
JASS:
constant function HM_Length takes integer Level returns real
    return 100.00*(Level/3.00)+Pwr(2.00, Level)
endfunction

Instead of having to find where it's used in the code.

Also, Condition(function HM_IsAlly)) leaks a Boolexpr, and GetUnitsInRangeOfLocMatching(...) is a BJ function; replace it with the appropriate natives.

Last, all of your constants should be in one big block at the top of the code, and the spell should have a header like so:
JASS:
//***************************************
//      Spell Name: Homing Missiles     *
//          Spell Author: kc102         *
//       Follows the JESP Standard      *
//***************************************

//*************************************
//    Start Configuration Functions    
//*************************************

constant function HM_Length takes integer Level returns real
    return 100.00*(Level/3.00)+Pwr(2.00, Level)
endfunction

//And so on and so forth...

//*************************************
//     End Configuration Functions     
//*************************************
 

PurgeandFire

zxcvmkgdfg
Reaction score
509
Nice spell! I didn't actually look and download the map, but the code is good! :p

Anyways, though it does not seem it, there were a couple of BJs that I removed, here is the improved version:
JASS:
//////////////////////////////////////////////////////////////////////////
//  Homing Missiles are created whenever you cast the spell provided.
//  By design, only alive and enemy units are attacked by the homing missiles.
//////////////////////////////////////////////////////////////////////////

constant function HM_RawSpellCode takes nothing returns integer
	return 'A000' //Replace A000 with your spell ID.
endfunction

constant function HM_GetTarget takes nothing returns real
	return 500.00 //This is the range in which we will grab a unit.
endfunction

constant function HM_Loops takes nothing returns integer
    return 4 //This is how many units this spell will create, this is multiplied by the level of the ability. Change this to create or lessen the units created per level.
endfunction

constant function HM_Length takes nothing returns real
	return 100.00 //This is how long the flame lasts.
endfunction

function HM_IsAlly takes nothing returns boolean
	return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0.405 //This checks to make sure we will only attack enemy units and alive units.
endfunction

function HM_Dummy_ID takes integer i returns integer
	local integer array p //Replace the n001, n002 and n003 with your dummy units IDs, I have created an ability for each.
	set p[1] = 'n002'
	set p[2] = 'n003'
	set p[3] = 'n001'
	return p<i>
endfunction

function HM_Actions takes nothing returns nothing
	local unit caster = GetTriggerUnit()
	local unit dummy
	local unit target
	local integer splvl = GetUnitAbilityLevel(caster, HM_RawSpellCode())
    	local integer loopa = 1
	local integer failsafe
	local real cx = GetUnitX(caster)
	local real cy = GetUnitY(caster)
	local group g = CreateGroup()
	call GroupEnumUnitsInRange(g,cx,cy,HM_GetTarget(),Condition(function HM_IsAlly))
	loop
	exitwhen loopa &gt; splvl * HM_Loops()
		set failsafe = CountUnitsInGroup(g)
		if failsafe &lt;= 0 then
			set dummy = null              
			set target = null
			set caster = null
			call GroupClear(g)
			call DestroyGroup(g)
			set g = null
			return
		endif
		set dummy = CreateUnit(GetOwningPlayer(caster), HM_Dummy_ID(splvl), cx, cy, 0.00)
		set target = FirstOfGroup(g)
		call SelectUnit(dummy,false)
		call IssueImmediateOrder(dummy, &quot;selfdestructon&quot;)
		call IssueTargetOrder(dummy, &quot;attackonce&quot;, target)
		call GroupRemoveUnit(g, target)
		call UnitApplyTimedLife(dummy, &#039;BTLF&#039;, HM_Length())
		set dummy = null
		set target = null
		set loopa = loopa + 1
	endloop
	set caster = null
	call GroupClear(g)
	call DestroyGroup(g)
endfunction

//===========================================================================
function HM_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == HM_RawSpellCode()
endfunction

function InitTrig_Homing_Missiles takes nothing returns nothing
    set gg_trg_Homing_Missiles = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Homing_Missiles, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_Homing_Missiles, Condition(function HM_Conditions))
    call TriggerAddAction(gg_trg_Homing_Missiles, function HM_Actions)
endfunction</i>


@Pyrogasm: Boolexprs don't leak. If they did leak, every single GUI trigger in the entire universe for WE would leak a boolexpr due to the fact that TriggerAddCondition uses "Condition()".

@kc102: GetUnitsInRangeOfLocMatching is hazardous (dangerous :p) to use because it destroys the boolexpr, which is what you do not want to do. :)

Good job, +REP if I can!!
 

Pyrogasm

There are some who would use any excuse to ban me.
Reaction score
134
I believe that the issue of Boolexprs is a moot point. Vexorian ran tests, but I don't think most people really know whether or not destroying them is a bad idea and/or if they leak.

I said they did because I've always thought they did, else there wouldn't be the DestroyBoolExpr(whichBoolexpr) native.

Additionally, the reason that TriggerAddCondition(...) uses "Condition(function ...)" instead of a boolexpr variable is that if you did this:
JASS:
function InitTrig_SomeTrigger takes nothing returns nothing
    local boolexpr B = Condition(function SomeConditionFunc)
    call TriggerAddAction(gg_trg_SomeTrigger, B)
    call DestroyBoolExpr(B)
    set B = null
endfunction

The trigger would never pass the condition, since it wouldn't exist after being destroyed.
 

PurgeandFire

zxcvmkgdfg
Reaction score
509
:D Well, not only Vexorian said that, grim001, Earth-Fury, and many more said not to destroy condition Boolexprs. I know it exists, but I thought that would be for something like "Filter()" or somethin'.

Anyways, go ahead and believe what you want; I'm not trying to convert you. :p

Also, "TriggerAddAction" doesn't take Boolexprs!! lol :D
Pyrogasm said:

Code:
function InitTrig_SomeTrigger takes nothing returns nothing
    local boolexpr B = Condition(function SomeConditionFunc)
    [B]call TriggerAddAction(gg_trg_SomeTrigger, B)[/B]
    call DestroyBoolExpr(B)
    set B = null
endfunction
 

Halo_king116

Working As Intended
Reaction score
153
NOTE that I am using the first version you sent me.

I found it annoying to test. The units swarmed on me and it killed them all instantly when I used the move. I didn't get to see what exactly happened. Gibe her blink, and maybe make the footmen walk a bit slower. Make the creeps respawn after a while.

Also, the flames live for too long, IMO. That damage is insane too, if the units are all close to them. They would get OWNED. And especially with the time they last, anyone nearby is doomed :p

Yes, add locust, or was it meant to be able to control? Doubt it, but that would be cool.


My thoughts :) Good job.
 

Prometheus

Everything is mutable; nothing is sacred
Reaction score
589
The fireballs fly, I need to fix that and I will ASAP.
 

Prometheus

Everything is mutable; nothing is sacred
Reaction score
589
~-\|/Updated\|/-~
Check changelog for some of the changes
 

Prometheus

Everything is mutable; nothing is sacred
Reaction score
589
Its versatility
And the rest is on our IM conversation.
 

PurgeandFire

zxcvmkgdfg
Reaction score
509
Fan of knives doesn't use specific projectiles. That's what makes this better. The actual fan of knives has an effect that actually plays its animation to make the effect, it isn't a bunch of projectiles.

I also believe fan of knives can't have a projectile speed.

And I think this one is homing, but I never looked.

@kc102:
Well, it seems you didn't correctly c'n'p my code:
JASS:
local location l = Location(cx,cy)
...
call RemoveLocation(l)
set l = null


This is bad because it wastes 3 whole lines and it isn't even being used! :p

Just remove this and you should be set to go! :D
 

PurgeandFire

zxcvmkgdfg
Reaction score
509
No, if I just use Location(cx, cy) it leaks.

But you don't even use it. xD

When I optimized you code, you used GetUnitsInRangeOfLoc or something like that. This creates a group and gets the units in range of the loc, but it is a BJ. So you made the "cx and cy" into a location. So I thought of removing the BJ. To remove it, did "local group g = CreateGroup()" then I just simply did "call GroupEnumUnitsInRange(g,cx,cy,blahblah)". So that means that I used "cx and cy" not the location so that location is useless thus can be removed. :D
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    How can you tell the difference between real traffic and indexing or AI generation bots?
  • The Helper The Helper:
    The bots will show up as users online in the forum software but they do not show up in my stats tracking. I am sure there are bots in the stats but the way alot of the bots treat the site do not show up on the stats
  • Varine Varine:
    I want to build a filtration system for my 3d printer, and that shit is so much more complicated than I thought it would be
  • Varine Varine:
    Apparently ABS emits styrene particulates which can be like .2 micrometers, which idk if the VOC detectors I have can even catch that
  • Varine Varine:
    Anyway I need to get some of those sensors and two air pressure sensors installed before an after the filters, which I need to figure out how to calculate the necessary pressure for and I have yet to find anything that tells me how to actually do that, just the cfm ratings
  • Varine Varine:
    And then I have to set up an arduino board to read those sensors, which I also don't know very much about but I have a whole bunch of crash course things for that
  • Varine Varine:
    These sensors are also a lot more than I thought they would be. Like 5 to 10 each, idk why but I assumed they would be like 2 dollars
  • Varine Varine:
    Another issue I'm learning is that a lot of the air quality sensors don't work at very high ambient temperatures. I'm planning on heating this enclosure to like 60C or so, and that's the upper limit of their functionality
  • Varine Varine:
    Although I don't know if I need to actually actively heat it or just let the plate and hotend bring the ambient temp to whatever it will, but even then I need to figure out an exfiltration for hot air. I think I kind of know what to do but it's still fucking confusing
  • The Helper The Helper:
    Maybe you could find some of that information from AC tech - like how they detect freon and such
  • Varine Varine:
    That's mostly what I've been looking at
  • Varine Varine:
    I don't think I'm dealing with quite the same pressures though, at the very least its a significantly smaller system. For the time being I'm just going to put together a quick scrubby box though and hope it works good enough to not make my house toxic
  • Varine Varine:
    I mean I don't use this enough to pose any significant danger I don't think, but I would still rather not be throwing styrene all over the air
  • The Helper The Helper:
    New dessert added to recipes Southern Pecan Praline Cake https://www.thehelper.net/threads/recipe-southern-pecan-praline-cake.193555/
  • The Helper The Helper:
    Another bot invasion 493 members online most of them bots that do not show up on stats
  • Varine Varine:
    I'm looking at a solid 378 guests, but 3 members. Of which two are me and VSNES. The third is unlisted, which makes me think its a ghost.
    +1
  • The Helper The Helper:
    Some members choose invisibility mode
    +1
  • The Helper The Helper:
    I bitch about Xenforo sometimes but it really is full featured you just have to really know what you are doing to get the most out of it.
  • The Helper The Helper:
    It is just not easy to fix styles and customize but it definitely can be done
  • The Helper The Helper:
    I do know this - xenforo dropped the ball by not keeping the vbulletin reputation comments as a feature. The loss of the Reputation comments data when we switched to Xenforo really was the death knell for the site when it came to all the users that left. I know I missed it so much and I got way less interested in the site when that feature was gone and I run the site.
  • Blackveiled Blackveiled:
    People love rep, lol
    +1
  • The Helper The Helper:
    The recipe today is Sloppy Joe Casserole - one of my faves LOL https://www.thehelper.net/threads/sloppy-joe-casserole-with-manwich.193585/
  • The Helper The Helper:
    Decided to put up a healthier type recipe to mix it up - Honey Garlic Shrimp Stir-Fry https://www.thehelper.net/threads/recipe-honey-garlic-shrimp-stir-fry.193595/

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top