System Key Timers 2

Blackrage

Ultra Cool Member
Reaction score
25
You know a long time ago I made a much better version of this system
(it is called Collections, you can find it on wc3c)

But the problem with macro systems is that people don't like textmacros.
Textmacros are not meant to be used by people anyways.
They are meant as a help tool for making systems and should be used only inside the system and invisible to the end users.

The war between the systems :nuts:
 

Cohadar

master of fugue
Reaction score
209
Then I guess I am the lames warlord of all times,
because after war with me most people end up having better army...
 

Jesus4Lyf

Good Idea™
Reaction score
397
The only reason I've kept the text macro is because it makes this system the most efficient, and keeps it easy to use (once learned).

Fair enough on the scope point (since libraries contain a scope anyway) but I won't update it properly for that.

Now I'm going to have to disagree about making it public. There's times I've had to use two Key Timers in a single system library (such as one for setting a camera, and one for checking if the camera should be changed to a different unit because the latter is a lot more process intensive and doesn't need to be executed as often). This isn't the only occasion. Making it public would make it so I couldn't do this. I like to keep it simple and efficient, and at the moment, this is. So I don't think I'll be making it a public function, and I don't think I'll be changing it from a text macro, because both of these impairs the system.

Oh, and I know my army is stronger now... :p
 

Cohadar

master of fugue
Reaction score
209
The only reason I've kept the text macro is because it makes this system the most efficient, and keeps it easy to use (once learned).
No I believe you don't know how to make it without a macro :p

Making it public would make it so I couldn't do this.
Whaaaaat? You need to read jasshelper documentation once again.
Search for SCOPE_PREFIX

I like to keep it simple and efficient, and at the moment, this is.
It is only efficient

Oh, and I know my army is stronger now... :p
Yeah but I got special units somewhere in the fog of war :D

I have a very important question now:
Do you realize your system fails if PERIOD > 0.5 ?
 

duyen

New Member
Reaction score
214
I actually got a laugh out of that...

Well I might update it some time. :)

Touché, Cohadar, touché.

Thanks for being the only person who actually responded to this at all... o_O

PS. $SUBJECT$TimerStart is used to register whether or not the timer is running, and needs to be started.

PPS. I just removed it because i figured that I can use $SUBJECT$TimerMax==1 instead (since it has 1 added to it just before checking). Also I understand why count down instead of up, but I can't be bothered right now.

He's also the only person with enough knowledge of JASS and beyond.

(Although I do know some C++, I don't know JASS)
 

Jesus4Lyf

Good Idea™
Reaction score
397
You saying this is beyond everyone else on the forum? o_O
I don't think so...

>Do you realize your system fails if PERIOD > 0.5 ?
Uhhhhh.... No? Why?

EDIT: Just tested it. Works fine.

EDIT: I'm not going to change it to scope prefix, if for no other reason, then because it fails at compatability with all the maps I've made.
 

Flare

Stops copies me!
Reaction score
662
confused

ok, im really confused by the system. im looking at the sample of the system where footmen are periodically spawned, but theres a few things i dont understand
JASS:
call AddSpawn(i)
call AddSpawn(spawninstance.create())

ive only seen those lines once between the part in the map header and in the spawn test. how exactly is that supposed to work, or is that just part of the magic of JASS?

also, what is the value for this?
JASS:
private constant real $SUBJECT$Period=$PERIOD$

was $PERIOD$ alredy defined somewhere?


its very confusing since everything looks like a variable, but there isnt any variables created in Variable Editor. from what i understand, the timer is always running? and that you are just adding different things to that timer via the text macro?

edit: do i need to use that library and struct stuff everytime i want to use the system?
 

Jesus4Lyf

Good Idea™
Reaction score
397
Sorry, I imagine that I should make a new demo map altogether. Those two AddSpawns are actually adding two seperate instances to the timer. The second one is just using the default of 5 units while the first sets it to 10 (or is the other way around, I forget). That's why it spawns 2 units at a time for a while, then one. Just neglect "call AddSpawn(spawninstance.create())". Or even comment it out to see what it does. :)

Don't worry about what's in the text macro too much. If you can understand it, fantastic, otherwise, it doesn't matter much. Just put the text macro somewhere in the Custom Script section ("map header") and then just use...
JASS:
//! runtextmacro KeyTimer("Subject","Period")

For example...
JASS:
//! runtextmacro KeyTimer("FireSpell","0.035")

And then you'd have a function (just above that line) defined as...
JASS:
private function DoFireSpell takes struct s returns boolean

And use...
JASS:
call AddFireSpell(struct)

to add an instance.

Refer to the examples to see how these go together. :)

