• 🏆 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!

[vJASS]Simple Spawn System [v1.1b] - GUI FRIENDLY-

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
  • Like
Reactions: Zealon
Oh yes this is a remake of my other system in GUI Link which I will update soon enough :p

Requirements:

T32 by Jesus4Lyf

Some more information about the system:

The system is meant to be very very simple to use. It's very simple made and provides with a few functions.

I kept all the features of the GUI version and I made them better, fixed some bugs with special effect and collision and a huge performance upgrade due to vJASS less BJs and such (it doesn't contain any BJ).

More information is inside the trigger and I also have a heavy documentation trigger where everything is explained to you!

Also ofc a nice GUI example which GUI users can use.

The system provides with these functions.

JASS:
    function CreateSpawnWave takes integer unitid, integer waves, integer amount, real x, real y, real rmin, real rmax, real face, player owner, boolean collision, string eff returns SpawnSystem

    function CreateSpawnWaveLoc takes integer unitid, integer waves, integer amount, location loc, real rmin, real rmax, real face, player owner, boolean collision, string eff returns SpawnSystem

    function CreateSpawnWaveConstant takes integer unitid, integer waves, integer amount, real x, real y, real period, real face, player owner, boolean collision, string eff returns SpawnSystem

    function CreateSpawnWaveConstantLoc takes integer unitid, integer waves, integer amount, location loc, real period, real face, player owner, boolean collision, string eff returns SpawnSystem

    //BELOW ARE THE EX FUNCTIONS
    
    function CreateSpawnWaveEx takes integer unitid, integer waves, integer amount, real x, real y, real rmin, real rmax, real face, boolean collision, string eff returns SpawnSystem
    
    function CreateSpawnWaveExCoord takes integer unitid, integer waves, integer amount, real rmin, real rmax, real face, boolean collision, string eff returns SpawnSystem
    
    function CreateSpawnWaveExAll takes integer unitid returns SpawnSystem

and let's have some features so we can explain what Ex functions are:

  • Supports spawning type (w00t awesome)
  • Supports spawning amount each interval
  • Supports interval
  • Supports amount of units aka waves you want to spawn them
  • Supports location (converted to coordinates later but for the GUIers)
  • Supports random interval between spawning and constant interval as well
  • Supports the facing of the spawning unit
  • Collision WITHOUT BUG
  • Spawning Effects WITHOUT BUG
  • Very easy to apply and import
  • Very useful for TD and AOS maps and hero defenses as well
  • Heavyily documentated

Those were standard except for the bug fix and coordinate conversion. Let's see some new features about the Ex functions.

These functions are made with some predefined globals, which mean that every argument except unittype in function CreateSpawnWave is premade in function CreateSpawnWaveExAll. Awesome huh?

Where is the damn code?!

alright alright it's down here:

JASS:
library SimpleSpawnSystem requires T32
//
//      *Simple Spawn System*
//          by baassee
//
//      *Requirements*
//          T32 by Jesus4Lyf
//
//      *Standard information*
//
//          A perfect system for TDs, AOSes, hero defences etc. It can create waves that spawn
//          different amount of units. Waves are of course chooseable and you can also choose
//          if you want the units to have no collision or maybe a different owner. This is a bit
//          different towards my other system yet it's the same but with more features and better
//          coding. The system have a few globals which starts with SPAWN"LETTERS". These are used
//          for the the functions which ends with an "Ex". Basically if the spawnings like in mauls
//          ,tds the owner of the creeps are the same so you can set this to this "player" and the
//          system will use this and you will have less arguments to think of, nice huh?
//
//          I remade my Simple Spawn System in GUI into vJASS, this means that the system
//          exists in GUI too for those who want it yet it will be a huge performance
//          increaser to use this system but of course it won't matter which one you choose
//          they will do exactly the same thing.
//
//          After v1.1b, the spawnsystem uses J4L's T32 Which is the best timer system out there
//          please beaware that the period is no longer choose able but instead this is a
//          major performance increase.
//
//          Read the how to import below and read about the functions and how to use them.
//          I also showed in an example how to use this in GUI as this is GUI-Friendly.
//
//
//      *How to import*
//
//          1. Copy over T32, either the trigger in this category or from here:
//             http://www.thehelper.net/forums/showthread.php/132538-Timer32
//
//          2. Copy over this trigger. Follow the setup below this section for extra
//             configurations.
//
//          3. Credit me for this system and Jesus4Lyf for T32.
//
//          4. Now you are done! You can now use the system!
//
//
//      *SETUP PART*
//

    globals
        //where the effect is attached to a spawned unit
        
        private constant string ATTACH              = "origin"
//
//      BELOW HERE YOU CAN SET SOME CONSTANT GLOBALS WHICH ARE USED FOR THE FUNCTIONS
//      WHICH ENDS WITH "Ex". They are used to predefine all stuff except the unit type.
//      Also there are more than one "Ex" function for your needs.
//
//      As example I've chosen Lightblue just for the example but just change the number "9"
//      to the number of the player.
//      REMEMBER! that player red is number 0 and blue number 1 and so on.
//
        private constant player SPAWNPLAYER         = Player(9)
//
//      The interval between each "wave" of spawnings. This is used if you want
//      a constant spawning flow. Useful I guess.
//
        private constant real SPAWNINTERVAL         = 1.5
//
//      The x coordinate which the units will spawn on, if you have multiple spawning coordinates
//      but still wants to use the Ex functions use the normal Ex function.
//
        private constant real SPAWNX                = 894.
//
//      The y coordinate which the units will spawn on. Same as above.
//
        private constant real SPAWNY                = -1276.
//
//      The spawns facing angle, please have a value between 0 and 360.
//
        private constant real SPAWNFACE             = 180.
//
//      The spawn amount each interval, prefer 1. Won't bug with more of course.
//
        private constant integer SPAWNAMOUNT        = 1
//
//      The amount of spawn waves, this can be a bit tricky if you have a boss stage
//      so use another function for the boss in that case.
//
        private constant integer SPAWNWAVES         = 10
//
//      If spawned units should have collision or not.
//
        private constant boolean SPAWNCOLLISION     = false
//
//      If you want a special effect when the unit is spawned, set it here else just set it to ""
//
        private constant string SPAWNEFFECT         = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl"
    endglobals
    
    private struct SpawnSystem
        //members that the create method takes
        integer     id //the unit id
        integer     w // the amount of waves
        integer     am// spawn amount per spawning, usually 1
        real        sx// spawn x coordinate
        real        sy// spawn y coordinate
        real        rmin// random minimum value
        real        rmax// random maximum value
        real        face// the facing of the spawned unit
        player      owner// the owner of the spawned unit
        boolean     coll = true // if the collision should be turned on
        string      eff = ""//the spawning effects
                                // initially it's on
        //members which is just inside the struct
        real        count = 0. //just a count variable
        real        dur        //the duration of each spawning interval
        boolean     multi = false// if the units are more than 1, initially false
        
        //the loop method
        private method periodic takes nothing returns nothing
            local integer i // and integer used if the .multi member is true else not
            // ordinary if to check if the instance has ended or not
            //it ends when the number of waves equals to 0
            if .w > 0 then
                //if not we do another check if we should spawn a unit
                //or just increase the count member
                if .count >= .dur then
                    // if it has reached or are above we reset the count
                    set .count = 0.
                    set .w = .w - 1 //reduces amount of waves
                    // now we check if the amount is bigger than 1
                    // which is what we set into the multi member
                    if .multi then
                        set i = .am // here we use the integer i
                        // we loop threw amount of spawned units
                        loop
                            exitwhen i == 0 // i is used for this cause
                            // creates unit
                            // the bj is used for the pathing 
                            set bj_lastCreatedUnit = CreateUnit(.owner, .id, .sx, .sy, .face)
                            // if collision should be off then we set the pathing of the unit to false
                            if not .coll then
                                call SetUnitPathing(bj_lastCreatedUnit, false) //which we do here
                            endif
                            if .eff != "" then
                                call DestroyEffect(AddSpecialEffectTarget(.eff, bj_lastCreatedUnit, ATTACH))
                            endif
                            // reduce i so the loop can end
                            set i = i - 1
                        endloop
                        //else we check some other stuff like not collision
                        //to set the unit into the variable so we do like this
                    else
                        set bj_lastCreatedUnit = CreateUnit(.owner, .id, .sx, .sy, .face)
                        call SetUnitPathing(bj_lastCreatedUnit, .coll)
                    endif
                    //check the effect stuff
                    if .eff != "" then
                    //we create the effect if needed
                        call DestroyEffect(AddSpecialEffectTarget(.eff, bj_lastCreatedUnit, ATTACH))
                    endif
                    // here is just a check if the interval is constant
                    // else we just re-set the interval to a new randomized value
                    if .rmin != .rmax then
                        set .dur = GetRandomReal(.rmin, .rmax)
                    endif
                else
                // if the count isn't above the interval
                // we increase it
                    set .count = .count + T32_PERIOD
                endif
                // if the instance has ended, we recycle
            else
                call .stopPeriodic()
                call .destroy() // and the struct
            endif // that was it! like I said, simple.
        endmethod
        //the spawn system create method
        static method create takes integer unitid, integer waves, integer amount, real x, real y, real rmin, real rmax, real facing, player owner, boolean collision, string eff returns thistype
            local thistype this = thistype.allocate() //initiallies
            //below we set necessary information into our struct members
            set .id = unitid //the id of the unit type
            set .w = waves // amount of waves
            set .am = amount // amount of spawnings each "wave"
            //just some performance and bug fixes with collision
            if amount > 1 then
                set .multi = true //used if the amount spawned are greater than 1
            endif
            // spawn coordinates
            set .sx = x //x coordinate
            set .sy = y //y coordinate
            // this is used for our feature "random spawning interval"
            // uses min value and max value for GetRandomReal.
            // if it's constant, it's checks a few lines below
            set .rmin = rmin //the minimum value
            set .rmax = rmax //the maxium value
            set .face = facing //facing of the spawned unit
            set .owner = owner //the owner of the spawned unit
            //checks if the effect string is not nothing so we can store the string.
            if eff != "" then
                set .eff = eff
            endif
            // as collision is set to true by default
            //I'll set the collision anyways
            set .coll = collision
            // here are some debugging
            // if the minimum value is greater than the max value
            // it resets the min value with a random value added
            if rmin > rmax then
                set .rmin = rmax - GetRandomReal(0., rmax - 1)
                // debug message
                debug call BJDebugMsg("Spawn System Error - Your random minimum value was greater than the max value.")
            endif
            // here comes the check if the intervals are constant
            // if not then we just randomize the duration
            if rmin != rmax then
                set .dur = GetRandomReal(rmin, rmax)
            else // else we set it to the rmin
                set .dur = rmin
            endif
            call .startPeriodic()
            // now we're done, move on to the loop!
            return this
        endmethod
        implement T32x
    endstruct
    
    function CreateSpawnWave takes integer unitid, integer waves, integer amount, real x, real y, real rmin, real rmax, real face, player owner, boolean collision, string eff returns SpawnSystem
        return SpawnSystem.create(unitid, waves, amount, x, y, rmin, rmax, face, owner, collision, eff)
    endfunction
    
    function CreateSpawnWaveLoc takes integer unitid, integer waves, integer amount, location loc, real rmin, real rmax, real face, player owner, boolean collision, string eff returns SpawnSystem
        return SpawnSystem.create(unitid, waves, amount, GetLocationX(loc), GetLocationY(loc), rmin, rmax, face, owner, collision, eff)
    endfunction
    
    function CreateSpawnWaveConstant takes integer unitid, integer waves, integer amount, real x, real y, real period, real face, player owner, boolean collision, string eff returns SpawnSystem
        return SpawnSystem.create(unitid, waves, amount, x, y, period, period, face, owner, collision, eff)
    endfunction
    
    function CreateSpawnWaveConstantLoc takes integer unitid, integer waves, integer amount, location loc, real period, real face, player owner, boolean collision, string eff returns SpawnSystem
        return SpawnSystem.create(unitid, waves, amount, GetLocationX(loc), GetLocationY(loc), period, period, face, owner, collision, eff)
    endfunction
    
    function CreateSpawnWaveEx takes integer unitid, integer waves, integer amount, real x, real y, real rmin, real rmax, real face, boolean collision, string eff returns SpawnSystem
        return SpawnSystem.create(unitid, waves, amount, x, y, rmin, rmax, face, SPAWNPLAYER, collision, eff)
    endfunction
    
    function CreateSpawnWaveExCoord takes integer unitid, integer waves, integer amount, real rmin, real rmax, real face, boolean collision, string eff returns SpawnSystem
        return SpawnSystem.create(unitid, waves, amount, SPAWNX, SPAWNY, rmin, rmax, face, SPAWNPLAYER, collision, eff)
    endfunction
    
    function CreateSpawnWaveExAll takes integer unitid returns SpawnSystem
        return SpawnSystem.create(unitid, SPAWNWAVES, SPAWNAMOUNT, SPAWNX, SPAWNY, SPAWNINTERVAL, SPAWNINTERVAL, SPAWNFACE, SPAWNPLAYER, SPAWNCOLLISION, SPAWNEFFECT)
    endfunction
endlibrary

That's it?

Of course not, here is the documentation trigger, beware, can hurt your eyes!

JASS:
    *Simple Spawn System vJASS*
        by baassee
            
    Documentation starts below:
    
    What are the requirement to use this system?
    
    The only requirement is the library TimerUtils made by Vexorian.
    You can either copy the TimerUtils trigger or you go into wc3c.net and search in the
    resources -> code resources -> scripts and search there.
    
    How does the random/constant interval work?
    
    Well first of all it uses the function GetRandomReal which takes a low value and a high value
    its the same as GUI Math - Random Number. Basically the RMin value is the low value and RMax
    value is the high value. This will create a random interval each wave. But also you can set both
    to the same value which the system will threat as constant interval and just make it a little simplier.
    That is how the random/constant interval works.
    
    How the system works?
    
    The system is completly made in vJASS, a remaked version of my GUI system. That system had some bugs
    which have been fixed in this version, also this version doesnt contain any BJs and have a much
    better performance than the GUI version although this system is meant to be used by anyone
    from GUIers to vJASSers.
    
    Alright the API aka all the functions this system provides the user with.
    
    function CreateSpawnWave takes integer unitid, integer waves, integer amount, real x, real y, real rmin, real rmax, real face, player owner, boolean collision, string eff returns SpawnSystem

    function CreateSpawnWaveLoc takes integer unitid, integer waves, integer amount, location loc, real rmin, real rmax, real face, player owner, boolean collision, string eff returns SpawnSystem

    function CreateSpawnWaveConstant takes integer unitid, integer waves, integer amount, real x, real y, real period, real face, player owner, boolean collision, string eff returns SpawnSystem

    function CreateSpawnWaveConstantLoc takes integer unitid, integer waves, integer amount, location loc, real period, real face, player owner, boolean collision, string eff returns SpawnSystem

    //BELOW ARE THE EX FUNCTIONS
    
    function CreateSpawnWaveEx takes integer unitid, integer waves, integer amount, real x, real y, real rmin, real rmax, real face, boolean collision, string eff returns SpawnSystem
    
    function CreateSpawnWaveExCoord takes integer unitid, integer waves, integer amount, real rmin, real rmax, real face, boolean collision, string eff returns SpawnSystem
    
    function CreateSpawnWaveExAll takes integer unitid returns SpawnSystem
    
    In my GUI example I use the "CreateSpawnWaveLoc" function which is made for GUI as you dont use
    locations in vJASS (except for heights).
    
    All functions are based on the first one and the functions which contains an "Ex" in it are for
    predefined stuff which you can read more about in the system trigger.
    
    The first one takes integer unitid. That is the unittype which in JASS will be an integer value.
    
    The second argument are integer waves. That is how many waves that should be spawned. More about
    this when I get to amount.
    
    Third argument is integer amount, which is the amount of units spawned each "wave". Lets get it straight:
    
    The waves defines how many waves which will be spawned. These waves will have an interval between them
    which you can read about later in this section. The amount is how many units that spawns when the
    interval reaches 0.
    
    Example
    
    5 waves will be like this * - * - * - * - * where the stars are when the interval reaches 0.
    
    When every star triggers, the waves are reduced by 1 and we spawn the "amount" of chosen
    unittype. So if we had the amount of 2, we would spawned 5 * 2 units aka 10 units totally.
    
    Next argument is real x which is the x coordinate the unit will spawn on. This doesnt the users
    that use the CreateSpawnWaveLoc function worry about but still for others.
    
    Next argument is real y which is as above but the y coordinate.
    
    The next TWO arguments are for the feature of random intervals. Hope you noticed that I said
    two arguments, the real RMin and real RMax. So this is how the random feature works:
    
    The interval is set to a random value between the rmin and rmax. If these are the same, the
    intervals will be constant and the system will threat it like that. However if the rmin is
    bigger than the rmax, the system will fix this issue on its own and just decrease the rmin with a
    enough high random value to make it lower than the rmax.
    
    Next argument is real face which is the facing of the spawned unit. Simple.
    I guess radians will work here.
    
    Next argument is player owner, the player which the units will be spawned for.
    
    Next argument is boolean collision which probably speaks for itself.
    True if you want the units to have collision and false for the other.
    
    Last argument is string eff which is the spawned effect that will be created at the origin
    of the spawned unit (this is ofc chooseable in the globals). Set it to "" for no special effect.
    
    Create a normal action create special effect, choose the model you want to spawn, now you will see
    a string. Copy that string:
    Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
    
    And you are done! Thanks to D4RK_G4NDALF for the bug

Now what?

You thought it was all over? Hell no, now the GUI example trigger with documentation and just a test trigger for the game! With in hidden tags


  • GUI TRIGGER
    • Events
    • Conditions
    • Actions
      • -------- Here is a full trigger which GUI'ers can use. --------
      • -------- It contains all the documentation you need and for easier use. --------
      • -------- You set all the needed values into GUI variables. --------
      • -------- Good huh? Let's start reading. --------
      • -------- First we have the unittype of the spawned unit. --------
      • -------- Set it to your needs --------
      • Set Type = Footman
      • -------- Now we have the waves, which are more explained in the --------
      • -------- Heavy documentation trigger but I'll explain it short. --------
      • -------- It's the amount of waves that will be spawned. --------
      • -------- When a wave triggers, it spawns "AMOUNT" units and reduces itself --------
      • -------- Set it to whatever you want to, it's more explained below amount --------
      • Set Waves = 15
      • -------- And here is the amount variable --------
      • -------- As said the amount stands for the amount of units spawned each wave trigger --------
      • -------- So just a simple example, if the wave is 30 and amount is 1 then it will spawn --------
      • -------- 1 unit each wave when it triggers total 30 units (30*1) --------
      • -------- If we have 30 waves and 2 amount then it will spawn 60 units and 2 units --------
      • -------- when a wave triggers --------
      • -------- it can be a plus to have collision off if you spawn more than 1 unit --------
      • Set Amount = 1
      • -------- The location where the units will be spawned at --------
      • -------- set whatever you want --------
      • Set TempLoc = (Center of (Playable map area))
      • -------- And here is another feature of the system --------
      • -------- random and constant intervals --------
      • -------- basic the time between each wave --------
      • -------- explained more in the heavy documentation --------
      • -------- here is the low value anyways --------
      • Set RMin = 1.00
      • -------- and ofc the high value --------
      • -------- with the values that I've set now in this test trigger GUI TRIGGER --------
      • -------- the intervals will be a random number between 1. and 4. seconds. --------
      • Set RMax = 4.00
      • -------- Here is the facing of the spawned unit --------
      • -------- basic any value between 0 and 360 --------
      • -------- I guess radians will work too --------
      • Set Facing = 180.00
      • -------- Now this is simple, the owner of the unit! Hard one! --------
      • Set Owner = Player 1 (Red)
      • -------- Next one is also simple, if the spawned units should have collision or not --------
      • -------- if amount is greater than 1 I suggest to set this as false --------
      • Set Collision = True
      • -------- The effect string --------
      • -------- special thanks to D4RK_G4NDALF for this one --------
      • Set Effect = Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
      • -------- and here we call the function of the system --------
      • -------- simple as that --------
      • -------- just copy this trigger to your map and use it --------
      • -------- ALSO REMEMBER IF YOU RENAME THE VARIABLES, YOU HAVE TO CHANGE THE CUSTOM SCRIPT TOO! --------
      • Custom script: call CreateWaveLoc(udg_Type, udg_Waves, udg_Amount, udg_TempLoc, udg_RMin, udg_RMax, udg_Facing, udg_Owner, udg_Collision, udg_Effect)
      • -------- ----------------------------- --------
      • -------- leak removal --------
      • Custom script: call RemoveLocation(udg_TempLoc)


And ofc the actual trigger that is used in-game with our Ex predefined awesome values!


  • Test Trigger 1
    • Events
      • Time - Every 15.00 seconds of game time
    • Conditions
    • Actions
      • Set Type = Peasant Custom
      • Game - Display to (All players) the text: New wave incomming!
      • Custom script: call CreateSpawnWaveExAll(udg_Type)


Yeah yeah it was really short the last one.

My own note:

If you don't get how to use this system, respond in this thread.

If you think this is just something among the spawn systems that are much better, yeah they probably are I haven't said otherwise, I just said that this one is simple.

If you use it, please for god's sake credit me and Vexorian for this (Vexorian for TimerUtils, me for the actual system!).

Special thanks goes to D4RK_G4NDALF for noticing my string mistake!

Enjoy using it!

~baassee

Keywords:
simple, spawn, system, by, baassee, remake, from, gui, to ,vjass, friendly, heavy, documentation
Contents

Spawn System vJASS v1.1b (Map)

Reviews
12th Dec 2015 IcemanBo: For long time as NeedsFix. Rejected. Bribe: Currently it would create the special effect twice on a unit the way you have the block set up, if .multi is true. So the second effect creation should be placed in the "else"...

Moderator

M

Moderator

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

Bribe:

Currently it would create the special effect twice on a unit the way you have the block set up, if .multi is true. So the second effect creation should be placed in the "else" block to prevent this handle waste.

T32x should be above the create method, remember that struct generate trigger evaluations to call methods that are below it, so it should still be located underneath the periodic method (.stopPeriodic() will always be a trigger evaluation, but it's unavoidable and really doesn't matter so much)

The nature of an "Ex" method is that it takes extra parameters from the ones that don't have it. The name "CreateSpawnWaveExAll" definitely doesn't fit. A more fitting would be to name "CreateSimpleSpawnWave" perhaps.
 
Level 19
Joined
Feb 4, 2009
Messages
1,313
comment.gif
-------- The effect string --------
empty.gif
join.gif
comment.gif
-------- you have to remember that in GUI there are one less \ in every slice --------
empty.gif
join.gif
comment.gif
-------- notice that this below has double \\ which is used --------
empty.gif
join.gif
comment.gif
-------- remember when you set this, have double \\! --------
empty.gif
join.gif
set.gif
Set Effect = Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl
  • SomeTriggerName
    • Events
    • Conditions
    • Actions
      • Set string = Abilities\Spells\Other\TalkToMe\TalkToMe.mdl
      • Set string = Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl
      • Special Effect - Create a special effect attached to the overhead of (Triggering unit) using Abilities\Spells\Other\TalkToMe\TalkToMe.mdl
=>
JASS:
function Trig_SomeTriggerName_Actions takes nothing returns nothing
    set udg_string = "Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl"
    set udg_string = "Abilities\\\\Spells\\\\Other\\\\TalkToMe\\\\TalkToMe.mdl"
    call AddSpecialEffectTargetUnitBJ( "overhead", GetTriggerUnit(), "Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl" )
endfunction

//===========================================================================
function InitTrig_SomeTriggerName takes nothing returns nothing
    set gg_trg_SomeTriggerName = CreateTrigger(  )
    call TriggerAddAction( gg_trg_SomeTriggerName, function Trig_SomeTriggerName_Actions )
endfunction
 
Level 14
Joined
Nov 18, 2007
Messages
1,084
Code Review

  • JASS:
    //      The spawns facing angle, please have a value between 0 and 360.
    //      I guess radians work too.
    Radians wouldn't work which is a weird design on Blizzard's part considering that practically everything else besides facing angle uses radians.
  • Personally, I would just use a loop without checking with .multi to make the code more readable and concise, but I guess your way could save performance.
  • JASS:
                        elseif not .coll then
                            set bj_lastCreatedUnit = CreateUnit(.owner, .id, .sx, .sy, .face) // this
                        else // else we have to do as in the loop
                            set bj_lastCreatedUnit = CreateUnit(.owner, .id, .sx, .sy, .face)
                            call SetUnitPathing(bj_lastCreatedUnit, false)
                        endif
    ->
    JASS:
                        else
                            set bj_lastCreatedUnit = CreateUnit(.owner, .id, .sx, .sy, .face) // this
                            call SetUnitPathing(bj_lastCreatedUnit, .coll)
                        endif
    You could keep the check for .coll but I feel that it's not really something to be worked over. After all, despite how unlikely this might be, people may actually want the unit's pathing to be off by default.
  • JASS:
                if not collision then
                    set .coll = collision
                endif
    I don't think the if is that useful, considering the point I mentioned before.
  • JASS:
                if eff != "" then
                    set .eff = eff
                endif
    This check could cause problems if .eff was already set to something other than "" by a previous struct usage. I would remove the check.
    Of course, if you want to keep the check, then eff should be initially "" when it's declared as a struct member.
  • JASS:
    set .rmin = rmin - (rmin - rmax) - GetRandomReal(0., rmax - 1.)
    ->
    JASS:
    set .rmin = rmax - GetRandomReal(0., rmax - 1.)
  • You may want to protect users from themselves if they make waves a negative number. A simple fix would be to just have this check: if .w > 0 then in the static method Loop.
It's not required, but it would be nice if you allowed the struct to be accessible outside of the library. This could allow users with some knowledge of vJass to be able to end spawning waves prematurely, like if a building was destroyed. If you plan on adding this feature, just make sure that the struct correctly cleans up everything, like releasing the timer.

You might also want to consider allowing your system to handle infinite waves instead of making the user type an extremely large number. If you didn't fix the negative number check mentioned as the last point, you could actually document that using a negative number results in infinite waves. Of course, this feature would be much more useful if the user had control over the struct.
 
Level 22
Joined
Nov 14, 2008
Messages
3,256
1. Radians wouldn't work which is a weird design on Blizzard's part considering that practically everything else besides facing angle uses radians.
2. Personally, I would just use a loop without checking with .multi to make the code more readable and concise, but I guess your way could save performance.
3.
JASS:
                    elseif not .coll then
                        set bj_lastCreatedUnit = CreateUnit(.owner, .id, .sx, .sy, .face) // this
                    else // else we have to do as in the loop
                        set bj_lastCreatedUnit = CreateUnit(.owner, .id, .sx, .sy, .face)
                        call SetUnitPathing(bj_lastCreatedUnit, false)
                    endif
->
JASS:
                    else
                        set bj_lastCreatedUnit = CreateUnit(.owner, .id, .sx, .sy, .face) // this
                        call SetUnitPathing(bj_lastCreatedUnit, .coll)
                    endif
You could keep the check for .coll but I feel that it's not really something to be worked over. After all, despite how unlikely this might be, people may actually want the unit's pathing to be off by default.
4.
JASS:
            if not collision then
                set .coll = collision
            endif
I don't think the if is that useful, considering the point I mentioned before.
5.
JASS:
            if eff != "" then
                set .eff = eff
            endif
This check could cause problems if .eff was already set to something other than "" by a previous struct usage. I would remove the check.
Of course, if you want to keep the check, then eff should be initially "" when it's declared as a struct member.
6.
JASS:
set .rmin = rmin - (rmin - rmax) - GetRandomReal(0., rmax - 1.)
->
JASS:
set .rmin = rmax - GetRandomReal(0., rmax - 1.)
7.You may want to protect users from themselves if they make waves a negative number. A simple fix would be to just have this check: if .w > 0 then in the static method Loop.

8.
It's not required, but it would be nice if you allowed the struct to be accessible outside of the library. This could allow users with some knowledge of vJass to be able to end spawning waves prematurely, like if a building was destroyed. If you plan on adding this feature, just make sure that the struct correctly cleans up everything, like releasing the timer.

9.
You might also want to consider allowing your system to handle infinite waves instead of making the user type an extremely large number. If you didn't fix the negative number check mentioned as the last point, you could actually document that using a negative number results in infinite waves. Of course, this feature would be much more useful if the user had control over the struct.

1. Fixed.

2. Nah I'll keep it :p

3. Fixed but I'd kept the collision as true initially :D

4. Fixed.

5. Made the member initially ""

6. Fixed.

7. Fixed.

8. I'll just add some takes Spawnsystem s functions to change all members of the current struct :) I thought of this too although I just recoded my other system into this so I forgot it.

9. Hmm this is a little bit tricky, I really like your idea but still I get the current "bug" with the .w != 0 although it's really nice to use as a infinite waver. Maybe I'll change it back to .w != 0 or add a member of some 'cause to make this check return true at all times.

But I'll add alot more functions to control the struct as mentioned :D

Thanks again for the awesome review!

This will take a little while for me to update, have some homework to do first.

This looks great, i will test it soon ;)

