| 05-05-2006, 12:41 AM | #1 |
alright, here is the code, its a doozy JASS:function Bouncy_Ball_Smaller takes nothing returns real return .05 //factor for use with bounce distance size reducing endfunction //Example of how it works: //Each bounces maxdist is divided by a variable x after each bounce to make it smaller, and x is doubled after each bounce //This variable x is determined by x=2-[(channel time)*Bouncy_Ball_Smaller()] //For example, if you were to channel for 5 seconds, x would be 2-(5*.05)=1.75, thus each each bounce distance would be 75% smaller //At the max channel length(10 as it stands), x=1.5, thus each bounce distance is 50% smaller each time function Bouncy_Ball_Distance takes nothing returns real return 75. //smallest distance between ball and next bounce location before it is removed endfunction function Bouncy_Ball_ID takes nothing returns integer return 'n000' // Bouncy Ball Rawcode endfunction function Bounce_Ball_Rawcode takes nothing returns integer return 'A002' //Rawcode of Bouncy Ball Channel Ability endfunction function Trig_Bouncy_Ball_Channel_Conditions takes nothing returns boolean return GetSpellAbilityId() == 'A002' //Rawcode of Bouncy Ball Channel Ability endfunction function Bouncy_Ball_Max_Duration takes nothing returns real return 10. // max channel length endfunction function Bouncy_Ball_Damageing takes integer level returns integer return level*70 // damage endfunction function Bouncy_Ball_Area takes nothing returns real return 70. // damage area endfunction //###################################################// function Bouncy_Ball_Conditions takes nothing returns boolean return GetSpellAbilityId() == 'A002' endfunction function Bouncy_Ball_Parabola takes real dist, real maxdist,real curve returns real local real t = (dist*2)/maxdist-1 return (-t*t+1)*(maxdist/curve) endfunction function Bouncy_Ball_Filter takes nothing returns boolean return IsUnitEnemy(GetFilterUnit(), bj_groupEnumOwningPlayer)==true endfunction function Bouncy_Ball_Damage takes unit damageUnit, real radius, real x, real y, real amount, boolean attack, boolean ranged, attacktype attackType, damagetype damageType, weapontype weaponType returns nothing local group g = CreateGroup() local boolexpr b = Condition(function Bouncy_Ball_Filter) local unit u set bj_groupEnumOwningPlayer = GetOwningPlayer(damageUnit) call GroupEnumUnitsInRange(g, x, y, radius, b) call DestroyBoolExpr(b) loop set u = FirstOfGroup(g) exitwhen u == null call GroupRemoveUnit(g,u) call UnitDamageTarget(damageUnit,u,amount,attack, ranged,attackType,damageType,weaponType) endloop call DestroyGroup(g) set g = null set b = null endfunction function Ball_Init_Bounce takes nothing returns nothing local timer t = GetExpiredTimer() local unit ball = GetHandleUnit(t,"ball") local real ang = GetHandleReal(t,"ang") local real maxdist = GetHandleReal(t,"maxdist") local real movedist = GetHandleReal(t,"movedist") local real xtarg = GetHandleReal(t,"xtarg") local real ytarg = GetHandleReal(t,"ytarg") local real x = GetUnitX(ball) local real y = GetUnitY(ball) local real dist = SquareRoot((x-xtarg)*(x-xtarg) + (y-ytarg)*(y-ytarg)) local real height = JumpUnit_Parabola(dist,maxdist,1.5) local integer i = GetHandleInt(t,"i") call SetUnitPosition(ball, x + movedist * Cos(ang * bj_DEGTORAD) , y + movedist * Sin(ang * bj_DEGTORAD)) call SetUnitFlyHeight(ball,height,null) call SetHandleInt(t,"i",i + 1) if i == 100 then call PauseTimer(t) call FlushHandleLocals(t) call DestroyTimer(t) call Bouncy_Ball_Damage( ball, Bouncy_Ball_Area(), GetUnitX(ball), GetUnitY(ball), GetHandleInt(ball,"damage"), false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null) endif set ball = null endfunction function Ball_After_Bounce_Child takes nothing returns nothing local timer t = GetExpiredTimer() local unit ball = GetHandleUnit(t,"ball") local real ang = GetHandleReal(t,"ang") local real maxdist = GetHandleReal(t,"maxdist") local real movedist = GetHandleReal(t,"movedist") local real xtarg = GetHandleReal(t,"xtarg") local real ytarg = GetHandleReal(t,"ytarg") local real x = GetUnitX(ball) local real y = GetUnitY(ball) local real dist = SquareRoot((x-xtarg)*(x-xtarg) + (y-ytarg)*(y-ytarg)) local real height = JumpUnit_Parabola(dist,maxdist,1.5) local integer i = GetHandleInt(t,"i") call SetUnitPosition(ball, x + movedist * Cos(ang * bj_DEGTORAD) , y + movedist * Sin(ang * bj_DEGTORAD)) call SetUnitFlyHeight(ball,height,null) call SetHandleInt(t,"i",i + 1) if i == 100 then call SetUnitFlyHeight(ball,GetUnitDefaultFlyHeight(ball),9999) call PauseTimer(t) call FlushHandleLocals(t) call DestroyTimer(t) call Bouncy_Ball_Damage( ball, Bouncy_Ball_Area(), GetUnitX(ball), GetUnitY(ball), GetHandleInt(ball,"damage"), false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null) endif set ball = null endfunction function Ball_After_Bounce takes nothing returns nothing local timer t2 = GetExpiredTimer() local timer t = CreateTimer() local unit ball = GetHandleUnit(t2,"ball") local real ang = GetHandleReal(t2,"ang") local real smaller = GetHandleReal(t2,"smaller") local real maxdist = GetHandleReal(t2,"maxdist")/smaller local real movedist = maxdist/100 local real xtarg = GetUnitX(ball) + maxdist * Cos(ang * bj_DEGTORAD) local real ytarg = GetUnitY(ball) + maxdist * Sin(ang * bj_DEGTORAD) if maxdist<Bouncy_Ball_Distance() then call SetUnitFlyHeight(ball,GetUnitDefaultFlyHeight(ball),9999) call PauseTimer(t2) call FlushHandleLocals(t2) call DestroyTimer(t2) call FlushHandleLocals(ball) call KillUnit(ball) else call SetHandleReal(t,"maxdist", maxdist) call SetHandleReal(t,"movedist",movedist) call SetHandleReal(t,"ang",ang) call SetHandleReal(t,"xtarg",xtarg) call SetHandleReal(t,"ytarg",ytarg) call SetHandleHandle(t,"ball",ball) call SetHandleInt(t,"i",0) call TimerStart(t,GetHandleReal(t2,"speed"),true,function Ball_After_Bounce_Child) call SetHandleReal(t2,"smaller",smaller+GetHandleReal(t2,"smallerchange")) endif set ball = null endfunction function Bouncy_Ball_Actions takes nothing returns nothing local trigger stopchan = GetTriggeringTrigger() local timer t = CreateTimer() local timer t2 = CreateTimer() local timer tchan = GetHandleTimer(stopchan,"tchan") local unit u = GetHandleUnit(stopchan,"u") local real time = TimerGetElapsed(tchan) local real x = GetUnitX(u) local real y = GetUnitY(u) local real xtarg = GetHandleReal(stopchan,"xtarg") local real ytarg = GetHandleReal(stopchan,"ytarg") local real ang = bj_RADTODEG * Atan2(ytarg - y, xtarg - x) local real dist = SquareRoot((x-xtarg)*(x-xtarg) + (y-ytarg)*(y-ytarg)) local unit ball = CreateUnit(GetOwningPlayer(u),Bouncy_Ball_ID(),x + 50 * Cos(ang * bj_DEGTORAD),y + 50 * Sin(ang * bj_DEGTORAD),0) local real speed = .015 - (time/1000) call UnitAddAbility( ball,'A000' ) call UnitRemoveAbility( ball,'A000' ) call PauseTimer(tchan) call DestroyTimer(tchan) call SetHandleInt(ball,"damage",Bouncy_Ball_Damageing(GetUnitAbilityLevel(u,Bounce_Ball_Rawcode()))) call SetHandleReal(t,"maxdist", dist) call SetHandleReal(t,"movedist",dist/100) call SetHandleReal(t,"ang",ang) call SetHandleReal(t,"xtarg",xtarg) call SetHandleReal(t,"ytarg",ytarg) call SetHandleHandle(t,"ball",ball) call SetHandleInt(t,"i",0) call TimerStart(t,speed,true,function Ball_Init_Bounce) call SetHandleReal(t2,"maxdist", dist) call SetHandleReal(t2,"ang",ang) call SetHandleReal(t2,"xtarg",xtarg + dist * Cos(ang * bj_DEGTORAD)) call SetHandleReal(t2,"ytarg",ytarg + dist * Sin(ang * bj_DEGTORAD)) call SetHandleHandle(t2,"ball",ball) call SetHandleReal(t2,"smaller",2-(time*Bouncy_Ball_Smaller())) call SetHandleReal(t2,"smallerchange",2-(time*Bouncy_Ball_Smaller())) call SetHandleReal(t2,"speed",speed) call TimerStart(t2,speed*100,true,function Ball_After_Bounce) call FlushHandleLocals(stopchan) call DestroyTrigger(stopchan) set u = null set ball = null set stopchan = null set tchan = null set stopchan = null endfunction function Trig_Bouncy_Ball_Channel_Actions takes nothing returns nothing local unit u = GetTriggerUnit() local trigger stopchan = CreateTrigger() local location l = GetSpellTargetLoc() local real xtarg = GetLocationX(l) local real ytarg = GetLocationY(l) local timer tchan = CreateTimer() call TimerStart(tchan,Bouncy_Ball_Max_Duration()+1,false,null) call TriggerRegisterUnitEvent( stopchan,u, EVENT_UNIT_SPELL_ENDCAST ) call TriggerAddCondition( stopchan, Condition( function Bouncy_Ball_Conditions ) ) call TriggerAddAction( stopchan, function Bouncy_Ball_Actions ) call SetHandleHandle(stopchan,"u",u) call SetHandleHandle(stopchan,"tchan",tchan) call SetHandleReal(stopchan,"xtarg",xtarg) call SetHandleReal(stopchan,"ytarg",ytarg) call RemoveLocation(l) set l = null endfunction //=========================================================================== function InitTrig_Bouncy_Ball_Channel takes nothing returns nothing set gg_trg_Bouncy_Ball_Channel = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Bouncy_Ball_Channel, EVENT_PLAYER_UNIT_SPELL_CHANNEL ) call TriggerAddCondition( gg_trg_Bouncy_Ball_Channel, Condition( function Trig_Bouncy_Ball_Channel_Conditions ) ) call TriggerAddAction( gg_trg_Bouncy_Ball_Channel, function Trig_Bouncy_Ball_Channel_Actions ) endfunction basically u target a point, and channel for up to 10 seconds, when u break chaneling u throw a ball in that direction,, which bounces(dealing damage on each), progressively smaller, untill they are real small and the ball is destroyed, the longer you channel, the farther the distance between each bounce, and the faster the bounces are suposed to be everything worked up until the point where i tried to make the ball go faster the longer you channeled, which is determinend here(in function Bouncy_Ball_Actions) local real time = TimerGetElapsed(tchan) local real speed = .015 - (time/1000) call TimerStart(t,speed,true,function Ball_Init_Bounce) that starts the first bounce, a total of 100 executions are ran, at time speed now I start a second timer that runs once the first timer has run 100 times, and through the equation call TimerStart(t2,speed*100,true,function Ball_After_Bounce) now that timer keeps the ball bouncing until it is time it is to be destroyed i set my speed into that timer call SetHandleReal(t2,"speed",speed) and start another 100 exection timer in there call TimerStart(t,GetHandleReal(t2,"speed"),true,function Ball_After_Bounce_Child) at the same speed now before I tried this, it worked fine, now however the shorter you channel for, the slower the ball bounces, but the farther it goes, but the longer you channel, the faster it bounces, but shorter it goes where the distance between bounces should have never changed, just the speed at which it does so any ideas...?? |
| 05-05-2006, 10:37 PM | #2 |
Don't be intimidated by 249 lines of code. This spell is really sweet and I think a lot of people could put it to good use. Let me add another glitch. Between the first bounce and the second the ball kind of lags/glitches. Its like lag in a FPS. After that its fine though. |
| 05-06-2006, 02:37 AM | #3 |
im with stupid |
| 05-06-2006, 07:03 AM | #4 |
Hey now :( |
| 05-06-2006, 07:59 AM | #5 |
Probably because he is determining the timer's speed by the channeling time, if the timer speed is that low, even lower than .01, it can cause lags. |
| 05-06-2006, 03:30 PM | #6 |
I don't think you need 2 timers at all. Could you please show the first version the one that worked well ? I can then add acceleration correctly |
| 05-06-2006, 06:36 PM | #7 |
for the version that worked corretly, instead of using the formula I did to change the timer length, just use .01 both times, that is the only thing that was changed call TimerStart(t,GetHandleReal(t2,"speed"),true,function Ball_After_Bounce_Child) and call TimerStart(t,speed,true,function Ball_Init_Bounce) and change this to 1. call TimerStart(t2,speed*100,true,function Ball_After_Bounce) which is the total length for each bounce(.01*100 executions) that is all that I changed :( before then it worked perfectly |
| 05-08-2006, 08:19 AM | #8 |
I don't know a lot about JASS, but I can tell what those lines do and fail to see why they fuck up the whole spell. BTW, any ideas emjlr3 about what is causing that lag between first and second bounce? |
| 05-08-2006, 04:20 PM | #9 |
still no lclue, the only thing I could guess is that the timers are not quite as accurate as we would like here, since the one is runnign every .01, 100 times, so should last 1 second, and the other starts and runs every 1., thus that should start where the last one ends, maybe something with the fly height being screwed up, but I really dont feel liek messing with it anymore unless we can find out if it can be fixed |
| 05-09-2006, 03:13 AM | #10 |
I hope Vexorian comes back to check up on this soon. The only thing that I can think of is that .01 is causing problems. |
| 05-17-2006, 09:34 PM | #11 |
Bump from page 4 |
