1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. The 15th Mini-Mapping Contest came to an end. The Secrets of Warcraft 3 are soon to be revealed! Come and vote in the public poll for your favorite maps.
    Dismiss Notice
  4. The 12th incarnation of the Music Contest is LIVE! The theme is Synthwave. Knight Rider needs a song to listen to on his journey. You should definitely have some fun with this theme!
    Dismiss Notice
  5. Join other hivers in a friendly concept-art contest. The contestants have to create a genie coming out of its container. We wish you the best of luck!
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Rain of Arrows v1.01

Submitted by scorpion182
This bundle is marked as approved. It works and satisfies the submission rules.
Rain of Arrows

Fires a fire arrow into the sky which explodes and scatters at the center of the point target, showering the target area. Deals amount of damage each.


Code (vJASS):

//! zinc
    /*
    -------------------------------------------------------------------------------------------
        Rain of Arrows v1.01 by scorpion182
        requires:
       
        [-X-] TimerUtils, SimError, BoundSentinel, xe by vexorian
        [-X-] ParabolicMovement by Moyack & Spec
    -------------------------------------------------------------------------------------------
    */

    library RainofArrows requires TimerUtils, ParabolicMovement, SimError, xefx, xedamage, optional BoundSentinel
    {
    /*
    -------------------------------------------------------------------------------------------
        CALIBRATION SECTION
    -------------------------------------------------------------------------------------------
    */

        constant integer SPELL_ID    = 'A000'; /*spell id*/
        constant string  ARROW_PATH  = "Abilities\\Weapons\\SearingArrow\\SearingArrowMissile.mdl"; /*the arrow effect path*/
        constant string  FLASH_PATH  = "Abilities\\Weapons\\FragDriller\\FragDriller.mdl"; /*the arrow flash effect path*/
        constant string  DAMAGE_FX   = "Abilities\\Weapons\\Rifle\\RifleImpact.mdl"; /*on-damage effect*/
        constant string  DAMAGE_ATCH = "origin"; /*on-damage effect attachment point*/
        constant integer ARROW_SCALE = 1; /*arrow scale*/
        constant real    MAX_H       = 500.; /*maximum parabola height*/
        constant real    SPEED       = 800. * XE_ANIMATION_PERIOD; /*missile speed*/
        constant real    MIN_DIST    = 300.; /*minimum casting distance, the parabolic movement looks weird if the distance is too short*/
        constant real    MIN_H       = 80.; /*minimum distance for the rain arrows, must higher than 80., otherwise it won't work*/
        constant string  ERROR_MSG   = "Inside Minimum Range." ; /*display error message*/
        constant boolean PRELOAD_FX  = true; /*preload effect?*/
       
        function GetAoE(integer lvl)->real
        {
            return 400. + lvl * 0; /*spell aoe, must match the object editor field*/
        }
   
        function GetDamage(integer lvl)->real
        {
            return 25. * lvl; /*deals damage each arrow*/
        }
       
        function GetCollisionSize(integer lvl)->real
        {
            return 125. + lvl * 0; /*collision size each arrow*/
        }
   
        function GetArrowCount(integer lvl)->integer
        {
            return 12 + lvl * 0; /*how many arrows*/
        }
       
        /* damage filter */
        function DamageOptions(xedamage spellDamage)
        {
            spellDamage.dtype = DAMAGE_TYPE_UNIVERSAL;
            spellDamage.atype = ATTACK_TYPE_NORMAL;
            spellDamage.exception=UNIT_TYPE_STRUCTURE; /*doesn't damage building*/
            spellDamage.visibleOnly = true;
            spellDamage.damageAllies = false; /* damage allies if true */
            spellDamage.damageTrees = true; /* damage destructables? */
            spellDamage.useSpecialEffect(DAMAGE_FX, DAMAGE_ATCH);
        }
       
    /*
    -------------------------------------------------------------------------------------------
        END OF CALIBRATION SECTION
    -------------------------------------------------------------------------------------------
    */

        constant real A = 2 * bj_PI;
        location l = Location(0, 0);
        xedamage xed;
       
        function GetPointZ(real x, real y)->real
        {
            MoveLocation(l, x, y);
            return GetLocationZ(l);
        }
       
        /*rain of arrows*/
        struct rain
        {
            unit caster; /*the caster*/
            timer t;
            real tx; /*spell target x*/
            real ty; /*spell target y*/
            xefx fx;
            integer lvl; /*ability level*/
            real zpoint; /*spell target z*/
           
            static method create(unit c, real x, real y, real tx, real ty, integer lvl)->thistype
            {
                thistype this = thistype.allocate();
                real dx = tx - x;
                real dy = ty - y;
                real angle = Atan2(dy, dx);
               
                this.caster = c;
                this.t = NewTimer();
                this.tx = tx;
                this.ty = ty;
                this.lvl = lvl;
                this.fx = xefx.create(x, y, angle);
                this.fx.fxpath = ARROW_PATH;
                this.fx.scale = ARROW_SCALE;
                this.fx.z = MAX_H;
                this.zpoint = GetPointZ(tx, ty);
                SetTimerData(this.t, this);
                TimerStart(this.t, XE_ANIMATION_PERIOD, true, function thistype.onMove);
               
                return this;
            }
           
            static method onMove()
            {
                thistype this = thistype(GetTimerData(GetExpiredTimer()));
                real x = this.tx - this.fx.x;
                real y = this.ty - this.fx.y;
                real z = -this.fx.z + SPEED;
                real distance = SquareRoot(x*x + y*y + z*z);
                real angle1 = Atan2(y, x);
                real angle2 = Acos(z / distance);
                real angle3 = Atan2(z, SquareRoot(x*x + y*y));
               
                if (distance > MIN_H && this.fx.z + this.zpoint > this.zpoint + MIN_H)
                {
                    this.fx.xyangle = angle1;
                    this.fx.x += SPEED * Cos(angle1) * Sin(angle2);
                    this.fx.y += SPEED * Sin(angle1) * Sin(angle2);
                    this.fx.z += SPEED * Cos(angle2);
                    this.fx.zangle = angle3;
                }
                else
                {
                    this.destroy();
                }
               
               
            }
           
           
            method onDestroy()
            {
                xed.damageAOE(this.caster,this.fx.x, this.fx.y, GetCollisionSize(this.lvl), GetDamage(this.lvl));
                this.fx.flash(FLASH_PATH);
                ReleaseTimer(this.t);
                this.fx.destroy();
            }
           
        }
       
        constant real factor = 2.;
       
        /*parabolic arrow*/
        struct data
        {
            unit caster; /*the caster*/
            timer t;
            real pos; /*current pos*/
            real dist; /*total distance*/
            integer lvl; /*ability level*/
            xefx fx;
            real tx; /*spell target x*/
            real ty; /*spell target y*/
           
            static method create(unit c, real tx, real ty)->thistype
            {
                thistype this = thistype.allocate();
                real x = GetUnitX(c);
                real y = GetUnitY(c);
                real dx = tx - x;
                real dy = ty - y;
                real angle = Atan2(dy, dx);
               
                this.caster = c;
                this.t = NewTimer();
                this.lvl = GetUnitAbilityLevel(c, SPELL_ID);
                this.tx = tx;
                this.ty = ty;
                this.pos = SquareRoot(dx * dx + dy * dy)*factor;
                this.dist = this.pos;
                this.fx = xefx.create(x, y, angle);
                this.fx.fxpath = ARROW_PATH;
                this.fx.scale = ARROW_SCALE;
               
               
                return this;
            }
           
            method onDestroy()
            {
                integer i = 0;
                real x = this.fx.x;
                real y = this.fx.y;
                real angle;
                real dis;
                real tx;
                real ty;
                rain s;
           
                this.fx.flash(FLASH_PATH);
                ReleaseTimer(this.t);
                this.fx.destroy();
                /*create rain arrows*/
                for(i = 0; i<GetArrowCount(this.lvl); i += 1)
                {
                    angle = GetRandomReal(0, A);
                    dis = GetRandomReal(1, GetAoE(this.lvl));
                    tx = x + dis * Cos (angle);
                    ty = y + dis * Sin (angle);
                    s = s.create(this.caster, x, y, tx, ty, this.lvl);
                }
               
            }
           
            /*move the parabolic arrow*/
            static method onLoop()
            {
                thistype this = thistype (GetTimerData(GetExpiredTimer()));
                real x = this.fx.x;
                real y = this.fx.y;
                real z = this.fx.z;
                real dx;
                real dy;
                real dz;
               
                if (this.pos>this.dist/factor)
                {
                    this.fx.x += SPEED * Cos(this.fx.xyangle);
                    this.fx.y += SPEED * Sin(this.fx.xyangle);
                    this.fx.z = ParabolaZ(MAX_H, this.dist, this.pos);
                    dx = this.fx.x - x;
                    dy = this.fx.y - y;
                    dz = this.fx.z - z;
                    this.fx.zangle = Atan(dz * dz / (dx * dx + dy * dy) );
                    this.pos -= SPEED;
                }
                else
                {
                    this.destroy();
                }
               
            }
           
            static method SpellEffect()->boolean
            {
                thistype this;
               
                if (GetSpellAbilityId() == SPELL_ID)
                {
                    this = thistype.create(GetTriggerUnit(), GetSpellTargetX(), GetSpellTargetY());
                    SetTimerData(this.t, this);
                    TimerStart(this.t, XE_ANIMATION_PERIOD, true, function thistype.onLoop);
                }
                return false;
            }
           
            /*check minimum casting distance*/
            static method CheckMinDistance()->boolean
            {
                unit u = GetTriggerUnit();
                real x = GetUnitX(u);
                real y = GetUnitY(u);
                real dx = x - GetSpellTargetX();
                real dy = y - GetSpellTargetY();
           
                if (GetSpellAbilityId() == SPELL_ID && dx * dx + dy * dy<MIN_DIST * MIN_DIST)
                {
                    SimError(GetOwningPlayer(u), ERROR_MSG);
                    PauseUnit(u, true);
                    IssueImmediateOrder(u, "stop");
                    PauseUnit(u, false);
                }
           
                u = null;
                return false;
            }
           
            static method onInit()
            {
                trigger t = CreateTrigger();
                TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT);
                TriggerAddCondition(t, Condition(function thistype.SpellEffect));
               
                t = CreateTrigger();
                TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CHANNEL);
                TriggerAddCondition(t, Condition(function thistype.CheckMinDistance));
               
                /* init xedamage */
                xed = xedamage.create();
                DamageOptions(xed);
               
                /*preload effect*/
                static if (PRELOAD)
                {
                    Preload(ARROW_PATH);
                    Preload(FLASH_PATH);
                    Preload(DAMAGE_FX);
                }
            }
           
        }
    }

