wc3campaigns
WC3C Homepage - www.wc3c.netUser Control Panel (Requires Log-In)Engage in discussions with other users and join contests in the WC3C forums!Read one of our many tutorials, ranging in difficulty from beginner to advanced!Show off your artistic talents in the WC3C Gallery!Download quality models, textures, spells (vJASS/JASS), systems, and scripts!Download maps that have passed through our rigorous approval process!

Go Back   Wc3C.net > Warcraft III Modding > Developer's Corner > Triggers & Scripts
User Name
Password
Register Rules Get Hosted! Chat Pastebin FAQ and Rules Members List Calendar



Reply
 
Thread Tools Search this Thread
Old 01-28-2010, 08:04 PM   #1
Titanhex
User
 
Join Date: Jul 2008
Posts: 34

Titanhex has little to show at this moment (5)

Default Help using xefx

Unfortunately I couldn't get much out of xefx's demo spell, seeing as how it incorporated collider and whatnot. So I was setback trying to use it for my purposes.

I have two spells. One where the unit throws a vial concoction at a target point which subsequently explodes upon landing and damages enemies in an area with smaller damage over time. So it's pretty much flamestrike with a missile.

The other is where a unit throws a glaive that hits a targeted enemy.

Now I'm just entering into vJASS, and am still researching all it can do. So far I've just been using it to replace hashtables.

Anyways any help using the xefx system would be appreciated. Here is the code I'm doing too.

Hidden information:
Collapse JASS:
scope AlcheBomb initializer InitTrig_AlcheBomb

globals
    private constant integer    SpellID = 'bomb'
    private constant damagetype dmg     = DAMAGE_TYPE_FIRE
    private constant weapontype wpn     = WEAPON_TYPE_WHOKNOWS
    private constant attacktype atk     = ATTACK_TYPE_MAGIC
    private constant string  MODEL_PATH_MISSILE       = "Abilities\\Weapons\\BatTrollMissile\\BatTrollMissile.mdl"
    private constant string  MODEL_PATH_FLASH         = null
endglobals

private function speed takes nothing returns integer
    return 700
endfunction

   private function castRecycleDelay takes real level, real bonuslevel returns real
       return 5.0 * level + 0.0*bonuslevel + 0.0
   endfunction
   
private struct Data
    unit c
    real X2
    real Y2
    real til
    real dur
    group g
    
    static method create takes unit caster, real targX, real targY, real until, real duration, group gro returns Data
     local Data D = Data.allocate()
        set D.c = caster
        set D.X2 = targX
        set D.Y2 = targY
        set D.til = until
        set D.dur = duration
        set D.g = gro
     return D
    endmethod
    
endstruct

private function AlcheBomb_Conditions takes nothing returns boolean    
    return GetSpellAbilityId() == SpellID
endfunction

private function AlcheBomb_Timer takes nothing returns nothing
    local timer tim = GetExpiredTimer()
    local Data D = Data(GetTimerData(tim))
    local unit t
    local real X1
    local real Y1
    if D.dur >= 5. then
        call ReleaseTimer(tim)
        call D.destroy()
    else
    call GroupEnumUnitsInRange(D.g, D.X2, D.Y2, 350 + 85. * (GetUnitAbilityLevel(D.c, SpellID) - 1), null)
    loop
        set t = FirstOfGroup(D.g)
    exitwhen t == null
        if IsUnitEnemy(t, GetOwningPlayer(D.c)) and GetWidgetLife(t) >= 1 then
            call UnitDamageTarget(D.c, t, 5 * GetUnitAbilityLevel(D.c, SpellID), true, false, atk, dmg, wpn)
            call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl", t, "origin"))
        endif
        set X1 = GetUnitX(t)
        set Y1 = GetUnitY(t)
        call GroupRemoveUnit(D.g, t)
    endloop
    set D.dur = D.dur + 1.
    endif
 set t = null
endfunction

