Discussion Total JassHelper overhaul project

Should JassHelper be updated?

  • Yes

    Votes: 15 60.0%
  • No

    Votes: 6 24.0%
  • Wait for Vexorian

    Votes: 4 16.0%

  • Total voters
    25

tooltiperror

Super Moderator
Reaction score
231
Ah, son, you've got 99 problems but a bitch ain't one. I'm not sure of all of them but I would assume some of them are with language design based upon your current rough draft.

You are also using shitty out-of-vJASS standards. asInt() and toString() are not made for vJASS, and don't let Nestharus tell you they are.

Make it more sane, make it more beautiful, make it more Boa.

Extending unit is basically AIDS without a textmacro?

Why are you getting rid of real? that's pointless.

At least add in ' quotes and make " direct quotations. So..

JASS:
init
    int x = 10
    string friday = "Friday"
    print("$friday is a good day") // "Friday is a good day" -- this is a low level feature
    print('$friday is a good day') // "$friday is a good day"
    print("x + 1 = 11") // "10 + 1 = 11"
    print('x + 1 == 1') // "x + 1 == 1"

Something like that.

Free-form declaration is a big no-no. It makes stuff unreadable. DO NOT IMPLEMENT IT.

unit structs are too sloppy. Make the syntax cleaner.

Add in throwing and catching errors and stuff, that's fun. and switch statements.

Rewrite optimizer while you're at it
 

Bribe

vJass errors are legion
Reaction score
67
I see what you mean by free-form declaration. How about:

JASS:
globals
    hashtable h //Private by default, like Zinc
    public int yes //Non-prefixed public variable
    public int _yes //Prefixed public variable


>> Extending unit is basically AIDS without a textmacro?

No, it means it takes "unit" instead of "integer"

>> Why are you getting rid of real? that's pointless.

"float" is more descriptive of what it actually is. If I include support for "real", I need to abolish the float keyword to keep things as neat as possible.

>> At least add in ' quotes and make " direct quotations.

Good thinking, that should be fine to implement. I assume you meant to write this:?

JASS:
    print("$x + 1 = 11") // "10 + 1 = 11"
    print('$x + 1 == 1') // "$x + 1 == 1"


>> unit structs are too sloppy. Make the syntax cleaner.

You have to say what's sloppy and you have to say what you think would make it better. That's the beauty of constructive criticism.

>> Add in throwing and catching errors and stuff, that's fun. and switch statements.

Throwing is already going to be in (throw your own syntax errors), but catching errors ... that's basically the same as a static if.

>> Make it more sane, make it more beautiful, make it more Boa.

I don't know what Boa is supposed to look like nor do I think it's fair I totally copy Vexorian's language and its name.

>> Rewrite optimizer

I'll be partially doing this (just optimizing JASS code).
 

tooltiperror

Super Moderator
Reaction score
231
That's better. I like [LJASS]:[/LJASS] from Python, but that may be overkill.

I'm talking about in functions, by the way, you use i without declaring it (BAD BAD BAD BAD BAD)

init block is a bad idea because it will all be merged in a weird way. Just support init functions, please. Call void onInit on Init.

Will it use [LJASS]//! luck[/lJASS]?
 

Bribe

vJass errors are legion
Reaction score
67
"init" is not going to be merged in a weird way. Each init block is going to be called top-to-bottom sort, except module & struct inits will run first, respectively. Each block will use ExecuteFunc to run.

I also edited my post since your reply was posted.

# luck and # endluck will be used so it seperates JASS from Luck. The hash will be used instead of the current //! for faster typing.

>> That's better. I like : from Python, but that may be overkill.

Yes, I don't include the colon because it doesn't need the colon. Same reason I didn't include semicolons and curly brackets, because they aren't needed. Piling statements on one line is bad practice in general, hurts readability, and multiline statements are already supported so there is no need for semicolon.

I used i without initializing it because I was typing it quickly. I'm glad someone noticed.
 

tooltiperror

Super Moderator
Reaction score
231
So it's a bug, not a feature :p

Moyack's Runes in Luck.

JASS:

# luck
library Runes
	globals
		constant integer SpellID = 'A000'
		constant integer RuneID  = 'o000'
		constant real    dt      = 0.2

	//==========================================================
	//  CONFIGURATION
	//==========================================================

	float Range(int level)                    // The range where the runes detect units.
		return 120. + 50. * (level - 1)

	float Radius(int level)                   // The radius where the runes will be placed.
		return 2 * Range(level)

	integer Amount(int level)                 // The amount of runes to be placed
		return 4 + 1 * (level - 1)

	float Damage(integer level)               // The damage dealt to units near the rune.
		return 350. + 50. * (level - 1)

	float Duration(integer level)             // The damage dealt to units near the runes.
		return 40. + 5. * (level - 1)		

	//==========================================================
	//  END OF CONFIGURATION
	//==========================================================

	globals
		group G = CreateGroup()

	string GetFX(integer id)
		return GetAbilityEffectById(SpellID, EFFECT_TYPE_SPECIAL, id)

	class rune
		public unit c
		public player p
		public effect f
		public float x
		public float y
		public float d = 0.
		public integer l
		public integer i

		static integer counter=0
		static thistype array runes
		static integer do=0
		static integer id=0
		public static unit dummy=null

		filter GetUnits() // This is a filter type, so just throw in return false for me at the end, please.
			unit u = GetFilterUnit()
			if (GetWidgetLife(u) > 0.405 and !IsUnitType(u, UNIT_TYPE_FLYING)) 
				SetUnitOwner(rune.dummy,rune.runes[rune.id].p,false)
				if (GetWidgetLife(rune.runes[rune.id].c) > 0.405)
					UnitDamageTarget(rune.runes[rune.id.c,u,Damage(rune.runes[rune.id].l),false,false,ATTACK_TYPE_SIEGE,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_ROCK_HEAVY_BASH)

				else
					UnitDamageTarget(rune.dummy,u,Damage(rune.runes[rune.id].l),false,false,ATTACK_TYPE_SIEGE,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_ROCK_HEAVY_BASH)
			rune.do++
			u=null

		void destroy()
			DestroyEffect(.f)
			if (.d < Duration(.L))
				DestroyEffect(AddSpecialEffect(GetFX(1),.x,.y))
				DestroyEffect(AddSpecialEffect(GetFX(2),.x,.y))
			rune.counter--
			rune.runes[rune.counter].i=.i
			rune.runes[.i]=rune.runes[rune.counter]

		public static void Start(unit c,real x,real y)
			rune R=thistype.allocate()
			if (IsPlayerAlly(GetLocalPlayer(),GetOwningPlayer(c))
				set R.f=AddSpecialEffect(GetFX(0),x,y)
			else
				set R.f=AddSpecialEffect("Abilities\\Spells\\NightElf\\TreeofLifeUpgrade\\TreeofLifeUpgradeTargetArt.mdl",x,y)
			R.c=c
			R.p=GetOwningPlayer(c)
			R.x=x
			R.y=y
			R.l=GetUnitAbilityLevel(c,SpellID)
			R.i=rune.counter
			rune.runes[rune.counter]=integer(R)
			rune.counter++

		public method Update()
			integer i=0
			loop
				exitwhen i >= rune.counter
				rune.id = i
				rune.do = 0
				rune.runes<i>.d=rune.runes<i>.d+dt
				GroupEnumUnitsInRange(G,rune.runes<i>.x,rune.runes<i>.y,Range(rune.runes<i>.l),Condition(rune.GetUnits))
				if (rune.do&gt;0 or rune.runes<i>.d&gt;=Duration(rune.runes<i>.l))
					rune.runes<i>.destroy()
				i++

	boolean Conditions()
		return GetUnitTypeId(GetSummonedUnit()) == RuneID

	void Actions()
		unit c=GetSummoningUnit()
		unit r=GetSummonedUnit()
		real lx=GetUnitX(r)
		real ly=GetUnitY(r)
		real fc=GetUnitFacing(c)*bj_DEGTORAD
		real a=Amount(GetUnitAbilityLevel(c,SpellID))
		real R=Radius(GetUnitAbilityLeveL(c,SpellID))
		real angle=2*bj_PI/a
		integer count=0
		real x
		real y
		RemoveUnit(r)
		Rune.start(c,lx,ly)
		loop exitwhen count == a // just push it down one line.
			x = lx + R * Cos(fc + count * angle)
			y = ly + R * SIN(fc + count * angle)
			rune.Start(c,x,y)
			count++
		c=null
		r=null

	void onInit
		trigger t=CreateTrigger()
		TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SUMMON)
		TriggerAddCondition(t,Condition(Conditions))
		TriggerAddAction(t,Actions)
		Preload(GetFX(0))
		Preload(GetFX(1))
		Preload(GetFX(2))
		rune.dummy=CreateUnit(Player(15),RuneID,0,0,0)
		ShowUnit(rune.dummy,false)
		TimerStart(CreateTimer(),dt,true,rune,Update)

# endluck
</i></i></i></i></i></i></i></i>
 

Bribe

vJass errors are legion
Reaction score
67
I like the idea for the filter type, that definitely will be simple to add to the compiler to just add a return false (will make things a lot easier actually).

"public" keyword is not required in structs (like Zinc). I apologize for not making that clear.

I should add "while" and "for" loops as well.

Are you now settled on float?

I'll pick a system and convert it to Luck so that people can see exactly what it should look like.
 

tooltiperror

Super Moderator
Reaction score
231
Thanks, filter will be magnificent.

for...loops are really annoying. Just add while and you'll be all set, for is just adding too much complexity for something that can be accomplished in two other ways.

Float is growing on me :)

