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

Spell - Water Explosion 2.1b

Spell: Water Explosion - Creates water explosions around caster dealing x damage, depending on spells level.



Version 1.1 - Added non-selection trigger for dummy's.

Version 1.2 - Paused timer before destroying it and nulled handle variables.

Version 1.3 - Now Fully MUI and code optimized a bit.

Version 1.3b - Fix whit leeks.

Version 1.3c - Only nulled a bit of variables.

Version 1.3d - In filter function replaced local variable to function GetFilterUnit() as I guess it is a bit of leek when using a variable.

Version 1.4 - Many important fixes, first timer activation area affection fix + first cast lag fix.

Version 1.5 - Uber update which gives this spell mass speed update jass->vjass ofc i don't mean its faster because of vjass it can only be slower in vjass if you don't know how it compiles it in jass however i do know and i can say this is the last update of this spell. Note this spell has no leaks and is completely fast as much as possible!

Version 1.6 Final - Last update improved speed decreased code size and make spell more configurable. It was by request of nerovesper to make it more configurable but i did increase speed a lot more and make code less in size. Its now at top speed and its last update i made for this spell.

Version 1.7 - Was a must update to make it 1.24 compatible! as well code is decreased and fast, using JNGPS.

Version 2.0 - Water Explosion Remasterd
- Totally recoded in zinc
- Fixed bug when units enter "water effect" area just after damage is dealt
- Caster now deals damage
- Fixed bug when caster did not deal damage, thats why dummy was used
Seems like UnitDamageTarget might not deal damage when unit casts/channels spell
- Primarely this is all fixed by adding timed area damage and g_once group which makes sure that units are damaged only once
- Now uses mini library

Version 2.1 - Recoded in Warcraft 3 v1.30
- Spell no longer requires JNGP
- Bug fixes, spell now tends to deal single damage per water explosion wave
- Alterd visuals, water shoots are shoot from far away from caster to closer range


Version 2.1b - Fixed desync sound bug




JASS:
// -------------------------------------------------------------------------
//                 *** Spell: Water Explosion
//                 *** Autor: Dark Dragon
//
//
// * Made on Warcraft III v1.30.4
//
// -------------------------------------------------------------------------
//                      *** Installation ***
//
// * Copy this trigger and DD Library to your map
// * Copy abilitie 'Water Explosion' to your map
// * Export and import 'WaterExplosion.mdx' from this map to your map (Credits: JetFangInferno)
// * Modify data below to your will, WEX_RAWCODE must be matched to your 'spell rawcode' in your map
// * Add water explosion to unit you want and edit below spell data to your needs
// * Enjoy!
// -------------------------------------------------------------------------