//! endzinc
 


Requires:
- TimerUtils by Vexorian
- xe by Vexorian
- BoundSentinel by Vexorian
- Parabolic Function by moyack
- SimError by Vexorian

History:
~ v1.00 First Release.
~ v1.01 Fixed minor bugs, added on-damage effect.



Keywords:
zinc, rain, of, arrow, arrows, parabola, area, damage, target, many, scatter, shard, whatever, archer, fire, mui
Contents

Rain of Arrows v1.01 (Map)

Reviews
Moderator
20:31, 2nd Mar 2010 The_Reborn_Devil: The coding looks good and I couldn't find any leaks. Status: Approved Rating: Recommended
  1. 20:31, 2nd Mar 2010
    The_Reborn_Devil:

    The coding looks good and I couldn't find any leaks.


    Status: Approved
    Rating: Recommended
     
  2. Klingo

    Klingo

    Joined:
    Dec 19, 2009
    Messages:
    246
    Resources:
    5
    Spells:
    5
    Resources:
    5
    Nice spell but there's a bug
     

    Attached Files:

  3. scorpion182

    scorpion182

    Joined:
    Jun 9, 2008
    Messages:
    575
    Resources:
    21
    Maps:
    5
    Spells:
    16
    Resources:
    21
    thanks i just realized that, it's because BoundSentinel :hohum:, fixed.

    UPDATED v1.01
     
  4. Justify

    Justify

    Joined:
    Mar 16, 2008
    Messages:
    935
    Resources:
    5
    Models:
    1
    Icons:
    1
    Spells:
    3
    Resources:
    5
    Seems to be well coded, but afaik Zinc isn't allowed, at least is wasn't for some time, would wonder if they changed the rules.
     
  5. scorpion182

    scorpion182

    Joined:
    Jun 9, 2008
    Messages:
    575
    Resources:
    21
    Maps:
    5
    Spells:
    16
    Resources:
    21
    why not? zinc is a part of jasshelper. if you want to use vjass, you need jasshelper too. so why zinc not allowed?
     
  6. Justify

    Justify

    Joined:
    Mar 16, 2008
    Messages:
    935
    Resources:
    5
    Models:
    1
    Icons:
    1
    Spells:
    3
    Resources:
    5
    Zinc was added quite late, people got used to vJass and the site doesn't want zinc. If Vex adds another 10 languages, do you want them all to be accepted? Would be quite a mess and I can understand the rules, see it as some standard. I'd vote for accepting Zinc too, and I think there are mods that do so, but I'm not quite sure.

     
  7. scorpion182

    scorpion182

    Joined:
    Jun 9, 2008
    Messages:
    575
    Resources:
    21
    Maps:
    5
    Spells:
    16
    Resources:
    21
    as i already said that zinc is a part of the jasshelper, it doesn't need an additional tool to compile except the jasshelper itself.

    this spell was approved, and coded in zinc
    http://www.hiveworkshop.com/forums/...-9-9-5-a-148321/?prev=search=zinc&d=list&r=20

    and this

    http://www.hiveworkshop.com/forums/spells-569/beacon-149221/?prev=search=zinc&d=list&r=20

     
  8. Sheephunter

    Sheephunter

    Joined:
    Dec 21, 2008
    Messages:
    760
    Resources:
    0
    Resources:
    0
    if you need all those things for a spell i say my ass :p
    I think its even easyer to make this spell in GuI Heh
     
  9. cookies4you

    cookies4you

    Joined:
    May 9, 2009
    Messages:
    530
    Resources:
    0
    Resources:
    0
    is that even possible???!!!!!

    oh wait yeah it is. still, i'll accept zinc. i'll view the code and identify what i see from it.

    Edit goes here:
     
  10. _Shadow_

    _Shadow_

    Joined:
    Jan 21, 2010
    Messages:
    10
    Resources:
    0
    Resources:
    0
    I cannot save this (Have JNGP and 1.24 version)
     
  11. cedi

    cedi

    Joined:
    May 19, 2008
    Messages:
    165
    Resources:
    7
    Icons:
    2
    Spells:
    5
    Resources:
    7
    Then you've maybe an old ver of jasshelper ...

    cedi
     
  12. _Shadow_

    _Shadow_

    Joined:
    Jan 21, 2010
    Messages:
    10
    Resources:
    0
    Resources:
    0
    new JNGP and jasshelper, here is only one problem with two lines, WE shows up.
     
  13. scorpion182

    scorpion182

    Joined:
    Jun 9, 2008
    Messages:
    575
    Resources:
    21
    Maps:
    5
    Spells:
    16
    Resources:
    21
    meh, do it then. everyone can easily said it.

    you should update your jasshlper, not the JNGP.
     
  14. 88WaRCraFT3

    88WaRCraFT3

    Joined:
    Jun 9, 2009
    Messages:
    1,139
    Resources:
    1
    Spells:
    1
    Resources:
    1
    thats true for me. I don't know JASS or vJASS but isn't easy to do that in GUI.
    Thanks for answer.
     
  15. cedi

    cedi

    Joined:
    May 19, 2008
    Messages:
    165
    Resources:
    7
    Icons:
    2
    Spells:
    5
    Resources:
    7
    Two things:

    1. Don't create the explosion sfx of the splitters on them. Because the effects has then the angle of the missile, which looks a bit bad.

    2. Add the possibility to set a start z. ( looks bad when the missile starts out of the ground )

    But anyway, nice spell.

    cedi
     
  16. Dynasti

    Dynasti

    Joined:
    Oct 18, 2007
    Messages:
    877
    Resources:
    4
    Maps:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    4
    Looks cool, but you should make the exploding arrows travel at just a pinch different speeds, so it doesn't sound and look so stiff.

    ~Dynasti