• 🏆 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!
  • ✅ HD Level Design Contest #1 POLL is now OPEN! Check out the stunning visuals of the final entries. 🔗Click here to cast your vote!

[vJASS] Creating second instance of an object

Status
Not open for further replies.
Level 8
Joined
Jun 13, 2008
Messages
344
Hi...I tried to modify this spell:

http://www.hiveworkshop.com/forums/spells-569/laser-v1-2a-153037/

so just wanted to add second lightning object that is next to the original one...as if they both come from the hero's eyes. Simply I declared another lightning type variable and all other coordinates for the second one...like x1,y1,z1,tx1,tx2,tx3.....they all set correctly with their match I suppose but I got compile error like I cannot convert real to lightning and stuff...but its impossible because it already does for original lightning object and works.
So Here's the codes:

JASS:
//////////////////////////////////
//LASER v1.2a                   //
//Requires:                     //
//    T32                       //
//    GT                        //
//    Recycle                   //
scope Laser

    native UnitAlive takes unit id returns boolean

    globals
        private constant integer    RAWCODE     = 'A00Y'            //~Spell Rawcode
        private constant integer    DUMMY       = 'h007'            //~Shadow Dummy Rawcode
        
        private constant string     L_FX        = "AFOD"            //~The lightning effect
        private constant string     L_FX2       = "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnMissile.mdl"           //~The effect on the happy trails
        //private constant string     L_FX3       = "Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl"//~The effect on hit
        private constant string     L_FX3       =  "Abilities\\Spells\\Demon\\DemonBoltImpact\\DemonBoltImpact.mdl"
        private constant string     ANIMATION   = "spell third"     //The animation of the shadow
        
        private constant real       L_HEIGHT    = 225               //~Height of lightning.  Just right for Balnazzar :D
        private constant real       AOE         = 150               //~AoE of lightning
        private constant real       DURATION    = .75               //~DURATION OF SPELL ^___^
        private constant real       SHADOWLIFE  = 2.5               //~The duration of the shadow
        
        private constant attacktype ATK_TYPE    = ATTACK_TYPE_HERO  //~Attack type
        private constant damagetype DMG_TYPE    = DAMAGE_TYPE_MAGIC //~Damage type
    endglobals
    
    private function RANGE takes integer lvl returns real
        return 1000. + (lvl * 500.)
    endfunction
    
    private function DMG takes integer lvl returns real
        return lvl * 75.
    endfunction
    
