Name | Type | is_array | initial_value |
Amount | integer | No | |
Collision | boolean | No | |
Effect | string | No | |
Facing | real | No | |
Owner | player | No | |
Points | location | Yes | |
RMax | real | No | |
RMin | real | No | |
TempLoc | location | No | |
Type | unitcode | No | |
Waves | integer | No |
//TESH.scrollpos=36
//TESH.alwaysfold=0
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~ Timer32 ~~ By Jesus4Lyf ~~ Version 1.06 ~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// What is Timer32?
// - Timer32 implements a fully optimised timer loop for a struct.
// - Instances can be added to the loop, which will call .periodic every
// PERIOD until .stopPeriodic() is called.
//
// =Pros=
// - Efficient.
// - Simple.
//
// =Cons=
// - Only allows one period.
// - The called method must be named ".periodic".
//
// Methods:
// - struct.startPeriodic()
// - struct.stopPeriodic()
//
// - private method periodic takes nothing returns nothing
//
// This must be defined in structs that implement Periodic Module.
// It will be executed by the module every PERIOD until .stopPeriodic() is called.
// Put "implement T32x" BELOW this method.
//
// Modules:
// - T32x
// Has no safety on .stopPeriodic or .startPeriodic (except debug messages
// to warn).
//
// - T32xs
// Has safety on .stopPeriodic and .startPeriodic so if they are called
// multiple times, or while otherwise are already stopped/started respectively,
// no error will occur, the call will be ignored.
//
// - T32
// The original, old version of the T32 module. This remains for backwards
// compatability, and is deprecated. The periodic method must return a boolean,
// false to continue running or true to stop.
//
// Details:
// - Uses one timer.
//
// - Do not, within a .periodic method, follow a .stopPeriodic call with a
// .startPeriodic call.
//
// How to import:
// - Create a trigger named T32.
// - Convert it to custom text and replace the whole trigger text with this.
//
// Thanks:
// - Infinitegde for finding a bug in the debug message that actually altered
// system operation (when in debug mode).
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library T32 initializer OnInit
globals
public constant real PERIOD=0.03125
public constant integer FPS=R2I(1/PERIOD)
public integer Tick=0 // very useful.
//==============================================================================
private trigger Trig=CreateTrigger()
endglobals
//==============================================================================
// The standard T32 module, T32x.
//
module T32x
private thistype next
private thistype prev
private static method PeriodicLoop takes nothing returns boolean
local thistype this=thistype(0).next
loop
exitwhen this==0
call this.periodic()
set this=this.next
endloop
return false
endmethod
method startPeriodic takes nothing returns nothing
debug if this.prev!=0 or thistype(0).next==this then
debug call BJDebugMsg("T32 ERROR: Struct #"+I2S(this)+" had startPeriodic called while already running!")
debug endif
set thistype(0).next.prev=this
set this.next=thistype(0).next
set thistype(0).next=this
set this.prev=thistype(0)
endmethod
method stopPeriodic takes nothing returns nothing
debug if this.prev==0 and thistype(0).next!=this then
debug call BJDebugMsg("T32 ERROR: Struct #"+I2S(this)+" had stopPeriodic called while not running!")
debug endif
// This is some real magic.
set this.prev.next=this.next
set this.next.prev=this.prev
// This will even work for the starting element.
debug set this.prev=0
endmethod
private static method onInit takes nothing returns nothing
call TriggerAddCondition(Trig,Condition(function thistype.PeriodicLoop))
endmethod
endmodule
//==============================================================================
// The standard T32 module with added safety checks on .startPeriodic() and
// .stopPeriodic(), T32xs.
//
module T32xs
private thistype next
private thistype prev
private boolean runningPeriodic
private static method PeriodicLoop takes nothing returns boolean
local thistype this=thistype(0).next
loop
exitwhen this==0
call this.periodic()
set this=this.next
endloop
return false
endmethod
method startPeriodic takes nothing returns nothing
if not this.runningPeriodic then
set thistype(0).next.prev=this
set this.next=thistype(0).next
set thistype(0).next=this
set this.prev=thistype(0)
set this.runningPeriodic=true
endif
endmethod
method stopPeriodic takes nothing returns nothing
if this.runningPeriodic then
// This is some real magic.
set this.prev.next=this.next
set this.next.prev=this.prev
// This will even work for the starting element.
set this.runningPeriodic=false
endif
endmethod
private static method onInit takes nothing returns nothing
call TriggerAddCondition(Trig,Condition(function thistype.PeriodicLoop))
endmethod
endmodule
//==============================================================================
// The original T32 module, for backwards compatability only.
//
module T32 // deprecated.
private thistype next
private thistype prev
private static method PeriodicLoop takes nothing returns boolean
local thistype this=thistype(0).next
loop
exitwhen this==0
if this.periodic() then
// This is some real magic.
set this.prev.next=this.next
set this.next.prev=this.prev
// This will even work for the starting element.
debug set this.prev=0
endif
set this=this.next
endloop
return false
endmethod
method startPeriodic takes nothing returns nothing
debug if this.prev!=0 or thistype(0).next==this then
debug call BJDebugMsg("T32 ERROR: Struct #"+I2S(this)+" had startPeriodic called while already running!")
debug endif
set thistype(0).next.prev=this
set this.next=thistype(0).next
set thistype(0).next=this
set this.prev=thistype(0)
endmethod
private static method onInit takes nothing returns nothing
call TriggerAddCondition(Trig,Condition(function thistype.PeriodicLoop))
endmethod
endmodule
//==============================================================================
// System Core.
//
private function OnExpire takes nothing returns nothing
set Tick=Tick+1
call TriggerEvaluate(Trig)
endfunction
private function OnInit takes nothing returns nothing
call TimerStart(CreateTimer(),PERIOD,true,function OnExpire)
endfunction
endlibrary
//TESH.scrollpos=71
//TESH.alwaysfold=0
*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.
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
//TESH.scrollpos=0
//TESH.alwaysfold=0
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