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 > Resources > Code Resources > Spells
User Name
Password
Register Rules Get Hosted! Chat Pastebin FAQ and Rules Members List Calendar



Reply
 
Thread Tools Search this Thread
Old 08-30-2006, 03:31 PM   #1
Daelin
Kelani Mage
 
Daelin's Avatar
 
Join Date: Oct 2003
Posts: 737

Submissions (48)

Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)

Hero Contest - First place

Default Summon Leviathan

Summon Leviathan - Morphs a leviathan out of water, that quickly disappears if standing on land. With level, new abilities are unlocked. If cast from water, abilities have various advantages.

Aqua Rhapsody [buff spell] - If target should die while under the effect of the spell, it will be fully healed but will have its mana pool halved and will no longer be able to attack.

Coral Wisdom [chain+buff spell] - Links a couple of units together. If one of the units loses mana, the loss is split to all the units.

Sea Chant [AoE spell] - Sacrifices the caster by creating a triangle of arcane energy that drains mana from spellcasters and life from the rest. If casters are killed or channeling is stopped before spell finishes, the life&mana stolen is taken by the units around them.

Comments and suggestions like always are welcome! :)

~Daelin
Attached Images
File Type: jpg SeaChant.jpg (101.7 KB, 1100 views)
Attached Files
File Type: w3x SummonLeviathan.w3x (51.0 KB, 815 views)
__________________
I am Grand Magister Daelin Silverwing not Grand Admiral Daelin Proudmoore!!!




Last edited by Daelin : 09-02-2006 at 08:17 PM.
Daelin is offline   Reply With Quote
Sponsored Links - Login to hide this ad!
Old 08-30-2006, 06:06 PM   #2
FireFreak
User
 
Join Date: Jan 2006
Posts: 16

FireFreak has little to show at this moment (4)

Default

ok great spells.. I've seen them on the contest and I'am sure they will be approved

BUT ONCE FOR ALL!!

Collapse JASS:
function SeaChant_PointInTriangle takes real x1, real y1, real x2, real y2, real x3, real y3, real x, real y returns boolean
    local real calc1 = (y-y1)*(x2-x1) - (x-x1)*(y2-y1)
    local real calc2 = (y-y3)*(x1-x3) - (x-x3)*(y1-y3)
    local real calc3 = (y-y2)*(x3-x2) - (x-x2)*(y3-y2)
    return (calc1*calc2>0) and (calc3*calc2>0)
endfunction

is pain in my eyes and should it be for averyone who thinks he is programmer!

Collapse JASS:
function IsOriginInTriangle takes real x1,real y1,real x2,real y2,real x3,real y3 returns boolean
 local real a=x1*y2-x2*y1
 local real b=x2*y3-x3*y2
 local real c=x3*y1-x1*y3
    return (a>=0 and b>=0 and c>=0)!=(a<=0 and b<=0 and c<=0)
endfunction
function IsPointInTriangle takes real x,real y,real x1,real y1,real x2,real y2,real x3,real y3 returns boolean
    return IsOriginInTriangle(x1-x,y1-y,x2-x,y2-y,x3-x,y3-y)
endfunction

ok yours needs 15 times subtraction, 8 times real multiplication and 3comperisons
mine need 9 times subtraction, 6 times multiplication and 7 comperisons

guess whichs faster, even if you not consider that real-multi needs some* more steps then a comparison

I've seen this way of checking first done by GRATER he used it for a (convex) quad.
i needed it for a triangle and was kinda unsatisfied by vex's one (ugh tan())
there are many ways to interpret those calculation (e.g. angles,vector-product..)
the main results are:
one value == 0 and the others have the same sign:
the point is one a side of the triangle
two value == 0:
the point is in a corner of the triangle
all three value == 0
the point is on a line going through all 3 corners -> no triangle

otherwise the point is inside the triangle if a,b and c have the same sign
if you only want to know if it really inside and touch a line, you can even save some steps.
FireFreak is offline   Reply With Quote
Old 08-30-2006, 08:38 PM   #3
PipeDream
Moderator
 
PipeDream's Avatar


Code Moderator
 