// -------------------------------------------------------------------------
//                  *** Main WaterExplosion library ***
//! zinc
library WaterExplosion requires DDLib
{

    //********************************************************************************
    //                        Edit following to your wish
    //********************************************************************************


    constant integer    WEX_RAWCODE         = 'WTex';    // Ability Water Explosion
    constant real     EXPLOSION_DELAY     = .5;        // How often explosions are created (in seconds)
    constant integer    WATER_SHOOTS       = 4;         // How much water shoots will happen, water sfx shoots
 constant real    INITIAL_EXPLOSION_OFFSET  = 50.;   // Extra offset to NEXT_EXPLOSION_OFFSET, on first water explosion
 constant real    NEXT_EXPLOSION_OFFSET   = 110.;   // How far does each next cycle explosion occure (linear damage/effect version)
 constant real    WATER_EXPLOSION_DENSITY   = 160.;   // Smaller numbers mean that explosions are closer together, it means how much of perimiter does it use (circular effect version)
 //constant real    EXPLOSION_ENHANCE_PERC   = 120.;   // This is correction of units being picked in percentage of NEXT_EXPLOSION_OFFSET, it means it will alternate area in which units are damaged
 constant boolean   DUMMY_DAMAGE     = false;   // Does dummy or caster deal damage?
 constant boolean   USE_TEXTTAG      = true;   // Enable or disable damage display

 constant integer   PROJECTILE_N     = 12;   // Missiles max number
 constant real    PROJECTILE_SIZE     = 1.3;   // Missiles size
    constant real     PROJECTILE_SPEED      = 750.;   // Missiles speed
    constant real     PROJECTILE_ARC        = 360.;   // Missiles max reached z
    constant real     PROJECTILE_RANGE      = 710.;   // Missiles max travel distance
 constant real     PROJECTILE_INIT_Z      = 0.;   // Missiles offset z
    
        // This are constant defined effects
    constant string    EXPLOSION_DAMAGE_EFFECT      = "Abilities\\Spells\\Other\\CrushingWave\\CrushingWaveDamage.mdl";
    constant string    EXPLOSION_DAMAGE_EFFECT_ATTACH_POINT  = "origin";
    constant real     EXPLOSION_DAMAGE_EFFECT_INTERVAL   = .33;
    constant real     EXPLOSION_DAMAGE_EFFECT_DURATION   = 4.;
    constant string    WATER_EXPLOSION_EFFECT       = "Objects\\Spawnmodels\\Naga\\NagaDeath\\NagaDeath.mdl";
    constant string    MISSILE_EFFECT               = "Abilities\\Weapons\\WaterElementalMissile\\WaterElementalMissile.mdl";
    constant string    MISSILE_SPAWN_EFFECT           = "war3mapImported\\WaterExplosion.mdx";
    constant real     MISSILE_SPAWN_EFFECT_SIZE       = .5;
    constant real     MISSILE_SPAWN_EFFECT_ANIMATION_SPEED  = 200.;

    private keyword waterexp;
 
 // *** Amount of damage dealed per level, if you use more or less than 3 levels, just delete or add additional lines in function below
 function WaterDamage(integer level) -> real {
  real damage[];

  // -----------------------------------------
  // *** edit this variables to your will
  damage[1] = 70.;
  damage[2] = 100.;
  damage[3] = 140.;
  damage[4] = 190.;
  damage[5] = 260.;
  // -----------------------------------------

  return damage[level];
 }

 // *** area of effect, that is max radius that spell will effect
 function WaterAoE(integer level) -> real {
  real aoe[];

  // -----------------------------------------
  // *** edit this variables to your will
  // you can use your custom aoe, but this uses n water explosions formula.
  //                 ˇˇ
  aoe[1] = INITIAL_EXPLOSION_OFFSET + NEXT_EXPLOSION_OFFSET*(4.);
  aoe[2] = INITIAL_EXPLOSION_OFFSET + NEXT_EXPLOSION_OFFSET*(4.);
  aoe[3] = INITIAL_EXPLOSION_OFFSET + NEXT_EXPLOSION_OFFSET*(5.);
  aoe[4] = INITIAL_EXPLOSION_OFFSET + NEXT_EXPLOSION_OFFSET*(5.);
  aoe[5] = INITIAL_EXPLOSION_OFFSET + NEXT_EXPLOSION_OFFSET*(6.);
  //                 ^^
  // -----------------------------------------

  return aoe[level];
 }
 
    function WaterMaxDamage(integer level) -> real {
        real max_damage[];

  // -----------------------------------------
  // *** edit this variables to your will
  // the max damage spell can deal per cast, use value of -1. to make spell have no limit of damage
  //
  max_damage[1] = 500.;
  max_damage[2] = 850.;
  max_damage[3] = 1100.;
  max_damage[4] = 1500.;
  max_damage[5] = 1600.;
  //                   ^^
  // -----------------------------------------

  return max_damage[level];

    }

 // *** Filtrate units to be damaged
 function DamageFilter(unit filterUnit, player casterOwner) -> boolean {
   return  !IsUnitType(filterUnit, UNIT_TYPE_DEAD)     &&
     IsUnitEnemy(filterUnit, casterOwner)       &&
     !IsUnitType(filterUnit, UNIT_TYPE_STRUCTURE)    &&
     !IsUnitType(filterUnit, UNIT_TYPE_MAGIC_IMMUNE)   &&
     !IsUnitType(filterUnit, UNIT_TYPE_ANCIENT)     &&
     !IsUnitType(filterUnit, UNIT_TYPE_FLYING)     &&
     !DDIsUnitWard(filterUnit)        &&
     BlzIsUnitSelectable(filterUnit)       &&
     !BlzIsUnitInvulnerable(filterUnit);
 }

 // ==============================================================================================================
 // *
 // *       *** Non-Editable code below ***
 // *
 // ==============================================================================================================

    //===============================================
    // Do not edit bellow if you don't know jass
    //===============================================


 // * Timed effect on unit
 struct timeffect {
  unit u;
  effect e;
  real timeout;

  static timeffect UnitData[];

  static method AddWaterEffect(unit u) {
   timeffect this;
   integer id = H2ID(u);
 
   if (UnitData[H2ID(u)] == p_null) {
    this = allocate();
    UnitData[id] = this;
    this.u = u;
    this.e = AddSpecialEffectTarget(EXPLOSION_DAMAGE_EFFECT, u, EXPLOSION_DAMAGE_EFFECT_ATTACH_POINT);
 
    DDStartTim(EXPLOSION_DAMAGE_EFFECT_INTERVAL, true, this, static method() {
     timeffect te = DDTimData();
 
     BlzPlaySpecialEffect(te.e, ANIM_TYPE_BIRTH);
     te.timeout -= EXPLOSION_DAMAGE_EFFECT_INTERVAL;
     if (te.timeout <= 0. || IsUnitType(te.u, UNIT_TYPE_DEAD)) {
      DestroyEffect(te.e);
      UnitData[H2ID(te.u)] = p_null;
      te.e = null;
      te.u = null;
      te.destroy();
      DDQuitTim();
     }
    });
   } else {
    this = UnitData[id];
   }
 
   this.timeout = EXPLOSION_DAMAGE_EFFECT_DURATION;
  }
 }

 // *** Group of missiles
 struct nexus {
  ddeffect e[PROJECTILE_N];
  effect se[PROJECTILE_N];
  real dx[PROJECTILE_N], dy[PROJECTILE_N];
  real wz, dist, max_dist;
  real offset_range;

  // *** Calculates missile z motion, default elliptical motion
  method MissileZ() -> real {
   return ((-4.*PROJECTILE_ARC/Pw_2(max_dist)) * Pw_2(dist-offset_range)) + PROJECTILE_ARC;
   //return SquareRoot( Pw_2(PROJECTILE_ARC) * (1. - Pw_2(((dist-offset_range)/(max_dist/2.))-1.)) );
  }
 }

 //--------------------------------------------------
    // *** WaterExplosion main struct ***
    struct waterexp {
        // Objects
        unit   caster;
  unit   dummy;
  real   x, y;
  player   owner;
        integer  level;
        integer  shoots;
        real   radius;
  real  dmg, cdmg, max_dmg;
  fogmodifier fm;

    
    
  // ------------------------------------------
        //     # Methodes
  // ------------------------------------------
    
  // ------------------------------------------
        //     *** Write constructor ***
        static method create() -> waterexp {
            waterexp this = allocate();
        
            // *** Assign members ***
            this.caster   = GetTriggerUnit();
            this.owner    = GetOwningPlayer(this.caster);
            this.level    = GetUnitAbilityLevel(this.caster, WEX_RAWCODE);
            this.radius   = INITIAL_EXPLOSION_OFFSET;
            this.x     = GetUnitX(this.caster);
            this.y     = GetUnitY(this.caster);
            this.shoots   = 0;
   this.cdmg   = 0.;
   this.dmg   = WaterDamage(level);
   this.max_dmg  = WaterMaxDamage(level);
   this.fm    = CreateFogModifierRadius(this.owner, FOG_OF_WAR_VISIBLE, this.x, this.y, WaterAoE(this.level) + NEXT_EXPLOSION_OFFSET, true, false);
   FogModifierStart(this.fm);
 
   static if (DUMMY_DAMAGE) {
    this.dummy = DDLoadDummy();
    SetUnitOwner(dummy, owner, false);
    SetUnitX(this.dummy, this.x);
    SetUnitY(this.dummy, this.y);
   }
        
            return (this);
        }
    


        // ------------------------------------------
        //     *** Write destructor ***
        method destroy() {
   static if (DUMMY_DAMAGE)
    DDRecycleDummy(this.dummy);
 
   FogModifierStop(this.fm);
   DestroyFogModifier(this.fm);
   this.fm = null;
   this.caster = null;
   deallocate();
        }
    }

 
    //===========================================================================
    //               **** Init water expl ****
    //===========================================================================
    function onInit() {
        trigger t = CreateTrigger();
        TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT);
        TriggerAddCondition(t, Condition(function() -> boolean {
            // Main Condition
            if (GetSpellAbilityId() != WEX_RAWCODE)
                // *** Skip remainig code
                return false;
 
            // *** Condition passed
            DDStartTimInst(EXPLOSION_DELAY, true, waterexp.create(), function() {
    // -------------------------------------
    // *** locals ***
    waterexp we = DDTimData();
    nexus n;
    integer i, max_i;
    real rad;
    // -------------------------------------
 
    // ================================================================================================
    //        *** Load water shoots ***
    // ================================================================================================
    if ( we.shoots < WATER_SHOOTS ) {
     // *** Increase shoots ***
     we.shoots += 1;
     n = nexus.create(); // Missiles
     n.dist = we.radius;
     n.max_dist = PROJECTILE_RANGE-we.radius;
     n.offset_range = we.radius+(n.max_dist/2.);
     n.wz = BlzGetUnitZ(we.caster);
 
     // *** Add enum graphics ***
     for(i=0; i < PROJECTILE_N; i+=1) {
      // *** Do calcs ***
      rad = i*(2.*bj_PI/PROJECTILE_N);
      // *** Add missiles ***
      n.dx[I] = Cos(rad);
      n.dy[I] = Sin(rad);
      n.e[I] = ddeffect.create(MISSILE_EFFECT, we.x + PROJECTILE_RANGE * n.dx[I], we.y + PROJECTILE_RANGE * n.dy[I], rad, PROJECTILE_SIZE);
      n.dx[I] *= -DD_INTERVAL*PROJECTILE_SPEED;
      n.dy[I] *= -DD_INTERVAL*PROJECTILE_SPEED;
    
      n.se[I] = AddSpecialEffect(MISSILE_SPAWN_EFFECT, n.e[I].X, n.e[I].Y);
      BlzSetSpecialEffectScale(n.se[I], MISSILE_SPAWN_EFFECT_SIZE);
      BlzSetSpecialEffectTimeScale(n.se[I], MISSILE_SPAWN_EFFECT_ANIMATION_SPEED/100.);
      BlzPlaySpecialEffect(n.se[I], ANIM_TYPE_STAND);
     }
   
     DDStartTim(200./MISSILE_SPAWN_EFFECT_ANIMATION_SPEED, false, n, function() {
      nexus n = DDTimData();
      integer i;
    
      for(i=00; i < PROJECTILE_N; i+=01) {
       DestroyEffect(n.se[I]);
       n.se[I] = null;
      }
    
      if (n.e[00] == p_null)
       n.destroy();
      DDQuitTim();
     });
   
     // ------------------------------------------------------------
     // *** Missile motion
     DDStartTim(DD_INTERVAL, true, n, function() {
      nexus n = DDTimData();
      integer i;
    
      // *** vars change apply ***
      n.dist += DD_INTERVAL*PROJECTILE_SPEED;
    
      // *** check if we still have a way to go ***
      if (n.dist < PROJECTILE_RANGE) {
       // *** Do the loop and move missiles
       for(i=0; i < PROJECTILE_N; i+=1) {
        n.e[I].PositionZ(n.e[I].X + n.dx[I], n.e[I].Y + n.dy[i],
              n.wz + PROJECTILE_INIT_Z + n.MissileZ());
       }
      } else {
       // *** Clear missiles and end motion ***
       for(i=0; i < PROJECTILE_N; i+=1) {
        n.e[i].destroy();
        n.e[i] = p_null;
       }
       if (n.se[00] == null)
        n.destroy();
       DDQuitTim();
      }
     });
    }
  
    // ================================================================================================
    //       *** Start Damage and explosions ***
    // ================================================================================================
  
    // ***
    // *** Increase distance
    // ***
    we.radius += NEXT_EXPLOSION_OFFSET;
    max_i = R2I(2.*we.radius*bj_PI / WATER_EXPLOSION_DENSITY);
  
    // -------------------------------------------
    // Loop ( loads water explosion effects )
    for(i=0; i < max_i; i+=1) {
     rad = (i * 2.*bj_PI) / max_i;
     DestroyEffect( AddSpecialEffect(WATER_EXPLOSION_EFFECT,
             we.x + we.radius * Cos( rad ),
             we.y + we.radius * Sin( rad )) );
    }
  
    // *** Start periodic scan for damage
    DDGroupFilterArea(we.x, we.y, we.radius+NEXT_EXPLOSION_OFFSET, we, function() -> boolean {
     waterexp we = DDGFilterData();
     unit f = GetFilterUnit();
     real life, damage = we.dmg;
     effect e;
   
     // Target unit has to be between target radius and radius - explosion offset
     if (DDHypot(GetUnitX(f)-we.x, GetUnitY(f)-we.y) >= Pw_2(we.radius-NEXT_EXPLOSION_OFFSET) && DamageFilter(f, we.owner)) {
      if (we.max_dmg != -1.) {
       life = GetWidgetLife(f);
     
       if (we.max_dmg-we.cdmg < damage)
        damage = we.max_dmg-we.cdmg;
      
       if (life < damage)
        damage = life;
     
       we.cdmg += damage;
      }
    
      static if (DUMMY_DAMAGE)
       DDSpellDamage(we.dummy, f, we.dmg);
      else
       DDSpellDamage(we.caster, f, we.dmg);
    
      static if (USE_TEXTTAG)
       if (damage >= 1.)
        DDNewTextTagUnit(f, "+"+I2S(R2I(damage)), 4., 10., 90., 88., 20.);
    
      timeffect.AddWaterEffect(f);
     }
     f = null;
     return false;
    });
  
    // ===========================================
    // * End when distance is out of area
    if (we.radius+1. > WaterAoE(we.level)) {
     static if (USE_TEXTTAG)
      DDNewTextTagUnit(we.caster, I2S(R2I(we.cdmg))+" damage dealt!", 5., 27., 84., 10., 20.);
     we.destroy();
     DDQuitTim();
    }
  
    // ===============================
    // ---- End main timer ------
    // ===============================
   });
          
            return false; // End Trigger condition
        }));
 
  // End onInit
    }
 
}