//Do not touch the remaining part, or else you will be a victim of a killer.

    
    private struct Data
    
        private static group            GROUP   = CreateGroup()
        private static thistype         this
        private static conditionfunc    cf
        
        unit caster
        unit shadow
        player p
        group dmgUnits
        real x
        real x1
        real y
        real y1
        real z
        real z1
        real tx
        real tx1
        real ty
        real ty1
        real tz
        real tz1
        real angle
        real angle2
        real range
        real speed
        real dmg
        real cos
        real sin
        integer lvl
        integer ticks
        lightning l
        lightning 2
        
        private static method DoDamage takes nothing returns boolean
            local thistype  this    = thistype.this
            local unit      u       = GetFilterUnit()
            if IsUnitEnemy(u,.p) and UnitAlive(u) and IsUnitType(u,UNIT_TYPE_STRUCTURE) == false and not IsUnitInGroup(u,.dmgUnits) then
                call UnitDamageTarget(.caster,u,.dmg,true,false,ATK_TYPE,DMG_TYPE,null)
                call DestroyEffect(AddSpecialEffectTarget(L_FX3,u,"origin"))
                call GroupAddUnit(.dmgUnits,u)
            endif
            return false
        endmethod
        
        private method periodic takes nothing returns nothing
            if .ticks >= T32_Tick then
                set .tx = .tx + .cos
                set .tx1 = .tx1 + .cos
                set .ty = .ty + .sin
                set .ty1 = .ty1 + .sin
                set .tz = GetLocationZ(Location(.tx,.ty))
                set .tz1 = GetLocationZ(Location(.tx1,.ty1))
                if UnitAlive(.caster) then
                    call MoveLightningEx(.l,true,.x,.y,.z,.tx,.ty,.tz)
                    call MoveLightningEx(.2,true,.x1,.y1,.z1,.tx1,.ty1,.tz1)
                    call DestroyEffect(AddSpecialEffect(L_FX2,.tx,.ty))
                    call DestroyEffect(AddSpecialEffect(L_FX2,.tx1,.ty1))
                    call PlaySoundAtPointBJ(gg_snd_LightningBolt,100,Location(.x,.y),.z) 
                    call PlaySoundAtPointBJ(gg_snd_LightningBolt,100,Location(.x1,.y1),.z1) 
                    set thistype.this = this
                    call GroupEnumUnitsInRange(thistype.GROUP,.tx,.ty,AOE,thistype.cf)
                    call GroupEnumUnitsInRange(thistype.GROUP,.tx1,.ty1,AOE,thistype.cf)
                else
                    call DestroyLightning(.l)
                    call DestroyLightning(.2)
                endif
            else
                call DestroyLightning(.l)
                call DestroyLightning(.2)
                call .stopPeriodic()
                call Group.release(.dmgUnits)
                set .caster = null
                set .l = null
                set .2 = null
            endif
        
        endmethod
        
        implement T32x
        
        private static method Action takes nothing returns boolean
            local thistype this = thistype.create()

            set .caster     = GetTriggerUnit()
            set .p          = GetOwningPlayer(.caster)
            set .x          = GetUnitX(.caster)
            set .x1         = GetUnitX(.caster)+50
            set .y          = GetUnitY(.caster)
            set .y1         = GetUnitY(.caster)
            set .z          = GetLocationZ(Location(.x,.y)) + L_HEIGHT + GetUnitFlyHeight(.caster)
            set .z1         = GetLocationZ(Location(.x1,.y1)) + L_HEIGHT + GetUnitFlyHeight(.caster)
            set .tx         = GetSpellTargetX()
            set .tx1        = GetSpellTargetX()
            set .ty         = GetSpellTargetY()
            set .ty1        = GetSpellTargetY()
            set .tz         = GetLocationZ(Location(.tx,.ty))
            set .tz1        = GetLocationZ(Location(.tx1,.ty1))
            set .lvl        = GetUnitAbilityLevel(.caster,RAWCODE)
            set .angle      = Atan2(.ty-.y,.tx-.x)
            set .angle2      = Atan2(.ty1-.y1,.tx1-.x1)
            set .range      = RANGE(.lvl)
            set .speed      = .range / R2I(DURATION/T32_PERIOD)
            set .dmg        = DMG(.lvl)
            set .cos        = .speed * Cos(.angle)
            set .sin        = .speed * Sin(.angle)
            set .l          = AddLightningEx(L_FX,true,.x,.y,.z,.x,.y,.tz)
            set .2          = AddLightningEx(L_FX,true,.x1,.y1,.z1,.x1,.y1,.tz1)
            set .ticks      = T32_Tick + R2I(DURATION/T32_PERIOD)
            set .dmgUnits   = Group.get()
            set .tx         = .x
            set .tx1         = .x1
            set .ty         = .y
            set .ty1         = .y1
            
            call .startPeriodic()
            

            return false
        endmethod
        
        private static method Action2 takes nothing returns boolean
            local thistype this = thistype.create()
            set .caster         = GetTriggerUnit()
            set .p              = GetOwningPlayer(.caster)
            set .x              = GetUnitX(.caster)
            set .x1              = GetUnitX(.caster)
            set .y              = GetUnitY(.caster)
            set .y1              = GetUnitY(.caster)
            set .tx             = GetSpellTargetX()
            set .ty             = GetSpellTargetY()
            set .tx1             = GetSpellTargetX()
            set .ty1             = GetSpellTargetY()
            set .angle          = Atan2(.ty-.y,.tx-.x)
            set .angle2          = Atan2(.ty1-.y1,.tx1-.x1)
            set .shadow         = CreateUnit(.p,DUMMY,.x,.y,.angle*bj_RADTODEG)
            
            call SetUnitAnimation(.shadow,ANIMATION)
            call SetUnitVertexColor(.shadow,100,100,100,50)
            call SetUnitScale(.shadow,1.5,1.5,1.5)
            call UnitApplyTimedLife(.shadow,'BTLF',SHADOWLIFE)
            call UnitAddAbility(.shadow,'Amrf')
            call UnitRemoveAbility(.shadow,'Amrf')
            call SetUnitFlyHeight(.shadow,GetUnitFlyHeight(.caster),0)
            
            //Optional only.==========================================================//
            call PlaySoundAtPointBJ(gg_snd_MarkOfChaos,100,Location(.x,.y),.z)         
            //========================================================================//
            
            set .shadow         = null
            set .caster         = null
            return false
        endmethod

        private static method onInit takes nothing returns nothing
            call GT_AddStartsEffectAction(function thistype.Action,RAWCODE)
            call GT_AddBeginsCastingAction(function thistype.Action2,RAWCODE)
            
            set thistype.cf = Condition(function thistype.DoDamage)
        endmethod

    endstruct
    
