1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Melee Mapping contest #3 - Poll is up! Vote for the best 4v4 melee maps!
    Dismiss Notice
  3. The 30th edition of the Modeling Contest is finally up! The Portable Buildings need your attention, so come along and have a blast!
    Dismiss Notice
  4. We have a new contest going on right now! Join the 11th Music Contest! You are to make a Cinematic modern sound-track for this contest, so come and compete with other people for fun.
    Dismiss Notice

Time Warp - Revisited

Submitted by Bribe
This bundle is marked as approved. It works and satisfies the submission rules.
Basic idea by teuncreemers. Inspired by writing complex 2-D arrays, I made Time Warp a group spell by using 2D arrays within a hashtable. This spell is fully-MUI and heavily bug-proofed.

Launch this spell on a target area and you have them right where you want them! Units that attempt to flee will be attacked by the magic of the portal; units that stick around are at your mercy... there is no escape!

Video


A fleet of inter-dimensional banshees haunt the targets in a select area until the link collapses, thrusting each victim back through time, retracing their steps.

Magic lasts longer and has higher Area of Effect at each level.

Credits:
- Berb for Projectile, Knockback Lite
- Grim001 for AutoIndex and AutoEvents
- Anitarf for Vector

Spell requires Warcraft 3 patch 1.30, extensive modification for Projectile (to use Effect type instead of Unit) and slight modification for AutoIndex (player count increase) and Vector (replace null return value with 0).

Keywords:
Time, warp, travel, system, machine, original, spell, bribe, teuncreemers, vjass, Zinc, fun, high, performance, versatile, youtube
Contents

Time Warp (Map)