//! endzinc

// ============================================================================================
// Lua generation of objects!
// Change me from /* to // and then back to /* after saving and reopening the map
    // |
    // ˇ
      /*
    
// Credits: PurgeandFire for lua tutorial
//! externalblock extension=lua ObjectMerger $FILENAME$
     //! i -- ===================================================
   
     //! i WATER_EXPLOSION_ABIL_ID               = "WTex"
  
     //! i -- ===================================================
  
     //! i setobjecttype("abilities")
     //! i createobject("AHtc", WATER_EXPLOSION_ABIL_ID)
     //! i makechange(current,"anam", "Water Explosion")
     //! i makechange(current,"alev", "5")
     //! i makechange(current,"abpx", "3")
  //! i makechange(current,"arpx", "3")
  //! i makechange(current,"aart", "ReplaceableTextures\\CommandButtons\\BTNCrushingWave.blp")
  //! i makechange(current,"arar", "ReplaceableTextures\\CommandButtons\\BTNCrushingWave.blp")
  //! i makechange(current,"ahky", "W")
  //! i makechange(current,"arhk", "W")
  //! i makechange(current,"acat", nil)
  //! i makechange(current,"aret", "Learn |cff1a8cd0W|rater Explosion - [|cff0080c0Level "..string.char(37).."d|r]")
  //! i makechange(current,"arut", "|cff008040Deals damage in area around caster.|r|n|n|cff0080ffLevel 1|r -|cff80ffff Each explosion deals 70 damage, up to max 500 damage, in 470 aoe|r. |n|cff0080ffLevel 2|r - |cff80ffffEach explosion deals 100 damage, up to max 850 damage, in 470 aoe|r. |cff80ffff|n|r|cff0080ffLevel 3|r -|cff80ffff Each explosion deals 140 damage, up to max 1100 damage, in 610 aoe|r.|cff80ffff|n|r|cff0080ffLevel 4|r -|cff80ffff Each explosion deals 190 damage, up to max 1500 damage, in 610 aoe|r.|cff80ffff|n|r|cff0080ffLevel 5|r -|cff80ffff Each explosion deals 260 damage, up to max 1600 damage, in 610 aoe|r.")
 
   
     //! i local i = 0
     //! i local dmg = { "70", "100", "140", "190", "260" }
  //! i local maxdmg = { "500", "850", "1100", "1500", "1600" }
  //! i local aoe = { "470", "470", "610", "610", "610" }
     //! i for i=1, 5 do
        //! i local si = tostring(i)
        //! i makechange(current,"Htc1",si,"0.")
        //! i makechange(current,"aare",si,"0.")
        //! i makechange(current,"Htc3",si,"0.")
  //! i makechange(current,"Htc4",si,"0.")
  //! i makechange(current,"abuf",si,nil)
        //! i makechange(current,"ahdu",si,".01")
        //! i makechange(current,"adur",si,".01")
        //! i makechange(current,"amcs",si,tostring(100 + 25*i))
        //! i makechange(current,"atp1",si,"|cff1a8cd0W|rater Explosion - [|cffffcc00Level "..si.."|r]")
  //! i makechange(current,"aub1",si,"|cff1a8cd0Deals "..dmg[i].." damage per explosion, up to max "..maxdmg[i].." damage, in "..aoe[i].." aoe.|r")
 
     //! i end
//! endexternalblock

       */
    // ^
    // |