$PERIOD$ is the second parameter of the "//! runtextmacro KeyTimer("Subject","Period")" line.

I gather you don't know how text macros work. They copy out the contents each time (when you hit save map) and replace the $FIELDS$ with what is entered into the //! run line.

You're nearly right about your understanding. The timers always exist, but they automatically pause and unpause themselves when nothing is added or when something is added and its paused. Yes, the structs are added and removed to the timer.

If you don't like using libraries and scopes and such, just put the //! runtextmacro line in a scope along with the DoSubject function. In other words, using the above...

JASS:
scope FireSpell
private function DoFireSpell takes struct s returns boolean
// Do things
return DoIWantThisStructToBeRemovedFromTheTimer
endfunction
//! runtextmacro KeyTimer("FireSpell","0.035")
endscope

Then just call AddFireSpell(struct) to add an instance (struct).

Hope that helps clear some things up...
 

Flare

Stops copies me!
Reaction score
662
is FireSpell the name of the trigger at the left side of trigger editor, or the name of the struct?

and for all AddFireSpell(struct), i just replaced 'struct' with my structs name?

edit: lets say i made a trigger called FireSpell, do i just add the section of code at the end of your post to the FireSpell trigger? would this require 2 triggers or just one and how exactly would i stop the effect from occuring after X amount of occurences?


btw, is this how you made your Fire spell in that Aeon of Strife map you made (i forget its name but it was cool for such a small and simple-looking game)


edit: i have a problem ^^ everything ive done seems to be right (im trying to make a periodic damage effect) but nothing happens...

JASS:
function Trig_Something_Conditions takes nothing returns boolean
        return (GetSpellAbilityId ()=='A000')
endfunction

//==========================================================================
library Thing
    struct thinginstance
        integer counter=5
    endstruct
    
    private function DoThing takes thinginstance i returns boolean
    call UnitDamageTarget ((GetTriggerUnit ()), (GetSpellTargetUnit ()), 10, false, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_ACID, WEAPON_TYPE_WHOKNOWS)
    call AddSpecialEffectTargetUnitBJ ("head", (GetSpellTargetUnit ()), "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl")
    call DestroyEffect (GetLastCreatedEffectBJ ())
        if i.counter==00 then
            call i.destroy ()
            return true
        endif
        return false
    endfunction
//! runtextmacro KeyTimer("Thing","0.5")
endlibrary
//===========================================================================
function Trig_Something_Actions takes nothing returns nothing
    local thinginstance i=thinginstance.create()
    set i.counter=10
    call AddThing (i)
endfunction

//===========================================================================
function InitTrig_Something takes nothing returns nothing
    set gg_trg_Something = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ (gg_trg_Something, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddAction( gg_trg_Something, function Trig_Something_Actions )
    call TriggerAddCondition (gg_trg_Something, Condition (function Trig_Something_Conditions) )
endfunction
 

Jesus4Lyf

Good Idea™
Reaction score
397
There, I made a demo map to demonstrate key timers in a simple spell that needs a timer for the effect. It would usually take me about 5-10 mins to make, but I was doing other stuff too, so sorry about the delay.

It's a little fire spell that actually looks like it burn units' heads off. Fully multi-instance. Leak free.

Also, you can change the period and it doesn't alter the spell in any way except how much fire is created. So have a play if you like. :D
 

Attachments

  • KeyTimersFireSpell.w3x
    15.8 KB · Views: 315

Jesus4Lyf

Good Idea™
Reaction score
397
Sorry about the delay. See the above post! And, yes , it's relatively commented. It should be relatively easy to follow, I hope. :)

Update... V1.4... Turns out sometimes Jass NewGen doesn't pick up on the private constant period variable as being private, and thus returns syntax errors. So I've made it non-private. No big deal.
 

Flare

Stops copies me!
Reaction score
662
ah, so you set the units within the scope and they are referred to by i.(var name)? what exactly is the i there for? is that just referring back to an integer, and if so, which integer exactly? ty for the demo man, uve been huge help :)