Join Date: Feb 2006
Posts: 1,405

Submissions (6)

PipeDream is a glorious beacon of light (463)PipeDream is a glorious beacon of light (463)PipeDream is a glorious beacon of light (463)PipeDream is a glorious beacon of light (463)

Default

Unfortunately your speculation is wrong, wrong, wrong.
Some benchmarks on my machine:
Collapse JASS:
function IsPointInTri takes real x1, real y1, real x2, real y2, real x3, real y3, real px, real py returns boolean
//	local real ux = x2-x1	//u is vector from 1 to 2
//	local real uy = y2-y1
//	local real vx = x3-x1	//v is vector from 1 to 3
//	local real vy = y3-y1
    local real ax = px-x1    //a is vector from p to 1
    local real ay = py-y1
    local real bx = px-x2    //b is vector from p to 2
    local real by = py-y2
    local real cx = px-x3    //c is vector from p to 3
    local real cy = py-y3
//A = 1/2 | u cross v |
//Drop factor of 1/2 since we're doing a comparison
    local real area_tri = (x2-x1)*(y3-y1)-(y2-y1)*(x3-x1)
    local real area1 = ax*by-ay*bx    //area between 1 2 p
    local real area2 = bx*cy-by*cx    //area between 2 3 p
    local real area3 = cx*ay-cy*ax    //area between 3 1 p
    if area_tri < 0. then
        set area_tri = -area_tri
    endif
    if area1 < 0. then
        set area1 = -area1
    endif
    if area2 < 0. then
        set area2 = -area2
    endif
    if area3 < 0. then
        set area3 = -area3
    endif
    return area1+area2+area3 <= area_tri*1.001    //some TOL for rounding
endfunction

function SeaChant_PointInTriangle takes real x1, real y1, real x2, real y2, real x3, real y3, real x, real y returns boolean
    local real calc1 = (y-y1)*(x2-x1) - (x-x1)*(y2-y1)
    local real calc2 = (y-y3)*(x1-x3) - (x-x3)*(y1-y3)
    local real calc3 = (y-y2)*(x3-x2) - (x-x2)*(y3-y2)
    return (calc1*calc2>0) and (calc3*calc2>0)
endfunction

function IsOriginInTriangle takes real x1,real y1,real x2,real y2,real x3,real y3 returns boolean
 local real a=x1*y2-x2*y1
 local real b=x2*y3-x3*y2
 local real c=x3*y1-x1*y3
    return (a>=0 and b>=0 and c>=0)!=(a<=0 and b<=0 and c<=0)
endfunction
function IsPointInTriangle takes real x,real y,real x1,real y1,real x2,real y2,real x3,real y3 returns boolean
    return IsOriginInTriangle(x1-x,y1-y,x2-x,y2-y,x3-x,y3-y)
endfunction

function Trig_testtimer_Actions takes nothing returns nothing
    local integer stopwatch
    local integer i = 0
    local real t
    call TriggerSleepAction(0.)
    call BJDebugMsg("\nTimer test")
    set stopwatch = StopWatchCreate()

    loop
        exitwhen i >= 10000
    call IsPointInTriangle(0.,0.,0.,0.,0.,0.,0.,0.)
    call IsPointInTriangle(0.,0.,0.,0.,0.,0.,0.,0.)
    call IsPointInTriangle(0.,0.,0.,0.,0.,0.,0.,0.)
    call IsPointInTriangle(0.,0.,0.,0.,0.,0.,0.,0.)
    call IsPointInTriangle(0.,0.,0.,0.,0.,0.,0.,0.)
        set i = i + 1
    endloop

    call BJDebugMsg(R2S(StopWatchMark(stopwatch)*1000.)+"ms")

    call StopWatchDestroy(stopwatch)
endfunction
Code:
50,000 iterations
units are milliseconds
empty loop:  6 7 6
Daelin SeaChant_PointInTriangle: 502 492 496
PipeDream IsPointInTri:  761 759 763
FireFreak IsPointInTriangle:  630 635 634

Daelin's implementation is clearly fastest. You would probably be equally fast if you used local variables instead of an extra function call.
Mine would be even slower in practice since the final sets would run 50% of the time.