private function AlcheBomb_Actions takes nothing returns nothing
 local timer tim = NewTimer()
 local Data D = Data.create(GetTriggerUnit(), GetSpellTargetX(), GetSpellTargetY(), 0., 0., CreateGroup())
 local unit t
 local real X1 = GetUnitX(D.c)
 local real Y1 = GetUnitY(D.c)
    set D.til = SquareRoot(Pow(X1 - D.X2, 2) + Pow(Y1 - D.Y2, 2)) / 650.
    call TriggerSleepAction(D.til)
    call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl", D.X2, D.Y2))
    call GroupEnumUnitsInRange(D.g, D.X2, D.Y2, 350 + 85. * (GetUnitAbilityLevel(D.c, SpellID) - 1), null)
    loop
        set t = FirstOfGroup(D.g)
    exitwhen t == null
        if IsUnitEnemy(t, GetOwningPlayer(D.c)) then
            call UnitDamageTarget(D.c, t, 125 + (50 * GetUnitAbilityLevel(D.c, SpellID)), true, false, atk, dmg, wpn)
        endif
        call GroupRemoveUnit(D.g, t)
    endloop
    call SetTimerData(tim, D)
    call TimerStart(tim, D.til, true, function AlcheBomb_Timer)
 set t = null
 set tim = null
endfunction

//===========================================================================
public function InitTrig_AlcheBomb takes nothing returns nothing  
 local trigger AlcheBomb = CreateTrigger()
  call TriggerRegisterAnyUnitEventBJ( AlcheBomb, EVENT_PLAYER_UNIT_SPELL_EFFECT )  
  call TriggerAddCondition( AlcheBomb, Condition( function AlcheBomb_Conditions ) )  
  call TriggerAddAction( AlcheBomb, function AlcheBomb_Actions )
endfunction

endscope[
Titanhex is offline   Reply With Quote
Sponsored Links - Login to hide this ad!
Old 01-28-2010, 08:37 PM   #2
Themerion
Brahms-fan
 
Themerion's Avatar
 
Join Date: Jan 2006
Posts: 642

Submissions (2)

Themerion has a spectacular aura about (114)Themerion has a spectacular aura about (114)Themerion has a spectacular aura about (114)Themerion has a spectacular aura about (114)

Default

Hello!

For a starter in vJASS, you're doing pretty well. Let me give you some pointers before we get into the real issue!

Collapse JASS:
 // Since you're using keywords, you don't need ugly prefixes in the names:

private function AlcheBomb_Conditions takes nothing returns boolean
private function AlcheBomb_Actions takes nothing returns nothing

// Scope initializers need not be public. Make it private.
public function InitTrig_AlcheBomb takes nothing returns nothing

Collapse JASS:
 // This is redundant code!
  // You have almost exactly the same thing in two places.

    call GroupEnumUnitsInRange(D.g, D.X2, D.Y2, 350 + 85. * (GetUnitAbilityLevel(D.c, SpellID) - 1), null)
    loop
        set t = FirstOfGroup(D.g)
    exitwhen t == null
        if IsUnitEnemy(t, GetOwningPlayer(D.c)) and GetWidgetLife(t) >= 1 then
            call UnitDamageTarget(D.c, t, 5 * GetUnitAbilityLevel(D.c, SpellID), true, false, atk, dmg, wpn)
            call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl", t, "origin"))
        endif
        set X1 = GetUnitX(t)
        set Y1 = GetUnitY(t)
        call GroupRemoveUnit(D.g, t)
    endloop

// =============================================
// Move the code to a separate function

function DamageUnitsInRange takes integer damage, Data d returns nothing
  // ...
endfunction

You could also do the looping in a more efficient way. The trick is to use the filterFunction as the loop, and let the groupEnum call do the loop for you. If you're interested, you can follow the link in my sig.

Concerning xefx

A very short tutorial.

Collapse JASS:
function Tutorial takes nothing returns nothing
    local unit caster = GetSpellAbilityUnit()
    local integer x = GetSpellTargetX()
    local integer y = GetSpellTargetY()
    local integer facing = 0

  // Create the effect at the point (x,y)
  // Effect will face right (0 radians)
    local xefx fx = xefx.create(x, y, facing)

  // Give the effect an appearance.
    set fx.fxpath = "Human\\DeathMissile.mdx"

    call TriggerSleepAction(3)

  // Spell is now above caster's head
    set fx.x = GetUnitX( caster )
    set fx.y = GetUnitY( caster )
    set fx.z = 200  // z means height

    call TriggerSleepAction(3)

    call fx.destroy()
    set caster = null
endfunction
__________________
Submissions::
(v)JASS Tutorial
Covers how to make fast and safe coding for common tasks in vJASS/JASS.
Creep Respawn System
It has never been easier to respawn creep groups...

Last edited by Themerion : 01-28-2010 at 09:06 PM.
Themerion is offline   Reply With Quote
Old 01-30-2010, 04:31 AM   #3
Titanhex
User
 
Join Date: Jul 2008
Posts: 34

Titanhex has little to show at this moment (5)

Default

Quick update! Thanks much, this has been very helpful and informative and I'm reading your tutorial right now. It's very helpful in learning vJASS and some general things =)