edit: oh, i is referring to local integer i in the stuff at map header, nvm :p


edit again: ownage, just made a periodic damage/fire effect trigger. once i get back from cinema, im gonna see what else i can make with this. so far, thumbs up for all the help you've given me with working the system
 

Jesus4Lyf

Good Idea™
Reaction score
397
Notice that function takes struct i?

That i is the struct that has been attached. i.varname are all the different variables attached through that struct. The reason the macro has "integer" instead of "struct" is because integers and structs are actually the same thing, so Key Timers passes it as an integer so that you don't have to tell it your struct type. When the integer is passed to the Do function it is converted back to a struct.

A struct, fyi, is just an integer that is plugged into global arrays using the struct.variable syntax. That's why it can be passed as an integer. Hope that info is useful.

Keep asking all your questions! :D

Edit: Just read your "edit again". I'm glad you've taken a liking to this system (+rep it? XD) and I hope it helps a lot. It's particularly useful for spells that move units and such, as well as special effects... I was thinking of making a spell that uses key timers to make fireballs, and then those fireballs are controlled by another key timer to make them fly around and such. So fireballs are launched over time, and controlled with a timed effect. Just an idea to get you thinking about some possibilities. Start small perhaps. ;)
 

Jesus4Lyf

Good Idea™
Reaction score
397
Yes. You just need to store the angle or x/y velocities in the struct.

I think you need to better understand what the i is and how it works.

When you attach a struct to the timer, it means from then on, every PERIOD seconds, DoSUBJECT will be called with that struct as the parameter, until it returns true. This is the equivilent of making a new timer that executes DoSUBJECT as a function, attaching the struct, and loading the struct at the start of the DoSUBJECT function as "i", and returning true is the equivilent of detaching the struct and destroying the timer (you need to destroy the struct yourself first). The difference is, that this is by far more efficient, and once learned, faster to set up. :D

Hope that helps.
 

Flare

Stops copies me!
Reaction score
662
ok, im having a weird problem with my second spell using Key Timers that i didnt have with the first... for some reason, when i save the map its saying that the call Add<library name> is an undeclared variable, but i havent an idea why. when i refer back to the code for first spell, i dont see what could be wrong

JASS:
//==========================================================================
library Knockback
    struct kbinstance
        integer noname
        unit kbuser
        unit kbtarget
        real time=2.0
        location targetloc
        location pushloc
        location casterloc
        real kbangle
    endstruct
    
    private function DoKnockback takes kbinstance i returns boolean
        set i.targetloc=(GetUnitLoc (i.kbtarget))
        set i.pushloc=PolarProjectionBJ (i.targetloc, 10, i.kbangle)
        call SetUnitPositionLoc (i.kbtarget, i.pushloc)
        call RemoveLocation (i.pushloc)
        call RemoveLocation (i.targetloc)
        set i.time=i.time-0.035
            if i.time&lt;=0 then
                call i.destroy ()
                    return true
                        endif
                    return false
    endfunction
//! runtextmacro KeyTimer(&quot;Knockback&quot;,&quot;0.03&quot;)
endlibrary
//==========================================================================
function Trig_Single_target_knockback_Actions takes nothing returns nothing
    local kbinstance i=kbinstance.create ()
    set i.kbuser=(GetTriggerUnit ())
    set i.kbtarget=(GetSpellTargetUnit ())
    set i.casterloc=(GetUnitLoc (i.kbuser))
    set i.targetloc=(GetUnitLoc (i.kbtarget))
    set i.kbangle=AngleBetweenPoints (i.casterloc, i.targetloc)
    call RemoveLocation (i.casterloc)
    call RemoveLocation (i.targetloc)
    call AddKnockback (i)// error on this line &quot;undeclared variable&quot;
endfunction
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      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