endscope

is there anything I missed or there are another things I have to deal with?
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
This is caused by the font you use. The first lightning variable's name is small L, and it looks a lot like 1.

Variable names in Jass nor vJass can start with letter, so change the name to l2, and change all the references to that lightning accordingly.

The error specifically is because you do this.2 or .2 or even 2(I noticed the second form, but all three forms are valid for referencing nonstatic data inside struct inside nonstatic methods, or in methods with this variable declared), and while the first one could be parsable, the second one is actually a real, and the compiler sees it as so, and the third is actually integer. Therefore the compiler thinks you are passing real value of 0.2 into MoveLightningEx etc, whereas you are trying to pass in lightning 2.
 
Level 8
Joined
Jun 13, 2008
Messages
344
thanks...fixed it... with what kind of thought I actually named that variable with a number I still cant believe:)
it works now. two lightnings come out of hero's eyes. but only when it looks up and down. when I make it look right and left the starting positions of lightnings mess up because these operations only stores the X point of the unit not the facing angle X of it.

JASS:
set .x          = GetUnitX(.caster)-20
set .x1         = GetUnitX(.caster)+20

I need something like GetUnitFacingAngleX or something...I hope JASS has that kind of operation. -20 and +20 are the X distance between the lightnings. but I guess I need to make this difference to Y coordinate, too. Z stays same, its just the height of the lightnings.
 
Level 8
Joined
Jun 13, 2008
Messages
344
I want those 2 lightning projectiles look like coming from the hero's eyes from every angle the hero turns. I think I also should use GetUnitFacing with GetUnitX and GetUnitY somehow. Just need a correct equation for this.
 
Level 8
Joined
Jun 13, 2008
Messages
344
This is what I've done:
JASS:
            set .x          = GetUnitX(.caster)-10*Cos(GetUnitFacing(.caster)*bj_DEGTORAD)
            set .x1         = GetUnitX(.caster)+10*Cos(GetUnitFacing(.caster)*bj_DEGTORAD)
            set .y          = GetUnitY(.caster)-10*Sin(GetUnitFacing(.caster)*bj_DEGTORAD)
            set .y1         = GetUnitY(.caster)+10*Sin(GetUnitFacing(.caster)*bj_DEGTORAD)
            set .z          = GetLocationZ(Location(.x,.y)) + L_HEIGHT + GetUnitFlyHeight(.caster)
            set .z1         = GetLocationZ(Location(.x1,.y1)) + L_HEIGHT + GetUnitFlyHeight(.caster)
            set .tx         = GetSpellTargetX()-10
            set .tx1        = GetSpellTargetX()+10
            set .ty         = GetSpellTargetY()-10
            set .ty1        = GetSpellTargetY()+10
            set .tz         = GetLocationZ(Location(.tx,.ty))
            set .tz1        = GetLocationZ(Location(.tx1,.ty1))

still its not working proper...by distance if you mean the distance between two lightning it should be just 10(smallest value to show that they come from eyes) everything here so far is true right?...x starting point of lightning and tx is the end point of course....x1 to tx1 is same also(this is for the second lightning)....codes show everything you need to see. dont know what else to do
 
Level 8
Joined
Jun 13, 2008
Messages
344
Im not sure if I should change - with + but there is a logical problem at there.
If I look down or up, cos(90 or 270) is gonna give me 0 which will make the starting points of lightnings same, I mean they wont look like as if they come from eyes it will be seen like one lightning.

cant figuring out a simple stuff like this is really devastating:|
 
Level 8
Joined
Jun 13, 2008
Messages
344
anyways, got it finally...here's the correct codes if you want this spell to look like superman's heatvision