// Change me from */ to // and then back to */ after saving and reopening the map
// ============================================================================================
[/I][/I][/I][/I][/I][/I][/I][/I][/I][/I][/I][/I][/I][/I][/I][/I][/I][/I][/I]


Credits: JetFangInferno

If you have any future questions ask here.
Have Fun!

~Dark Dragon


Keywords:
Water, Explosion, Spells, any, other, DD, wave, nova
Contents

Spell - Water Explosion (Map)

Reviews
Diablo-dk: [Approved] The spell is MUI and works fine ingame.

Moderator

M

Moderator

Diablo-dk: [Approved]
The spell is MUI and works fine ingame.
 
Level 15
Joined
Jul 19, 2007
Messages
618
I used constant functions all ready so I don't understand what should I do more, if you think that when I use globals whit no array that its not MUI that is not true because if you look better this variables are used in instant actions. Not sure is it fully MUI but MPI is for sure that is enough if its a hero spell right?

Now I know I am not so good but I am still learning jass and how to code a good spell or anything, ty for teaching me about PauseTimer did not know it must be used before destroying it.
 
Level 10
Joined
Nov 10, 2004
Messages
351
According to the rules, a JASS spell must be fully MUI. Take a look at KaTTaNa's local handle variables system, which is great at making MUI Jass spells. http://www.wc3jass.com/viewtopic.php?t=224

