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

[JASS] xe: Why is it useful?

Status
Not open for further replies.
Level 13
Joined
Mar 16, 2008
Messages
941
If you know what you're doing, TimerUtils, GroupUtils and the rest are not more efficient. If you know what you're doing, the "GetWidgetLife" check is a perfect death indicator, if not, it might bug everything.

Honestly, 99% of the systems are unefficient for safety reasons, but xe is performant enough and the reason why people use it, is that it's unbelievable simple. The code to run a spell via xe vs a normal selfmade missle is just so much shorter and easier to achieve, why would you write the missle movement again and again if you can use xecollider? Why would you add "enemy-checks" all the time if xe does it automaticly? It's just a thing of lazyness :)

What I'm saying: "xe" is not that amazing-uber-imba that no one could code something similar to this, but it's finished, works, and quite nice to use. If you don't like it, write your own caster/missle/... systems and love them ;)
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Justify said:
If you know what you're doing, TimerUtils, GroupUtils and the rest are not more efficient.

No matter how much knowledge you have of vJass you won't be able to fix blizzard's bugs with destroying groups/timers. Any attempt to "bypass" these bugs would result in something exactly like the utility library, and there is no sense in typing code out that has been typed out before.

xe on the other hand is a preference. If you don't understand xe but you want to use it, its there for you to use. If you do understand it, but you still would rather do things your own way, then you shouldn't be forced to have it in your map.

If you're making a system as "wide-ranged" as a projectiles system, you shouldn't have it require "preference" libraries.

Justify said:
What I'm saying: "xe" is not that amazing-uber-imba that no one could code something similar to this, but it's finished, works, and quite nice to use. If you don't like it, write your own caster/missle/... systems and love them ;)

Okay, but then why should a projectiles library that would have an even wider audience require the xe library? If you're using your own version of xe in your map, you shouldn't be forced to have xe in it as well. If you were to make it optional then you wouldn't have to worry about it, since those who want the xe library will have it, and those who choose to not have may omit it from their script.
 
Level 7
Joined
Nov 6, 2009
Messages
279
Well, you could either create a complete missle-movement and trigger all the calculation, or do it with xe in about 10 lines. You could either do inefficient dummy-casting with a lot of lines, or use a single on in the end with xe and it recycles dummies. And so on :D

LOL i tried creating a shockwave spell this morning with xe and its too complicated i can make better projectiles by myself but preload basic and damage are pretty useful. FX :thumbs_down:
 
Level 13
Joined
Mar 16, 2008
Messages
941
are you kidding me?^^
xe to complicate? This is a spell of mine, in Zinc but I think you can understand what xe does (it is fixed so some values because I need it like this :p) If I'd need only one missle, I could remove the "streams" struct completly and the code would be short like... "createMissle" and "onUnitHit" is the part of xe.
JASS:
//! zinc

    library ChillingStreams requires xecollider, xedamage, xecast, xepreload, CustomTrigger, GroupUtils
    {
    
        constant integer SPELL_ID  = 'A000';
        constant integer STUN_ID   = 'A001';
        
        constant string SFX_HIT    = "Abilities\\Spells\\Undead\\FrostArmor\\FrostArmorDamage.mdl";
        constant string SFX_MISSLE = "FrozenOrb.MDX";
        
        xedamage xed;
        xecast   xec;
        
        
        function SetupDamage()
        {
            xed = xedamage.create();
            
            xed.dtype = DAMAGE_TYPE_NORMAL;
            xed.atype = ATTACK_TYPE_NORMAL;
            
            xed.exception = UNIT_TYPE_STRUCTURE;
            
            xed.useSpecialEffect(SFX_HIT, "chest");
        }
        function SetupCast()
        {
            xec = xecast.create();
            
            xec.abilityid = STUN_ID;
            xec.orderstring = "thunderbolt";
        }
        
        function GetDamage(integer lvl) -> real
        {   
            return lvl*70.;
        }
        
        struct Missle extends xecollider
        {
            Streams parent;
            group hit;
            
            method onDestroy()
            {
                ReleaseGroup(this.hit);
                if (this == parent.missle[0])
                {    
                    parent.destroy();
                }
            }
            
            method onUnitHit(unit hitUnit)
            {
                Missle tempMissle;
                if (!IsUnitInGroup(hitUnit, hit) && xed.allowedTarget(parent.caster, hitUnit))
                {
                    xed.damageTarget(parent.caster, hitUnit, parent.damage);
                    tempMissle = parent.missle[0];
                    if (tempMissle == this)
                    {
                        tempMissle = parent.missle[1];
                    }
                    if (IsUnitInGroup(hitUnit, tempMissle.hit))
                    {
                        xec.castOnTarget(hitUnit);
                    }
                    GroupAddUnit(hit, hitUnit);
                }
            }
            
            static method createMissle(real x, real y, real angle, Streams stream) -> thistype
            {
                thistype this = thistype.allocate(x, y, angle);
                this.speed = 500.;
                this.fxpath = SFX_MISSLE;
                this.collisionSize = 100.;
                this.scale = 1.5;
                this.expirationTime = 2.;
                this.z = 100.;
                
                parent = stream;
                hit = NewGroup();
                
                return this;
            }
        }
        
        struct Streams
        {
            Missle missle[2];
            
            unit caster;
            player owner;
            real damage;
            
            static method createStreams()
            {
                thistype this = thistype.allocate();
                real cx;
                real cy;
                real sx;
                real sy;
                real mx;
                real my;
                real facing;
                real angle;
                
                caster = GetTriggerUnit();
                owner = GetOwningPlayer(caster);
                damage = GetDamage(GetUnitAbilityLevel(caster, SPELL_ID));
                
                cx = GetUnitX(caster);
                cy = GetUnitY(caster);
                sx = GetSpellTargetX();
                sy = GetSpellTargetY();
                
                facing = Atan2(sy-cy, sx-cx)+bj_PI/2.;
                mx = PolarX(cx, facing, 100.);
                my = PolarY(cy, facing, 100.);
                angle = Atan2(sy-my, sx-mx);
                missle[0] = Missle.createMissle(mx, my, angle, this);
                
                facing = facing+bj_PI;
                mx = PolarX(cx, facing, 100.);
                my = PolarY(cy, facing, 100.);
                angle = Atan2(sy-my, sx-mx);
                missle[1] = Missle.createMissle(mx, my, angle, this);
            }
        }
            
        function onInit()
        {
            RegisterSpellAction(SPELL_ID, Streams.createStreams);
            
            SetupDamage();
            SetupCast();
            
            XE_PreloadAbility(STUN_ID);
            Preload(SFX_HIT);
            Preload(SFX_MISSLE);
        }
    }
    