JASS:
scope Laser

    native UnitAlive takes unit id returns boolean

    globals
        private constant integer    RAWCODE     = 'A00Y'            //~Spell Rawcode
        private constant integer    DUMMY       = 'h007'            //~Shadow Dummy Rawcode
        
        private constant string     L_FX        = "AFOD"            //~The lightning effect
        private constant string     L_FX2       = "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnMissile.mdl"           //~The effect on the happy trails
        //private constant string     L_FX3       = "Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl"//~The effect on hit
        private constant string     L_FX3       =  "Abilities\\Spells\\Demon\\DemonBoltImpact\\DemonBoltImpact.mdl"
        private constant string     ANIMATION   = "spell third"     //The animation of the shadow
        
        private constant real       L_HEIGHT    = 225               //~Height of lightning.  Just right for Balnazzar :D
        private constant real       AOE         = 150               //~AoE of lightning
        private constant real       DURATION    = .75               //~DURATION OF SPELL ^___^
        private constant real       SHADOWLIFE  = 2.5               //~The duration of the shadow
        
        private constant attacktype ATK_TYPE    = ATTACK_TYPE_HERO  //~Attack type
        private constant damagetype DMG_TYPE    = DAMAGE_TYPE_MAGIC //~Damage type
    endglobals
    
    private function RANGE takes integer lvl returns real
        return 1000. + (lvl * 500.)
    endfunction
    
    private function DMG takes integer lvl returns real
        return lvl * 75.
    endfunction
    