, if you think that when I use globals whit no array that its not MUI that is not true because if you look better this variables are used in instant actions
I didn't say it had anything about the spell being MUI. It was a suggestion, so you don't have to follow it, since i do understand why you used globals.

Make the spell fully MUI and null the handle variables, then i'll approve it. (If you don't know what nulling handle variables means, search for a jass tutorial. I'm sure you can find an answer there)
 
Level 12
Joined
Aug 20, 2007
Messages
866
Simple improvements

The first, I noticed you used degrees for the angle, as this makes it very easy to write the code, it is almost always more efficient to use radians, I studied your code a bit, and every single time WE needs to loop, it needs to make those unnecessary bj_DEGTORAD calculations

The second, your system to retrieve timer data is good, but I don't see anywhere that you nulled/cleared the timer data global for finished timers, your system would be very good, but it will keep looping through all of your un-used timers every time you retrieve the data, which you do every time the timer expires, almost like putting a loop inside a loop

Either get a different system that doesn't need to loop, or just make sure you clear + null the variables so the system doesn't need to loop through 200 expired timers your not even using

These are both pretty minor, but will definitely improve your code


[For the timer data system, if you'd like a guage on how mcuh better a loopless system would be, those systems only loop once, so if your system only looped once it would be slightly more efficient (less if/thens), but every time it needs to loop, it becomes that many more times slower, in other words if you have 50 timers stored in the data, your system would be 50x slower than a loopless(give or take 5x due to if/thens)]
 
Level 15
Joined
Jul 19, 2007
Messages
618
Hi Herman!

Well its nice you got a look in a spell so lets start to explain things out ^^.

1. Using bj_DEGTORAD is much faster then any other conversion as its a global already calculated constant in blizzard.j Its always much better to use constants as they are very fast.

2. There is only one timer per cast which gets destroyed very fast, as function ClearUserTimerData( timer whichTimer, boolean destroy ) so I don't need to do manual destroy. Note that only one timer loops the spell function, and gets soon destroyed.

3. The system of timer data which you say are lot, well as I explained there are timers equal to instant spell casting times. So if 3 players cast spell at same time there will be 3 timers (3 loops) btw jass if/then is fast GUI one creates function which is slow but in jass thats not a problem.

4. Thanks for commenting!

Edit: Lol sorry when I started to make this spell I made it MPI and then I waste my time on why Handle Locals dont work for me, in that time I forget to make ClearTimerData, thanks now its fixed.
 
Level 12
Joined
Aug 20, 2007
Messages
866
What I ment with the DEGTORAD, was that you should use the RADTODEG function, and just calculate in radians (one of the things that will cost you more time, but will improve your code)

If you don't need/want to do that (or don't know how) it's ok, its a pretty minor thing, should be kept in mind for big systems though