//! endzinc
 
Level 7
Joined
Nov 6, 2009
Messages
279
are you kidding me?^^
xe to complicate? This is a spell of mine, in Zinc but I think you can understand what xe does (it is fixed so some values because I need it like this :p) If I'd need only one missle, I could remove the "streams" struct completly and the code would be short like... "createMissle" and "onUnitHit" is the part of xe.
JASS:
//! zinc

    library ChillingStreams requires xecollider, xedamage, xecast, xepreload, CustomTrigger, GroupUtils
    {
    
        constant integer SPELL_ID  = 'A000';
        constant integer STUN_ID   = 'A001';
        
        constant string SFX_HIT    = "Abilities\\Spells\\Undead\\FrostArmor\\FrostArmorDamage.mdl";
        constant string SFX_MISSLE = "FrozenOrb.MDX";
        
        xedamage xed;
        xecast   xec;
        
        
        function SetupDamage()
        {
            xed = xedamage.create();
            
            xed.dtype = DAMAGE_TYPE_NORMAL;
            xed.atype = ATTACK_TYPE_NORMAL;
            
            xed.exception = UNIT_TYPE_STRUCTURE;
            
            xed.useSpecialEffect(SFX_HIT, "chest");
        }
        function SetupCast()
        {
            xec = xecast.create();
            
            xec.abilityid = STUN_ID;
            xec.orderstring = "thunderbolt";
        }
        
        function GetDamage(integer lvl) -> real
        {   
            return lvl*70.;
        }
        
        struct Missle extends xecollider
        {
            Streams parent;
            group hit;
            
            method onDestroy()
            {
                ReleaseGroup(this.hit);
                if (this == parent.missle[0])
                {    
                    parent.destroy();
                }
            }
            
            method onUnitHit(unit hitUnit)
            {
                Missle tempMissle;
                if (!IsUnitInGroup(hitUnit, hit) && xed.allowedTarget(parent.caster, hitUnit))
                {
                    xed.damageTarget(parent.caster, hitUnit, parent.damage);
                    tempMissle = parent.missle[0];
                    if (tempMissle == this)
                    {
                        tempMissle = parent.missle[1];
                    }
                    if (IsUnitInGroup(hitUnit, tempMissle.hit))
                    {
                        xec.castOnTarget(hitUnit);
                    }
                    GroupAddUnit(hit, hitUnit);
                }
            }
            
            static method createMissle(real x, real y, real angle, Streams stream) -> thistype
            {
                thistype this = thistype.allocate(x, y, angle);
                this.speed = 500.;
                this.fxpath = SFX_MISSLE;
                this.collisionSize = 100.;
                this.scale = 1.5;
                this.expirationTime = 2.;
                this.z = 100.;
                
                parent = stream;
                hit = NewGroup();
                
                return this;
            }
        }
        
        struct Streams
        {
            Missle missle[2];
            
            unit caster;
            player owner;
            real damage;
            
            static method createStreams()
            {
                thistype this = thistype.allocate();
                real cx;
                real cy;
                real sx;
                real sy;
                real mx;
                real my;
                real facing;
                real angle;
                
                caster = GetTriggerUnit();
                owner = GetOwningPlayer(caster);
                damage = GetDamage(GetUnitAbilityLevel(caster, SPELL_ID));
                
                cx = GetUnitX(caster);
                cy = GetUnitY(caster);
                sx = GetSpellTargetX();
                sy = GetSpellTargetY();
                
                facing = Atan2(sy-cy, sx-cx)+bj_PI/2.;
                mx = PolarX(cx, facing, 100.);
                my = PolarY(cy, facing, 100.);
                angle = Atan2(sy-my, sx-mx);
                missle[0] = Missle.createMissle(mx, my, angle, this);
                
                facing = facing+bj_PI;
                mx = PolarX(cx, facing, 100.);
                my = PolarY(cy, facing, 100.);
                angle = Atan2(sy-my, sx-mx);
                missle[1] = Missle.createMissle(mx, my, angle, this);
            }
        }
            
        function onInit()
        {
            RegisterSpellAction(SPELL_ID, Streams.createStreams);
            
            SetupDamage();
            SetupCast();
            
            XE_PreloadAbility(STUN_ID);
            Preload(SFX_HIT);
            Preload(SFX_MISSLE);
        }
    }
    
//! endzinc

well i didnt read the code but i was talking only about projectiles.
But i found a library named (xe)projectile by azenricepuff and it made things simpler
why do u like Zinc?
 
Status
Not open for further replies.
Top