I'll look at the spells later.
--
benchmarking is so much more fun with no execution limit and timing natives.
Lesson here is that counting arithmetic operations is a stupid way to compare efficiency when you're within an order of magnitude.
--
The other probable reason daelin's is faster is that "and" is a bunch of ops as it's an if/then/else. a single integer multiply is pretty much irrelevantly fast, as a typical run through the VM probably has a dozen other multiplies. Same deal with those comparisons, bunch more runs through the VM.
Finally using integer arithmetic is only a percent faster. You lose all that if you try to R2I anyway, but the point is that chugging through the VM is mostly slower than any arithmetic.
__________________
PipeDream is offline   Reply With Quote
Old 08-31-2006, 11:33 AM   #4
FireFreak
User
 
Join Date: Jan 2006
Posts: 16

FireFreak has little to show at this moment (4)

Default

thats really surprising for me, but does what u say mean the != operator is slower than "and not() " ?

im busy right now, but has anyone checked how fast vex version is ?
NO i dont fear that to calls of tan beat us all
FireFreak is offline   Reply With Quote
Old 08-31-2006, 02:12 PM   #5
Daelin
Kelani Mage
 
Daelin's Avatar
 
Join Date: Oct 2003
Posts: 737

Submissions (48)

Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)

Hero Contest - First place

Default

Quote:
Originally Posted by FireFreak
is pain in my eyes and should it be for averyone who thinks he is programmer!

Aham... I never assumed that it was perfect or that it was the fastest way to do it, but clearly PipeDream's checkings proves it. How about checking it compared to Vex's too? ;)

~Daelin
__________________
I am Grand Magister Daelin Silverwing not Grand Admiral Daelin Proudmoore!!!



Daelin is offline   Reply With Quote
Old 08-31-2006, 06:29 PM   #6
blu_da_noob
Nonchalant
 
blu_da_noob's Avatar


Respected User
 
Join Date: Mar 2006
Posts: 1,933

Submissions (2)

blu_da_noob is just really nice (398)blu_da_noob is just really nice (398)blu_da_noob is just really nice (398)blu_da_noob is just really nice (398)blu_da_noob is just really nice (398)blu_da_noob is just really nice (398)

