• 🏆 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] Unexpected end of line

Status
Not open for further replies.
How can I keep the organization the way it is and avoid this error?
 

Attachments

  • d3dgf4g66.gif
    d3dgf4g66.gif
    149.6 KB · Views: 236
You're putting linebreaks between those ands when instead you should be putting comment delimiters:

JASS:
if ble
and bla
and blo then

->

JASS:
if ble /*
*/ and bla /*
*/ and blo then

This is because JassHelper deletes everything between comment delimiters.. even linebreaks.

Your algorithm is uberslow, you should do something like this instead;

JASS:
globals
    Table isDummy
endglobals

function onInit takes nothing returns nothing
    set isDummy = Table.create()
    set isDummy[unitId] = true
    set isDummy[otherUnitId] = true
    ...
endfunction

function yourfunction takes nothing returns nothing
    if conditions and not isDummy[GetUnitTypeId(unit)] then
        // do stuff
    endif
endfunction

By the way, doesn't GetUnitTypeId only take one argument? (a unit argument)
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
JASS:
static hashtable TABLE

static method ExcludeUnitTypeId takes integer id returns nothing
    call SaveBoolean(thistype.TABLE, id, 0, true)
endfunction

static method onInit takes nothing returns nothing
    set thistype.TABLE = InitHashtable()

    call thistype.ExcludeUnitTypeId('h01E')
    call thistype.ExcludeUnitTypeId('e002')
    call thistype.ExcludeUnitTypeId('h00J')
    //...
endmethod

call:

JASS:
if (LoadInteger(thistype.TABLE, GetUnitTypeId(filter), 0) == false) then
 
I'll go ahead and post the whole spell as I'm lost.

JASS:
library MeatGrinder initializer start uses AIDS,T32,TimerUtils,AutoFly
//====================================================//
//                   MEAT GRINDER
//====================================================//
//                   made by Dirac

//best used with default settings and tower model Slaughterhouse with "work" animation
//if you want to prevent any unit in your map from being summoed as a corpse make sure to add it to MeatGrinder_AvoidGroup

    globals
//main setup
        private constant integer DUMMY='e000' //raw code of the dummy
        private constant integer TOWER='u5IN' //raw code of the tower
//damage and stats
        private constant real ANGLEGAP=35 //aperture of the angle it takes the corpse to adquire a target based on it's facing
        private constant real SPEED=950*T32_PERIOD //speed of the corpse when attacking
        private constant real NORMALSPEED=450*T32_PERIOD //speed of the corpse when spinning around tower
        private constant real SPIN=147.2*T32_PERIOD //angle rotation speed around tower
        private constant real DELAY=0.5 //the delay between summoning corpses
        private constant real COOLDOWN=0 //attack cooldown
        private constant real DMG=0
        private constant real AOE=270
        private constant real HPDMG=0.30 //corpses can deal a fraction of the unit's max life if wanted
        private constant real AOEMULT=1 //this multiplies the damage done to the target and deals that number to AoE targets.
        private constant real ADQUISITION=1200
        private constant real RANGE=800
        private constant real MAXCORPSES=6
//stetics
        private constant real TOWERANGLE=90 //facing angle of the corpse towards the tower
        private constant real RADIUS=100 //radius the corpses rotate around
        private constant real HEIGHT=290 //initial height of the corpses
        private constant real CORPSESIZE=1.2 //size of each corpse (1.00=100%)
        private constant string CORPSEFX="Abilities\\Weapons\\MeatwagonMissile\\MeatwagonMissile.mdl" //corpse effect
        private constant string SUMMONFX="Abilities\\Spells\\Undead\\RaiseSkeletonWarrior\\RaiseSkeleton.mdl" //effect created when summons a corpse
    endglobals