I'm trying this out and will see how I do. If I have any problems I'll post here again.
Titanhex is offline   Reply With Quote
Old 01-31-2010, 12:37 AM   #4
Titanhex
User
 
Join Date: Jul 2008
Posts: 34

Titanhex has little to show at this moment (5)

Default

Alright I'm working with a mobile fx. I'm clueless on proper mathmatics to move it towards the destination. I looked at this tutorial:
http://www.hiveworkshop.com/forums/t...apes-gui-7337/
And was checking out the line portion, but I can't wrap my head around it. :( In part because it's in GUI and in part because I never got to Trig or Calculus in highschool.

How would I move the fx from it's current target to the target point at a speed of 700. I know I'd create a timer and tell it to move a few units on a line that runs from the target caster to the target point every 0.x seconds. I just don't know how to figure out those numbers.

Last edited by Titanhex : 01-31-2010 at 12:37 AM.
Titanhex is offline   Reply With Quote
Old 01-31-2010, 01:44 AM   #5
Anitarf
Procrastination Incarnate


Development Director
 
Join Date: Feb 2004
Posts: 8,190

Submissions (19)

Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)Anitarf has a brilliant future (903)

2008 Spell olympics - Fire - SilverApproved Map: Old School Alliance TacticsHero Contest #2 - 3rd PlaceSpell making session 2 winner

Default

Well, you'd need to use trigonometry to convert your movement speed (700 multiplied by whatever your timer period is) and movement angle into usable x and y coordinate offsets.
__________________
Anitarf is offline   Reply With Quote
Old 01-31-2010, 06:22 PM   #6
Titanhex
User
 
Join Date: Jul 2008
Posts: 34

Titanhex has little to show at this moment (5)

Default

I may have to look at some example codes in order to understand this. It seems pretty simple as far as the equation would go. The destination doesn't move, and the missile moves along a straight line with a fixed course.

Alright I found a pretty worthwhile formula to use for a grenade spell. Unfortunately I don't know how to transfer the FX from the XE system from the acitons trigger into the timer trigger in order to allow it to move. Any help here?

Also, how can I optomize and make this trigger work properly?

I was thinking of running all the data inside the struct, as I've seen it done before and it doesn't seem to hard. Just make the create static method run the starting actions, then create a static method Loop and have that one run like the timer, but I'm not sure if it'll work properly, as it was done for activatables.

So any help? =) I'm looking forward to figure this out and doing this spell :) I can start my Beta map once it's done.


AlcheBomb

Collapse JASS:
scope AlcheBomb initializer Init