Yeah, I wasn't sure about the timers getting destroyed, it would only be slower if the timers were not removed, but I *think* you said you did

The timer thing is very very efficient way of doing if everything is used properly (I might even switch over to it, because I only ever put handlevars on timers)

Great job !!! :D
 
Level 15
Joined
Jul 19, 2007
Messages
618
You were right as I sad I did not destroy timers before I mean I did but did not clear the stored data on timer that was a leak but now its fixed. Only one thing about RADTODEG and DEGTORAD this are not the functions they are global constant variables and its same to say:

set var = 2*3
or
set var = 2 * bj_DEGTORAD

look:

constant real bj_DEGTORAD = bj_PI / 180.
constant real bj_RADTODEG = 180. / bj_PI

where bj_PI is:

constant real bj_PI = 3.14159

So only for your info, it does not matter which one you use they are the same its like you use:

set var = 2/4
set var2 = 4/2

it does not rely matter, note I only tried to explain you, this is for sure same thing as you can find them in blizzard.j dont tread this as function for conversion this is only a constant global variable.

I guess I explained it well, once more ty for comment.
 
Level 12
Joined
Aug 20, 2007
Messages
866
sorry I keep referring to it as a function, but yeah I udnerstand what you mean by the calculations, what I'm saying is inside your actual code you need to constantly flip between radians and degrees, because most of the functions take measurements in radians or return in radians