[Quicksilver #2] - 2nd Place[Quicksilver#1] 1st place

Send a message via MSN to blu_da_noob
Default

Hrmm, hrmm. Geometrical benchmarks aside...

Summon Leviathan:
JESP requires that the spell uses no spell-specific globals. Your array fits that description, no? I'm sure you could store the abilities in gamecache or something.

I'll plug myself again, and say that you could combine your triggers to prevent casting on non-water areas and the actual spell effects into one. Example: http://www.wc3campaigns.net/showthread.php?t=83132.

Aqua Rhapsody:
All things attached to public objects (eg the target of the spell) must use your spell prefix followed by "_". Eg:
Collapse JASS:
    call SetHandleInt(targ, "AquaRhapsodyOn", 1) //Spell works
//Should be:
    call SetHandleInt(targ, "AquaRhapsody_AquaRhapsodyOn", 1) //Spell works
//Or if that was already your prefix:
    call SetHandleInt(targ, "AquaRhapsody_On", 1) //Spell works

A possible better method of cleaning up the Unit Damaged trigger would be to have a condition inside the action that checks if the unit has the buff, and cleans itself up if it doesn't (so it would clean up the first time the unit is damaged without the buff).

Coral Wisdom:
Same public naming thing applies here.

I'm not sure if your chain search function is supposed to find the nearest unit, but it currently won't because you don't update the distance when you find a unit within it.

You leak a handle reference in the target search function. An easy fix in this instance is:
Collapse JASS:
    set u = targ //u is a parameter so it doesn't leak
    set targ = null
    return u
endfunction

Sea Chant:
You used the correct public naming on private objects in this one :P
__________________
blu_da_noob is offline   Reply With Quote
Old 08-31-2006, 06:59 PM   #7
PipeDream
Moderator
 
PipeDream's Avatar


Code Moderator
 
Join Date: Feb 2006
Posts: 1,405

Submissions (6)

PipeDream is a glorious beacon of light (463)PipeDream is a glorious beacon of light (463)PipeDream is a glorious beacon of light (463)PipeDream is a glorious beacon of light (463)

Default

Collapse JASS:
    set u = targ //u is a parameter so it doesn't leak
    set targ = null
    return u
endfunction
No, set will always alter the reference count of a handle. Passing via an argument doesn't use set so it doesn't alter the count, but if you then set the arg, it will alter it like any other variable. So, got to integer return bug, global, or box it up.
__________________
PipeDream is offline   Reply With Quote
Old 08-31-2006, 07:48 PM   #8
blu_da_noob
Nonchalant
 
blu_da_noob's Avatar


Respected User
 
Join Date: Mar 2006
Posts: 1,933

Submissions (2)

blu_da_noob is just really nice (398)blu_da_noob is just really nice (398)blu_da_noob is just really nice (398)blu_da_noob is just really nice (398)blu_da_noob is just really nice (398)blu_da_noob is just really nice (398)

[Quicksilver #2] - 2nd Place[Quicksilver#1] 1st place

Send a message via MSN to blu_da_noob
Default

Hmm, ok. Integer return bug it would be then.
__________________
blu_da_noob is offline   Reply With Quote
Old 09-02-2006, 11:27 AM   #9
Daelin
Kelani Mage
 
Daelin's Avatar
 
Join Date: Oct 2003
Posts: 737

Submissions (48)

Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)

Hero Contest - First place

Default

Fixed all stuff except the damage condition stuff which I won't search for it right now. But I find that it is fast enough. And I like the way I check if spell is not cast on water, but thanks for the tip. I'll keep it in mind.

~Daelin
__________________
I am Grand Magister Daelin Silverwing not Grand Admiral Daelin Proudmoore!!!



Daelin is offline   Reply With Quote
Old 09-02-2006, 06:57 PM   #10
PipeDream
Moderator
 
PipeDream's Avatar


Code Moderator
 
Join Date: Feb 2006
Posts: 1,405

Submissions (6)

PipeDream is a glorious beacon of light (463)PipeDream is a glorious beacon of light (463)PipeDream is a glorious beacon of light (463)PipeDream is a glorious beacon of light (463)

Default

great job on these spells, they are pretty clean. just a few potential problems:

- Leviathan valid displays the error message to all players
- Lots of timer nulling
- Frequently you use a TriggerSleepAction for delays, for example AquaRhapsody_Main to wait for a buff to take effect. This may work ok in single player but it will be a mixed bag online.
__________________
PipeDream is offline   Reply With Quote
Old 09-02-2006, 08:16 PM   #11
Daelin
Kelani Mage
 
Daelin's Avatar
 
Join Date: Oct 2003
Posts: 737

Submissions (48)

Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)

Hero Contest - First place

Default

Quote:
Originally Posted by PipeDream
Leviathan valid displays the error message to all players
Problem solved, simply forgot about this.

Quote:
Originally Posted by PipeDream
Lots of timer nulling
Hmm.. don't know how to fix this. Any suggestions? Would it be better if I used a repetitive trigger (call TriggerRegisterTimerEvent) or the bug still occurs?

Quote:
Originally Posted by PipeDream
Frequently you use a TriggerSleepAction for delays, for example AquaRhapsody_Main to wait for a buff to take effect. This may work ok in single player but it will be a mixed bag online.
I have no idea how waits behave online. Could you be more specific about this problem? Sorry but I never tested stuff online or on lan and it would be great if I knew of any potential problems.

Thanks for the info!

~Daelin
__________________
I am Grand Magister Daelin Silverwing not Grand Admiral Daelin Proudmoore!!!



Daelin is offline   Reply With Quote
Old 09-02-2006, 09:47 PM   #12
PipeDream
Moderator
 
PipeDream's Avatar


Code Moderator
 
Join Date: Feb 2006
Posts: 1,405

Submissions (6)

PipeDream is a glorious beacon of light (463)PipeDream is a glorious beacon of light (463)PipeDream is a glorious beacon of light (463)PipeDream is a glorious beacon of light (463)