globals
    private constant integer    SpellID = 'bomb'
    private constant damagetype dmg     = DAMAGE_TYPE_FIRE
    private constant weapontype wpn     = WEAPON_TYPE_WHOKNOWS
    private constant attacktype atk     = ATTACK_TYPE_MAGIC
    private constant string  MODEL_PATH_MISSILE       = "Abilities\\Weapons\\BatTrollMissile\\BatTrollMissile.mdl"
    private constant string  MODEL_PATH_FLASH         = null
endglobals

private function JumpParabola takes real dist, real maxdist,real maxheight returns real
    local real t = (dist*2)/maxdist-1    
    return (-t*t+1)*maxheight
endfunction
   
private struct Data
    unit c
    real X2
    real Y2
    real til
    real dur
    group g
    real X3
    real Y3
    real maxDist
    
    static method create takes unit caster, real targX, real targY, group gro, real X3, real Y3 returns Data
     local Data D = Data.allocate()
        set D.c = caster
        set D.X2 = targX
        set D.Y2 = targY
        set D.dur = 0.
        set D.g = gro
        set D.maxDist = SquareRoot((D.X2 - D.X3)*(D.X2 - D.X3)+(D.Y2 - D.Y3)*(D.Y2 - D.Y3))
     return D
    endmethod
    
endstruct

private function Conditions takes nothing returns boolean    
    return GetSpellAbilityId() == SpellID
endfunction

private function MissileMove takes nothing returns nothing
 local timer tim = GetExpiredTimer()
 local Data D = Data(GetTimerData(tim))
 local real maxHeight = 500.
 local real cur_dist = SquareRoot((fx.x - D.X2)*(fx.x - D.X2)+(fx.y - D.Y2)*(fx.y-D.Y2))
 local real fly = JumpParabola(cur_dist, maxDist, maxHeight)//Shadow1500 jump parabola 
 local real angle = Atan2(D.X2 - GetUnitY(D.c), D.Y2 - GetUnitX(D.c))
 local real moveX              = fx.x + 15. * Cos(angle)
 local real moveY              = fx.y + 15. * Sin(angle)
 
    if curDist <= 15.0 then
        call fx.destroy
        call RemoveTimer(tim)
        //Do Damage Stuff Here
        
    else
        set fx.x = GetUnitX( moveX )
        set fx.y = GetUnitY( moveY )
        set fx.z = fly  // z means height
    endif
    
endfunction

private function Timer takes nothing returns nothing
    local timer tim = GetExpiredTimer()
    local Data D = Data(GetTimerData(tim))
    local unit t
    local real X1
    local real Y1
    if D.dur >= 5. then
        call ReleaseTimer(tim)
        call D.destroy()
    else
    call GroupEnumUnitsInRange(D.g, D.X2, D.Y2, 350 + 85. * (GetUnitAbilityLevel(D.c, SpellID) - 1), null)
    loop
        set t = FirstOfGroup(D.g)
    exitwhen t == null
        if IsUnitEnemy(t, GetOwningPlayer(D.c)) and GetWidgetLife(t) >= 1 then
            call UnitDamageTarget(D.c, t, 5 * GetUnitAbilityLevel(D.c, SpellID), true, false, atk, dmg, wpn)
            call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\FireBallMissile\\FireBallMissile.mdl", t, "origin"))
        endif
        set X1 = GetUnitX(t)
        set Y1 = GetUnitY(t)
        call GroupRemoveUnit(D.g, t)
    endloop
    set D.dur = D.dur + 1.
    endif
 set t = null
endfunction