//====================================================//
//                END CONFIGURATION
//====================================================//

    globals
        private unit TempUnit
        private group Group=CreateGroup()
        private group TowerGroup=CreateGroup()
        public group AvoidGroup=CreateGroup() //units inside this group won't be summoned as corpses
    endglobals
    
    //===========TOWER STRUCT==========//
    private struct MeatGrinder extends array
        readonly real x
        readonly real y
        readonly real z
        real tick
        real cooldown
        integer corpsecount
        group corpsegroup
        
        private static method AIDS_filter takes unit u returns boolean
            return GetUnitTypeId(u)==TOWER
        endmethod
        
        private method periodic takes nothing returns nothing
            set .tick=RMaxBJ(.tick-T32_PERIOD,0.) //i use T32 here because i wan't this to be very exact, using TimerUtils would give me a I2S(DELAY) margin of error
            set .cooldown=.cooldown-T32_PERIOD
        endmethod
        
        implement T32x
        
        private method AIDS_onCreate takes nothing returns nothing
            set .corpsecount=0
            set .cooldown=0.
            set .tick=0.
            set .corpsegroup=CreateGroup()
            set .x=GetUnitX(.unit)
            set .y=GetUnitY(.unit)
            set .z=GetLocationZ(Location(.x,.y))
        endmethod
        
        private method AIDS_onDestroy takes nothing returns nothing
            set .corpsecount=0
            set .tick=0.
            call DestroyGroup(.corpsegroup)
        endmethod

        //! runtextmacro AIDS()
    endstruct
    
    //===========INDEX CORPSE==========//
    private struct CorpseIndex extends array
        integer data //this attaches every corpse their struct.
        //I made this to remove the corpses when the tower dies
        
        static method AIDS_filter takes unit u returns boolean
            return GetUnitTypeId(u)==DUMMY
        endmethod
        //! runtextmacro AIDS()
    endstruct
    
    //===========CORPSE STRUCT==========//
    private struct Corpse
        MeatGrinder tower
        readonly real towerX
        readonly real towerY
        readonly real distance
        private real selfdelay
        private real damage
        private real ux
        private real uy
        private real ua
        private player owner
        private unit thecorpse
        private unit target
        private unit dead
        private effect fx
        private static thistype currentdata

        method operator x takes nothing returns real
            return .ux
        endmethod
        method operator x= takes real a returns nothing
            call SetUnitX(.thecorpse,a)
            set .ux=a
        endmethod
        method operator y takes nothing returns real
            return .uy
        endmethod
        method operator y= takes real a returns nothing
            call SetUnitY(.thecorpse,a)
            set .uy=a
        endmethod
        method operator xyangle takes nothing returns real
            return .ua
        endmethod
        method operator xyangle= takes real a returns nothing
            call SetUnitFacing(.thecorpse,a*bj_RADTODEG)
            set .ua=a
        endmethod

        method destroy takes nothing returns nothing
            call DestroyEffect(.fx)
            call RemoveUnit(.thecorpse)
            set .target=null
            set .thecorpse=null
            call .stopPeriodic()
            call .deallocate()
        endmethod

        static method AddCorpse takes nothing returns boolean
            local unit filter=GetFilterUnit()
            local MeatGrinder this=MeatGrinder[TempUnit]
            if IsUnitAlly(TempUnit,GetOwningPlayer(filter))==false and IsUnitInGroup(filter,AvoidGroup)==false and this.corpsecount<MAXCORPSES and GetWidgetLife(filter)<=0
            //Dummy Units
            and GetUnitTypeId(filter,'h01E')==false and GetUnitTypeId(filter,'e002')==false and GetUnitTypeId(filter,'h00J')==false and GetUnitTypeId(filter,'h00P')==false
            and GetUnitTypeId(filter,'h01J')==false and GetUnitTypeId(filter,'e003')==false and GetUnitTypeId(filter,'h00T')==false and GetUnitTypeId(filter,'h013')==false
            and GetUnitTypeId(filter,'e1LL')==false and GetUnitTypeId(filter,'e007')==false and GetUnitTypeId(filter,'h00Y')==false and GetUnitTypeId(filter,'h012')==false
            and GetUnitTypeId(filter,'e009')==false and GetUnitTypeId(filter,'e000')==false and GetUnitTypeId(filter,'h00V')==false and GetUnitTypeId(filter,'h4CQ')==false
            and GetUnitTypeId(filter,'e008')==false and GetUnitTypeId(filter,'e004')==false and GetUnitTypeId(filter,'h003')==false and GetUnitTypeId(filter,'h5G4')==false
            and GetUnitTypeId(filter,'h5G3')==false and GetUnitTypeId(filter,'h7P1')==false and GetUnitTypeId(filter,'h5UD')==false and GetUnitTypeId(filter,'h7P2')==false
            and GetUnitTypeId(filter,'h7P3')==false and GetUnitTypeId(filter,'h8UD')==false and GetUnitTypeId(filter,'h5G0')==false and GetUnitTypeId(filter,'h4UF')==false
            and GetUnitTypeId(filter,'h01K')==false and GetUnitTypeId(filter,'hL7X')==false and GetUnitTypeId(filter,'h01B')==false and GetUnitTypeId(filter,'h01C')==false
            and GetUnitTypeId(filter,'h00F')==false and GetUnitTypeId(filter,'h3T2')==false and GetUnitTypeId(filter,'h3T0')==false and GetUnitTypeId(filter,'h3T1')==false
            and GetUnitTypeId(filter,'h00Z')==false and GetUnitTypeId(filter,'h0B9')==false and GetUnitTypeId(filter,'h001')==false and GetUnitTypeId(filter,'h00M')==false
            and GetUnitTypeId(filter,'h00N')==false and GetUnitTypeId(filter,'h018')==false and GetUnitTypeId(filter,'h00O')==false and GetUnitTypeId(filter,'h006')==false
            and GetUnitTypeId(filter,'h008')==false and GetUnitTypeId(filter,'h00H')==false and GetUnitTypeId(filter,'h011')==false and GetUnitTypeId(filter,'h00Q')==false
            and GetUnitTypeId(filter,'h00R')==false and GetUnitTypeId(filter,'h00S')==false and GetUnitTypeId(filter,'h016')==false and GetUnitTypeId(filter,'h00D')==false
            and GetUnitTypeId(filter,'h00L')==false and GetUnitTypeId(filter,'h00X')==false and GetUnitTypeId(filter,'h00W')==false and GetUnitTypeId(filter,'h01A')==false
            and GetUnitTypeId(filter,'h01F')==false and GetUnitTypeId(filter,'hLC2')==false and GetUnitTypeId(filter,'h01H')==false and GetUnitTypeId(filter,'h01D')==false
            and GetUnitTypeId(filter,'h004')==false and GetUnitTypeId(filter,'o00C')==false and GetUnitTypeId(filter,'oK97')==false and GetUnitTypeId(filter,'dumy')==false
            and GetUnitTypeId(filter,'dmy2')==false and GetUnitTypeId(filter,'drks')==false and GetUnitTypeId(filter,'n014')==false and GetUnitTypeId(filter,'n00D')==false
            and GetUnitTypeId(filter,'n006')==false and GetUnitTypeId(filter,'n00U')==false and GetUnitTypeId(filter,'n00I')==false and GetUnitTypeId(filter,'n00N')==false
            and GetUnitTypeId(filter,'n012')==false and GetUnitTypeId(filter,'n018')==false and GetUnitTypeId(filter,'n019')==false and GetUnitTypeId(filter,'n017')==false
            and GetUnitTypeId(filter,'n00X')==false and GetUnitTypeId(filter,'n00Z')==false and GetUnitTypeId(filter,'n003')==false and GetUnitTypeId(filter,'n00J')==false
            and GetUnitTypeId(filter,'n016')==false and GetUnitTypeId(filter,'n015')==false and GetUnitTypeId(filter,'n010')==false and GetUnitTypeId(filter,'n00K')==false
            and GetUnitTypeId(filter,'n00L')==false and GetUnitTypeId(filter,'n00Y')==false and GetUnitTypeId(filter,'n00G')==false and GetUnitTypeId(filter,'n00O')==false
            and GetUnitTypeId(filter,'n00C')==false and GetUnitTypeId(filter,'n00M')==false and GetUnitTypeId(filter,'n00P')==false and GetUnitTypeId(filter,'n011')==false
            and GetUnitTypeId(filter,'n00R')==false and GetUnitTypeId(filter,'n005')==false and GetUnitTypeId(filter,'n001')==false and GetUnitTypeId(filter,'n007')==false
            and GetUnitTypeId(filter,'u003')==false
            //Special Units
            and GetUnitTypeId(filter,'uJ5P')==false and GetUnitTypeId(filter,'N00Q')==false
            then
                call thistype.create(GetUnitX(filter),GetUnitY(filter),DELAY,filter,this)
            endif
            set filter=null
            return false
        endmethod

        private static method SetTarget takes nothing returns boolean
            local unit filter=GetFilterUnit()
            local real x
            local real y
            local real a
            local real dif

            if GetWidgetLife(filter)>0 and IsUnitAlly(filter,currentdata.owner)!=true and currentdata.tower.cooldown<=0 and currentdata.selfdelay>=0.8 then
                //first check if the unit is a valid target to then do the math
                set x=GetUnitX(filter)
                set y=GetUnitY(filter)
                set a=Atan2(y-currentdata.y,x-currentdata.x)
                set dif=(currentdata.xyangle-a)*bj_RADTODEG
                if ((dif<=(ANGLEGAP/2) and dif>=-(ANGLEGAP/2)) or (dif<=360+(ANGLEGAP/2) and dif>=360-(ANGLEGAP/2)) or (dif<=-360+(ANGLEGAP/2) and dif>=-360-(ANGLEGAP/2))) then
                    set currentdata.target=filter
                    set currentdata.tower.cooldown=COOLDOWN
                endif
            endif
            set filter=null
            return false
        endmethod
        
        private static method aoedmg takes nothing returns boolean
            local unit filter=GetFilterUnit()
            local real x=GetUnitX(filter)
            local real y=GetUnitY(filter)
            if GetUnitState(filter,UNIT_STATE_LIFE)>0 and IsUnitAlly(filter,currentdata.owner)!=true and currentdata.target!=filter then
                call UnitDamageTarget(currentdata.tower.unit,filter,currentdata.damage*AOEMULT,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
            endif
            set filter=null
            return false
        endmethod

        private method periodic takes nothing returns nothing
            local real a
            local real x
            local real y
            local real z
            local real dist
            
            if GetUnitTypeId(.target)==0 then
                set dist=SquareRoot((.towerX-.x)*(.towerX-.x)+(.towerY-.y)*(.towerY-.y))
                set .selfdelay=RADIUS/dist
                set a=Atan2(.towerY-.y,.towerX-.x)-90*((RADIUS)/(dist))*bj_DEGTORAD
                set .currentdata=this
                call GroupEnumUnitsInRange(Group,.x,.y,RANGE,function thistype.SetTarget)
                set z=HEIGHT+.tower.z+(((HEIGHT+.tower.z)/(.distance-RADIUS))*(.distance-dist)-HEIGHT-.tower.z)
                set x=.x+NORMALSPEED*Cos(a)
                set y=.y+NORMALSPEED*Sin(a)
            else
                set x=GetUnitX(.target)
                set y=GetUnitY(.target)
                set a=Atan2(y-.y,x-.x)
                set .distance=SquareRoot((.towerX-x)*(.towerX-x)+(.towerY-y)*(.towerY-y))
                set dist=SquareRoot((.x-towerX)*(.x-towerX)+(.y-towerY)*(.y-towerY))
                if SquareRoot((.x-x)*(.x-x)+(.y-y)*(.y-y))<=SPEED+1 then
                    call UnitDamageTarget(.tower.unit,.target,.damage,true,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
                    set .tower.corpsecount=.tower.corpsecount-1
                    if .tower.corpsecount==0 then //this add unused corpses nearby to the tower
                        set TempUnit=.tower.unit
                        call GroupEnumUnitsInRange(Group,.towerX,.towerY,ADQUISITION,Filter(function thistype.AddCorpse))
                    endif
                    set currentdata=this
                    call GroupEnumUnitsInRange(Group,x,y,AOE,function thistype.aoedmg)
                    call DestroyEffect(AddSpecialEffect(CORPSEFX,x,y))
                    call .destroy()
                    return
                endif
                set x=.x+SPEED*Cos(a)
                set y=.y+SPEED*Sin(a)
                set z=HEIGHT+.tower.z+(((HEIGHT+.tower.z)/(.distance-RADIUS))*(.distance-dist)-HEIGHT-.tower.z)
            endif
            set .xyangle=a
            set .x=x
            set .y=y
            call SetUnitFlyHeight(.thecorpse,z-GetLocationZ(Location(.x,.y)),0.)
        endmethod
        
        implement T32x
        
        private static method summon takes nothing returns nothing
            local timer t=GetExpiredTimer()
            local thistype this=GetTimerData(t)
            
            if IsUnitInGroup(.tower.unit,TowerGroup) then
                set .fx=AddSpecialEffectTarget(CORPSEFX,.thecorpse,"origin")
                call DestroyEffect(AddSpecialEffect(SUMMONFX,.x,.y))
                call .startPeriodic()
            else
                call RemoveUnit(.thecorpse)
            endif
            call RemoveUnit(.dead)
            set .dead=null
            call ReleaseTimer(t)
        endmethod
        
        static method create takes real x,real y,real delay,unit whichUnit,MeatGrinder whichStruct returns thistype
            local thistype this=thistype.allocate()
            local real centerX=GetUnitX(whichStruct.unit)
            local real centerY=GetUnitY(whichStruct.unit)
            local real a=Atan2(centerY-y,centerX-x)
            local timer t=NewTimer()
            
            call SetTimerData(t,this)
            set whichStruct.tick=whichStruct.tick+delay
            set whichStruct.corpsecount=whichStruct.corpsecount+1
            call GroupAddUnit(AvoidGroup,whichUnit)
            call TimerStart(t,whichStruct.tick,false,function thistype.summon)
            set .distance=SquareRoot((centerX-x)*(centerX-x)+(centerY-y)*(centerY-y))
            set .towerX=centerX
            set .towerY=centerY
            set .target=null
            set .tower=whichStruct
            set .selfdelay=1.2
            set .dead=whichUnit
            set .damage=HPDMG*GetUnitState(whichUnit,UNIT_STATE_MAX_LIFE)+DMG
            set .owner=GetOwningPlayer(whichStruct.unit)
            set .thecorpse=CreateUnit(.owner,DUMMY,x,y,a*bj_RADTODEG)
            set CorpseIndex[.thecorpse].data=this
            set .ux=GetUnitX(.thecorpse)
            set .uy=GetUnitY(.thecorpse)
            call SetUnitScale(.thecorpse,CORPSESIZE,CORPSESIZE,CORPSESIZE)
            call GroupAddUnit(whichStruct.corpsegroup,.thecorpse)
            set t=null
            return this
        endmethod
    endstruct

//===========STARTUP AND UNIT DEATH==========//
    private function range takes nothing returns nothing
        local unit filter=GetEnumUnit()
        local MeatGrinder this=MeatGrinder[filter]
        local real x1=GetUnitX(filter)
        local real y1=GetUnitY(filter)
        local real x2=GetUnitX(TempUnit)
        local real y2=GetUnitY(TempUnit)
        local real xy=SquareRoot((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
        
        if xy<=ADQUISITION and IsUnitAlly(TempUnit,GetOwningPlayer(filter))==false and IsUnitInGroup(TempUnit,AvoidGroup)==false and this.corpsecount<MAXCORPSES then
            call Corpse.create(x2,y2,DELAY,TempUnit,this)
            return
        endif
        set filter=null
    endfunction
    
    private function DeleteCorpse takes nothing returns nothing
        local Corpse this=CorpseIndex[GetEnumUnit()].data
        call this.destroy()
    endfunction

    private function UnitDeath takes nothing returns boolean
        set TempUnit=GetTriggerUnit()
        call ForGroup(TowerGroup,function range)
        if GetUnitTypeId(TempUnit)==TOWER then
            call ForGroup(MeatGrinder[TempUnit].corpsegroup,function DeleteCorpse)
            call GroupRemoveUnit(TowerGroup,TempUnit)
        endif
        return false
    endfunction

    private function EnableTower takes nothing returns boolean
        local unit u=GetTriggerUnit()
        
        if GetUnitTypeId(u)==TOWER then
            call MeatGrinder[u].startPeriodic()
            call GroupAddUnit(TowerGroup,u)
            set TempUnit=u
            call GroupEnumUnitsInRange(Group,GetUnitX(u),GetUnitY(u),ADQUISITION,function Corpse.AddCorpse)
        endif
        set u=null
        return false
    endfunction
    
    private function InitTower takes nothing returns boolean
        local unit u=GetFilterUnit()
        
        if GetUnitTypeId(u)==TOWER then
            call MeatGrinder[u].startPeriodic()
            call GroupAddUnit(TowerGroup,u)
        endif
        set u=null
        return false
    endfunction
    
    private function start takes nothing returns nothing
        local trigger trig=CreateTrigger()
        local trigger construction=CreateTrigger()
        local integer i=0
        loop
            call TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_DEATH, null)
            call TriggerRegisterPlayerUnitEvent(construction,Player(i),EVENT_PLAYER_UNIT_CONSTRUCT_FINISH, null)
            set i=i+1
            exitwhen i==bj_MAX_PLAYER_SLOTS
        endloop
        call TriggerAddCondition(trig,function UnitDeath)
        call TriggerAddCondition(construction,function EnableTower)
        call GroupEnumUnitsInRect(Group,bj_mapInitialPlayableArea,function InitTower)
        set trig=null
    endfunction
endlibrary
 
Level 19
Joined
Aug 8, 2007
Messages
2,765
Give all those units a special passive hidden ability and check to make sure the selected target doesnt have that ability.. much easier than doing it via code
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Of course, browsing through the slow object editor, configuring an ability, entering each unit's properties and adding this ability manually, turning it ugly because it's shared data, is easier than just listing all the ids in an init function.[/irony]

I agree however that if you just want to exclude all dummy units, this would probably be the case in different occasions. So create some header function for this task.
 
Status
Not open for further replies.
Top