//Do not touch the remaining part, or else you will be a victim of a killer.

    
    private struct Data
    
        private static group            GROUP   = CreateGroup()
        private static thistype         this
        private static conditionfunc    cf
        
        unit caster
        unit shadow
        player p
        group dmgUnits
        real x
        real x1
        real y
        real y1
        real z
        real z1
        real tx
        real tx1
        real ty
        real ty1
        real tz
        real tz1
        real angle
        real angle2
        real range
        real speed
        real dmg
        real cos
        real sin
        integer lvl
        integer ticks
        lightning l
        lightning l2
        
        private static method DoDamage takes nothing returns boolean
            local thistype  this    = thistype.this
            local unit      u       = GetFilterUnit()
            if IsUnitEnemy(u,.p) and UnitAlive(u) and IsUnitType(u,UNIT_TYPE_STRUCTURE) == false and not IsUnitInGroup(u,.dmgUnits) then
                call UnitDamageTarget(.caster,u,.dmg,true,false,ATK_TYPE,DMG_TYPE,null)
                call DestroyEffect(AddSpecialEffectTarget(L_FX3,u,"origin"))
                call GroupAddUnit(.dmgUnits,u)
            endif
            return false
        endmethod
        
        private method periodic takes nothing returns nothing
            if .ticks >= T32_Tick then
                set .tx = .tx + .cos
                set .tx1 = .tx1 + .cos
                set .ty = .ty + .sin
                set .ty1 = .ty1 + .sin
                set .tz = GetLocationZ(Location(.tx,.ty))
                set .tz1 = GetLocationZ(Location(.tx1,.ty1))
                if UnitAlive(.caster) then
                    call MoveLightningEx(.l,true,.x,.y,.z,.tx,.ty,.tz)
                    call MoveLightningEx(.l2,true,.x1,.y1,.z1,.tx1,.ty1,.tz1)
                    call DestroyEffect(AddSpecialEffect(L_FX2,.tx,.ty))
                    call DestroyEffect(AddSpecialEffect(L_FX2,.tx1,.ty1))
                    call PlaySoundAtPointBJ(gg_snd_LightningBolt,100,Location(.x,.y),.z) 
                    call PlaySoundAtPointBJ(gg_snd_LightningBolt,100,Location(.x1,.y1),.z1) 
                    set thistype.this = this
                    call GroupEnumUnitsInRange(thistype.GROUP,.tx,.ty,AOE,thistype.cf)
                    call GroupEnumUnitsInRange(thistype.GROUP,.tx1,.ty1,AOE,thistype.cf)
                else
                    call DestroyLightning(.l)
                    call DestroyLightning(.l2)
                endif
            else
                call DestroyLightning(.l)
                call DestroyLightning(.l2)
                call .stopPeriodic()
                call Group.release(.dmgUnits)
                set .caster = null
                set .l = null
                set .l2 = null
            endif
        
        endmethod
        
        implement T32x
        
        private static method Action takes nothing returns boolean
            local thistype this = thistype.create()

            set .caster     = GetTriggerUnit()
            set .p          = GetOwningPlayer(.caster)
            set .x          = GetUnitX(.caster)-20*Sin(GetUnitFacing(.caster)*bj_DEGTORAD)
            set .x1         = GetUnitX(.caster)+20*Sin(GetUnitFacing(.caster)*bj_DEGTORAD)
            set .y          = GetUnitY(.caster)+20*Cos(GetUnitFacing(.caster)*bj_DEGTORAD)
            set .y1         = GetUnitY(.caster)-20*Cos(GetUnitFacing(.caster)*bj_DEGTORAD)
            set .z          = GetLocationZ(Location(.x,.y)) + L_HEIGHT + GetUnitFlyHeight(.caster)
            set .z1         = GetLocationZ(Location(.x1,.y1)) + L_HEIGHT + GetUnitFlyHeight(.caster)
            set .tx         = GetSpellTargetX()-20*Sin(GetUnitFacing(.caster)*bj_DEGTORAD)
            set .tx1        = GetSpellTargetX()+20*Sin(GetUnitFacing(.caster)*bj_DEGTORAD)
            set .ty         = GetSpellTargetY()+20*Cos(GetUnitFacing(.caster)*bj_DEGTORAD)
            set .ty1        = GetSpellTargetY()-20*Cos(GetUnitFacing(.caster)*bj_DEGTORAD)
            set .tz         = GetLocationZ(Location(.tx,.ty))
            set .tz1        = GetLocationZ(Location(.tx1,.ty1))
            set .lvl        = GetUnitAbilityLevel(.caster,RAWCODE)
            set .angle      = Atan2(.ty-.y,.tx-.x)
            set .angle2      = Atan2(.ty1-.y1,.tx1-.x1)
            set .range      = RANGE(.lvl)
            set .speed      = .range / R2I(DURATION/T32_PERIOD)
            set .dmg        = DMG(.lvl)
            set .cos        = .speed * Cos(.angle)
            set .sin        = .speed * Sin(.angle)
            set .l          = AddLightningEx(L_FX,true,.x,.y,.z,.x,.y,.tz)
            set .l2          = AddLightningEx(L_FX,true,.x1,.y1,.z1,.x1,.y1,.tz1)
            set .ticks      = T32_Tick + R2I(DURATION/T32_PERIOD)
            set .dmgUnits   = Group.get()
            set .tx         = .x
            set .tx1         = .x1
            set .ty         = .y
            set .ty1         = .y1
            
            call .startPeriodic()
            

            return false
        endmethod
        
        private static method Action2 takes nothing returns boolean
            local thistype this = thistype.create()
            set .caster         = GetTriggerUnit()
            set .p              = GetOwningPlayer(.caster)
            set .x              = GetUnitX(.caster)
            set .x1              = GetUnitX(.caster)
            set .y              = GetUnitY(.caster)
            set .y1              = GetUnitY(.caster)
            set .tx             = GetSpellTargetX()
            set .ty             = GetSpellTargetY()
            set .tx1             = GetSpellTargetX()
            set .ty1             = GetSpellTargetY()
            set .angle          = Atan2(.ty-.y,.tx-.x)
            set .angle2          = Atan2(.ty1-.y1,.tx1-.x1)
            set .shadow         = CreateUnit(.p,DUMMY,.x,.y,.angle*bj_RADTODEG)
            
            call SetUnitAnimation(.shadow,ANIMATION)
            call SetUnitVertexColor(.shadow,100,100,100,50)
            call SetUnitScale(.shadow,1.5,1.5,1.5)
            call UnitApplyTimedLife(.shadow,'BTLF',SHADOWLIFE)
            call UnitAddAbility(.shadow,'Amrf')
            call UnitRemoveAbility(.shadow,'Amrf')
            call SetUnitFlyHeight(.shadow,GetUnitFlyHeight(.caster),0)
            
            //Optional only.==========================================================//
            call PlaySoundAtPointBJ(gg_snd_MarkOfChaos,100,Location(.x,.y),.z)         
            //========================================================================//
            
            set .shadow         = null
            set .caster         = null
            return false
        endmethod

        private static method onInit takes nothing returns nothing
            call GT_AddStartsEffectAction(function thistype.Action,RAWCODE)
            call GT_AddBeginsCastingAction(function thistype.Action2,RAWCODE)
            
            set thistype.cf = Condition(function thistype.DoDamage)
        endmethod

    endstruct
    
endscope

thanks for your time guys.
 
Status
Not open for further replies.
Top