| 03-16-2009, 09:35 AM | #1 |
i have a spell that knockbacks every units is front of the caster. but somehow, it knockbacks the unit instantly. It doesnt move. Heres the code: JASS:scope Bash globals private constant integer BASH_ABILITY_ID = 'A008' private constant string BASH_CAST_EFFECT = "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl" private constant string BASH_CAST_ATTACH_1 = "hand,left" private constant string BASH_CAST_ATTACH_2 = "hand,right" private constant string BASH_SLIDING_EFFECT = "Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" private constant string BASH_SLIDING_ATTACH = "origin" private constant real MS_SLIDE_REDUCTION = 0.50 // IN PERCENTAGE // private constant attacktype ATTACK_TYPE = ATTACK_TYPE_SIEGE private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS private constant integer MAXIMUM_PUSHED = 250 endglobals private function Damage takes integer lvl returns real if lvl == 1 then return 120.00 // DAMAGE AT LEVEL 1 // elseif lvl == 2 then return 200.00 // DAMAGE AT LEVEL 2 // elseif lvl == 3 then return 320.00 // DAMAGE AT LEVEL 3 // elseif lvl == 4 then return 400.00 // DAMAGE AT LEVEL 4 // endif return 490.00 // DAMAGE AT LEVEL 5 // endfunction private function Distance takes integer lvl returns real if lvl == 1 then return 300.00 // KNOCKBACK DISTANCE AT LEVEL 1 // elseif lvl == 2 then return 350.00 // KNOCKBACK DISTANCE AT LEVEL 2 // elseif lvl == 3 then return 400.00 // KNOCKBACK DISTANCE AT LEVEL 3 // elseif lvl == 4 then return 450.00 // KNOCKBACK DISTANCE AT LEVEL 4 // endif return 500.00 // KNOCKBACK DISTANCE AT LEVEL 5 // endfunction private struct Bash unit caster real cx real cy integer num = 0 unit array target [ MAXIMUM_PUSHED ] real array tx [ MAXIMUM_PUSHED ] real array ty [ MAXIMUM_PUSHED ] real array n [ MAXIMUM_PUSHED ] real array cos [ MAXIMUM_PUSHED ] real array sin [ MAXIMUM_PUSHED ] real array rate [ MAXIMUM_PUSHED ] real array dec [ MAXIMUM_PUSHED ] real distance static method Move takes nothing returns boolean local Bash b = TT_GetData() local boolean flag = false local integer i = 0 local real x local real y local real nx local real ny loop set i = i + 1 set x = GetUnitX( b.target[ i ] ) set y = GetUnitY( b.target[ i ] ) call DestroyEffect( AddSpecialEffectTarget( BASH_SLIDING_EFFECT, b.target[ i ], BASH_SLIDING_ATTACH ) ) set nx = x + b.rate * b.cos[ i ] set ny = y + b.rate * b.sin[ i ] call SetUnitPosition( b.target[ i ], nx, ny ) set b.n[ i ] = b.n[ i ] + b.rate set b.rate[ i ] = b.rate[ i ] - b.dec[ i ] if b.rate[ i ] <= 0.00 or b.n[ i ] >= b.distance then call PauseUnit( b.target[ i ], false ) set b.target[ i ] = null set b.num = b.num - 1 endif exitwhen i >= b.num endloop if b.num <= 0 then set flag = true endif return flag endmethod static method Actions takes nothing returns nothing local Bash b = Bash.create() local real q = 1.00 / TT_PERIOD local group g = CreateGroup() local unit u = null local real angle local integer lvl local real damage set b.caster = GetTriggerUnit() set b.cx = GetUnitX( b.caster ) set b.cy = GetUnitY( b.caster ) set lvl = GetUnitAbilityLevel( b.caster, BASH_ABILITY_ID ) set damage = Damage( lvl ) set b.distance = Distance( lvl ) set g = UnitsInFront( b.caster, 225.00 ) loop set u = FirstOfGroup( g ) if IsUnitEnemy( u, GetOwningPlayer( b.caster ) ) == true and IsUnitType( u, UNIT_TYPE_STRUCTURE ) == false and IsUnitType( u, UNIT_TYPE_FLYING ) == false then set b.num = b.num + 1 set b.n[ b.num ] = 0.00 set b.target[ b.num ] = u set b.tx[ b.num ] = GetUnitX( b.target[ b.num ] ) set b.ty[ b.num ] = GetUnitY( b.target[ b.num ] ) set angle = bj_RADTODEG * Atan2( b.ty[ b.num ] - b.cy , b.tx[ b.num ] - b.cx ) set b.cos[ b.num ] = Cos( angle * bj_DEGTORAD ) set b.sin[ b.num ] = Sin( angle * bj_DEGTORAD ) set b.rate[ b.num ] = ( 2 * b.distance ) / ( q + 1 ) set b.dec[ b.num ] = b.rate[ b.num ] / q call BJDebugMsg( I2S( b.num ) + ", b.rate : " + R2S( b.rate[ b.num ] ) ) call BJDebugMsg( I2S( b.num ) + ", b.dec : " + R2S( b.dec[ b.num ] ) ) call UnitDamageTarget( b.caster, b.target[ b.num ], damage, true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE ) call PauseUnit( b.target[ b.num ], true ) endif exitwhen u == null call GroupRemoveUnit( g, u ) endloop call DestroyEffect( AddSpecialEffectTarget( BASH_CAST_EFFECT, b.caster, BASH_CAST_ATTACH_1 ) ) call DestroyEffect( AddSpecialEffectTarget( BASH_CAST_EFFECT, b.caster, BASH_CAST_ATTACH_2 ) ) call TT_Start( function Bash.Move, b ) call DestroyGroup( g ) set g = null endmethod static method Check_ID takes nothing returns boolean return GetSpellAbilityId() == BASH_ABILITY_ID endmethod //=========================================================================== static method onInit takes nothing returns nothing local trigger B = CreateTrigger( ) local integer i = 0 loop exitwhen i > 15 call TriggerRegisterPlayerUnitEvent( B, Player( i ), EVENT_PLAYER_UNIT_SPELL_EFFECT, Condition( function True ) ) set i = i + 1 endloop call TriggerAddCondition( B, Condition( function Bash.Check_ID ) ) call TriggerAddAction( B, function Bash.Actions ) set B = null call Preload( BASH_SLIDING_EFFECT ) call Preload( BASH_CAST_ATTACH_1 ) call Preload( BASH_CAST_ATTACH_2 ) call Preload( BASH_CAST_EFFECT ) call Preload( BASH_SLIDING_ATTACH ) endmethod endstruct endscope The Debug Messages display the right thing but it knockbacks too fast, almost (actually really)instantly Also for some reason, the distance it knockbacks increases with every cast of the spell.. Can anyone help? [ + rep ] EDIT: I also followed the efficient knockback tutorial in this spell. |
| 03-16-2009, 10:18 AM | #2 |
b.rate should probably be b.rate[i] in your periodic function. |
| 03-16-2009, 12:56 PM | #3 |
Why bother with arrays, why not have a struct per knockbacked unit instead? Would simplify the code a bit and reduce the chance of such errors. |
| 03-16-2009, 01:01 PM | #4 |
u use a loop, loop is "instant", so ye. u have to use a time delayed method. which isnt loop but timer |
| 03-16-2009, 02:04 PM | #5 |
JASS:private function Distance takes integer lvl returns real if lvl == 1 then return 300.00 // KNOCKBACK DISTANCE AT LEVEL 1 // elseif lvl == 2 then return 350.00 // KNOCKBACK DISTANCE AT LEVEL 2 // elseif lvl == 3 then return 400.00 // KNOCKBACK DISTANCE AT LEVEL 3 // elseif lvl == 4 then return 450.00 // KNOCKBACK DISTANCE AT LEVEL 4 // endif return 500.00 // KNOCKBACK DISTANCE AT LEVEL 5 // endfunction Can easilly be optimized into: JASS:private function Distance takes integer lvl returns real return lvl * 50. + 250. endfunction |
| 03-17-2009, 01:39 PM | #6 | |
actually Viikuna's suggestion worked. Quote:
Thanks for the suggestion every one! :D |
| 03-17-2009, 04:37 PM | #7 |
Little mistakes like that are really anoying and really hard to spot, because when you read your own code, you dont only use your eyes but also your memory ( so you see what you want to see ). Just debug your code properly and use some logic. If knocback is nearly instant, the velocity variable is the first thing you should check. |