Make T32 (short and structy) and then make kingking's typecasting library (shows textmacro use) and then finally make, like, something long and complicated.
 

Bribe

vJass errors are legion
Reaction score
67
That "Runes" build would have a few syntax errors. This is Timer32 written in Luck:

JASS:
library T32
    
    globals
        public constant float _PERIOD = 0.03125
        public constant int   _FPS    = R2I(1 / PERIOD)
        public int            _Tick   = 0
        
        trigger Trig = CreateTrigger()
    
    init
        TimerStart(CreateTimer(), PERIOD, true, lambda
            Tick++
            TriggerEvaluate(Trig)
        )
    
    public module T32x
        private thistype next
        private thistype prev
        
        #if ! thistype.periodic.exists
            throw &quot;T32 Error: The .periodic() method could not be found in the struct!&quot;
        
        void startPeriodic()
            debug if this.prev != 0 | thistype:0.next == this
                print &quot;T32 ERROR: Struct #$this had startPeriodic called while already running!&quot;
            thistype:0.next.prev = this
            this.next = thistype:0.next
            thistype:0.next = this
            this.prev = 0
        
        void stopPeriodic()
            debug if this.prev == 0 &amp; thistype:0.next != this
                print &quot;T32 ERROR: Struct #$this had stopPeriodic called while not running!&quot;
            this.prev.next = this.next
            this.next.prev = this.prev
            debug this.prev = 0
        
        init
            TriggerAddCondition(Trig, Condition(filter
                thistype this = thistype:0.next
                while this != 0
                    this.periodic()
                    this = this.next
            ))
 

tooltiperror

Super Moderator
Reaction score
231
Ew, _convention. Please nip that in the bud.

#if is useless, just use if, you're not getting any bonus functionality, control, structure, or noticeable readability.

Aren't things private by default?
 

Bribe

vJass errors are legion
Reaction score
67
Public-prefixed terms are really bad as it is. Some issues:

1. I like making library members private by default
2. The public keyword shouldn't force a library prefix in such a case
3. The "_" should only be added to the global's declaration?

Struct members are public by default.

#if is for static-if.
 

tooltiperror

Super Moderator
Reaction score
231
What is wrong with you?

Make everything private by default, members, methods, functions, everything. Also make out of library code run errors. Don't use _.

Don't make struct members public, JASS is an inherently privacy based language (or at least we use it like that).

I figured out # if in your other thread.
 

Bribe

vJass errors are legion
Reaction score
67
struct members are public by default in Zinc because public struct members are more common. I see no reason to privatize them by default in Luck. library members are private by default in Zinc because private library members are more common.

JASS:
globals
    public integer _foo


That makes it possible to reference via LibraryName_foo, but internally it is referenced as just "foo". Maybe I should add the "prefixed" keyword.

JASS:
globals
    prefixed integer foo
 

tooltiperror

Super Moderator
Reaction score
231
No, maybe you should let users handle their own problems. [LJASS]Damage_Block[/LJASS] is an example of a bad function name. [LJASS]UnitBlockDamage[/LJASS], now that's JASSy.
 

Bribe

vJass errors are legion
Reaction score
67
I think you have the right idea. If they want to namespace a public variable they can just add it to a struct anyway.

I have coded TimerUtils in Luck, please reply if you spot any irregularities or reply with comments, and ask questions if you have any.