Default

You can't expect TriggerSleepAction to do better than 50-200% of the entered time. So if you hand tuned those numbers for single player, they'll be wildly different in different multiplayer games. Maybe this doesn't matter for the spells. TriggerSleepAction has a number of other problems- time elapses while the game is paused which is ok for short waits. A more serious problem is in one map I have seen TriggerSleepAction break down and not delay at all after thirty minutes of play. But I've never seen that anywhere else, so, *shrug*.

The only solution we know of is timers/time triggers, both of which are cumbersome.
---
The least invasive method for avoiding timer nulling is something like:
Collapse JASS:
    local integer it = HtoI(CreateTimer())
    local string key = I2S(it) //or use griffen's or karukef's timer attach methods
    call StoreInteger(GC(),key,"somedata",39)
    call TimerStart(ItoT(it),...)
__________________
PipeDream is offline   Reply With Quote
Old 09-03-2006, 07:17 AM   #13
Daelin
Kelani Mage
 
Daelin's Avatar
 
Join Date: Oct 2003
Posts: 737

Submissions (48)

Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)

Hero Contest - First place

Default

Quote:
Originally Posted by PipeDream
The least invasive method for avoiding timer nulling is something like:
Collapse JASS:
    local integer it = HtoI(CreateTimer())
    local string key = I2S(it) //or use griffen's or karukef's timer attach methods
    call StoreInteger(GC(),key,"somedata",39)
    call TimerStart(ItoT(it),...)

Jesus christ... does this mean that I would have to use in timer's function something like this??

Collapse JASS:
local integer t = H2I(GetExpiredTimer())
        local unit u = GetHandleUnit(I2T(t), "u")
        if GetTimerElapsed(I2T(t))>0 then
             //blah blah
        endif
        set u = null

This is not only super unefficient (considering that the function executed by a timer is executed a LOT of times) but it also looks odd. Or, doesn't this bug manifest in timer's function but only in any other function? Please be more specific here.

~Daelin
__________________
I am Grand Magister Daelin Silverwing not Grand Admiral Daelin Proudmoore!!!



Daelin is offline   Reply With Quote
Old 09-03-2006, 07:31 AM   #14
PipeDream
Moderator
 
PipeDream's Avatar


Code Moderator
 
Join Date: Feb 2006
Posts: 1,405

Submissions (6)

PipeDream is a glorious beacon of light (463)PipeDream is a glorious beacon of light (463)PipeDream is a glorious beacon of light (463)PipeDream is a glorious beacon of light (463)

Default

Actually the unusual way you've written things may make it all work out ok.
The problems should only occur if you increase the reference count above zero by assigning and then at some time reduce it to zero while you still intend to use it. Since you typically keep the parent thread reference around and use a sleep loop to determine when to destroy, such that the reference never drops below one, you'll probably be ok, but that's speculation.

Anywhere that you are doing the more classical orphaned timer thread with no references to the timer, the alternative to ItoT is a trick discovered by Cubasis:
Collapse JASS:
function Timer_cb_authentic takes timer t returns nothing
    //Spell code goes here.  don't null t.
endfunction
function Timer_cb takes nothing returns nothing
    call Timer_cb_authentic(GetExpiredTimer())
endfunction
this works because it turns out passing a handle doesn't take it hostage.

And return bug is plenty fast in all my measurements, so fast that in a spell I don't think you would ever notice a difference.
__________________
PipeDream is offline   Reply With Quote
Old 09-03-2006, 08:26 AM   #15
Daelin
Kelani Mage
 
Daelin's Avatar
 
Join Date: Oct 2003
Posts: 737

Submissions (48)

Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)Daelin is a glorious beacon of light (474)

Hero Contest - First place

Default

So where exactly can this bug occur? Anywhere you nullify a timer? Don't point me to the thread which explains this bug cuz I obviously did not get this aspect.

~Daelin
__________________
I am Grand Magister Daelin Silverwing not Grand Admiral Daelin Proudmoore!!!



Daelin 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 04:03 PM.


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

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