Although there are a select few that take degrees (like unit facing)
 
Level 15
Joined
Jul 19, 2007
Messages
618
Well I guess I explained it well so you now understand that its same do you want to work in RAD or DEG just 1 deg = PI / 180. or 180 deg = PI just what you like to work whit its your same but as its simple to work whit deg so I used deg. If you like more RAD then DEG you can always work in RAD, I just wanted to tell you its same about speed.
 
Level 15
Joined
Jul 19, 2007
Messages
618
Hmm...
1) Plz turn off the caps lock
2) You need to tell me exactly what is wrong!
- Like do you have problems importing it in your map or you want to make spell like that and you don't know how, or is it something else like you don't know JASS or something.

If so then just copy trigger in your map as well as units and ability. Now check which raw codes are used in your map for units and abilities and then simple edit code when you see 'e000' - this is a raw code edit it to match your map.

Good luck, if you cant make it work I may be able to import it for you, if you send me your map.
 
Level 1
Joined
May 26, 2008
Messages
6
Hey can someone import this spell into my map and send it to me because i am either stupid or something else is wrong, because i did everything the script asks even the custom raw codes, and when I save the map i get tons of PJass errors + i cant open the map in Frozen Throne. Please help me, this spell is very important for my map, of course both Dark_Dragon and the person who helps me will get full credit. :)
 
Level 5
Joined
May 27, 2008
Messages
62
Hi! I saw your spell and it was awesome! But i need help to one spell: I want to make &quot;Posession&quot; (banshees 3lvl ulti) Spell like but I want that Unit/Hero who casted Posession has able to come out from Controlled unit/hero and Controlled unit will come back to its original team. Can you please make that spell? please =)
 
Level 1
Joined
Jun 11, 2008
Messages
3
Please help me. I'm new at import spells so some help would be very kind. I have copied the trigger, the spell and the units(the dummy and the waterelemental). Do i have to put out the units on the map? If, then where? and where shall i edit those codes?
Please help me! (please excuse my bad english)
 
Level 15
Joined
Jul 19, 2007
Messages
618
How to installation this spell in your map?

Steps:

1. Copy spell in your map (code)
2. Create variables in your variable editor
you need this i have write at top of code
without udg_ prefix.
3. Copy units from unit editor in my map to
yours as well as spell.
4. In obiject editor go to View -&gt;
Display Values as Raw Data
5. Find units and spell see the raw code on
your left and right (take left one)
6. Go to main spell code find example:
Water Explosion RawCode

Then find something like this:
constant function WE_RawCode takes nothing returns integer
return 'A000'
endfunction

replace A000 to your raw code.
Do same whit units.

Now Save map and enjoy!
 
Level 1
Joined
Jun 11, 2008
Messages
3
Thanks!
I will try that

{EDIT}
I think i have done all the steps right except of step 5 and maybe step 6. Were there anything i should have replaced in the object editor? i just replaced the 4 rawcodes i saw in the trigger with A000. I guess i have to do something more in the object editor after step 4. Right? Plz replay.
 
Last edited by a moderator:
Level 15
Joined
Jul 19, 2007
Messages
618
After step 4 you need to find example a dummy i use (in your map) you will see some letters and numbers near that unit. The raw code on your left is the dummy unit and on right one is raw code of unit which it was created so you want to take left one and write it in code. Do this whit every custom unit and spell of course. Note: jass is case sensitive so are the raw codes.

Update: Note if you are using jass new gen pack it will ask you for raw codes when pasting units and spells so just type raw code which you want and which is not yet used.
 