private function Actions takes nothing returns nothing
 local timer tim = NewTimer()
 local timer tim2 = NewTimer()
 local real X1 = GetUnitX(GetTriggerUnit())
 local real Y1 = GetUnitY(GetTriggerUnit())
 local unit t 
 local real a = Atan2(GetSpellTargetX() - GetUnitY(GetTriggerUnit()), GetSpellTargetY() - GetUnitX(GetTriggerUnit()))
 local xefx fx = xefx.create(GetUnitX(GetTriggerUnit())+20.0*Cos(a), GetUnitY(GetTriggerUnit())+20.0*Sin(a), a)
 local Data D = Data.create(GetTriggerUnit(), GetSpellTargetX(), GetSpellTargetY(), CreateGroup(), fx.x, fx.y)
 
 local real til = SquareRoot(Pow(X1 - D.X2, 2) + Pow(Y1 - D.Y2, 2)) / 700.
    
    set fx.fxpath = "Abilities\\Weapons\\BatTrollMissile\\BatTrollMissile.mdl"
    
    call SetTimerData(tim, D)
    call TimerStart(tim, 0.03, true, function MissileMove)
    
    call TriggerSleepAction(til)
    call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl", D.X2, D.Y2))
    call GroupEnumUnitsInRange(D.g, D.X2, D.Y2, 150 + 65. * (GetUnitAbilityLevel(D.c, SpellID) - 1), null)
    loop
        set t = FirstOfGroup(D.g)
    exitwhen t == null
        if IsUnitEnemy(t, GetOwningPlayer(D.c)) then
            call UnitDamageTarget(D.c, t, 125 + (50 * GetUnitAbilityLevel(D.c, SpellID)), true, false, atk, dmg, wpn)
        endif
        call GroupRemoveUnit(D.g, t)
    endloop
    call SetTimerData(tim2, D)
    call TimerStart(tim2, til, true, function Timer)
 set t = null
 set tim = null
endfunction

//===========================================================================
private function Init takes nothing returns nothing  
 local trigger t = CreateTrigger()
  call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )  
  call TriggerAddCondition( t, Condition( function Conditions ) )  
  call TriggerAddAction( t, function Actions )
endfunction

endscope


Last edited by Titanhex : 01-31-2010 at 08:36 PM.
Titanhex is offline   Reply With Quote
Old 01-31-2010, 11:29 PM   #7
blanc_dummy
User
 
blanc_dummy's Avatar
 
Join Date: Jun 2007
Posts: 106

Submissions (1)

blanc_dummy has little to show at this moment (7)

Send a message via Yahoo to blanc_dummy
Default

move xefx fx to your struct instead create it as local variable
__________________
blanc_dummy is offline   Reply With Quote
Old 02-01-2010, 10:18 AM   #8
Themerion
Brahms-fan
 
Themerion's Avatar
 
Join Date: Jan 2006
Posts: 642

Submissions (2)

Themerion has a spectacular aura about (114)Themerion has a spectacular aura about (114)Themerion has a spectacular aura about (114)Themerion has a spectacular aura about (114)

Default

For linear movement in the XY-plane:

Collapse JASS:
private struct Data
    xefx fx
    real x_speed
    real y_speed
endstruct

globals
  // Move 700 each second.
    private constant real SPEED=700

  // Update 25 times per second
    private constant real TIMER_INTERVAL = 0.04

  // How much speed in each loop?
    private constant real SPEED_PER_INTERVAL = SPEED * TIMER_INTERVAL
  // 700 * 0.04 = 28
  // It runs 25 times per second, so it will move:
  // 28*25 = 700
  // each second, like we want it too.
endglobals

// Now, we know speed per loop.
// Warcraft, however, works with X and Y coordinates.
// We need to know how much to change x and y each loop.

local Data d = Data.create()
set d.fx = xefx.create( ... )

// Here's the trigonometry:

set d.x_speed = Cos(angle) * SPEED_PER_INTERVAL
set d.y_speed = Sin(angle) * SPEED_PER_INTERVAL


// And in the loop:
d.fx.x = d.fx.x + d.x_speed
d.fx.y = d.fx.y + d.y_speed
__________________
Submissions::
(v)JASS Tutorial
Covers how to make fast and safe coding for common tasks in vJASS/JASS.
Creep Respawn System
It has never been easier to respawn creep groups...
Themerion is offline   Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off


All times are GMT. The time now is 02:02 AM.


Affiliates
The Hubb The JASS Vault Clan WEnW Campaign Creations Clan CBS GamesModding Flixreel Videos

Powered by vBulletin (Copyright ©2000 - 2019, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services