Thanks :D Check it out, it's much much better than the GUI one.
 
Level 13
Joined
Mar 13, 2010
Messages
1,172
This system is awesome, as far as know, the coding and triggers are good, and its extremely useful, 5/5 +rep

Also, testing it was quite amusing ^^
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,456
JASS:
    function CreateSpawnWave takes integer unitid, integer waves, integer amount, real x, real y, real rmin, real rmax, real face, player owner, boolean collision, string eff returns SpawnSystem
        return SpawnSystem.create(unitid, waves, amount, x, y, rmin, rmax, face, owner, collision, eff)
    endfunction
    
    function CreateSpawnWaveLoc takes integer unitid, integer waves, integer amount, location loc, real rmin, real rmax, real face, player owner, boolean collision, string eff returns SpawnSystem
        return SpawnSystem.create(unitid, waves, amount, GetLocationX(loc), GetLocationY(loc), rmin, rmax, face, owner, collision, eff)
    endfunction
    
    function CreateSpawnWaveConstant takes integer unitid, integer waves, integer amount, real x, real y, real period, real face, player owner, boolean collision, string eff returns SpawnSystem
        return SpawnSystem.create(unitid, waves, amount, x, y, period, period, face, owner, collision, eff)
    endfunction
    
    function CreateSpawnWaveConstantLoc takes integer unitid, integer waves, integer amount, location loc, real period, real face, player owner, boolean collision, string eff returns SpawnSystem
        return SpawnSystem.create(unitid, waves, amount, GetLocationX(loc), GetLocationY(loc), period, period, face, owner, collision, eff)
    endfunction
    
    function CreateSpawnWaveEx takes integer unitid, integer waves, integer amount, real x, real y, real rmin, real rmax, real face, boolean collision, string eff returns SpawnSystem
        return SpawnSystem.create(unitid, waves, amount, x, y, rmin, rmax, face, SPAWNPLAYER, collision, eff)
    endfunction
    
    function CreateSpawnWaveExCoord takes integer unitid, integer waves, integer amount, real rmin, real rmax, real face, boolean collision, string eff returns SpawnSystem
        return SpawnSystem.create(unitid, waves, amount, SPAWNX, SPAWNY, rmin, rmax, face, SPAWNPLAYER, collision, eff)
    endfunction
    
    function CreateSpawnWaveExAll takes integer unitid returns SpawnSystem
        return SpawnSystem.create(unitid, SPAWNWAVES, SPAWNAMOUNT, SPAWNX, SPAWNY, SPAWNINTERVAL, SPAWNINTERVAL, SPAWNFACE, SPAWNPLAYER, SPAWNCOLLISION, SPAWNEFFECT)
    endfunction

All of these need to be moved below the struct itself. Why? Extract your war3map.j file before and after and look at the difference. It's about five million lines of generated code difference.
 
... You made every single TD on this planet seem useless ... I bet Ralle's really pissed right now xD

This system makes it a lot easier to create TDs, but i'm not going to implement it :( sorry.

Your system can only support a STANDARD TD. But anyways, good job! :D 5/5

I was thinking of making a system like this, but when i saw it pop-up in the spells section, i changed my mind.
 
Level 22
Joined
Nov 14, 2008
Messages
3,256
... You made every single TD on this planet seem useless ... I bet Ralle's really pissed right now xD

This system makes it a lot easier to create TDs, but i'm not going to implement it :( sorry.

Your system can only support a STANDARD TD. But anyways, good job! :D 5/5

I was thinking of making a system like this, but when i saw it pop-up in the spells section, i changed my mind.

A TD without towers? Nah.

There is a GUI version too. Even if it's GUI Friendly -.-

So what's a standard TD? You can play with this alot in matter of fact.

Better with one more than one less.
 
Top