Level 1
Joined
Jun 11, 2008
Messages
3
Well.. i think i have done it all right now but it still don't work. Could u do me a huge favor and make this spell in GUI :p. I really need it in my map.
 
Level 15
Joined
Jul 19, 2007
Messages
618
I could just import the spell in your map if you send me to &lt;[email protected]&gt; then you will have much better performances and btw i am rely not sure will it be possible to make it MUI in GUI and all of that stuff + it will require a few triggers. So i think its fastest and best you send me the map and i will import it in no time. Anyway when i check my mail (its sometimes more rare, sometimes less) so when i notice you send me the map i'll send you the map whit imported spell.
 
Level 15
Joined
Jul 19, 2007
Messages
618
That means you did not install it well. There you did not create all of variables, most like it did not change raw codes so it loads some sort of other units which maybe should not be. If you are sure you installed it correctly please tell me exactly what you did and what happens (which bug)! Otherwise read installation in comments below, which I wrote.
 
Level 17
Joined
Mar 2, 2009
Messages
332
nice spell but why is so special??? effects are not so good to be special as u are telling...and how are u creating those things under text line.....and i like the spell nice effect
 

Attachments

  • calex map terrain.w3x
    45.7 KB · Views: 60
Level 15
Joined
Jul 19, 2007
Messages
618
nice spell but why is so special??? effects are not so good to be special as u are telling...and how are u creating those things under text line.....and i like the spell nice effect

hi calex3!

i never said effects are so special but performances and leaks are different thing. If you check out the code you will know what i mean. many jass spells here have some leaks while this one does not have a single one and as well loads minimal static objects as possible. This spell uses most of dynamic objects and quick c++ filter loops while picking units. As well i think spell is enough usefull for someone its quite simple and adding more effects will make spell be just spam of stuff in my option. This is actually my first spell that i created and i think its fine as is but maybe ill make it in v2 mode well i am not sure but maybe and that will then be final.

i am creating things under text lines? whats that i am sry but i got no idea what are you talking / asking about!

Last of all i might really make in universal v2 mode but will see about that.

Thanks for comment!
~Dark Dragon
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
i think he's talking about ur signature (the text under ur every post) -- "things under text line"
& umm... the NICE thing about this spell... besides the no-leaks & etc (which i still dont knw much about)... is the simplicity of the effects... which makes it able to use it with any hero (well deffinetly water ones :p) in watever map... and being simple is nicer and more realistic
& World Editor also limits wat you can really do... so i dont think the effect can get much better :-/
 
Level 15
Joined
Jul 19, 2007
Messages
618
yeah that might be it about signature but lol why asking that here calex3 its off-topic and btw you should make your own one not copy my. but if you ask why well just go advanced and check all options that you have there then simple change text size, color and so on...

msaeed28 thanks i am glade you like the spell style and effects!
 
Level 17
Joined
Mar 2, 2009
Messages
332
yeah that might be it about signature but lol why asking that here calex3 its off-topic and btw you should make your own one not copy my. but if you ask why well just go advanced and check all options that you have there then simple change text size, color and so on...

msaeed28 thanks i am glade you like the spell style and effects!

but how can i make my signature im not coping yours ???
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
@ calex3

man, Dark_Dragon already mentioned that here its only to comment on the spell itself not anything else
& there is a tutorial forum in the hive... search for any tutorial you want there
& if in the end u dont find anything, pm some1 who u think might help

gd luk
 
Level 1
Joined
Mar 27, 2008
Messages
5
hmm ... the editor comes up with more than 200 script errors, if I want to save it. That's very sad because I think this spell looks awesome.
 
Level 15
Joined
Jul 19, 2007
Messages
618
hmm ... the editor comes up with more than 200 script errors, if I want to save it. That's very sad because I think this spell looks awesome.

that is not possible... the only reason why it could happen is coz you are using old version of jasshelper... make sure you dl the latest version of JNGP here: Link

once u dl it extract it to ur warcraft iii folder and then run New Gen Editor... and then save map and it will work!

Greets!
~Dark Dragon
 
Level 1
Joined
Mar 27, 2008
Messages
5
that is not possible... the only reason why it could happen is coz you are using old version of jasshelper... make sure you dl the latest version of JNGP here: Link

once u dl it extract it to ur warcraft iii folder and then run New Gen Editor... and then save map and it will work!

Greets!
~Dark Dragon

okay thanks! everything works fine. nice job!
 
Top