HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

XECollider spell

10-16-2008, 04:38 PM#1
WNxCryptic
Fixed :)

I've double checked all the dummy stuff (like the spell id is indeed A000 and whatnot), but when the spell fires the hero attacks (call SetUnitAnimation( caster, "attack" )) so I know its getting into the code, the problem is that I never see any missiles.

Collapse JASS:
library TransferSoul initializer init requires xecollider

    //==================================================================================
    // Config:
    //
    globals
        private constant integer SPELL_ID = 'A000' //The triggerer spell id.
    endglobals

    //==================================================================================
    // Code
    //
    private struct Soul extends xecollider 
        unit castingHero
        integer level 

        method onUnitHit takes unit hitunit returns nothing
            // verify we're colliding with the target unit
            if (this.targetUnit == hitunit ) then
                //Let's make the unit look as if it is taking fire, how? Let's make a fireball effect explode on them:
                call DestroyEffect( AddSpecialEffectTarget("Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl",hitunit, "origin") ) 

                // damage the target by using a dummy caster
                // isn't complete, obviously

                // We wish the missile to explode
                call this.terminate()
            endif
        endmethod

        method onDestroy takes nothing returns nothing
            //set this.castingHero = null
        endmethod
    endstruct

    private function onSpellEffect takes nothing returns nothing
        local unit tar = GetSpellTargetUnit()
        local unit caster = GetTriggerUnit()
        local real x
        local real y
        local Soul s
        local effect fx  =  AddSpecialEffectTarget("Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeTarget.mdl", tar, "origin")
        local integer i = 0

        loop
            exitwhen i==6

            set x = GetUnitX(caster)
            set y = GetUnitY(caster)

            set s = Soul.create( x, y, i*(bj_PI)/ 6 )

            set s.fxpath = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilMissile.mdl"
            set s.speed = 100.0
            set s.acceleration = 100.0
            set s.maxSpeed = 100.0
            set s.z = 50.0

            set s.angleSpeed = 1.5
            set s.targetUnit = tar

            set s.expirationTime = 5.0

            set s.castingHero = caster 
            set s.level = GetUnitAbilityLevel( caster, SPELL_ID)

            set i=i+1
        endloop
        call TriggerSleepAction(0.0)
        call SetUnitAnimation( caster, "attack" )
        call DestroyEffect(fx)

    set fx = null
    set tar = null
    set caster = null
    endfunction

    //==================================================================================
    // Init/Conditions
    //
    private function spellIdMatch takes nothing returns boolean
      return (GetSpellAbilityId() == SPELL_ID)
    endfunction
    
    private function init takes nothing returns nothing
        local trigger t=CreateTrigger()
            //preload ability
            //call XE_PreloadAbility(CAST_ABILITY_ID)
            
            //Setting up the spell's trigger:
            call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(t, Condition(function spellIdMatch))
            call TriggerAddAction(t, function onSpellEffect)
        set t=null
    endfunction
endlibrary

Edit: the onhit function is firing (I can see the death coil 'special' art firing) but no missiles still, trying to fix it.

EditEdit: Still can't get it to work right. I noticed the Nova spell is based of Doom, mine is based off of Death Coil, perhaps that's affecting it..going to try to see if a spell based off Doom will work.

Nope, I moved the Fire Nova Strike spell into my map (spell and all) and its not working =\ Going to try to port my spell into the xe 4.0 to see if I can get it working there.
10-16-2008, 07:56 PM#2
WNxCryptic
New issue that is for this spell but unrelated to XECollider:

How do you accurately detect the end of a channeling spell and how do you accurately detect if a channeling spell is ended prematurely?

I'm basing my spell off of channel.
10-16-2008, 08:05 PM#3
Bobo_The_Kodo
EVENT_PLAYER_UNIT_SPELL_FINISH?
10-16-2008, 08:23 PM#4
WNxCryptic
For a channeling spell, that successfully fires when the channeling begins (which I dont want), but not when the spell is cancelled.

Also, can I attach a struct to V's TimerUtils?
10-16-2008, 08:27 PM#5
Bobo_The_Kodo
oops i meant this:
EVENT_PLAYER_UNIT_SPELL_ENDCAST
10-16-2008, 10:33 PM#6
Toadcop
damn not another collider dude =\ ... (xD) curse you Vexorian !
10-16-2008, 10:58 PM#7
Anitarf
Quote:
Originally Posted by WNxCryptic
Also, can I attach a struct to V's TimerUtils?
Structs are just integers deep down, so yeah. For the sake of clarity, though, you should typecast them first (right now the code works even if you don't, but it may cause compile errors in the future). To typecast to a struct to integer, you just do integer(myStructVariable) and to typecast an integer back you do myStruct(integerVariable) or in your case myStruct( GetTimerData( GetExpiredTimer() ) ).
10-16-2008, 11:18 PM#8
WNxCryptic
EVENT_PLAYER_UNIT_SPELL_ENDCAST Doesn't work...

Ok, well already I'm having problems with my struct.

Collapse JASS:
    public struct inst
        unit tar
        unit caster
    endstruct
Collapse JASS:
    private function onSpellEffect takes nothing returns nothing
        local inst i
        local timer t
        
        set i.tar = GetSpellTargetUnit()
        set i.caster = GetTriggerUnit()
        
        call KillUnit(i.tar)
        
        set t = NewTimer()
        call SetTimerData(t, i)
        call TimerStart(t, .5, true, function spawnMissile)
        
        set t=null
    endfunction

Right now, even with the timer callback function disregarded, that killunit never actually kills anything...why? And yes, I've checked to make sure that the onSpellEffect code is being called (debug message).
10-17-2008, 12:13 AM#9
Rising_Dusk
You never allocate the struct that you are setting values to. Try local inst i = inst.create() for the first line of the function.
10-17-2008, 12:21 AM#10
Vexorian
Quote:
Edit: the onhit function is firing (I can see the death coil 'special' art firing) but no missiles still, trying to fix it.

EditEdit: Still can't get it to work right. I noticed the Nova spell is based of Doom, mine is based off of Death Coil, perhaps that's affecting it..going to try to see if a spell based off Doom will work.

Nope, I moved the Fire Nova Strike spell into my map (spell and all) and its not working =\ Going to try to port my spell into the xe 4.0 to see if I can get it working there.
Please tell me you implemented xebasic correctly (You copied the dummy unit, the model and set the rawcode correctly)

World editor sometimes unimports models, so if you actually got the model try importing it again, this time save immediately after importing.
10-17-2008, 01:13 AM#11
WNxCryptic
Yeah the problem was that the dummy model had been dropped off, idk why. Perhaps a random WE bug.

But its fixed now :)
10-18-2008, 02:40 AM#12
dead_or_alivex
Quote:
Structs are just integers deep down, so yeah. For the sake of clarity, though, you should typecast them first (right now the code works even if you don't, but it may cause compile errors in the future). To typecast to a struct to integer, you just do integer(myStructVariable) and to typecast an integer back you do myStruct(integerVariable) or in your case myStruct( GetTimerData( GetExpiredTimer() ) ).
Must structs be typecast into integers? Why might there be compile errors in future?

Collapse JASS:
function A takes integer structdata returns nothing
    local data d = data(structdata)
    call BJDebugMsg(GetUnitName(d.caster))
endfunction

function Actions takes nothing returns nothing
    local data d = data.create()
    set d.caster = GetTriggerUnit()
    call A(d) // I've always been doing this.
//    call A(integer(d)) // Is this needed?
endfunction

Just wondering, since I've made lots of stuff without typecasting.