JASS:
library TimerUtils
    
    #define
        USE_HASH_TABLE = true
        AUTO_PAUSE = true
        
        #if not USE_HASH_TABLE
            OFFSET   = 0x100000
            QUANTITY = 256
        #debug
            HELD     = -65915698
    
    globals
        timer array tT
        int tN = 0
        
        #if not USE_HASH_TABLE
            int array data
    
    #if not USE_HASH_TABLE and QUANTITY &lt;= 0
        throw &quot;TimerUtils QUANTITY must be greater than 0&quot;
    
    void SetTimerData (timer t, int value)
        #if USE_HASH_TABLE
            t.data = value //handle.data uses the built-in hashtable to reference data.
        #else
            #debug
                int i = t.id - OFFSET //handle.id == GetHandleId(handle)
                if i &lt; 0 or i &gt; 8190
                    print &quot;TIMER UTILS ERROR: ATTEMPT TO SET TIMER DATA OF BAD TIMER&quot;
                    return
            data[t.id - OFFSET] = value
    
    int GetTimerData (timer t)
        #if USE_HASH_TABLE
            return t.data
        #else
            #debug
                int i = t.id - OFFSET
                if i &lt; 0 or i &gt; 8190
                    print &quot;TIMER UTILS ERROR: ATTEMPT TO GET TIMER DATA OF BAD TIMER&quot;
                    return
            return data[t.id - OFFSET]
    
    timer NewTimer()
        #if USE_HASH_TABLE
            if tN == 0
                return CreateTimer()
        #debug
            if tN == 0
                print &quot;TIMER UTILS ERROR: EXCEEDED \&quot;QUANTITY\&quot; - INCREASE \&quot;QUANTITY\&quot; OR SET USE_HASH_TABLE TO TRUE AND ALWAYS RELEASE OLD TIMERS&quot;
                return null
        tN--
        #debug
            SetTimerData(tT[tN], 0)
        return tT[tN]
    
    void ReleaseTimer (timer t)
        #debug
            if t == null
                print &quot;TIMER UTILS ERROR: ATTEMPT TO RELEASE A NULL TIMER&quot;
                return
            elseif tN == IntegerTertiaryOp(USE_HASH_TABLE, 8191, QUANTITY)
                DestroyTimer(t)
                print &quot;TIMER UTILS ERROR: TIMER STACK IS FULL, DESTROYING TIMER $t&quot;
                return
            elseif GetTimerData(t) == HELD
                print &quot;TIMER UTILS ERROR: DOUBLE-FREE OF TIMER $t&quot;
                return
            SetTimerData(t, HELD)
        #if AUTO_PAUSE
            PauseTimer(t)
        tT[tN] = t
        tN++
    
    #if not USE_HASH_TABLE
        init
            int i = QUANTITY - 1
            while i &gt;= 0
                tT<i> = CreateTimer()
                i--
            tN = QUANTITY
            #debug
                int o = tT[0].id
                if o - OFFSET &gt;= 0
                    o = tT[tN - 1].id
                    if o - OFFSET &lt; 8191
                        return
                print &quot;TIMER UTILS ERROR: OFFSET $OFFSET IS OUT-OF-BOUNDS, SET IT TO $o TO MAKE IT WORK&quot;
</i>
 
Reaction score
456
Having no end blocks makes the code look like it doesn't have any idea of structure and all lines just seem to be floating in the middle of nowhere really. A good thing is that you have to indent properly (huge pro). Cons are that it defies eyes and brains damn hard (slows down writing).

Also void. Why void?
 

XeNiM666

I lurk for pizza
Reaction score
138
im not a fan of languages, and the only languages i know is basic C and JASS.
but can you make a version that uses the same JASS syntax?
"Luck" really seems... messy to me (no offense) :)
 

emjlr3

Change can be a good thing
Reaction score
395
fyi, if you go radically changing the structure and syntax - i don't think it will catch on
 

PurgeandFire

zxcvmkgdfg
Reaction score
509
IMO, you can add a syntax, but you should still support those features for vJASS. The syntax may or may not catch on, because to some it may be a neat syntax, and to others possibly "just another syntax to learn". Thus, I think it would be cool to have the option of whether to use that or vJASS. :)
 

tooltiperror

Super Moderator
Reaction score
231
I'm pretty sure the plan is to keep vJASS backwards compatibility.
 

Sevion

The DIY Ninja
Reaction score
424
I agree with Uberplayer. I generally dislike and will not use indention based syntax.

Keep opening and ending blocks. They help structure code and make it readable.
 
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