Reviews
Moderator
11:11, 26th May 2010 The_Reborn_Devil: The coding looks very good and it's well documented. Many constants which allow users to change it too. The effects are neat as well. Status: Approved Rating: Highly Recommended
  1. 11:11, 26th May 2010
    The_Reborn_Devil:

    The coding looks very good and it's well documented. Many constants which allow users to change it too. The effects are neat as well.


    Status: Approved
    Rating: Highly Recommended
     
  2. Lambdadelta

    Lambdadelta

    Joined:
    Jul 6, 2009
    Messages:
    730
    Resources:
    1
    Maps:
    1
    Resources:
    1
    -Why not just use SpellEvent or GTrigger? It saves having people to use 'yet' another system.
    -Your struct name is a bit ... strange. A? Something like data is much better.
    -Timer period is 0.01, 100 FPS is a bit too much, something like 0.03125 works.
    -Effects should be customizable.
    -GetDurationFromLevel() should be at the top of the script in configurables section. Make it a function if you must.
    -Why the hell are you using hashtables in a struct? Use TimerUtils or KeyTimers2 to pass data, it is much more cleaner looking.
    -Make the entire if line:
    if IsUnitEnemy() and 
    etc a configurable function at the top... so it'd be ValidateUnit( unit )....
    -Actually, unsure whats better, but use a filter method and do the 'actions' in there.

    ----------------------------------------------

    -Spell is terrible looking right now, Units collide each other resulting in ugly movement, either turn collision off or use SetUnitX/Y.
    -The spell idea is basically a 'Blink Back' or 'X Marks the Return' from DotA. Not particularly original.
     
  3. Sephalo

    Sephalo

    Joined:
    Oct 12, 2007
    Messages:
    1,791
    Resources:
    0
    Resources:
    0
    There goes my concept:(
     
  4. D4RK_G4ND4LF

    D4RK_G4ND4LF

    Joined:
    Feb 4, 2009
    Messages:
    1,196
    Resources:
    20
    Models:
    3
    Spells:
    15
    Tutorials:
    2
    Resources:
    20
    I agree with most points except with the last statement
    it's called "X marks the Spot" and this one is aoe and moves the unit back over the path it went there instead of just instantly teleporting it which leads me to the conclustion that's not just a cheap copy but a a very nice idea
    (well..mostlikely it would be even better with SetUnitX/Y as mentioned already)

    I'm not much into JASS so I'm not sure but aren't these libaries just wrapper functions for hashtables?
     
  5. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,723
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    I posted that at (my) 3:00AM so there isn't much going through my mind at that stage, and went to bed 5 minutes later. If I had posted it at a human hour, I wouldn't have missed that key note. I have to sincerely apologize.

    This is your idea, I've put that at the top of the spell, but I've also read about a lot of timetravel spells similar in principle to this one so by making it open source (since I did all the code anyway and I am a strong believer in open source) I don't see it as a problem. I've noted that this is your basic concept at the top of the description.

    Have you tried either spell, yet? I asked you if it worked and you didn't reply back.
     
  6. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,723
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    I don't use other systems. Ooooh 15 lines of easy code is suddenly a huge complex system that no one will ever understand. Really? TimerUtils is hundreds of lines, yet I could do everything I need just by good coding and my whole spell would be the same length as the stupid system.

    Thanks, i am new to structs. I think i'll use data from now on.
    Normally, yes, but in this case not.
    This spell is basic. A lot of things compacted into the fewest lines possible. For now it is what it is, hence 1.0. Later, I'll add UI-friendly features.

    lol, there is no way those can contain the massive amounts of unit-specific data I'm storing in that one hashtable. Again, I don't use other peoples' 500 lines of code overglorified systems. I just get the job done with maximum compatibility within the scope of the spell and to not cause lag.
    Yeah, I need to return it to SetX/Y, thing is I need the units to stand still during the callback process so I used SUP for convenience (Though when you bring it to my attention I should just add a "stop" command manually and go back to setunitx/y)
     
  7. Sephalo

    Sephalo

    Joined:
    Oct 12, 2007
    Messages:
    1,791
    Resources:
    0
    Resources:
    0
    Yeah I tried the spell and it worked fine.
    The thing was that I wanted to make this spell myself just to make my first real jass spell on my own. You made it for me which was great to learn stuff a bit but in the end I was planning to make this spell on my own anyway.
    I'm not mad or something, just a littlebit disappointed:p
     
  8. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,723
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Map & code updated with some configurables added and changed SetUnitPosition so it flows more smoothly.
     
  9. Inferior

    Inferior

    Joined:
    Nov 3, 2008
    Messages:
    110
    Resources:
    3
    Icons:
    1
    Spells:
    2
    Resources:
    3
    Ok. Sum Feedback. As xBlackrose said don't use hashtables. For that i recommend you to use another struct in combination with Tables by Vexorian. Do sth like this
    [jass="code"]struct data
    //your variables which needs to be saved go here
    static HandleTable "blub"
    static method get takes unit u returns data
    return "blub"
    endmethod

    static method create unit u returns data
    local data a=data.create()
    set "blub"=a
    return a
    endmethod

    endstruct[/jass]

    the HandleTable can be created in the Init function

    But as you havent mentioned yet, that you don't want to use others libs, you can use UnitUserData aswell, but that may malfunction with other peoples maps.

    you should know that hashtables are 2x slower than arrays ( structs )

    Common. That Spell Indexer library is just nonsense. What you do there is like A BJ of the TriggerRegisterAnyUnitEventBJ (lolz) no need to use this.

    Don't use bj_LastCreatedGroup. This may end up in a conflict, because it can be used anywhere else and then your group has more units as it actually should have to.
    FirstOfGroup loops are slow. Use a filter function to detect units.


    I will add more later, bit tired atm.
     
  10. War_Golum

    War_Golum

    Joined:
    Jan 12, 2010
    Messages:
    756
    Resources:
    7
    Models:
    3
    Icons:
    4
    Resources:
    7
    I agree with Bribe
     
  11. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,723
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Common knowledge. However, I need an array of essentially infinite size, and you can't do that without hashtables or some way of generating dozens to hundreds of extra arrays.[/quote]

    Unlike the BJ, this only registers events to players that are actually playing, so you're saving a lot of handles. Btw you type like a child.

    Thanks, I will change this when I get home :)
    I have a feeling you're dissecting much of my code without realizing why I'm doing it like that (such as the hashtables).
    Edit: On second look (now that I'm home) it turns out you are right here. I originally had some operators there that I thought would benefit more from inlining the code, but you're right :) Thanks again.
     
    Last edited: May 8, 2010
  12. Lambdadelta

    Lambdadelta

    Joined:
    Jul 6, 2009
    Messages:
    730
    Resources:
    1
    Maps:
    1
    Resources:
    1
    It does everything you need on its own with just a function call, it removes the need of having to do what you do, i'll potentiallly get tiresome repeating for every spell. Also, if you are uploading it to a public spell section, other people use such 'stupid' systems, and will want to use it.

    Set to configurable

    Public resource forum.

    Why are you having a stop order anyways? Stopping order is essentially recalcuating pathing, which results in the ugly movement. You didn't change much visual wise in this aspect, it still yields same result. If you want a unit to not be able to issue orders, use SetUnitPosition and turn collision off. But then again, users should be able to decide if this spell interrupts channeling or not.

    I have an ownership changing spell, it changes ownership to a random player, then it orders the target to spam all its spells on the a random area, wasting it, but, it somehow changes the ownership into an unused slot. And in result, it does not work as it's not registered for that player.

    --

    -I have LOC_FX_B set to "", I want not effect, yet handles are being wasted as an empty effect is being created.
    -Every if dependent on a constant boolean should be static, so it's not compiled, = effeciency
    -Ambience should be configurable, the colours and crap.
    -Since you insist on using as least handles as possible, add an if for each effect:

    Code (vJASS):
    if STRING_EFFECT != "" then
        call DestroyEffect( AddSpecialEffect() )
            endif
    - Area should be configurable.

    - return untrue, why not use false, it does the same thing.
    - o_O, duration should be in seconds. And should return a real.
    - Actually, your entire spell is messy, seriously, what the heck, modular?, tab?, released?, indeed (why not 'true'), I'm lost as to how it functions. And where you calculate how long until 'release back to normal' state.

    Gameplay wise:
    - Fog is somewhat strange how it is instant, add an option for fading it.
    - Have an area of effect indicator for the spell, which means new base spell, use Channel.

    --

    So too can alot of spells.

    Every public spell is open source .__. why state that it is?
     
    Last edited: May 8, 2010
  13. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,723
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Total code nazi O_O
     
  14. Cihparg

    Cihparg

    Joined:
    Jul 4, 2008
    Messages:
    958
    Resources:
    1
    Models:
    1
    Resources:
    1
    . . . Stop teh flame, Even I don't know anything of vJass, I have to say this:
    If he wants to make everything by himself and not to use stuff by other people, then he can do it.
    vJass is not probably about copying from other people. (Which seems to be atm the way everyone is doing)

    ~ Thanks for dropping my IQ, I normally don't even post on a vJass spell.
     
  15. Lambdadelta

    Lambdadelta

    Joined:
    Jul 6, 2009
    Messages:
    730
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Oops. Dunno what I was thinking, X Marks the Spot it is, mistake lol. But still, the only difference between this and DotA's is area of effect and that it is not instant.

    I am not a code nazi :(

    I'm MRFAN1231, and I'm a Bomb.

    Flaming? I see none.

    Of course he can, but then why would he upload it for other people to use? He's letting 'other people' use it.

    What?

    --

    For the spell, maybe you should add lightning effects, or just something that link's the unit to it's original position. To show where it will 'return to'. Also, since this spell will serve some use as it's DotA related and people love DotA. Maybe you would want to add a 'Force Return' spell, all the linked units will move back to the original spot.
     
  16. Cihparg

    Cihparg

    Joined:
    Jul 4, 2008
    Messages:
    958
    Resources:
    1
    Models:
    1
    Resources:
    1
    This is a spell, not a system.
    If people take the systems he has made out, its they'r decision. He made this as a spell, for people to copy it fully.
     
  17. Lambdadelta

    Lambdadelta

    Joined:
    Jul 6, 2009
    Messages:
    730
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Alright, it's up to him anyways, but just fix the ownership issue. Ok. Disregarding that, move onto the other problems I have mentioned :)
     
  18. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,723
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Spell updated with youtube video and version 1.03 =)
     
  19. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,415
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    Nice job overall. Neat spell. =)

    However, some notes on the code:
    Code (vJASS):
        constant boolean untrue = not true
        constant boolean indeed = not untrue


    Any particular need of this? =P

    Also, for the spell indexer problem, this:
    Code (vJASS):
        private function Init takes nothing returns nothing
            call CreateSpellTrigger(function data.Conditions)
            static if CHANGE_AMBIENCE then
                set fadeTimer = CreateTimer()
                call InitFadeValues()
            endif
        endfunction


    Could be:
    Code (vJASS):

    library TimeWarp initializer Init requires optional SpellIndexer
    //...

    private function Init takes nothing returns nothing
            local trigger t = null
            static if LIBRARY_SpellIndexer then
                call CreateSpellTrigger(function data.Conditions)
            else
                set t = CreateTrigger()
                call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
                call TriggerAddCondition(t,Condition(function data.Conditions))
            endif
            static if CHANGE_AMBIENCE then
                set fadeTimer = CreateTimer()
                call InitFadeValues()
            endif
        endfunction


    In case someone forgets to import the library or generally doesn't want to. If it is optional that'll fix the problem and make it less reliant.

    Also:
    Code (vJASS):
            if FX != "" then
                call DestroyEffect(AddSpecialEffect(FX,x,y))
            endif


    Should be static. Since it is a constant string, it won't be modified outside the scope and thus the evaluation will have the same result each time on execution.

    You could always use a linked list for speed with the timer, but that is up to you. It doesn't make much of a difference besides nanoseconds though. (and readability compared to the struct/stack loop)

    Overall, nice job. =D I like this spell.